* @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.
char **outbuf, size_t *outbuflen,
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
*
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)
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,
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,
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
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)