From 4878509652ab2ef7df1d35a8269e9265c6d71204 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 4 Sep 2019 14:02:20 -0500 Subject: [PATCH] mgr: accept MMgrCommand[Reply] messages (in addition to MCommand[Reply]) 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 --- src/messages/MMgrCommand.h | 46 ++++++++++++++++++++++ src/messages/MMgrCommandReply.h | 45 ++++++++++++++++++++++ src/mgr/DaemonServer.cc | 68 ++++++++++++++++++++++++++------- src/mgr/DaemonServer.h | 5 ++- src/msg/Message.cc | 10 +++++ src/msg/Message.h | 2 + 6 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 src/messages/MMgrCommand.h create mode 100644 src/messages/MMgrCommandReply.h diff --git a/src/messages/MMgrCommand.h b/src/messages/MMgrCommand.h new file mode 100644 index 00000000000..8a1f96881d6 --- /dev/null +++ b/src/messages/MMgrCommand.h @@ -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 + +#include "msg/Message.h" + +class MMgrCommand : public Message { +public: + uuid_d fsid; + std::vector 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 + +#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); + } +}; diff --git a/src/mgr/DaemonServer.cc b/src/mgr/DaemonServer.cc index 2e74eec4f26..669e1a5b1bd 100644 --- a/src/mgr/DaemonServer.cc +++ b/src/mgr/DaemonServer.cc @@ -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& m) return handle_close(ref_cast(m)); case MSG_COMMAND: return handle_command(ref_cast(m)); + case MSG_MGR_COMMAND: + return handle_command(ref_cast(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 m; + ceph::ref_t m_tell; + ceph::ref_t m_mgr; + const std::vector& 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 m) - : m{std::move(m)} { + : m_tell{std::move(m)}, + cmd(m_tell->cmd), + data(m_tell->get_data()) { + } + explicit CommandContext(ceph::ref_t 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& m) std::lock_guard l(lock); auto cmdctx = std::make_shared(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& m) +{ + std::lock_guard l(lock); + auto cmdctx = std::make_shared(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& m) } bool DaemonServer::_handle_command( - const ref_t& m, std::shared_ptr& 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(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 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); diff --git a/src/mgr/DaemonServer.h b/src/mgr/DaemonServer.h index 14ed023f06b..d299aaa4ea1 100644 --- a/src/mgr/DaemonServer.h +++ b/src/mgr/DaemonServer.h @@ -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& m); bool handle_report(const ceph::ref_t& m); bool handle_command(const ceph::ref_t& m); - bool _handle_command(const ceph::ref_t& m, - std::shared_ptr& cmdctx); + bool handle_command(const ceph::ref_t& m); + bool _handle_command(std::shared_ptr& cmdctx); void send_report(); void got_service_map(); void got_mgr_map(); diff --git a/src/msg/Message.cc b/src/msg/Message.cc index 1460132ea4e..af787e1e040 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -182,6 +182,8 @@ #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(); break; + case MSG_MGR_COMMAND: + m = make_message(); + break; + + case MSG_MGR_COMMAND_REPLY: + m = make_message(); + break; + case MSG_MGR_OPEN: m = make_message(); break; diff --git a/src/msg/Message.h b/src/msg/Message.h index 8a159044deb..3f6de8e2b74 100644 --- a/src/msg/Message.h +++ b/src/msg/Message.h @@ -215,6 +215,8 @@ #define MSG_SERVICE_MAP 0x707 #define MSG_MGR_CLOSE 0x708 +#define MSG_MGR_COMMAND 0x709 +#define MSG_MGR_COMMAND_REPLY 0x70a // ====================================================== -- 2.39.5