]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: support reverting to legacy blacklist op via neorados API 36527/head
authorJason Dillaman <dillaman@redhat.com>
Mon, 24 Aug 2020 15:24:31 +0000 (11:24 -0400)
committerNeha Ojha <nojha@redhat.com>
Mon, 24 Aug 2020 19:53:08 +0000 (19:53 +0000)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/neorados/RADOS.hpp
src/librbd/managed_lock/BreakRequest.cc
src/neorados/RADOS.cc
src/test/librados_test_stub/NeoradosTestStub.cc
src/test/librbd/managed_lock/test_mock_BreakRequest.cc

index 45932e1635462a64ec593fc6079640f860b124f7..f2d62eae9453537c0a74007ad1cc274119424061 100644 (file)
@@ -942,6 +942,17 @@ public:
     return init.result.get();
   }
 
+  template<typename CompletionToken>
+  auto blocklist_add(std::string_view client_address,
+                     std::optional<std::chrono::seconds> expire,
+                     CompletionToken&& token) {
+    boost::asio::async_completion<CompletionToken, SimpleOpSig> init(token);
+    blocklist_add(client_address, expire,
+                  SimpleOpComp::create(get_executor(),
+                                       std::move(init.completion_handler)));
+    return init.result.get();
+  }
+
   template<typename CompletionToken>
   auto wait_for_latest_osd_map(CompletionToken&& token) {
     boost::asio::async_completion<CompletionToken, SimpleOpSig> init(token);
@@ -1082,6 +1093,10 @@ private:
   void enable_application(std::string_view pool, std::string_view app_name,
                          bool force, std::unique_ptr<SimpleOpComp> c);
 
+  void blocklist_add(std::string_view client_address,
+                     std::optional<std::chrono::seconds> expire,
+                     std::unique_ptr<SimpleOpComp> c);
+
   void wait_for_latest_osd_map(std::unique_ptr<SimpleOpComp> c);
 
   // Proxy object to provide access to low-level RADOS messaging clients
index c3f9dfefd18ea6952f1ebbe9ede6030edb392ee2..e482d221e6fccf1e04a7fa433ee3cc4cecf71dfd 100644 (file)
@@ -159,19 +159,12 @@ void BreakRequest<I>::send_blocklist() {
     return;
   }
 
-  std::stringstream cmd;
-  cmd << "{"
-      << "\"prefix\": \"osd blocklist\", "
-      << "\"blocklistop\": \"add\", "
-      << "\"addr\": \"" << locker_addr << "\"";
+  std::optional<std::chrono::seconds> expire;
   if (m_blocklist_expire_seconds != 0) {
-    cmd << ", \"expire\": " << m_blocklist_expire_seconds << ".0";
+    expire = std::chrono::seconds(m_blocklist_expire_seconds);
   }
-  cmd << "}";
-
-  bufferlist in_bl;
-  m_asio_engine.get_rados_api().mon_command(
-    {cmd.str()}, in_bl, nullptr, nullptr,
+  m_asio_engine.get_rados_api().blocklist_add(
+    m_locker.address, expire,
     librbd::asio::util::get_callback_adapter(
       [this](int r) { handle_blocklist(r); }));
 }
index 54e2a23e1a859159a21d226e6b976d66f2ec8f36..4c85d44d83414cf0bddf143716d584b253f013b4 100644 (file)
@@ -1558,6 +1558,39 @@ void RADOS::enable_application(std::string_view pool, std::string_view app_name,
   }
 }
 
+void RADOS::blocklist_add(std::string_view client_address,
+                          std::optional<std::chrono::seconds> expire,
+                          std::unique_ptr<SimpleOpComp> c) {
+  auto expire_arg = (expire ?
+    fmt::format(", \"expire\": \"{}.0\"", expire->count()) : std::string{});
+  impl->monclient.start_mon_command(
+    { fmt::format("{{"
+                  "\"prefix\": \"osd blocklist\", "
+                  "\"blocklistop\": \"add\", "
+                  "\"addr\": \"{}\"{}}}",
+                  client_address, expire_arg) },
+    {},
+    [this, client_address = std::string(client_address), expire_arg,
+     c = std::move(c)](bs::error_code ec, std::string, cb::list) mutable {
+      if (ec != bs::errc::invalid_argument) {
+        ca::post(std::move(c), ec);
+        return;
+      }
+
+      // retry using the legacy command
+      impl->monclient.start_mon_command(
+        { fmt::format("{{"
+                      "\"prefix\": \"osd blacklist\", "
+                      "\"blacklistop\": \"add\", "
+                      "\"addr\": \"{}\"{}}}",
+                      client_address, expire_arg) },
+        {},
+        [c = std::move(c)](bs::error_code ec, std::string, cb::list) mutable {
+          ca::post(std::move(c), ec);
+        });
+    });
+}
+
 void RADOS::wait_for_latest_osd_map(std::unique_ptr<SimpleOpComp> c) {
   impl->objecter->wait_for_latest_osdmap(std::move(c));
 }
index 6a6a7ead8d694ce0f63f68759101e72990be6a86..17c5cab9cb260568c4c8cc4e3cc28550042daa27 100644 (file)
@@ -6,6 +6,7 @@
 #include "common/ceph_mutex.h"
 #include "common/hobject.h"
 #include "librados/AioCompletionImpl.h"
+#include "mon/error_code.h"
 #include "osd/error_code.h"
 #include "osd/osd_types.h"
 #include "osdc/error_code.h"
@@ -511,6 +512,15 @@ void RADOS::mon_command(std::vector<std::string> command,
           (r < 0 ? bs::error_code(-r, osd_category()) : bs::error_code()));
 }
 
+void RADOS::blocklist_add(std::string_view client_address,
+                          std::optional<std::chrono::seconds> expire,
+                          std::unique_ptr<SimpleOpComp> c) {
+  auto r = impl->test_rados_client->blocklist_add(
+    std::string(client_address), expire.value_or(0s).count());
+  c->post(std::move(c),
+          (r < 0 ? bs::error_code(-r, mon_category()) : bs::error_code()));
+}
+
 void RADOS::wait_for_latest_osd_map(std::unique_ptr<Op::Completion> c) {
   auto r = impl->test_rados_client->wait_for_latest_osd_map();
   c->dispatch(std::move(c),
index 96dc1ef516abedd516423d8d5b3a609beac7332d..d6239344b1ee7cf04df5439b052b5e7e5b20ae7c 100644 (file)
@@ -56,11 +56,6 @@ GetLockerRequest<librbd::MockTestImageCtx> *GetLockerRequest<librbd::MockTestIma
 // template definitions
 #include "librbd/managed_lock/BreakRequest.cc"
 
-MATCHER(IsBlocklistCommand, "") {
-  return (arg.size() == 1 &&
-          arg[0].find("\"blocklistop\": \"add\"") != std::string::npos);
-}
-
 namespace librbd {
 namespace managed_lock {
 
@@ -113,8 +108,7 @@ public:
   void expect_blocklist_add(MockTestImageCtx &mock_image_ctx, int r) {
     auto& mock_rados_client = librados::get_mock_rados_client(
       mock_image_ctx.rados_api);
-    EXPECT_CALL(mock_rados_client, mon_command(IsBlocklistCommand(), _, _, _))
-      .WillOnce(Return(r));
+    EXPECT_CALL(mock_rados_client, blocklist_add(_, _)).WillOnce(Return(r));
   }
 
   void expect_wait_for_latest_osd_map(MockTestImageCtx &mock_image_ctx, int r) {