]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/mon: resend mon command when session established
authorKefu Chai <kchai@redhat.com>
Tue, 2 Mar 2021 09:52:36 +0000 (17:52 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 2 Mar 2021 11:04:28 +0000 (19:04 +0800)
this behavior matches that of `MonClient::_resend_mon_commands()`. so
far the only user which sends mon command in crimson is
`OSD::_add_me_to_crush()`, but there is still (rare) chance that the connected
monitor cannot be reached when we send the command to it, in that case,
we should retry when the connection is re-established.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/mon/MonClient.cc
src/crimson/mon/MonClient.h

index 8c7326f3e35ac5479bda4e4c629f4f5e1cd031ef..3dcd4e699782d917e3db4fe0af742ed370a722eb 100644 (file)
@@ -397,6 +397,10 @@ crimson::net::ConnectionRef Connection::get_conn() {
   return conn;
 }
 
+Client::mon_command_t::mon_command_t(ceph::ref_t<MMonCommand> req)
+  : req(req)
+{}
+
 Client::Client(crimson::net::Messenger& messenger,
                crimson::common::AuthHandler& auth_handler)
   // currently, crimson is OSD-only
@@ -827,9 +831,9 @@ seastar::future<> Client::handle_mon_command_ack(Ref<MMonCommandAck> m)
   const auto tid = m->get_tid();
   if (auto found = mon_commands.find(tid);
       found != mon_commands.end()) {
-    auto& result = found->second;
+    auto& command = found->second;
     logger().trace("{} {}", __func__, tid);
-    result.set_value(std::make_tuple(m->r, m->rs, std::move(m->get_data())));
+    command.result.set_value(std::make_tuple(m->r, m->rs, std::move(m->get_data())));
     mon_commands.erase(found);
   } else {
     logger().warn("{} {} not found", __func__, tid);
@@ -1001,9 +1005,11 @@ Client::run_command(std::string&& cmd,
   m->set_tid(tid);
   m->cmd = {std::move(cmd)};
   m->set_data(std::move(bl));
-  auto& req = mon_commands[tid];
-  return send_message(m).then([&req] {
-    return req.get_future();
+  [[maybe_unused]] auto [command, added] =
+    mon_commands.try_emplace(tid, m);
+  assert(added);
+  return send_message(m).then([&result=command->second.result] {
+    return result.get_future();
   });
 }
 
@@ -1029,6 +1035,11 @@ seastar::future<> Client::on_session_opened()
     }
     pending_messages.clear();
     return seastar::now();
+  }).then([this] {
+    return seastar::parallel_for_each(mon_commands,
+      [this](auto &tid_command) {
+      return send_message(tid_command.second.req);
+    });
   });
 }
 
index 8c2447b5e687ff4fbad16fe3fdccf39639d0a433..335f76bf0a98832f78cec964532111cb76205588 100644 (file)
@@ -35,6 +35,7 @@ class MAuthReply;
 struct MMonMap;
 struct MMonSubscribeAck;
 struct MMonGetVersionReply;
+struct MMonCommand;
 struct MMonCommandAck;
 struct MLogAck;
 struct MConfig;
@@ -67,7 +68,12 @@ class Client : public crimson::net::Dispatcher,
   ceph_tid_t last_mon_command_id = 0;
   using command_result_t =
     seastar::future<std::tuple<std::int32_t, string, ceph::bufferlist>>;
-  std::map<ceph_tid_t, typename command_result_t::promise_type> mon_commands;
+  struct mon_command_t {
+    ceph::ref_t<MMonCommand> req;
+    typename command_result_t::promise_type result;
+    mon_command_t(ceph::ref_t<MMonCommand> req);
+  };
+  std::map<ceph_tid_t, mon_command_t> mon_commands;
 
   MonSub sub;