summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-06-12 16:36:39 -0700
committerSage Weil <sage@inktank.com>2013-06-13 09:26:44 -0700
commit420e02e818844b466465f75bcaedd62378b9ec3c (patch)
tree94ad8ef672192951c0a371bcb620f606b2dd9230
parentd1b83ff411603a59aaed3bf96f57665d4f221691 (diff)
downloadceph-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.h30
-rw-r--r--src/librados/RadosClient.cc38
-rw-r--r--src/librados/RadosClient.h6
-rw-r--r--src/librados/librados.cc39
-rw-r--r--src/pybind/rados.py21
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)