]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr: accept MMgrCommand[Reply] messages (in addition to MCommand[Reply])
authorSage Weil <sage@redhat.com>
Wed, 4 Sep 2019 19:02:20 +0000 (14:02 -0500)
committerSage Weil <sage@redhat.com>
Fri, 6 Sep 2019 02:29:56 +0000 (21:29 -0500)
MCommand is used both for tell-style commands and for CLI commands
implemented by the mgr.  Allow the latter to be send via MMgrCommand
instead.

Signed-off-by: Sage Weil <sage@redhat.com>
src/messages/MMgrCommand.h [new file with mode: 0644]
src/messages/MMgrCommandReply.h [new file with mode: 0644]
src/mgr/DaemonServer.cc
src/mgr/DaemonServer.h
src/msg/Message.cc
src/msg/Message.h

diff --git a/src/messages/MMgrCommand.h b/src/messages/MMgrCommand.h
new file mode 100644 (file)
index 0000000..8a1f968
--- /dev/null
@@ -0,0 +1,46 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <vector>
+
+#include "msg/Message.h"
+
+class MMgrCommand : public Message {
+public:
+  uuid_d fsid;
+  std::vector<std::string> cmd;
+
+  MMgrCommand()
+    : Message{MSG_MGR_COMMAND} {}
+  MMgrCommand(const uuid_d &f)
+    : Message{MSG_MGR_COMMAND},
+      fsid(f) { }
+
+private:
+  ~MMgrCommand() override {}
+
+public:
+  std::string_view get_type_name() const override { return "mgr_command"; }
+  void print(std::ostream& o) const override {
+    o << "mgr_command(tid " << get_tid() << ": ";
+    for (unsigned i=0; i<cmd.size(); i++) {
+      if (i) o << ' ';
+      o << cmd[i];
+    }
+    o << ")";
+  }
+
+  void encode_payload(uint64_t features) override {
+    using ceph::encode;
+    encode(fsid, payload);
+    encode(cmd, payload);
+  }
+  void decode_payload() override {
+    using ceph::decode;
+    auto p = payload.cbegin();
+    decode(fsid, p);
+    decode(cmd, p);
+  }
+};
diff --git a/src/messages/MMgrCommandReply.h b/src/messages/MMgrCommandReply.h
new file mode 100644 (file)
index 0000000..e0662b4
--- /dev/null
@@ -0,0 +1,45 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <string_view>
+
+#include "msg/Message.h"
+#include "MMgrCommand.h"
+
+class MMgrCommandReply : public Message {
+public:
+  errorcode32_t r;
+  std::string rs;
+
+  MMgrCommandReply()
+    : Message{MSG_MGR_COMMAND_REPLY} {}
+  MMgrCommandReply(MMgrCommand *m, int _r)
+    : Message{MSG_MGR_COMMAND_REPLY}, r(_r) {
+    header.tid = m->get_tid();
+  }
+  MMgrCommandReply(int _r, std::string_view s)
+    : Message{MSG_MGR_COMMAND_REPLY},
+      r(_r), rs(s) { }
+private:
+  ~MMgrCommandReply() override {}
+
+public:
+  std::string_view get_type_name() const override { return "mgr_command_reply"; }
+  void print(std::ostream& o) const override {
+    o << "mgr_command_reply(tid " << get_tid() << ": " << r << " " << rs << ")";
+  }
+
+  void encode_payload(uint64_t features) override {
+    using ceph::encode;
+    encode(r, payload);
+    encode(rs, payload);
+  }
+  void decode_payload() override {
+    using ceph::decode;
+    auto p = payload.cbegin();
+    decode(r, p);
+    decode(rs, p);
+  }
+};
index 2e74eec4f26416db419cf66b0c7358111195b4ad..669e1a5b1bd555f6d95a4c90bd8f4546510f548b 100644 (file)
@@ -30,6 +30,8 @@
 #include "messages/MMonMgrReport.h"
 #include "messages/MCommand.h"
 #include "messages/MCommandReply.h"
+#include "messages/MMgrCommand.h"
+#include "messages/MMgrCommandReply.h"
 #include "messages/MPGStats.h"
 #include "messages/MOSDScrub.h"
 #include "messages/MOSDScrub2.h"
