]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/DaemonServer: catch cmd_bad_get
authorSage Weil <sage@redhat.com>
Mon, 13 Aug 2018 18:29:08 +0000 (13:29 -0500)
committerSage Weil <sage@redhat.com>
Sat, 1 Sep 2018 21:38:58 +0000 (16:38 -0500)
Refactor handle_command slightly: establish the CommandContext, then call
_handle_command.  This keep the try block localized.

Signed-off-by: Sage Weil <sage@redhat.com>
src/mgr/DaemonServer.cc
src/mgr/DaemonServer.h

index ce30ac879e1bbcc6cf3f18f4a37b69badec54d45..14e7db45d5ed94e9a0f754c7511e7bb7a5a31de2 100644 (file)
@@ -719,86 +719,86 @@ bool DaemonServer::_allowed_command(
   return capable;
 }
 
-bool DaemonServer::handle_command(MCommand *m)
-{
-  Mutex::Locker l(lock);
-  int r = 0;
-  std::stringstream ss;
-  std::string prefix;
-
-  ceph_assert(lock.is_locked_by_me());
+/**
+ * The working data for processing an MCommand.  This lives in
+ * a class to enable passing it into other threads for processing
+ * outside of the thread/locks that called handle_command.
+ */
+class CommandContext {
+public:
+  MCommand *m;
+  bufferlist odata;
+  cmdmap_t cmdmap;
+
+  explicit CommandContext(MCommand *m_)
+    : m(m_) {
+  }
 
-  /**
-   * The working data for processing an MCommand.  This lives in
-   * a class to enable passing it into other threads for processing
-   * outside of the thread/locks that called handle_command.
-   */
-  class CommandContext
-  {
-    public:
-    MCommand *m;
-    bufferlist odata;
-    cmdmap_t cmdmap;
+  ~CommandContext() {
+    m->put();
+  }
 
-    explicit CommandContext(MCommand *m_)
-      : m(m_)
-    {
-    }
+  void reply(int r, const std::stringstream &ss) {
+    reply(r, ss.str());
+  }
 
-    ~CommandContext()
-    {
-      m->put();
+  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();
+    if (con) {
+      con->mark_disposable();
     }
 
-    void reply(int r, const std::stringstream &ss)
-    {
-      reply(r, ss.str());
+    if (r == 0) {
+      dout(4) << __func__ << " success" << dendl;
+    } else {
+      derr << __func__ << " " << cpp_strerror(r) << " " << rs << dendl;
     }
-
-    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();
-      if (con) {
-        con->mark_disposable();
-      }
-
-      if (r == 0) {
-        dout(4) << __func__ << " success" << dendl;
-      } else {
-        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 (con) {
+      MCommandReply *reply = new MCommandReply(r, rs);
+      reply->set_tid(m->get_tid());
+      reply->set_data(odata);
+      con->send_message(reply);
     }
-  };
+  }
+};
 
-  /**
  * A context for receiving a bufferlist/error string from a background
  * function and then calling back to a CommandContext when it's done
  */
-  class ReplyOnFinish : public Context {
-    std::shared_ptr<CommandContext> cmdctx;
+/**
+ * A context for receiving a bufferlist/error string from a background
+ * function and then calling back to a CommandContext when it's done
+ */
+class ReplyOnFinish : public Context {
+  std::shared_ptr<CommandContext> cmdctx;
 
-  public:
-    bufferlist from_mon;
-    string outs;
+public:
+  bufferlist from_mon;
+  string outs;
 
-    explicit ReplyOnFinish(const std::shared_ptr<CommandContext> &cmdctx_)
-      : cmdctx(cmdctx_)
+  explicit ReplyOnFinish(const std::shared_ptr<CommandContext> &cmdctx_)
+    : cmdctx(cmdctx_)
     {}
-    void finish(int r) override {
-      cmdctx->odata.claim_append(from_mon);
-      cmdctx->reply(r, outs);
-    }
-  };
+  void finish(int r) override {
+    cmdctx->odata.claim_append(from_mon);
+    cmdctx->reply(r, outs);
+  }
+};
 
+bool DaemonServer::handle_command(MCommand *m)
+{
+  Mutex::Locker l(lock);
   std::shared_ptr<CommandContext> cmdctx = std::make_shared<CommandContext>(m);
+  try {
+    return _handle_command(m, cmdctx);
+  } catch (const bad_cmd_get& e) {
+    cmdctx->reply(-EINVAL, e.what());
+    return true;
+  }
+}
 
+bool DaemonServer::_handle_command(
+  MCommand *m,
+  std::shared_ptr<CommandContext>& cmdctx)
+{
   auto priv = m->get_connection()->get_priv();
   auto session = static_cast<MgrSession*>(priv.get());
   if (!session) {
@@ -810,6 +810,8 @@ bool DaemonServer::handle_command(MCommand *m)
   std::string format;
   boost::scoped_ptr<Formatter> f;
   map<string,string> param_str_map;
+  std::stringstream ss;
+  int r = 0;
 
   if (!cmdmap_from_json(m->cmd, &(cmdctx->cmdmap), ss)) {
     cmdctx->reply(-EINVAL, ss);
@@ -821,6 +823,7 @@ bool DaemonServer::handle_command(MCommand *m)
     f.reset(Formatter::create(format));
   }
 
+  string prefix;
   cmd_getval(cct, cmdctx->cmdmap, "prefix", prefix);
 
   dout(4) << "decoded " << cmdctx->cmdmap.size() << dendl;
index e7a7658cb714fbac1986f3df97d90e52608cf0b8..419a00ddf47fb553e70a9c9f3d24173062e08114 100644 (file)
@@ -38,6 +38,7 @@ class MMgrClose;
 class MMonMgrReport;
 class MCommand;
 struct MonCommand;
+class CommandContext;
 
 
 /**
@@ -145,6 +146,7 @@ public:
   bool handle_close(MMgrClose *m);
   bool handle_report(MMgrReport *m);
   bool handle_command(MCommand *m);
+  bool _handle_command(MCommand *m, std::shared_ptr<CommandContext>& cmdctx);
   void send_report();
   void got_service_map();
   void got_mgr_map();