librbd: removed synchronous watcher check from remove image state machine

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2017-06-16 13:28:01 -04:00
parent 960c7cd809
commit 3086d2a085
2 changed files with 95 additions and 51 deletions

View File

@ -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);

View File

@ -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);