]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
common/admin_socket: allow dup prefixes
authorSage Weil <sage@redhat.com>
Tue, 10 Sep 2019 15:10:12 +0000 (10:10 -0500)
committerSage Weil <sage@redhat.com>
Tue, 1 Oct 2019 21:30:53 +0000 (16:30 -0500)
Allow multiple commands to register with the same prefix (but different
commands description strings).

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

index ead558a1ca0d57ab0044519633367154d002acab..e71e6543b7306f03c999751dc710064f7fc14213 100644 (file)
@@ -462,6 +462,14 @@ void AdminSocket::execute_command(
     return on_finish(-EINVAL, "unknown command prefix "s + prefix, empty);
   }
 
+  // make sure one of the registered commands with this prefix validates.
+  while (!validate_cmd(m_cct, p->second.desc, cmdmap, errss)) {
+    ++p;
+    if (p->first != prefix) {
+      return on_finish(-EINVAL, "invalid command json", empty);
+    }
+  }
+
   // Drop lock to avoid cycles in cases where the hook takes
   // the same lock that was held during calls to register/unregister,
   // and set in_hook to allow unregister to wait for us before
@@ -469,11 +477,8 @@ void AdminSocket::execute_command(
   in_hook = true;
   auto hook = p->second.hook;
   l.unlock();
-  if (!validate(prefix, cmdmap, empty)) {
-    on_finish(-EINVAL, "invalid command json", empty);
-  } else {
-    hook->call_async(prefix, cmdmap, format, inbl, on_finish);
-  }
+  hook->call_async(prefix, cmdmap, format, inbl, on_finish);
+
   l.lock();
   in_hook = false;
   in_hook_cond.notify_all();
@@ -487,20 +492,6 @@ void AdminSocket::queue_tell_command(ref_t<MCommand> m)
   wakeup();
 }
 
-
-bool AdminSocket::validate(const std::string& prefix,
-                          const cmdmap_t& cmdmap,
-                          bufferlist& out) const
-{
-  stringstream os;
-  if (validate_cmd(m_cct, hooks.at(prefix).desc, cmdmap, os)) {
-    return true;
-  } else {
-    out.append(os);
-    return false;
-  }
-}
-
 int AdminSocket::register_command(std::string_view cmddesc,
                                  AdminSocketHook *hook,
                                  std::string_view help)
@@ -509,8 +500,10 @@ int AdminSocket::register_command(std::string_view cmddesc,
   std::unique_lock l(lock);
   string prefix = cmddesc_get_prefix(cmddesc);
   auto i = hooks.find(prefix);
-  if (i != hooks.cend()) {
-    ldout(m_cct, 5) << "register_command " << prefix << " hook " << hook
+  if (i != hooks.cend() &&
+      i->second.desc == cmddesc) {
+    ldout(m_cct, 5) << "register_command " << prefix
+                   << " cmddesc " << cmddesc << " hook " << hook
                    << " EEXIST" << dendl;
     ret = -EEXIST;
   } else {
index 22606e7785d522788c00382fbea517a733855326..a866cae7685e5e31c81369db1001a79a23d30c80 100644 (file)
@@ -125,9 +125,6 @@ private:
   void entry() noexcept;
   bool do_accept();
   void do_tell_queue();
-  bool validate(const std::string& command,
-               const cmdmap_t& cmdmap,
-               ceph::buffer::list& out) const;
 
   CephContext *m_cct;
   std::string m_path;
@@ -156,7 +153,7 @@ private:
       : hook(hook), desc(desc), help(help) {}
   };
 
-  std::map<std::string, hook_info, std::less<>> hooks;
+  std::multimap<std::string, hook_info, std::less<>> hooks;
 
   friend class AdminSocketTest;
   friend class HelpHook;