diff options
author | Sage Weil <sage@inktank.com> | 2013-06-12 16:36:39 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-06-13 09:26:44 -0700 |
commit | 420e02e818844b466465f75bcaedd62378b9ec3c (patch) | |
tree | 94ad8ef672192951c0a371bcb620f606b2dd9230 | |
parent | d1b83ff411603a59aaed3bf96f57665d4f221691 (diff) | |
download | ceph-420e02e818844b466465f75bcaedd62378b9ec3c.tar.gz |
librados: new rados_mon_command_target to talk to a specific monitor
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/include/rados/librados.h | 30 | ||||
-rw-r--r-- | src/librados/RadosClient.cc | 38 | ||||
-rw-r--r-- | src/librados/RadosClient.h | 6 | ||||
-rw-r--r-- | src/librados/librados.cc | 39 | ||||
-rw-r--r-- | src/pybind/rados.py | 21 |
5 files changed, 126 insertions, 8 deletions
diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 69eeccb323b..eb1a30632b7 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -1712,7 +1712,7 @@ int rados_break_lock(rados_ioctx_t io, const char *o, const char *name, * @note Takes command string in carefully-formatted JSON; must match * defined commands, types, etc. * - * The result buffers are allocated on the heapt; the caller is + * The result buffers are allocated on the heap; the caller is * expected to release that memory with rados_buffer_free(). The * buffer and length pointers can all be NULL, in which case they are * not filled in. @@ -1733,6 +1733,34 @@ int rados_mon_command(rados_t cluster, const char **cmd, size_t cmdlen, char **outs, size_t *outslen); /** + * Send monitor command to a specific monitor. + * + * @note Takes command string in carefully-formatted JSON; must match + * defined commands, types, etc. + * + * The result buffers are allocated on the heap; the caller is + * expected to release that memory with rados_buffer_free(). The + * buffer and length pointers can all be NULL, in which case they are + * not filled in. + * + * @param cluster cluster handle + * @param name target monitor's name + * @param cmd an array of char *'s representing the command + * @param cmdlen count of valid entries in cmd + * @param inbuf any bulk input data (crush map, etc.) + * @param outbuf double pointer to output buffer + * @param outbuflen pointer to output buffer length + * @param outs double pointer to status string + * @param outslen pointer to status string length + * @returns 0 on success, negative error code on failure + */ +int rados_mon_command_target(rados_t cluster, const char *name, + const char **cmd, size_t cmdlen, + const char *inbuf, size_t inbuflen, + char **outbuf, size_t *outbuflen, + char **outs, size_t *outslen); + +/** * free a rados-allocated buffer * * Release memory allocated by librados calls like rados_mon_command(). diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index a2b54abf058..3b5fabe3f82 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -583,6 +583,44 @@ int librados::RadosClient::mon_command(const vector<string>& cmd, return rval; } +int librados::RadosClient::mon_command(int rank, const vector<string>& cmd, + bufferlist &inbl, + bufferlist *outbl, string *outs) +{ + Mutex mylock("RadosClient::mon_command::mylock"); + Cond cond; + bool done; + int rval; + lock.Lock(); + monclient.start_mon_command(rank, cmd, inbl, outbl, outs, + new C_SafeCond(&mylock, &cond, &done, &rval)); + lock.Unlock(); + mylock.Lock(); + while (!done) + cond.Wait(mylock); + mylock.Unlock(); + return rval; +} + +int librados::RadosClient::mon_command(string name, const vector<string>& cmd, + bufferlist &inbl, + bufferlist *outbl, string *outs) +{ + Mutex mylock("RadosClient::mon_command::mylock"); + Cond cond; + bool done; + int rval; + lock.Lock(); + monclient.start_mon_command(name, cmd, inbl, outbl, outs, + new C_SafeCond(&mylock, &cond, &done, &rval)); + lock.Unlock(); + mylock.Lock(); + while (!done) + cond.Wait(mylock); + mylock.Unlock(); + return rval; +} + int librados::RadosClient::osd_command(int osd, vector<string>& cmd, bufferlist& inbl, bufferlist *poutbl, string *prs) diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 9374553b0ad..337beff5750 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -108,6 +108,12 @@ public: void watch_notify(MWatchNotify *m); int mon_command(const vector<string>& cmd, bufferlist &inbl, bufferlist *outbl, string *outs); + int mon_command(int rank, + const vector<string>& cmd, bufferlist &inbl, + bufferlist *outbl, string *outs); + int mon_command(string name, + const vector<string>& cmd, bufferlist &inbl, + bufferlist *outbl, string *outs); int osd_command(int osd, vector<string>& cmd, bufferlist& inbl, bufferlist *poutbl, string *prs); int pg_command(pg_t pgid, vector<string>& cmd, bufferlist& inbl, diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 1dda70828fd..43c2584c390 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -1857,6 +1857,45 @@ extern "C" int rados_mon_command(rados_t cluster, const char **cmd, return ret; } +extern "C" int rados_mon_command_target(rados_t cluster, const char *name, + const char **cmd, + size_t cmdlen, + const char *inbuf, size_t inbuflen, + char **outbuf, size_t *outbuflen, + char **outs, size_t *outslen) +{ + librados::RadosClient *client = (librados::RadosClient *)cluster; + bufferlist inbl; + bufferlist outbl; + string outstring; + vector<string> cmdvec; + + // is this a numeric id? + char *endptr; + errno = 0; + long rank = strtol(name, &endptr, 10); + if ((errno == ERANGE && (rank == LONG_MAX || rank == LONG_MIN)) || + (errno != 0 && rank == 0) || + endptr == name || // no digits + *endptr != '\0') { // extra characters + rank = -1; + } + + for (size_t i = 0; i < cmdlen; i++) + cmdvec.push_back(cmd[i]); + + inbl.append(inbuf, inbuflen); + int ret; + if (rank >= 0) + ret = client->mon_command(rank, cmdvec, inbl, &outbl, &outstring); + else + ret = client->mon_command(name, cmdvec, inbl, &outbl, &outstring); + + do_out_buffer(outbl, outbuf, outbuflen); + do_out_buffer(outstring, outs, outslen); + return ret; +} + extern "C" int rados_osd_command(rados_t cluster, int osdid, const char **cmd, size_t cmdlen, const char *inbuf, size_t inbuflen, diff --git a/src/pybind/rados.py b/src/pybind/rados.py index 4a5ed961603..c4000465272 100644 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -518,9 +518,9 @@ Rados object in state %s." % (self.state)) raise make_ex(ret, "error opening ioctx '%s'" % ioctx_name) return Ioctx(ioctx_name, self.librados, ioctx) - def mon_command(self, cmd, inbuf, timeout=0): + def mon_command(self, cmd, inbuf, timeout=0, target=None): """ - mon_command(cmd, inbuf, outbuf, outbuflen, outs, outslen) + mon_command[_target](cmd, inbuf, outbuf, outbuflen, outs, outslen) returns (int ret, string outbuf, string outs) """ import sys @@ -531,11 +531,18 @@ Rados object in state %s." % (self.state)) outslen = c_long() cmdarr = (c_char_p * len(cmd))(*cmd) - ret = run_in_thread(self.librados.rados_mon_command, - (self.cluster, cmdarr, len(cmd), - c_char_p(inbuf), len(inbuf), - outbufp, byref(outbuflen), outsp, byref(outslen)), - timeout) + if target: + ret = run_in_thread(self.librados.rados_mon_command_target, + (self.cluster, target, cmdarr, len(cmd), + c_char_p(inbuf), len(inbuf), + outbufp, byref(outbuflen), outsp, byref(outslen)), + timeout) + else: + ret = run_in_thread(self.librados.rados_mon_command, + (self.cluster, cmdarr, len(cmd), + c_char_p(inbuf), len(inbuf), + outbufp, byref(outbuflen), outsp, byref(outslen)), + timeout) if ret == 0: # copy returned memory (ctypes makes a copy, not a reference) |