]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/common/admin_socket.cc
import ceph 14.2.5
[ceph.git] / ceph / src / common / admin_socket.cc
index c7f21f7b0f206c4b73b2d8abfc4e619c311f0bb4..25e8d8fafdcd2c15c32fe0dcd9240ba80a60f8d9 100644 (file)
@@ -317,6 +317,8 @@ bool AdminSocket::do_accept()
          c = "foo";
          break;
        }
+       //wrap command with new protocol
+       c = "{\"prefix\": \"" + c + "\"}";
        break;
       }
     } else {
@@ -334,8 +336,28 @@ bool AdminSocket::do_accept()
     }
   }
 
-  bool rval = false;
+  bool rval;
+  bufferlist out;
+  rval = execute_command(c, out);
+  if (rval) {
+    uint32_t len = htonl(out.length());
+    int ret = safe_write(connection_fd, &len, sizeof(len));
+    if (ret < 0) {
+      lderr(m_cct) << "AdminSocket: error writing response length "
+          << cpp_strerror(ret) << dendl;
+      rval = false;
+    } else {
+      if (out.write_fd(connection_fd) >= 0)
+        rval = true;
+    }
+  }
 
+  retry_sys_call(::close, connection_fd);
+  return rval;
+}
+
+int AdminSocket::execute_command(const std::string& cmd, ceph::bufferlist& out)
+{
   cmdmap_t cmdmap;
   string format;
   vector<string> cmdvec;
@@ -343,14 +365,13 @@ bool AdminSocket::do_accept()
   cmdvec.push_back(cmd);
   if (!cmdmap_from_json(cmdvec, &cmdmap, errss)) {
     ldout(m_cct, 0) << "AdminSocket: " << errss.str() << dendl;
-    retry_sys_call(::close, connection_fd);
     return false;
   }
+  string match;
   try {
     cmd_getval(m_cct, cmdmap, "format", format);
-    cmd_getval(m_cct, cmdmap, "prefix", c);
+    cmd_getval(m_cct, cmdmap, "prefix", match);
   } catch (const bad_cmd_get& e) {
-    retry_sys_call(::close, connection_fd);
     return false;
   }
   if (format != "json" && format != "json-pretty" &&
@@ -359,7 +380,6 @@ bool AdminSocket::do_accept()
 
   std::unique_lock l(lock);
   decltype(hooks)::iterator p;
-  string match = c;
   while (match.size()) {
     p = hooks.find(match);
     if (p != hooks.cend())
@@ -375,53 +395,41 @@ bool AdminSocket::do_accept()
     }
   }
 
-  bufferlist out;
   if (p == hooks.cend()) {
-    lderr(m_cct) << "AdminSocket: request '" << c << "' not defined" << dendl;
-  } else {
-    string args;
-    if (match != c) {
-      args = c.substr(match.length() + 1);
-    }
-
-    // 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
-    // removing this hook.
-    in_hook = true;
-    auto match_hook = p->second.hook;
-    l.unlock();
-    bool success = (validate(match, cmdmap, out) &&
-                    match_hook->call(match, cmdmap, format, out));
-    l.lock();
-    in_hook = false;
-    in_hook_cond.notify_all();
-
-    if (!success) {
-      ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args
-                     << "' to " << match_hook << " failed" << dendl;
-      out.append("failed");
-    } else {
-      ldout(m_cct, 5) << "AdminSocket: request '" << match << "' '" << args
-                      << "' to " << match_hook
-                      << " returned " << out.length() << " bytes" << dendl;
-    }
-    uint32_t len = htonl(out.length());
-    int ret = safe_write(connection_fd, &len, sizeof(len));
-    if (ret < 0) {
-      lderr(m_cct) << "AdminSocket: error writing response length "
-                  << cpp_strerror(ret) << dendl;
-    } else {
-      if (out.write_fd(connection_fd) >= 0)
-       rval = true;
-    }
+    lderr(m_cct) << "AdminSocket: request '" << cmd << "' not defined" << dendl;
+    return false;
+  }
+  string args;
+  if (match != cmd) {
+    args = cmd.substr(match.length() + 1);
   }
-  l.unlock();
 
-  retry_sys_call(::close, connection_fd);
-  return rval;
+  // 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
+  // removing this hook.
+  in_hook = true;
+  auto match_hook = p->second.hook;
+  l.unlock();
+  bool success = (validate(match, cmdmap, out) &&
+      match_hook->call(match, cmdmap, format, out));
+  l.lock();
+  in_hook = false;
+  in_hook_cond.notify_all();
+  if (!success) {
+    ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args
+        << "' to " << match_hook << " failed" << dendl;
+    out.append("failed");
+  } else {
+    ldout(m_cct, 5) << "AdminSocket: request '" << match << "' '" << args
+        << "' to " << match_hook
+        << " returned " << out.length() << " bytes" << dendl;
+  }
+  return true;
 }
 
+
+
 bool AdminSocket::validate(const std::string& command,
                           const cmdmap_t& cmdmap,
                           bufferlist& out) const