]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
monc: let users specify a callback when they reopen their monitor session
authorGreg Farnum <greg@inktank.com>
Wed, 12 Feb 2014 01:53:56 +0000 (17:53 -0800)
committerGreg Farnum <greg@inktank.com>
Thu, 13 Feb 2014 21:20:52 +0000 (13:20 -0800)
Then the callback is triggered when a new session is established, and the
daemon can do whatever it likes. There are no guarantees about how long it
might take to trigger, though. In particular we call the provided callback
while not holding our own lock in order to avoid deadlock. This could lead
to some funny ordering from the user's perspective if they call
reopen_session() again before getting the callback, but there's no way around
that, so they just have to use it appropriately.

Signed-off-by: Greg Farnum <greg@inktank.com>
src/mon/MonClient.cc
src/mon/MonClient.h

index 3782902cb076b4face0011852f8092e9b89ed5a3..c1403d58db16e413ed50f7d91a4640fb6197ceea 100644 (file)
@@ -66,6 +66,7 @@ MonClient::MonClient(CephContext *cct_) :
   want_monmap(true),
   want_keys(0), global_id(0),
   authenticate_err(0),
+  session_established_context(NULL),
   auth(NULL),
   keyring(NULL),
   rotating_secrets(NULL),
@@ -77,6 +78,7 @@ MonClient::MonClient(CephContext *cct_) :
 MonClient::~MonClient()
 {
   delete auth_supported;
+  delete session_established_context;
   delete auth;
   delete keyring;
   delete rotating_secrets;
@@ -462,6 +464,7 @@ int MonClient::authenticate(double timeout)
 
 void MonClient::handle_auth(MAuthReply *m)
 {
+  Context *cb = NULL;
   bufferlist::iterator p = m->result_bl.begin();
   if (state == MC_STATE_NEGOTIATING) {
     if (!auth || (int)m->protocol != auth->get_protocol()) {
@@ -521,11 +524,20 @@ void MonClient::handle_auth(MAuthReply *m)
        log_client->reset_session();
        send_log();
       }
+      if (session_established_context) {
+        cb = session_established_context;
+        session_established_context = NULL;
+      }
     }
   
     _check_auth_tickets();
   }
   auth_cond.SignalAll();
+  if (cb) {
+    monc_lock.Unlock();
+    cb->complete(0);
+    monc_lock.Lock();
+  }
 }
 
 
index 9aea5ad9382ec73f1e241de92b164ebaf02c40f8..4abefe6ce7614cff2e2e1cd363e4f471f2415b56 100644 (file)
@@ -179,6 +179,7 @@ private:
   int authenticate_err;
 
   list<Message*> waiting_for_session;
+  Context *session_established_context;
 
   string _pick_random_mon();
   void _finish_hunting();
@@ -280,8 +281,19 @@ public:
     Mutex::Locker l(monc_lock);
     _send_mon_message(m);
   }
-  void reopen_session() {
+  /**
+   * If you specify a callback, you should not call
+   * reopen_session() again until it has been triggered. The MonClient
+   * will behave, but the first callback could be triggered after
+   * the session has been killed and the MonClient has started trying
+   * to reconnect to another monitor.
+   */
+  void reopen_session(Context *cb=NULL) {
     Mutex::Locker l(monc_lock);
+    if (cb) {
+      delete session_established_context;
+      session_established_context = cb;
+    }
     _reopen_session();
   }