#include "common/dout.h"
+#include "common/HeartbeatMap.h"
+
#include "messages/MMDSBeacon.h"
#include "mon/MonClient.h"
sender = new C_MDS_BeaconSender(this);
timer.add_event_after(g_conf->mds_beacon_interval, sender);
+ if (!cct->get_heartbeat_map()->is_healthy()) {
+ /* If anything isn't progressing, let avoid sending a beacon so that
+ * the MDS will consider us laggy */
+ dout(1) << __func__ << " skipping beacon, heartbeat map not healthy" << dendl;
+ return;
+ }
+
++last_seq;
dout(10) << __func__ << " " << ceph_mds_state_name(want_state)
<< " seq " << last_seq
#include "common/ceph_argparse.h"
#include "common/errno.h"
-
#include "msg/Messenger.h"
#include "mon/MonClient.h"
#include "InoTable.h"
+#include "common/HeartbeatMap.h"
+
#include "common/perf_counters.h"
#include "common/Timer.h"
Dispatcher(m->cct),
mds_lock("MDS::mds_lock"),
timer(m->cct, mds_lock),
+ hb(NULL),
beacon(m->cct, mc, n),
authorize_handler_cluster_registry(new AuthAuthorizeHandlerRegistry(m->cct,
m->cct->_conf->auth_supported.length() ?
finisher(cct),
sessionmap(this), asok_hook(NULL) {
+ hb = cct->get_heartbeat_map()->add_worker("MDS");
+
orig_argc = 0;
orig_argv = NULL;
if (messenger)
delete messenger;
+
+ if (hb) {
+ cct->get_heartbeat_map()->remove_worker(hb);
+ }
}
class MDSSocketHook : public AdminSocketHook {
} else if (command == "session ls") {
mds_lock.Lock();
+ heartbeat_reset();
+
// Dump sessions, decorated with recovery/replay status
f->open_array_section("sessions");
const ceph::unordered_map<entity_name_t, Session*> session_map = sessionmap.get_sessions();
void MDS::tick()
{
+ heartbeat_reset();
+
tick_event = 0;
// reschedule
// shut down messenger
messenger->shutdown();
+
+ // Workaround unclean shutdown: HeartbeatMap will assert if
+ // worker is not removed (as we do in ~MDS), but ~MDS is not
+ // always called after suicide.
+ if (hb) {
+ cct->get_heartbeat_map()->remove_worker(hb);
+ hb = NULL;
+ }
}
void MDS::respawn()
{
bool ret;
mds_lock.Lock();
+
+ heartbeat_reset();
+
if (want_state == CEPH_MDS_STATE_DNE) {
dout(10) << " stopping, discarding " << *m << dendl;
m->put();
dout(1) << " " << this->mds_lock.is_locked_by_me() << dendl;
ls.front()->complete(0);
ls.pop_front();
+
+ heartbeat_reset();
}
}
dout(7) << " processing laggy deferred " << *old << dendl;
handle_deferrable_message(old);
}
+
+ heartbeat_reset();
}
// done with all client replayed requests?
beacon.notify_want_state(newstate);
}
}
+
+/**
+ * Call this when you take mds_lock, or periodically if you're going to
+ * hold the lock for a long time (e.g. iterating over clients/inodes)
+ */
+void MDS::heartbeat_reset()
+{
+ assert(hb != NULL);
+ // NB not enabling suicide grace, because the mon takes care of killing us
+ // (by blacklisting us) when we fail to send beacons, and it's simpler to
+ // only have one way of dying.
+ cct->get_heartbeat_map()->reset_timeout(hb, g_conf->mds_beacon_grace, 0);
+}
+