From f3cd04c6885d5d6356960acce2ac2f014043cf39 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 15 Mar 2016 15:25:06 -0400 Subject: [PATCH] librbd: helper methods for manipulating journal tags from API Signed-off-by: Jason Dillaman --- src/librbd/Journal.cc | 148 ++++++++++++++++++++++++++++++------------ src/librbd/Journal.h | 5 +- 2 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index de42fefd57354..a775c5ac16621 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -159,6 +159,52 @@ public: } }; +template +int open_journaler(I *image_ctx, J *journaler, bool *initialized, + uint64_t *tag_class, journal::TagData *tag_data) { + C_SaferCond init_ctx; + journaler->init(&init_ctx); + int r = init_ctx.wait(); + *initialized = (r >= 0); + if (r < 0) { + return r; + } + + cls::journal::Client client; + r = journaler->get_cached_client(Journal::IMAGE_CLIENT_ID, &client); + if (r < 0) { + return r; + } + + librbd::journal::ClientData client_data; + bufferlist::iterator bl_it = client.data.begin(); + try { + ::decode(client_data, bl_it); + } catch (const buffer::error &err) { + return -EINVAL; + } + + librbd::journal::ImageClientMeta *image_client_meta = + boost::get(&client_data.client_meta); + if (image_client_meta == nullptr) { + return -EINVAL; + } + + C_SaferCond get_tags_ctx; + Mutex lock("lock"); + *tag_class = image_client_meta->tag_class; + uint64_t tag_tid; + C_DecodeTags *tags_ctx = new C_DecodeTags( + image_ctx->cct, &lock, &tag_tid, tag_data, &get_tags_ctx); + journaler->get_tags(*tag_class, &tags_ctx->tags, tags_ctx); + + r = get_tags_ctx.wait(); + if (r < 0) { + return r; + } + return 0; +} + } // anonymous namespace using util::create_async_context_callback; @@ -172,6 +218,10 @@ const std::string Journal::IMAGE_CLIENT_ID(""); template const std::string Journal::LOCAL_MIRROR_UUID(""); +// mirror uuid to use for orphaned (demoted) images +template +const std::string Journal::ORPHAN_MIRROR_UUID(""); + template std::ostream &operator<<(std::ostream &os, const typename Journal::State &state) { @@ -392,64 +442,76 @@ int Journal::reset(librados::IoCtx &io_ctx, const std::string &image_id) { } template -int Journal::is_tag_owner(ImageCtx *image_ctx, bool *is_tag_owner) { +int Journal::is_tag_owner(I *image_ctx, bool *is_tag_owner) { + std::string mirror_uuid; + int r = get_tag_owner(image_ctx, &mirror_uuid); + if (r < 0) { + return r; + } - cls::journal::Client client; - librbd::journal::ClientData client_data; - bufferlist::iterator bl; - journal::TagData tag_data; - uint64_t tag_class; - librbd::journal::ImageClientMeta *image_client_meta; - Mutex lock("lock"); - C_SaferCond get_tags_ctx; - C_DecodeTags *tags_ctx; + *is_tag_owner = (mirror_uuid == LOCAL_MIRROR_UUID); + return 0; +} + +template +int Journal::get_tag_owner(I *image_ctx, std::string *mirror_uuid) { + CephContext *cct = image_ctx->cct; + ldout(cct, 20) << __func__ << dendl; Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID, image_ctx->cct->_conf->rbd_journal_commit_age); - C_SaferCond init_ctx; - journaler.init(&init_ctx); - int r = init_ctx.wait(); - if (r < 0) { - return r; + bool initialized; + uint64_t tag_class; + journal::TagData tag_data; + int r = open_journaler(image_ctx, &journaler, &initialized, &tag_class, + &tag_data); + if (r >= 0) { + *mirror_uuid = tag_data.mirror_uuid; } - r = journaler.get_cached_client(Journal::IMAGE_CLIENT_ID, &client); - if (r < 0) { - goto clean_up; + if (initialized) { + journaler.shut_down(); } + return r; +} - bl = client.data.begin(); - try { - ::decode(client_data, bl); - } catch (const buffer::error &err) { - r = -EINVAL; - goto clean_up; - } +template +int Journal::allocate_tag(I *image_ctx, const std::string &mirror_uuid) { + CephContext *cct = image_ctx->cct; + ldout(cct, 20) << __func__ << ": mirror_uuid=" << mirror_uuid << dendl; - image_client_meta = - boost::get(&client_data.client_meta); - if (image_client_meta == nullptr) { - r = -EINVAL; - goto clean_up; - } + Journaler journaler(image_ctx->md_ctx, image_ctx->id, IMAGE_CLIENT_ID, + image_ctx->cct->_conf->rbd_journal_commit_age); - tag_class = image_client_meta->tag_class; - uint64_t tag_tid; - tags_ctx = new C_DecodeTags( - image_ctx->cct, &lock, &tag_tid, &tag_data, &get_tags_ctx); - journaler.get_tags(tag_class, &tags_ctx->tags, tags_ctx); + bool initialized; + uint64_t tag_class; + journal::TagData tag_data; + int r = open_journaler(image_ctx, &journaler, &initialized, &tag_class, + &tag_data); + if (r >= 0) { + journal::TagData tag_data; + tag_data.mirror_uuid = mirror_uuid; - r = get_tags_ctx.wait(); - if (r < 0) { - goto clean_up; - } + // TODO: inject current commit position into tag data + tag_data.predecessor_mirror_uuid = mirror_uuid; - *is_tag_owner = (tag_data.mirror_uuid == LOCAL_MIRROR_UUID); + bufferlist tag_bl; + ::encode(tag_data, tag_bl); -clean_up: - journaler.shut_down(); + C_SaferCond allocate_tag_ctx; + cls::journal::Tag tag; + journaler.allocate_tag(tag_class, tag_bl, &tag, &allocate_tag_ctx); + r = allocate_tag_ctx.wait(); + if (r < 0) { + lderr(cct) << "failed to allocate tag: " << cpp_strerror(r) << dendl; + } + } + + if (initialized) { + journaler.shut_down(); + } return r; } diff --git a/src/librbd/Journal.h b/src/librbd/Journal.h index a8d651363c130..871b8d047d038 100644 --- a/src/librbd/Journal.h +++ b/src/librbd/Journal.h @@ -96,6 +96,7 @@ public: static const std::string IMAGE_CLIENT_ID; static const std::string LOCAL_MIRROR_UUID; + static const std::string ORPHAN_MIRROR_UUID; typedef std::list AioObjectRequests; @@ -109,7 +110,9 @@ public: static int remove(librados::IoCtx &io_ctx, const std::string &image_id); static int reset(librados::IoCtx &io_ctx, const std::string &image_id); - static int is_tag_owner(ImageCtx *image_ctx, bool *is_tag_owner); + static int is_tag_owner(ImageCtxT *image_ctx, bool *is_tag_owner); + static int get_tag_owner(ImageCtxT *image_ctx, std::string *mirror_uuid); + static int allocate_tag(ImageCtxT *image_ctx, const std::string &mirror_uuid); bool is_journal_ready() const; bool is_journal_replaying() const; -- 2.39.5