template <typename I>
void ImageRemoveRequest<I>::send() {
+ get_group();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::get_group() {
+ ldout(m_cct, 10) << dendl;
+ librados::ObjectReadOperation op;
+ cls_client::image_group_get_start(&op);
+
+ auto comp = create_rados_callback<
+ ImageRemoveRequest<I>, &ImageRemoveRequest<I>::handle_get_group>(this);
+ m_out_bl.clear();
+ int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op,
+ &m_out_bl);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::handle_get_group(int r) {
+ ldout(m_cct, 10) << "r=" << r << dendl;
+
+ if (r == 0) {
+ auto iter = m_out_bl.cbegin();
+ r = cls_client::image_group_get_finish(&iter, &m_group_spec);
+ }
+
+ if (r < 0) {
+ lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ get_mirror_group();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::get_mirror_group() {
+ if (!m_group_spec.is_valid()) {
+ m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+ remove_mirror_image();
+ return;
+ }
+
+ ldout(m_cct, 10) << dendl;
+
+ int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {},
+ &m_group_io_ctx);
+ if (r < 0) {
+ finish(r);
+ return;
+ }
+
+ librados::ObjectReadOperation op;
+ cls_client::mirror_group_get_start(&op, m_group_spec.group_id);
+
+ auto comp = create_rados_callback<
+ ImageRemoveRequest<I>,
+ &ImageRemoveRequest<I>::handle_get_mirror_group>(this);
+ m_out_bl.clear();
+ r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::handle_get_mirror_group(int r) {
+ ldout(m_cct, 10) << "r=" << r << dendl;
+
+ if (r == 0) {
+ auto iter = m_out_bl.cbegin();
+ r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group);
+ }
+
+ if (r == -ENOENT) {
+ m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+ } else if (r < 0) {
+ lderr(m_cct) << "failed to retrieve group mirroring state: "
+ << cpp_strerror(r) << dendl;
+ finish(r);
+ return;
+ }
+
remove_mirror_image();
}
template <typename I>
void ImageRemoveRequest<I>::notify_mirroring_watcher() {
+ // skip image notification if mirroring for the image group is disabling
+ if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_DISABLING) {
+ finish(0);
+ return;
+ }
+
ldout(m_cct, 10) << dendl;
auto ctx = util::create_context_callback<
*
* <start>
* |
+ * GET_GROUP
+ * |
+ * v
+ * GET_MIRROR_GROUP (skip if no group)
+ * |
+ * v
* REMOVE_MIRROR_IMAGE
* |
* v
- * NOTIFY_MIRRORING_WATCHER
+ * NOTIFY_MIRRORING_WATCHER (skip if not needed)
* |
* v
* <finish>
Context* m_on_finish;
CephContext* m_cct;
+ bufferlist m_out_bl;
+ librados::IoCtx m_group_io_ctx;
+ cls::rbd::GroupSpec m_group_spec;
+ cls::rbd::MirrorGroup m_mirror_group;
+
+ void get_group();
+ void handle_get_group(int r);
+
+ void get_mirror_group();
+ void handle_get_mirror_group(int r);
void remove_mirror_image();
void handle_remove_mirror_image(int r);
template <typename I>
void ImageStateUpdateRequest<I>::get_mirror_image() {
if (!m_mirror_image.global_image_id.empty()) {
- set_mirror_image();
+ if (m_mirror_image.state == m_mirror_image_state) {
+ finish(0);
+ return;
+ }
+
+ get_group();
return;
}
return;
}
- set_mirror_image();
+ if (m_mirror_image.state == m_mirror_image_state) {
+ finish(0);
+ return;
+ }
+
+ get_group();
}
template <typename I>
-void ImageStateUpdateRequest<I>::set_mirror_image() {
- if (m_mirror_image.state == m_mirror_image_state) {
- finish(0);
+void ImageStateUpdateRequest<I>::get_group() {
+ ldout(m_cct, 10) << dendl;
+ librados::ObjectReadOperation op;
+ cls_client::image_group_get_start(&op);
+
+ auto comp = create_rados_callback<
+ ImageStateUpdateRequest<I>,
+ &ImageStateUpdateRequest<I>::handle_get_group>(this);
+ m_out_bl.clear();
+ int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op,
+ &m_out_bl);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::handle_get_group(int r) {
+ ldout(m_cct, 10) << "r=" << r << dendl;
+
+ if (r == 0) {
+ auto iter = m_out_bl.cbegin();
+ r = cls_client::image_group_get_finish(&iter, &m_group_spec);
+ }
+
+ if (r < 0) {
+ lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r)
+ << dendl;
+ finish(r);
+ return;
+ }
+
+ get_mirror_group();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::get_mirror_group() {
+ if (!m_group_spec.is_valid()) {
+ m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+ set_mirror_image();
return;
} else if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLED ||
m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLING) {
m_mirror_image.group_spec = m_group_spec;
}
+ ldout(m_cct, 10) << dendl;
+
+ int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {},
+ &m_group_io_ctx);
+ if (r < 0) {
+ finish(r);
+ return;
+ }
+
+ librados::ObjectReadOperation op;
+ cls_client::mirror_group_get_start(&op, m_group_spec.group_id);
+
+ auto comp = create_rados_callback<
+ ImageStateUpdateRequest<I>,
+ &ImageStateUpdateRequest<I>::handle_get_mirror_group>(this);
+ m_out_bl.clear();
+ r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
+ ceph_assert(r == 0);
+ comp->release();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::handle_get_mirror_group(int r) {
+ ldout(m_cct, 10) << "r=" << r << dendl;
+
+ if (r == 0) {
+ auto iter = m_out_bl.cbegin();
+ r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group);
+ }
+
+ if (r == -ENOENT) {
+ m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+ } else if (r < 0) {
+ lderr(m_cct) << "failed to retrieve group mirroring state: "
+ << cpp_strerror(r) << dendl;
+ finish(r);
+ return;
+ }
+
+ set_mirror_image();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::set_mirror_image() {
ldout(m_cct, 10) << dendl;
m_mirror_image.state = m_mirror_image_state;
ldout(m_cct, 10) << "r=" << r << dendl;
if (r < 0) {
- lderr(m_cct) << "failed to disable mirroring image: " << cpp_strerror(r)
+ lderr(m_cct) << "failed to set mirror image: " << cpp_strerror(r)
<< dendl;
finish(r);
return;
template <typename I>
void ImageStateUpdateRequest<I>::notify_mirroring_watcher() {
+ // skip image notification if mirroring for the image group is disabled
+ if (m_mirror_group.state != cls::rbd::MIRROR_GROUP_STATE_DISABLED) {
+ finish(0);
+ return;
+ }
+
ldout(m_cct, 10) << dendl;
auto ctx = util::create_context_callback<
* GET_MIRROR_IMAGE
* |
* v
+ * GET_GROUP
+ * |
+ * v
+ * GET_MIRROR_GROUP (skip if no group)
+ * |
+ * v
* SET_MIRROR_IMAGE
* |
* v
- * NOTIFY_MIRRORING_WATCHER
+ * NOTIFY_MIRRORING_WATCHER (skip if not needed)
* |
* v
* <finish>
CephContext* m_cct;
bufferlist m_out_bl;
+ librados::IoCtx m_group_io_ctx;
+ cls::rbd::GroupSpec m_group_spec;
+ cls::rbd::MirrorGroup m_mirror_group;
void get_mirror_image();
void handle_get_mirror_image(int r);
+ void get_group();
+ void handle_get_group(int r);
+
+ void get_mirror_group();
+ void handle_get_mirror_group(int r);
+
void set_mirror_image();
void handle_set_mirror_image(int r);