From: Ricardo Dias Date: Thu, 10 Mar 2016 13:02:59 +0000 (+0000) Subject: rbd: rbd-mirroring: Support mirroring image disable in librbd X-Git-Tag: v10.1.0~94^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ec15120034edf25e88a7bbf7cb6f83386c607d07;p=ceph.git rbd: rbd-mirroring: Support mirroring image disable in librbd Signed-off-by: Ricardo Dias --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 6a18b1e3dadf..09ac2aa1904d 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -588,6 +588,7 @@ CEPH_RBD_API int rbd_metadata_list(rbd_image_t image, const char *start, uint64_ CEPH_RBD_API int rbd_mirror_image_enable(rbd_image_t image); +CEPH_RBD_API int rbd_mirror_image_disable(rbd_image_t image, bool force); #ifdef __cplusplus } diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index f1c8fc92e821..d16fd444b364 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -322,6 +322,7 @@ public: int metadata_list(const std::string &start, uint64_t max, std::map *pairs); int mirror_image_enable(); + int mirror_image_disable(bool force); private: friend class RBD; diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index e8761014af4e..b282d1df493f 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -19,6 +19,8 @@ #include "cls/rbd/cls_rbd.h" #include "cls/rbd/cls_rbd_client.h" +#include "cls/journal/cls_journal_types.h" +#include "cls/journal/cls_journal_client.h" #include "librbd/AioCompletion.h" #include "librbd/AioImageRequest.h" @@ -32,6 +34,7 @@ #include "librbd/ImageWatcher.h" #include "librbd/internal.h" #include "librbd/Journal.h" +#include "librbd/journal/Types.h" #include "librbd/ObjectMap.h" #include "librbd/Operations.h" #include "librbd/parent_types.h" @@ -39,6 +42,8 @@ #include "librbd/operation/TrimRequest.h" #include "include/util.h" +#include "journal/Journaler.h" + #include #include #include @@ -2365,6 +2370,119 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { return 0; } + int mirror_image_disable(ImageCtx *ictx, bool force) { + CephContext *cct = ictx->cct; + ldout(cct, 20) << "mirror_image_disable " << ictx << dendl; + + cls::rbd::MirrorImage mirror_image_internal; + std::vector snaps; + std::set clients; + std::string header_oid; + + bool is_primary; + int r = Journal<>::is_tag_owner(ictx, &is_primary); + if (r < 0) { + lderr(cct) << "cannot disable mirroring: failed to check tag ownership: " + << cpp_strerror(r) << dendl; + return r; + } + + if (!is_primary) { + if (!force) { + lderr(cct) << "Mirrored image is not the primary, add force option to" + " disable mirroring" << dendl; + return -EINVAL; + } + goto remove_mirroring_image; + } + + r = cls_client::mirror_image_get(&ictx->md_ctx, ictx->id, + &mirror_image_internal); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; + return r; + } + else if (r == -ENOENT) { + // mirroring is not enabled for this image + ldout(cct, 20) << "ignoring disable command: mirroring is not enabled " + "for this image" << dendl; + return 0; + } + + mirror_image_internal.state = + cls::rbd::MirrorImageState::MIRROR_IMAGE_STATE_DISABLING; + r = cls_client::mirror_image_set(&ictx->md_ctx, ictx->id, + mirror_image_internal); + if (r < 0) { + lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; + return r; + } + + header_oid = ::journal::Journaler::header_oid(ictx->id); + + while(true) { + r = cls::journal::client::client_list(ictx->md_ctx, header_oid, &clients); + if (r < 0) { + lderr(cct) << "cannot disable mirroring: " << cpp_strerror(r) << dendl; + return r; + } + + assert(clients.size() >= 1); + + if (clients.size() == 1) { + // only local journal client remains + break; + } + + for (auto client : clients) { + journal::ClientData client_data; + bufferlist::iterator bl = client.data.begin(); + ::decode(client_data, bl); + journal::ClientMetaType type = client_data.get_client_meta_type(); + + if (type != journal::ClientMetaType::MIRROR_PEER_CLIENT_META_TYPE) { + continue; + } + + journal::MirrorPeerClientMeta client_meta = + boost::get(client_data.client_meta); + + for (const auto& sync : client_meta.sync_points) { + r = ictx->operations->snap_remove(sync.snap_name.c_str()); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "cannot disable mirroring: failed to remove temporary" + " snapshot created by remote peer: " << cpp_strerror(r) << dendl; + return r; + } + } + + r = cls::journal::client::client_unregister(ictx->md_ctx, header_oid, + client.id); + if (r < 0 && r != -ENOENT) { + lderr(cct) << "cannot disable mirroring: failed to unregister remote" + " journal client: " << cpp_strerror(r) << dendl; + return r; + } + } + } + + remove_mirroring_image: + r = cls_client::mirror_image_remove(&ictx->md_ctx, ictx->id); + if (r < 0) { + lderr(cct) << "failed to remove image from mirroring directory: " + << cpp_strerror(r) << dendl; + return r; + } + + ldout(cct, 20) << "removed image state from rbd_mirroring object" << dendl; + + if (is_primary) { + // TODO: send notification to mirroring object about update + } + + return 0; + } + int mirror_mode_get(IoCtx& io_ctx, rbd_mirror_mode_t *mirror_mode) { CephContext *cct = reinterpret_cast(io_ctx.cct()); ldout(cct, 20) << __func__ << dendl; diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 7457ddb3ad24..6a3a5bc37aac 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -184,6 +184,7 @@ namespace librbd { const std::string &cluster_name); int mirror_image_enable(ImageCtx *ictx); + int mirror_image_disable(ImageCtx *ictx, bool force); } #endif diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 57fc3fbdf67d..f118488e787a 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -1231,6 +1231,11 @@ namespace librbd { return librbd::mirror_image_enable(ictx); } + int Image::mirror_image_disable(bool force) { + ImageCtx *ictx = (ImageCtx *)ctx; + return librbd::mirror_image_disable(ictx, force); + } + } // namespace librbd extern "C" void rbd_version(int *major, int *minor, int *extra) @@ -2564,6 +2569,12 @@ extern "C" int rbd_mirror_image_enable(rbd_image_t image) return librbd::mirror_image_enable(ictx); } +extern "C" int rbd_mirror_image_disable(rbd_image_t image, bool force) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + return librbd::mirror_image_disable(ictx, force); +} + extern "C" int rbd_aio_is_complete(rbd_completion_t c) { librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;