From 157f986d9103f28fc9a5faae88b8f50ffabfd7b4 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 8 Jun 2016 14:23:34 +0100 Subject: [PATCH] librados: expose mgr_command This involves giving RadosClient an embedded MgrClient. Signed-off-by: John Spray --- src/include/rados/librados.h | 33 +++++++++++++++++++++++++++++ src/include/rados/librados.hpp | 2 ++ src/librados/RadosClient.cc | 35 ++++++++++++++++++++++++++++--- src/librados/RadosClient.h | 4 ++++ src/librados/librados.cc | 38 ++++++++++++++++++++++++++++++++++ src/tracing/librados.tp | 36 ++++++++++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 3 deletions(-) diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 4c196424b63f7..126cb6a83320f 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -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 diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 82a2daa54ba34..bb7f2b9e59d6a 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -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, diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index dc98af4159f19..f73ff4ee89c52 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -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& cmd, return rval; } + +int librados::RadosClient::mgr_command(const vector& 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& 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; diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 55bf8af457888..a88da49ba7403 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -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& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs); + int mgr_command(const vector& cmd, const bufferlist &inbl, + bufferlist *outbl, string *outs); int osd_command(int osd, vector& cmd, const bufferlist& inbl, bufferlist *poutbl, string *prs); int pg_command(pg_t pgid, vector& cmd, const bufferlist& inbl, diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 944d0b3acd574..a544474fef7a3 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -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 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 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, diff --git a/src/tracing/librados.tp b/src/tracing/librados.tp index c4aaf4cedc65e..054bc6d956784 100644 --- a/src/tracing/librados.tp +++ b/src/tracing/librados.tp @@ -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, -- 2.39.5