.set_default(true)
.set_description("MDS will abort if dentry is detected newly corrupted."),
+ Option("mds_inject_rename_corrupt_dentry_first", Option::TYPE_FLOAT, Option::LEVEL_DEV)
+ .set_default(0.0)
+ .set_flag(Option::FLAG_RUNTIME)
+ .set_description("probabilistically inject corrupt CDentry::first at rename"),
+
+ Option("mds_inject_journal_corrupt_dentry_first", Option::TYPE_FLOAT, Option::LEVEL_DEV)
+ .set_default(0.0)
+ .set_flag(Option::FLAG_RUNTIME)
+ .set_description("probabilistically inject corrupt CDentry::first at journal load"),
+
Option("mds_kill_mdstable_at", Option::TYPE_INT, Option::LEVEL_DEV)
.set_default(0)
.set_description(""),
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_cap_acquisition_throttle_retry_request_time",
"mds_alternate_name_max",
"mds_dir_max_entries",
+ "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);
const std::string& option, const std::string& value,
std::ostream& ss);
+ 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.
Context *suicide_hook;
bool standby_replaying = false; // true if current replay pass is in standby-replay mode
+ 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 entries per directory changed to "
<< dir_max_entries << 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);
unsigned delegate_inos_pct = 0;
uint64_t dir_max_entries = 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();
}