services:
- mds
fmt_desc: MDS will abort if dentry is detected newly corrupted.
+- name: mds_inject_rename_corrupt_dentry_first
+ type: float
+ level: dev
+ default: 0.0
+ services:
+ - mds
+ fmt_desc: probabilistically inject corrupt CDentry::first at rename
+ flags:
+ - runtime
+- name: mds_inject_journal_corrupt_dentry_first
+ type: float
+ level: dev
+ default: 0.0
+ services:
+ - mds
+ fmt_desc: probabilistically inject corrupt CDentry::first at journal load
+ flags:
+ - runtime
- name: mds_kill_mdstable_at
type: int
level: dev
messenger(msgr), monc(monc_), mgrc(mgrc),
respawn_hook(respawn_hook_),
suicide_hook(suicide_hook_),
+ inject_journal_corrupt_dentry_first(g_conf().get_val<double>("mds_inject_journal_corrupt_dentry_first")),
starttime(mono_clock::now()),
ioc(ioc)
{
"mds_dir_max_entries",
"mds_symlink_recovery",
"mds_extraordinary_events_dump_interval",
+ "mds_inject_rename_corrupt_dentry_first",
+ "mds_inject_journal_corrupt_dentry_first",
NULL
};
return KEYS;
changed.count("fsid")) {
update_log_config();
}
+ if (changed.count("mds_inject_journal_corrupt_dentry_first")) {
+ inject_journal_corrupt_dentry_first = g_conf().get_val<double>("mds_inject_journal_corrupt_dentry_first");
+ }
finisher->queue(new LambdaContext([this, changed](int) {
std::scoped_lock lock(mds_lock);
std::ostream& ss);
void schedule_inmemory_logger();
+ double get_inject_journal_corrupt_dentry_first() const {
+ return inject_journal_corrupt_dentry_first;
+ }
+
// Reference to global MDS::mds_lock, so that users of MDSRank don't
// carry around references to the outer MDS, and we can substitute
// a separate lock here in future potentially.
bool standby_replaying = false; // true if current replay pass is in standby-replay mode
uint64_t extraordinary_events_dump_interval = 0;
+ double inject_journal_corrupt_dentry_first = 0.0;
private:
bool send_status = true;
Server::Server(MDSRank *m, MetricsHandler *metrics_handler) :
mds(m),
mdcache(mds->mdcache), mdlog(mds->mdlog),
+ inject_rename_corrupt_dentry_first(g_conf().get_val<double>("mds_inject_rename_corrupt_dentry_first")),
recall_throttle(g_conf().get_val<double>("mds_recall_max_decay_rate")),
metrics_handler(metrics_handler)
{
dout(20) << __func__ << " max fragment size changed to "
<< bal_fragment_size_max << dendl;
}
+ if (changed.count("mds_inject_rename_corrupt_dentry_first")) {
+ inject_rename_corrupt_dentry_first = g_conf().get_val<double>("mds_inject_rename_corrupt_dentry_first");
+ }
}
/*
mdcache->journal_cow_dentry(mdr.get(), metablob, destdn, CEPH_NOSNAP, 0, destdnl);
destdn->first = mdcache->get_global_snaprealm()->get_newest_seq() + 1;
+ {
+ auto do_corruption = inject_rename_corrupt_dentry_first;
+ if (unlikely(do_corruption > 0.0)) {
+ auto r = ceph::util::generate_random_number(0.0, 1.0);
+ if (r < do_corruption) {
+ dout(0) << "corrupting dn: " << *destdn << dendl;
+ destdn->first = -10;
+ }
+ }
+ }
if (destdn->is_auth())
metablob->add_primary_dentry(destdn, srci, true, true);
uint64_t dir_max_entries = 0;
int64_t bal_fragment_size_max = 0;
+ double inject_rename_corrupt_dentry_first = 0.0;
+
DecayCounter recall_throttle;
time last_recall_state;
in->state_clear(CInode::STATE_AUTH);
ceph_assert(g_conf()->mds_kill_journal_replay_at != 2);
+ {
+ auto do_corruption = mds->get_inject_journal_corrupt_dentry_first();
+ if (unlikely(do_corruption > 0.0)) {
+ auto r = ceph::util::generate_random_number(0.0, 1.0);
+ if (r < do_corruption) {
+ dout(0) << "corrupting dn: " << *dn << dendl;
+ dn->first = -10;
+ }
+ }
+ }
+
if (!(++count % mds->heartbeat_reset_grace()))
mds->heartbeat_reset();
}