From 1fb103da34bac70a2410d3a4d5bde0ead6a226ee Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 6 Sep 2019 09:43:01 -0500 Subject: [PATCH] mgr/MgrClient: add start_command variant that takes a target Note that the initial implementation can only target the active mgr! Signed-off-by: Sage Weil --- src/mgr/MgrClient.cc | 66 +++++++++++++++++++++++++++++++++++++++++--- src/mgr/MgrClient.h | 13 +++++++-- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/mgr/MgrClient.cc b/src/mgr/MgrClient.cc index a1075952bf9..2e48b703209 100644 --- a/src/mgr/MgrClient.cc +++ b/src/mgr/MgrClient.cc @@ -184,13 +184,35 @@ void MgrClient::reconnect() } // resend any pending commands - for (const auto &p : command_table.get_commands()) { - auto m = p.second.get_message( - {}, - HAVE_FEATURE(map.active_mgr_features, SERVER_OCTOPUS)); + auto p = command_table.get_commands().begin(); + while (p != command_table.get_commands().end()) { + auto tid = p->first; + auto& op = p->second; + ldout(cct,10) << "resending " << tid << dendl; + MessageRef m; + if (op.name.size()) { + if (op.name != map.active_name) { + // FIXME someday! + ldout(cct, 10) << "active mgr " << map.active_name << " != target " + << op.name << dendl; + if (op.on_finish) { + op.on_finish->complete(-ENXIO); + } + ++p; + command_table.erase(tid); + continue; + } + // note: will not work for pre-octopus mgrs + m = op.get_message({}, false); + } else { + m = op.get_message( + {}, + HAVE_FEATURE(map.active_mgr_features, SERVER_OCTOPUS)); + } ceph_assert(session); ceph_assert(session->con); session->con->send_message2(std::move(m)); + ++p; } } @@ -462,6 +484,42 @@ int MgrClient::start_command(const vector& cmd, const bufferlist& inbl, return 0; } +int MgrClient::start_tell_command( + const string& name, + const vector& cmd, const bufferlist& inbl, + bufferlist *outbl, string *outs, + Context *onfinish) +{ + std::lock_guard l(lock); + + ldout(cct, 20) << "target: " << name << " cmd: " << cmd << dendl; + + if (map.epoch == 0 && mgr_optional) { + ldout(cct,20) << " no MgrMap, assuming EACCES" << dendl; + return -EACCES; + } + + auto &op = command_table.start_command(); + op.name = name; + op.cmd = cmd; + op.inbl = inbl; + op.outbl = outbl; + op.outs = outs; + op.on_finish = onfinish; + + if (session && session->con && map.active_name == name) { + // Leaving fsid argument null because it isn't used. + // Note: this simply won't work we pre-octopus mgrs because they route + // MCommand to the cluster command handler. + auto m = op.get_message({}, false); + session->con->send_message2(std::move(m)); + } else { + ldout(cct, 5) << "no mgr session (no running mgr daemon?), or " + << name << " not active mgr, waiting" << dendl; + } + return 0; +} + bool MgrClient::handle_command_reply( uint64_t tid, bufferlist& data, diff --git a/src/mgr/MgrClient.h b/src/mgr/MgrClient.h index b6be89c187d..fa96ff46615 100644 --- a/src/mgr/MgrClient.h +++ b/src/mgr/MgrClient.h @@ -46,6 +46,7 @@ class MgrSessionState class MgrCommand : public CommandOp { public: + std::string name; explicit MgrCommand(ceph_tid_t t) : CommandOp(t) {} MgrCommand() : CommandOp() {} @@ -144,9 +145,15 @@ public: pgstats_cb = std::move(cb_); } - int start_command(const std::vector& cmd, const ceph::buffer::list& inbl, - ceph::buffer::list *outbl, std::string *outs, - Context *onfinish); + int start_command( + const std::vector& cmd, const ceph::buffer::list& inbl, + ceph::buffer::list *outbl, std::string *outs, + Context *onfinish); + int start_tell_command( + const string& name, + const std::vector& cmd, const ceph::buffer::list& inbl, + ceph::buffer::list *outbl, std::string *outs, + Context *onfinish); int service_daemon_register( const std::string& service, -- 2.39.5