@@ -256,6 +258,8 @@ bool DaemonServer::ms_dispatch2(const ref_t<Message>& m)
       return handle_close(ref_cast<MMgrClose>(m));
     case MSG_COMMAND:
       return handle_command(ref_cast<MCommand>(m));
+    case MSG_MGR_COMMAND:
+      return handle_command(ref_cast<MMgrCommand>(m));
     default:
       dout(1) << "Unhandled message type " << m->get_type() << dendl;
       return false;
@@ -716,12 +720,22 @@ bool DaemonServer::_allowed_command(
  */
 class CommandContext {
 public:
-  ceph::ref_t<MCommand> m;
+  ceph::ref_t<MCommand> m_tell;
+  ceph::ref_t<MMgrCommand> m_mgr;
+  const std::vector<std::string>& cmd;  ///< ref into m_tell or m_mgr
+  const bufferlist& data;               ///< ref into m_tell or m_mgr
   bufferlist odata;
   cmdmap_t cmdmap;
 
   explicit CommandContext(ceph::ref_t<MCommand> m)
-    : m{std::move(m)} {
+    : m_tell{std::move(m)},
+      cmd(m_tell->cmd),
+      data(m_tell->get_data()) {
+  }
+  explicit CommandContext(ceph::ref_t<MMgrCommand> m)
+    : m_mgr{std::move(m)},
+      cmd(m_mgr->cmd),
+      data(m_mgr->get_data()) {
   }
 
   void reply(int r, const std::stringstream &ss) {
@@ -730,7 +744,8 @@ public:
 
   void reply(int r, const std::string &rs) {
     // Let the connection drop as soon as we've sent our response
-    ConnectionRef con = m->get_connection();
+    ConnectionRef con = m_tell ? m_tell->get_connection()
+      : m_mgr->get_connection();
     if (con) {
       con->mark_disposable();
     }
@@ -741,10 +756,17 @@ public:
       derr << __func__ << " " << cpp_strerror(r) << " " << rs << dendl;
     }
     if (con) {
-      MCommandReply *reply = new MCommandReply(r, rs);
-      reply->set_tid(m->get_tid());
-      reply->set_data(odata);
-      con->send_message(reply);
+      if (m_tell) {
+       MCommandReply *reply = new MCommandReply(r, rs);
+       reply->set_tid(m_tell->get_tid());
+       reply->set_data(odata);
+       con->send_message(reply);
+      } else {
+       MMgrCommandReply *reply = new MMgrCommandReply(r, rs);
+       reply->set_tid(m_mgr->get_tid());
+       reply->set_data(odata);
+       con->send_message(reply);
+      }
     }
   }
 };
@@ -774,7 +796,19 @@ bool DaemonServer::handle_command(const ref_t<MCommand>& m)
   std::lock_guard l(lock);
   auto cmdctx = std::make_shared<CommandContext>(m);
   try {
-    return _handle_command(m, cmdctx);
+    return _handle_command(cmdctx);
+  } catch (const bad_cmd_get& e) {
+    cmdctx->reply(-EINVAL, e.what());
+    return true;
+  }
+}
+
+bool DaemonServer::handle_command(const ref_t<MMgrCommand>& m)
+{
+  std::lock_guard l(lock);
+  auto cmdctx = std::make_shared<CommandContext>(m);
+  try {
+    return _handle_command(cmdctx);
   } catch (const bad_cmd_get& e) {
     cmdctx->reply(-EINVAL, e.what());
     return true;
@@ -782,16 +816,22 @@ bool DaemonServer::handle_command(const ref_t<MCommand>& m)
 }
 
 bool DaemonServer::_handle_command(
-  const ref_t<MCommand>& m,
   std::shared_ptr<CommandContext>& cmdctx)
 {
+  MessageRef m;
+  if (cmdctx->m_tell) {
+    m = cmdctx->m_tell;
+  } else {
+    m = cmdctx->m_mgr;
+  }
   auto priv = m->get_connection()->get_priv();
   auto session = static_cast<MgrSession*>(priv.get());
   if (!session) {
     return true;
   }
-  if (session->inst.name == entity_name_t())
+  if (session->inst.name == entity_name_t()) {
     session->inst.name = m->get_source();
+  }
 
   std::string format;
   boost::scoped_ptr<Formatter> f;
@@ -799,7 +839,7 @@ bool DaemonServer::_handle_command(
   std::stringstream ss;
   int r = 0;
 
-  if (!cmdmap_from_json(m->cmd, &(cmdctx->cmdmap), ss)) {
+  if (!cmdmap_from_json(cmdctx->cmd, &(cmdctx->cmdmap), ss)) {
     cmdctx->reply(-EINVAL, ss);
     return true;
   }
@@ -863,7 +903,7 @@ bool DaemonServer::_handle_command(
       dout(1) << " access denied" << dendl;
       audit_clog->info() << "from='" << session->inst << "' "
                          << "entity='" << session->entity_name << "' "
-                         << "cmd=" << m->cmd << ":  access denied";
+                         << "cmd=" << cmdctx->cmd << ":  access denied";
       ss << "access denied: does your client key have mgr caps? "
             "See http://docs.ceph.com/docs/master/mgr/administrator/"
             "#client-authentication";
@@ -874,7 +914,7 @@ bool DaemonServer::_handle_command(
   audit_clog->debug()
     << "from='" << session->inst << "' "
     << "entity='" << session->entity_name << "' "
-    << "cmd=" << m->cmd << ": dispatch";
+    << "cmd=" << cmdctx->cmd << ": dispatch";
 
   // ----------------
   // service map commands
@@ -2253,7 +2293,7 @@ bool DaemonServer::_handle_command(
     }
 
     std::stringstream ds;
-    bufferlist inbl = cmdctx->m->get_data();
+    bufferlist inbl = cmdctx->data;
     int r = py_modules.handle_command(handler_name, cmdctx->cmdmap, inbl, &ds, &ss);
     cmdctx->odata.append(ds);
     cmdctx->reply(r, ss);
index 14ed023f06b97ed42c4f275501bfd5359ba40c8e..d299aaa4ea1511335b7038884f1dfc4f4539abf9 100644 (file)
@@ -36,6 +36,7 @@ class MMgrOpen;
 class MMgrClose;
 class MMonMgrReport;
 class MCommand;
+class MMgrCommand;
 struct MonCommand;
 class CommandContext;
 struct OSDPerfMetricQuery;
@@ -147,8 +148,8 @@ public:
   bool handle_close(const ceph::ref_t<MMgrClose>& m);
   bool handle_report(const ceph::ref_t<MMgrReport>& m);
   bool handle_command(const ceph::ref_t<MCommand>& m);
-  bool _handle_command(const ceph::ref_t<MCommand>& m,
-                      std::shared_ptr<CommandContext>& cmdctx);
+  bool handle_command(const ceph::ref_t<MMgrCommand>& m);
+  bool _handle_command(std::shared_ptr<CommandContext>& cmdctx);
   void send_report();
   void got_service_map();
   void got_mgr_map();
index 1460132ea4ed63da68092c6589429849e1f4da65..af787e1e04060b9e7a003678725a21046b82ce6b 100644 (file)
 #include "messages/MMgrClose.h"
 #include "messages/MMgrConfigure.h"
 #include "messages/MMonMgrReport.h"
+#include "messages/MMgrCommand.h"
+#include "messages/MMgrCommandReply.h"
 #include "messages/MServiceMap.h"
 
 #include "messages/MLock.h"
@@ -822,6 +824,14 @@ Message *decode_message(CephContext *cct, int crcflags,
     m = make_message<MMgrDigest>();
     break;
 
+  case MSG_MGR_COMMAND:
+    m = make_message<MMgrCommand>();
+    break;
+
+  case MSG_MGR_COMMAND_REPLY:
+    m = make_message<MMgrCommandReply>();
+    break;
+
   case MSG_MGR_OPEN:
     m = make_message<MMgrOpen>();
     break;
index 8a159044deb18c08cf5a690dffd73f8c6c050962..3f6de8e2b74fb5c150376807ff1f96740981f37f 100644 (file)
 #define MSG_SERVICE_MAP           0x707
 
 #define MSG_MGR_CLOSE             0x708
+#define MSG_MGR_COMMAND           0x709
+#define MSG_MGR_COMMAND_REPLY     0x70a
 
 // ======================================================