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);
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
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); }));
}
}
}
+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));
}
#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"
(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),
// 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 {
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) {