mirror of
https://github.com/ceph/ceph
synced 2025-01-20 01:51:34 +00:00
librbd: removed synchronous watcher check from remove image state machine
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
parent
960c7cd809
commit
3086d2a085
@ -165,11 +165,11 @@ void RemoveRequest<I>::check_image_snaps() {
|
||||
return;
|
||||
}
|
||||
|
||||
check_image_watchers();
|
||||
list_image_watchers();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::check_image_watchers() {
|
||||
void RemoveRequest<I>::list_image_watchers() {
|
||||
ldout(m_cct, 20) << dendl;
|
||||
|
||||
librados::ObjectReadOperation op;
|
||||
@ -177,7 +177,7 @@ void RemoveRequest<I>::check_image_watchers() {
|
||||
|
||||
using klass = RemoveRequest<I>;
|
||||
librados::AioCompletion *rados_completion =
|
||||
create_rados_callback<klass, &klass::handle_check_image_watchers>(this);
|
||||
create_rados_callback<klass, &klass::handle_list_image_watchers>(this);
|
||||
|
||||
int r = m_image_ctx->md_ctx.aio_operate(m_header_oid, rados_completion,
|
||||
&op, &m_out_bl);
|
||||
@ -186,50 +186,12 @@ void RemoveRequest<I>::check_image_watchers() {
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::filter_out_mirror_watchers() {
|
||||
if (m_watchers.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_image_ctx->features & RBD_FEATURE_JOURNALING) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
cls::rbd::MirrorImage mirror_image;
|
||||
int r = cls_client::mirror_image_get(&m_image_ctx->md_ctx, m_image_ctx->id,
|
||||
&mirror_image);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT) {
|
||||
lderr(m_cct) << "failed to retrieve mirroring state: "
|
||||
<< cpp_strerror(r) << dendl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mirror_image.state != cls::rbd::MIRROR_IMAGE_STATE_ENABLED) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<obj_watch_t> mirror_watchers;
|
||||
r = m_image_ctx->md_ctx.list_watchers(RBD_MIRRORING, &mirror_watchers);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT) {
|
||||
lderr(m_cct) << "error listing mirroring watchers: "
|
||||
<< cpp_strerror(r) << dendl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (auto &watcher : mirror_watchers) {
|
||||
m_watchers.remove_if([watcher] (obj_watch_t &w) {
|
||||
return (strncmp(w.addr, watcher.addr, sizeof(w.addr)) == 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::handle_check_image_watchers(int r) {
|
||||
void RemoveRequest<I>::handle_list_image_watchers(int r) {
|
||||
ldout(m_cct, 20) << "r=" << r << dendl;
|
||||
|
||||
if (r == 0 && m_ret_val < 0) {
|
||||
r = m_ret_val;
|
||||
}
|
||||
if (r < 0) {
|
||||
lderr(m_cct) << "error listing image watchers: " << cpp_strerror(r)
|
||||
<< dendl;
|
||||
@ -237,11 +199,85 @@ void RemoveRequest<I>::handle_check_image_watchers(int r) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If an image is being bootstrapped by rbd-mirror, it implies
|
||||
// that the rbd-mirror daemon currently has the image open.
|
||||
// Permit removal if this is the case.
|
||||
filter_out_mirror_watchers();
|
||||
get_mirror_image();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::get_mirror_image() {
|
||||
ldout(m_cct, 20) << dendl;
|
||||
if ((m_watchers.empty()) ||
|
||||
((m_image_ctx->features & RBD_FEATURE_JOURNALING) == 0)) {
|
||||
check_image_watchers();
|
||||
return;
|
||||
}
|
||||
|
||||
librados::ObjectReadOperation op;
|
||||
cls_client::mirror_image_get_start(&op, m_image_id);
|
||||
|
||||
using klass = RemoveRequest<I>;
|
||||
librados::AioCompletion *comp =
|
||||
create_rados_callback<klass, &klass::handle_get_mirror_image>(this);
|
||||
m_out_bl.clear();
|
||||
int r = m_image_ctx->md_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
|
||||
assert(r == 0);
|
||||
comp->release();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::handle_get_mirror_image(int r) {
|
||||
ldout(m_cct, 20) << "r=" << r << dendl;
|
||||
|
||||
if (r == -ENOENT || r == -EOPNOTSUPP) {
|
||||
check_image_watchers();
|
||||
return;
|
||||
} else if (r < 0) {
|
||||
ldout(m_cct, 5) << "error retrieving mirror image: " << cpp_strerror(r)
|
||||
<< dendl;
|
||||
}
|
||||
|
||||
list_mirror_watchers();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::list_mirror_watchers() {
|
||||
ldout(m_cct, 20) << dendl;
|
||||
|
||||
librados::ObjectReadOperation op;
|
||||
op.list_watchers(&m_mirror_watchers, &m_ret_val);
|
||||
|
||||
using klass = RemoveRequest<I>;
|
||||
librados::AioCompletion *rados_completion =
|
||||
create_rados_callback<klass, &klass::handle_list_mirror_watchers>(this);
|
||||
m_out_bl.clear();
|
||||
int r = m_image_ctx->md_ctx.aio_operate(RBD_MIRRORING, rados_completion,
|
||||
&op, &m_out_bl);
|
||||
assert(r == 0);
|
||||
rados_completion->release();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::handle_list_mirror_watchers(int r) {
|
||||
ldout(m_cct, 20) << "r=" << r << dendl;
|
||||
|
||||
if (r == 0 && m_ret_val < 0) {
|
||||
r = m_ret_val;
|
||||
}
|
||||
if (r < 0 && r != -ENOENT) {
|
||||
ldout(m_cct, 5) << "error listing mirror watchers: " << cpp_strerror(r)
|
||||
<< dendl;
|
||||
}
|
||||
|
||||
for (auto &watcher : m_mirror_watchers) {
|
||||
m_watchers.remove_if([watcher] (obj_watch_t &w) {
|
||||
return (strncmp(w.addr, watcher.addr, sizeof(w.addr)) == 0);
|
||||
});
|
||||
}
|
||||
|
||||
check_image_watchers();
|
||||
}
|
||||
|
||||
template<typename I>
|
||||
void RemoveRequest<I>::check_image_watchers() {
|
||||
if (m_watchers.size() > 1) {
|
||||
lderr(m_cct) << "image has watchers - not removing" << dendl;
|
||||
send_close_image(-EBUSY);
|
||||
|
@ -123,6 +123,7 @@ private:
|
||||
int m_ret_val = 0;
|
||||
bufferlist m_out_bl;
|
||||
std::list<obj_watch_t> m_watchers;
|
||||
std::list<obj_watch_t> m_mirror_watchers;
|
||||
|
||||
void open_image();
|
||||
void handle_open_image(int r);
|
||||
@ -145,9 +146,16 @@ private:
|
||||
void validate_image_removal();
|
||||
void check_image_snaps();
|
||||
|
||||
void filter_out_mirror_watchers();
|
||||
void list_image_watchers();
|
||||
void handle_list_image_watchers(int r);
|
||||
|
||||
void get_mirror_image();
|
||||
void handle_get_mirror_image(int r);
|
||||
|
||||
void list_mirror_watchers();
|
||||
void handle_list_mirror_watchers(int r);
|
||||
|
||||
void check_image_watchers();
|
||||
void handle_check_image_watchers(int r);
|
||||
|
||||
void check_group();
|
||||
void handle_check_group(int r);
|
||||
|
Loading…
Reference in New Issue
Block a user