From: Greg Farnum Date: Wed, 12 Feb 2014 01:53:56 +0000 (-0800) Subject: monc: let users specify a callback when they reopen their monitor session X-Git-Tag: v0.78~162^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1a8c43474bf36bfcf2a94bf9b7e756a2a99f33fd;p=ceph.git monc: let users specify a callback when they reopen their monitor session 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 --- diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index 3782902cb07..c1403d58db1 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -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(); + } } diff --git a/src/mon/MonClient.h b/src/mon/MonClient.h index 9aea5ad9382..4abefe6ce76 100644 --- a/src/mon/MonClient.h +++ b/src/mon/MonClient.h @@ -179,6 +179,7 @@ private: int authenticate_err; list 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(); }