From 45638cb81a8cfd7be1aa415610e512df948f7a51 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 18 Mar 2015 17:42:54 +0000 Subject: [PATCH] mds: implement Beacon::send_and_wait For callers that want to send a beacon, and then wait up to some timeout for a response from the mon. Specifically, shutdown handlers. Signed-off-by: John Spray --- src/mds/Beacon.cc | 27 ++++++++++++++++++++++++++- src/mds/Beacon.h | 10 ++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/mds/Beacon.cc b/src/mds/Beacon.cc index 5d6084391b7c4..e56a6362083e3 100644 --- a/src/mds/Beacon.cc +++ b/src/mds/Beacon.cc @@ -32,7 +32,8 @@ Beacon::Beacon(CephContext *cct_, MonClient *monc_, std::string name_) : - Dispatcher(cct_), lock("Beacon"), monc(monc_), timer(g_ceph_context, lock), name(name_) + Dispatcher(cct_), lock("Beacon"), monc(monc_), timer(g_ceph_context, lock), + name(name_), awaiting_seq(-1) { want_state = MDSMap::STATE_NULL; last_seq = 0; @@ -131,6 +132,11 @@ void Beacon::handle_mds_beacon(MMDSBeacon *m) while (!seq_stamp.empty() && seq_stamp.begin()->first <= seq) seq_stamp.erase(seq_stamp.begin()); + + // Wake a waiter up if present + if (awaiting_seq == seq) { + waiting_cond.Signal(); + } } else { dout(10) << "handle_mds_beacon " << ceph_mds_state_name(m->get_state()) << " seq " << m->get_seq() << " dne" << dendl; @@ -145,6 +151,25 @@ void Beacon::send() } +void Beacon::send_and_wait(const double duration) +{ + Mutex::Locker l(lock); + _send(); + awaiting_seq = last_seq; + dout(20) << __func__ << ": awaiting " << awaiting_seq + << " for up to " << duration << "s" << dendl; + + utime_t timeout; + timeout.set_from_double(ceph_clock_now(cct) + duration); + while ((!seq_stamp.empty() && seq_stamp.begin()->first <= awaiting_seq) + && ceph_clock_now(cct) < timeout) { + waiting_cond.WaitUntil(lock, timeout); + } + + awaiting_seq = -1; +} + + /** * Call periodically, or when you have updated the desired state */ diff --git a/src/mds/Beacon.h b/src/mds/Beacon.h index d229ae292fac3..ba2cb46c77f5d 100644 --- a/src/mds/Beacon.h +++ b/src/mds/Beacon.h @@ -78,6 +78,9 @@ class Beacon : public Dispatcher void _notify_mdsmap(MDSMap const *mdsmap); void _send(); + version_t awaiting_seq; + Cond waiting_cond; + public: Beacon(CephContext *cct_, MonClient *monc_, std::string name); ~Beacon(); @@ -99,6 +102,13 @@ public: void handle_mds_beacon(MMDSBeacon *m); void send(); + /** + * Send a beacon, and block until the ack is received from the mon + * or `duration` seconds pass, whichever happens sooner. Useful + * for emitting a last message on shutdown. + */ + void send_and_wait(const double duration); + bool is_laggy(); utime_t get_laggy_until() const; }; -- 2.39.5