]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librados: expose mgr_command
authorJohn Spray <john.spray@redhat.com>
Wed, 8 Jun 2016 13:23:34 +0000 (14:23 +0100)
committerJohn Spray <john.spray@redhat.com>
Thu, 29 Sep 2016 16:26:55 +0000 (17:26 +0100)
This involves giving RadosClient an embedded
MgrClient.

Signed-off-by: John Spray <john.spray@redhat.com>
src/include/rados/librados.h
src/include/rados/librados.hpp
src/librados/RadosClient.cc
src/librados/RadosClient.h
src/librados/librados.cc
src/tracing/librados.tp

index 4c196424b63f7badcf8f4317f0d9ad060dbefba1..126cb6a83320f24bc419c527ab258d99d205fda0 100644 (file)
@@ -3180,6 +3180,33 @@ CEPH_RADOS_API int rados_mon_command(rados_t cluster, const char **cmd,
                                      size_t *outbuflen, char **outs,
                                      size_t *outslen);
 
+/**
+ * Send ceph-mgr command.
+ *
+ * @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 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
+ */
+CEPH_RADOS_API int rados_mgr_command(rados_t cluster, const char **cmd,
+                                     size_t cmdlen, const char *inbuf,
+                                     size_t inbuflen, char **outbuf,
+                                     size_t *outbuflen, char **outs,
+                                     size_t *outslen);
+
 /**
  * Send monitor command to a specific monitor.
  *
@@ -3229,6 +3256,12 @@ CEPH_RADOS_API int rados_pg_command(rados_t cluster, const char *pgstr,
                                    char **outbuf, size_t *outbuflen,
                                    char **outs, size_t *outslen);
 
+CEPH_RADOS_API int rados_mgr_command(rados_t cluster,
+                                     const char **cmd, size_t cmdlen,
+                                    const char *inbuf, size_t inbuflen,
+                                    char **outbuf, size_t *outbuflen,
+                                    char **outs, size_t *outslen);
+
 /*
  * This is not a doxygen comment leadin, because doxygen breaks on
  * a typedef with function params and returns, and I can't figure out
index 82a2daa54ba34b2786368983a9d97c6a023e089b..bb7f2b9e59d6addae4cabf364599741e43dd40e5 100644 (file)
@@ -1203,6 +1203,8 @@ namespace librados
 
     int mon_command(std::string cmd, const bufferlist& inbl,
                    bufferlist *outbl, std::string *outs);
+    int mgr_command(std::string cmd, const bufferlist& inbl,
+                   bufferlist *outbl, std::string *outs);
     int osd_command(int osdid, std::string cmd, const bufferlist& inbl,
                     bufferlist *outbl, std::string *outs);
     int pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
index dc98af4159f19e3e2a8ce2da07ad7afb56b03caa..f73ff4ee89c52701b9034f6b72e58f95b5627433 100644 (file)
@@ -68,6 +68,7 @@ librados::RadosClient::RadosClient(CephContext *cct_)
     conf(cct_->_conf),
     state(DISCONNECTED),
     monclient(cct_),
+    mgrclient(cct_, nullptr),
     messenger(NULL),
     instance_id(0),
     objecter(NULL),
@@ -262,15 +263,18 @@ int librados::RadosClient::connect()
   objecter->set_balanced_budget();
 
   monclient.set_messenger(messenger);
+  mgrclient.set_messenger(messenger);
 
   objecter->init();
+  messenger->add_dispatcher_head(&mgrclient);
   messenger->add_dispatcher_tail(objecter);
   messenger->add_dispatcher_tail(this);
 
   messenger->start();
 
   ldout(cct, 1) << "setting wanted keys" << dendl;
-  monclient.set_want_keys(CEPH_ENTITY_TYPE_MON | CEPH_ENTITY_TYPE_OSD);
+  monclient.set_want_keys(
+      CEPH_ENTITY_TYPE_MON | CEPH_ENTITY_TYPE_OSD | CEPH_ENTITY_TYPE_MGR);
   ldout(cct, 1) << "calling monclient init" << dendl;
   err = monclient.init();
   if (err) {
@@ -287,14 +291,18 @@ int librados::RadosClient::connect()
   }
   messenger->set_myname(entity_name_t::CLIENT(monclient.get_global_id()));
 
+  // MgrClient needs this (it doesn't have MonClient reference itself)
+  monclient.sub_want("mgrmap", 0, 0);
+  monclient.renew_subs();
+
+  mgrclient.init();
+
   objecter->set_client_incarnation(0);
   objecter->start();
   lock.Lock();
 
   timer.init();
 
-  monclient.renew_subs();
-
   finisher.start();
 
   state = CONNECTED;
@@ -350,6 +358,8 @@ void librados::RadosClient::shutdown()
   if (need_objecter) {
     objecter->shutdown();
   }
+  mgrclient.shutdown();
+
   monclient.shutdown();
   if (messenger) {
     messenger->shutdown();
@@ -801,6 +811,24 @@ int librados::RadosClient::mon_command(const vector<string>& cmd,
   return rval;
 }
 
+
+int librados::RadosClient::mgr_command(const vector<string>& cmd,
+                                      const bufferlist &inbl,
+                                      bufferlist *outbl, string *outs)
+{
+  Mutex::Locker l(lock);
+
+  C_SaferCond cond;
+  mgrclient.start_command(cmd, inbl, outbl, outs, &cond);
+
+  lock.Unlock();
+  int r = cond.wait();
+  lock.Lock();
+
+  return r;
+}
+
+
 int librados::RadosClient::mon_command(int rank, const vector<string>& cmd,
                                       const bufferlist &inbl,
                                       bufferlist *outbl, string *outs)
@@ -926,6 +954,7 @@ int librados::RadosClient::monitor_log(const string& level, rados_log_callback_t
   // (re)start watch
   ldout(cct, 10) << __func__ << " add cb " << (void*)cb << " level " << level << dendl;
   monclient.sub_want(watch_level, 0, 0);
+
   monclient.renew_subs();
   log_cb = cb;
   log_cb_arg = arg;
index 55bf8af457888399dcc6e6b7561e8b2f07340a30..a88da49ba7403f63ebef5075f133322b78714d83 100644 (file)
@@ -21,6 +21,7 @@
 #include "include/rados/librados.h"
 #include "include/rados/librados.hpp"
 #include "mon/MonClient.h"
+#include "mgr/MgrClient.h"
 #include "msg/Dispatcher.h"
 
 #include "IoCtxImpl.h"
@@ -47,6 +48,7 @@ private:
   } state;
 
   MonClient monclient;
+  MgrClient mgrclient;
   Messenger *messenger;
 
   uint64_t instance_id;
@@ -131,6 +133,8 @@ public:
   int mon_command(string name,
                  const vector<string>& cmd, const bufferlist &inbl,
                  bufferlist *outbl, string *outs);
+  int mgr_command(const vector<string>& cmd, const bufferlist &inbl,
+                 bufferlist *outbl, string *outs);
   int osd_command(int osd, vector<string>& cmd, const bufferlist& inbl,
                   bufferlist *poutbl, string *prs);
   int pg_command(pg_t pgid, vector<string>& cmd, const bufferlist& inbl,
index 944d0b3acd5740fb3bd4f66f99ec7f1336a10270..a544474fef7a39ddc7f56822af17178ff595a5b4 100644 (file)
@@ -2288,6 +2288,16 @@ int librados::Rados::osd_command(int osdid, std::string cmd, const bufferlist& i
   return client->osd_command(osdid, cmdvec, inbl, outbl, outs);
 }
 
+int librados::Rados::mgr_command(std::string cmd, const bufferlist& inbl,
+                                 bufferlist *outbl, std::string *outs)
+{
+  vector<string> cmdvec;
+  cmdvec.push_back(cmd);
+  return client->mgr_command(cmdvec, inbl, outbl, outs);
+}
+
+
+
 int librados::Rados::pg_command(const char *pgstr, std::string cmd, const bufferlist& inbl,
                                 bufferlist *outbl, std::string *outs)
 {
@@ -3124,7 +3134,35 @@ extern "C" int rados_osd_command(rados_t cluster, int osdid, const char **cmd,
   return ret;
 }
 
+extern "C" int rados_mgr_command(rados_t cluster, const char **cmd,
+                                size_t cmdlen,
+                                const char *inbuf, size_t inbuflen,
+                                char **outbuf, size_t *outbuflen,
+                                char **outs, size_t *outslen)
+{
+  tracepoint(librados, rados_mgr_command_enter, cluster, cmdlen, inbuf,
+      inbuflen);
 
+  librados::RadosClient *client = (librados::RadosClient *)cluster;
+  bufferlist inbl;
+  bufferlist outbl;
+  string outstring;
+  vector<string> cmdvec;
+
+  for (size_t i = 0; i < cmdlen; i++) {
+    tracepoint(librados, rados_mgr_command_cmd, cmd[i]);
+    cmdvec.push_back(cmd[i]);
+  }
+
+  inbl.append(inbuf, inbuflen);
+  int ret = client->mgr_command(cmdvec, inbl, &outbl, &outstring);
+
+  do_out_buffer(outbl, outbuf, outbuflen);
+  do_out_buffer(outstring, outs, outslen);
+  tracepoint(librados, rados_mgr_command_exit, ret, outbuf, outbuflen, outs,
+      outslen);
+  return ret;
+}
 
 extern "C" int rados_pg_command(rados_t cluster, const char *pgstr,
                                const char **cmd, size_t cmdlen,
index c4aaf4cedc65ee99cf7e5911eaae0f05a25a0cf4..054bc6d9567844e23fa6fa3561738d45a086fd9e 100644 (file)
@@ -542,6 +542,42 @@ TRACEPOINT_EVENT(librados, rados_osd_command_exit,
     )
 )
 
+TRACEPOINT_EVENT(librados, rados_mgr_command_enter,
+    TP_ARGS(
+        rados_t, cluster,
+        size_t, cmdlen,
+        const char*, inbuf,
+        size_t, inbuflen),
+    TP_FIELDS(
+        ctf_integer_hex(rados_t, cluster, cluster)
+        ctf_integer(size_t, cmdlen, cmdlen)
+        ceph_ctf_sequence(unsigned char, inbuf, inbuf, size_t, inbuflen)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_mgr_command_cmd,
+    TP_ARGS(
+        const char*, cmd),
+    TP_FIELDS(
+        ctf_string(cmd, cmd)
+    )
+)
+
+TRACEPOINT_EVENT(librados, rados_mgr_command_exit,
+    TP_ARGS(
+        int, retval,
+        char**, outbuf,
+        size_t*, outbuflen,
+        char**, outs,
+        size_t*, outslen),
+    TP_FIELDS(
+        ctf_integer(int, retval, retval)
+        ceph_ctf_stringp(outs, outs)
+        ceph_ctf_sequencep(unsigned char, outbuf, outbuf, size_t, outbuflen)
+        ceph_ctf_integerp(size_t, outslen, outslen)
+    )
+)
+
 TRACEPOINT_EVENT(librados, rados_pg_command_enter,
     TP_ARGS(
         rados_t, cluster,