mirror of
https://github.com/ceph/ceph
synced 2025-02-28 05:22:19 +00:00
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 <dillaman@redhat.com>
This commit is contained in:
parent
c87c669a78
commit
44a0d7c839
src
@ -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 <typename I>
|
||||
BreakRequest<I>::BreakRequest(librados::IoCtx& ioctx,
|
||||
AsioEngine& asio_engine,
|
||||
@ -173,13 +151,29 @@ void BreakRequest<I>::send_blacklist() {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: need async version of RadosClient::blacklist_add
|
||||
using klass = BreakRequest<I>;
|
||||
Context *ctx = create_context_callback<klass, &klass::handle_blacklist>(
|
||||
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 <typename I>
|
||||
@ -192,6 +186,30 @@ void BreakRequest<I>::handle_blacklist(int r) {
|
||||
finish(r);
|
||||
return;
|
||||
}
|
||||
|
||||
wait_for_osd_map();
|
||||
}
|
||||
|
||||
template <typename I>
|
||||
void BreakRequest<I>::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 <typename I>
|
||||
void BreakRequest<I>::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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -56,6 +56,11 @@ GetLockerRequest<librbd::MockTestImageCtx> *GetLockerRequest<librbd::MockTestIma
|
||||
// template definitions
|
||||
#include "librbd/managed_lock/BreakRequest.cc"
|
||||
|
||||
MATCHER(IsBlacklistCommand, "") {
|
||||
return (arg.size() == 1 &&
|
||||
arg[0].find("\"blacklistop\": \"add\"") != std::string::npos);
|
||||
}
|
||||
|
||||
namespace librbd {
|
||||
namespace managed_lock {
|
||||
|
||||
@ -106,9 +111,17 @@ public:
|
||||
|
||||
|
||||
void expect_blacklist_add(MockTestImageCtx &mock_image_ctx, int r) {
|
||||
EXPECT_CALL(*get_mock_io_ctx(mock_image_ctx.md_ctx).get_mock_rados_client(),
|
||||
blacklist_add(_, _))
|
||||
.WillOnce(Return(r));
|
||||
auto& mock_rados_client = librados::get_mock_rados_client(
|
||||
mock_image_ctx.rados_api);
|
||||
EXPECT_CALL(mock_rados_client, mon_command(IsBlacklistCommand(), _, _, _))
|
||||
.WillOnce(Return(r));
|
||||
}
|
||||
|
||||
void expect_wait_for_latest_osd_map(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, wait_for_latest_osd_map())
|
||||
.WillOnce(Return(r));
|
||||
}
|
||||
|
||||
void expect_break_lock(MockTestImageCtx &mock_image_ctx, int r) {
|
||||
@ -142,6 +155,7 @@ TEST_F(TestMockManagedLockBreakRequest, DeadLockOwner) {
|
||||
0);
|
||||
|
||||
expect_blacklist_add(mock_image_ctx, 0);
|
||||
expect_wait_for_latest_osd_map(mock_image_ctx, 0);
|
||||
expect_break_lock(mock_image_ctx, 0);
|
||||
|
||||
C_SaferCond ctx;
|
||||
@ -171,6 +185,7 @@ TEST_F(TestMockManagedLockBreakRequest, ForceBreak) {
|
||||
0);
|
||||
|
||||
expect_blacklist_add(mock_image_ctx, 0);
|
||||
expect_wait_for_latest_osd_map(mock_image_ctx, 0);
|
||||
expect_break_lock(mock_image_ctx, 0);
|
||||
|
||||
C_SaferCond ctx;
|
||||
@ -428,6 +443,7 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockMissing) {
|
||||
0);
|
||||
|
||||
expect_blacklist_add(mock_image_ctx, 0);
|
||||
expect_wait_for_latest_osd_map(mock_image_ctx, 0);
|
||||
expect_break_lock(mock_image_ctx, -ENOENT);
|
||||
|
||||
C_SaferCond ctx;
|
||||
@ -457,6 +473,7 @@ TEST_F(TestMockManagedLockBreakRequest, BreakLockError) {
|
||||
0);
|
||||
|
||||
expect_blacklist_add(mock_image_ctx, 0);
|
||||
expect_wait_for_latest_osd_map(mock_image_ctx, 0);
|
||||
expect_break_lock(mock_image_ctx, -EINVAL);
|
||||
|
||||
C_SaferCond ctx;
|
||||
|
Loading…
Reference in New Issue
Block a user