From: Ricardo Dias Date: Tue, 22 Mar 2016 12:24:03 +0000 (+0000) Subject: rbd: rbd-mirroring: Disable image mirroring when pool-level mirroring is disabled X-Git-Tag: v10.1.1~78^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=490dc4f3d8cc95470d00ba312930d2a9b63a0982;p=ceph.git rbd: rbd-mirroring: Disable image mirroring when pool-level mirroring is disabled Signed-off-by: Ricardo Dias Fixes: #15217 --- diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 8de3d53bbced..3d2b6df7b81f 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -2779,6 +2779,34 @@ int validate_mirroring_enabled(ImageCtx *ictx) { return 0; } + int list_mirror_images(IoCtx& io_ctx, + std::set& mirror_image_ids) { + CephContext *cct = reinterpret_cast(io_ctx.cct()); + + std::string last_read = ""; + int max_read = 1024; + int r; + do { + std::map mirror_images; + r = cls_client::mirror_image_list(&io_ctx, last_read, max_read, + &mirror_images); + if (r < 0) { + lderr(cct) << "error listing mirrored image directory: " + << cpp_strerror(r) << dendl; + return r; + } + for (auto it = mirror_images.begin(); it != mirror_images.end(); ++it) { + mirror_image_ids.insert(it->first); + } + if (!mirror_images.empty()) { + last_read = mirror_images.rbegin()->first; + } + r = mirror_images.size(); + } while (r == max_read); + + return 0; + } + int mirror_mode_set(IoCtx& io_ctx, rbd_mirror_mode_t mirror_mode) { CephContext *cct = reinterpret_cast(io_ctx.cct()); ldout(cct, 20) << __func__ << dendl; @@ -2911,6 +2939,50 @@ int validate_mirroring_enabled(ImageCtx *ictx) { return r; } + rb_state.img_ctxs.push_back(std::make_pair(img_ctx, true)); + } + } + } else if (next_mirror_mode == cls::rbd::MIRROR_MODE_DISABLED) { + + std::set image_ids; + r = list_mirror_images(io_ctx, image_ids); + if (r < 0) { + lderr(cct) << "Failed listing images: " << cpp_strerror(r) << dendl; + return r; + } + + for (const auto& img_id : image_ids) { + if (current_mirror_mode == cls::rbd::MIRROR_MODE_IMAGE) { + cls::rbd::MirrorImage mirror_image; + r = cls_client::mirror_image_get(&io_ctx, img_id, &mirror_image); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "failed to retrieve mirroring state for image id " + << img_id << ": " << cpp_strerror(r) << dendl; + return r; + } + if (mirror_image.state == cls::rbd::MIRROR_IMAGE_STATE_ENABLED) { + lderr(cct) << "Failed to disable mirror mode: there are still " + "images with mirroring enabled" << dendl; + return -EINVAL; + } + } else { + ImageCtx *img_ctx = new ImageCtx("", img_id, nullptr, io_ctx, false); + r = img_ctx->state->open(); + if (r < 0) { + lderr(cct) << "error opening image id "<< img_id << ": " + << cpp_strerror(r) << dendl; + delete img_ctx; + return r; + } + + r = mirror_image_disable(img_ctx, false); + if (r < 0) { + lderr(cct) << "error disabling mirroring for image id " << img_id + << cpp_strerror(r) << dendl; + rb_state.img_ctxs.push_back(std::make_pair(img_ctx, false)); + return r; + } + rb_state.img_ctxs.push_back(std::make_pair(img_ctx, true)); } }