mount_cond.Signal();
remove_session_caps(s);
kick_requests_closed(s);
+ mds_ranks_closing.erase(s->mds_num);
mds_sessions.erase(s->mds_num);
}
for (auto &p : mds_sessions) {
if (p.second.state != MetaSession::STATE_CLOSING) {
_close_mds_session(&p.second);
+ mds_ranks_closing.insert(p.first);
}
}
// wait for sessions to close
- ldout(cct, 2) << "waiting for " << mds_sessions.size() << " mds sessions to close" << dendl;
- mount_cond.Wait(client_lock);
+ double timo = cct->_conf.get_val<std::chrono::seconds>("client_shutdown_timeout").count();
+ ldout(cct, 2) << "waiting for " << mds_ranks_closing.size() << " mds session(s) to close (timeout: "
+ << timo << "s)" << dendl;
+ if (!timo) {
+ mount_cond.Wait(client_lock);
+ } else {
+ int r = 0;
+ utime_t t;
+ t.set_from_double(timo);
+ while (!mds_ranks_closing.empty() && r == 0) {
+ r = mount_cond.WaitInterval(client_lock, t);
+ }
+ if (r != 0) {
+ ldout(cct, 1) << mds_ranks_closing.size() << " mds(s) did not respond to session close -- timing out." << dendl;
+ while (!mds_ranks_closing.empty()) {
+ auto session = mds_sessions.at(*mds_ranks_closing.begin());
+ // this prunes entry from mds_sessions and mds_ranks_closing
+ _closed_mds_session(&session);
+ }
+ }
+ }
+
+ mds_ranks_closing.clear();
}
}
// mds sessions
map<mds_rank_t, MetaSession> mds_sessions; // mds -> push seq
+
+ std::set<mds_rank_t> mds_ranks_closing; // mds ranks currently tearing down sessions
list<Cond*> waiting_for_mdsmap;
// FSMap, for when using mds_command
Option("debug_allow_any_pool_priority", Option::TYPE_BOOL, Option::LEVEL_DEV)
.set_default(false)
.set_description("Allow any pool priority to be set to test conversion to new range"),
+
+ Option("client_shutdown_timeout", Option::TYPE_SECS, Option::LEVEL_ADVANCED)
+ .set_flag(Option::FLAG_RUNTIME)
+ .set_default(30)
+ .set_min(0)
+ .set_description("timeout for shutting down CephFS")
+ .set_long_description("Timeout for shutting down CephFS via unmount or shutdown.")
+ .add_tag("client")
});
}