From 44a0d7c839b31d9cccc6b28443830c3ff6d9701b Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 14 Jul 2020 18:38:17 -0400 Subject: [PATCH] librbd: utilize neorados to issue async blacklist request The librados API does not currently offer an async 'mon_command' API method. Instead of adding one just to support this effort, re-use the neorados API to issue an asynchronous 'mon_command' for blacklisting a client. Signed-off-by: Jason Dillaman --- src/librbd/managed_lock/BreakRequest.cc | 78 ++++++++++++------- src/librbd/managed_lock/BreakRequest.h | 6 ++ .../managed_lock/test_mock_BreakRequest.cc | 23 +++++- 3 files changed, 74 insertions(+), 33 deletions(-) diff --git a/src/librbd/managed_lock/BreakRequest.cc b/src/librbd/managed_lock/BreakRequest.cc index 62605704890..2c8e3c54f01 100644 --- a/src/librbd/managed_lock/BreakRequest.cc +++ b/src/librbd/managed_lock/BreakRequest.cc @@ -12,6 +12,7 @@ #include "librbd/ImageCtx.h" #include "librbd/Utils.h" #include "librbd/asio/ContextWQ.h" +#include "librbd/asio/Utils.h" #include "librbd/managed_lock/GetLockerRequest.h" #define dout_subsys ceph_subsys_rbd @@ -25,29 +26,6 @@ namespace managed_lock { using util::create_context_callback; using util::create_rados_callback; -namespace { - -struct C_BlacklistClient : public Context { - librados::IoCtx &ioctx; - std::string locker_address; - uint32_t expire_seconds; - Context *on_finish; - - C_BlacklistClient(librados::IoCtx &ioctx, const std::string &locker_address, - uint32_t expire_seconds, Context *on_finish) - : ioctx(ioctx), locker_address(locker_address), - expire_seconds(expire_seconds), on_finish(on_finish) { - } - - void finish(int r) override { - librados::Rados rados(ioctx); - r = rados.blacklist_add(locker_address, expire_seconds); - on_finish->complete(r); - } -}; - -} // anonymous namespace - template BreakRequest::BreakRequest(librados::IoCtx& ioctx, AsioEngine& asio_engine, @@ -173,13 +151,29 @@ void BreakRequest::send_blacklist() { return; } - // TODO: need async version of RadosClient::blacklist_add - using klass = BreakRequest; - Context *ctx = create_context_callback( - this); - m_asio_engine.get_work_queue()->queue( - new C_BlacklistClient(m_ioctx, m_locker.address, - m_blacklist_expire_seconds, ctx), 0); + entity_addr_t locker_addr; + if (!locker_addr.parse(m_locker.address.c_str(), 0)) { + lderr(m_cct) << "unable to parse locker address: " << m_locker.address + << dendl; + finish(-EINVAL); + return; + } + + std::stringstream cmd; + cmd << "{" + << "\"prefix\": \"osd blacklist\", " + << "\"blacklistop\": \"add\", " + << "\"addr\": \"" << locker_addr << "\""; + if (m_blacklist_expire_seconds != 0) { + cmd << ", \"expire\": " << m_blacklist_expire_seconds << ".0"; + } + cmd << "}"; + + bufferlist in_bl; + m_asio_engine.get_rados_api().mon_command( + {cmd.str()}, in_bl, nullptr, nullptr, + librbd::asio::util::get_callback_adapter( + [this](int r) { handle_blacklist(r); })); } template @@ -192,6 +186,30 @@ void BreakRequest::handle_blacklist(int r) { finish(r); return; } + + wait_for_osd_map(); +} + +template +void BreakRequest::wait_for_osd_map() { + ldout(m_cct, 10) << dendl; + + m_asio_engine.get_rados_api().wait_for_latest_osd_map( + librbd::asio::util::get_callback_adapter( + [this](int r) { handle_wait_for_osd_map(r); })); +} + +template +void BreakRequest::handle_wait_for_osd_map(int r) { + ldout(m_cct, 10) << "r=" << r << dendl; + + if (r < 0) { + lderr(m_cct) << "failed to wait for updated OSD map: " << cpp_strerror(r) + << dendl; + finish(r); + return; + } + send_break_lock(); } diff --git a/src/librbd/managed_lock/BreakRequest.h b/src/librbd/managed_lock/BreakRequest.h index 640c0146e07..3c812999810 100644 --- a/src/librbd/managed_lock/BreakRequest.h +++ b/src/librbd/managed_lock/BreakRequest.h @@ -58,6 +58,9 @@ private: * BLACKLIST (skip if disabled) * | * v + * WAIT_FOR_OSD_MAP + * | + * v * BREAK_LOCK * | * v @@ -99,6 +102,9 @@ private: void send_blacklist(); void handle_blacklist(int r); + void wait_for_osd_map(); + void handle_wait_for_osd_map(int r); + void send_break_lock(); void handle_break_lock(int r); diff --git a/src/test/librbd/managed_lock/test_mock_BreakRequest.cc b/src/test/librbd/managed_lock/test_mock_BreakRequest.cc index e9ac8be7e9e..4c810fab05e 100644 --- a/src/test/librbd/managed_lock/test_mock_BreakRequest.cc +++ b/src/test/librbd/managed_lock/test_mock_BreakRequest.cc @@ -56,6 +56,11 @@ GetLockerRequest *GetLockerRequest