From 7dfdf4f8de16155edd434534e161e06ba7c79d7d Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Mon, 23 Jul 2012 14:05:53 -0700 Subject: [PATCH] librbd: replace assign_bid with client id and random number The assign_bid method has issues with replay because it is a write that also returns data. This means that the replayed operation would return success, but no data, and cause a create to fail. Instead, let the client set the bid based on its global id and a random number. This only affects the creation of new images, since the bid is put into an opaque string as part of the object prefix. Keep the server side assign_bid around in case there are old clients still using it. Signed-off-by: Josh Durgin --- src/librbd.cc | 41 +++++++++--------------------------- src/librbd/cls_rbd_client.cc | 18 ---------------- src/librbd/cls_rbd_client.h | 3 --- 3 files changed, 10 insertions(+), 52 deletions(-) diff --git a/src/librbd.cc b/src/librbd.cc index 73fd6cbd639c0..754ac283fb726 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -586,8 +586,7 @@ namespace librbd { void trim_image(ImageCtx *ictx, uint64_t newsize, ProgressContext& prog_ctx); int read_rbd_info(IoCtx& io_ctx, const string& info_oid, struct rbd_info *info); - int touch_rbd_info(IoCtx& io_ctx, const string& info_oid); - int rbd_assign_bid(IoCtx& io_ctx, const string& info_oid, uint64_t *id); + uint64_t rbd_assign_bid(IoCtx& io_ctx); int read_header_bl(IoCtx& io_ctx, const string& md_oid, bufferlist& header, uint64_t *ver); int notify_change(IoCtx& io_ctx, const string& oid, uint64_t *pver, ImageCtx *ictx); int read_header(IoCtx& io_ctx, const string& md_oid, struct rbd_obj_header_ondisk *header, uint64_t *ver); @@ -661,13 +660,15 @@ void init_rbd_header(struct rbd_obj_header_ondisk& ondisk, { uint32_t hi = bid >> 32; uint32_t lo = bid & 0xFFFFFFFF; + uint32_t extra = rand() % 0xFFFFFFFF; memset(&ondisk, 0, sizeof(ondisk)); memcpy(&ondisk.text, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT)); memcpy(&ondisk.signature, RBD_HEADER_SIGNATURE, sizeof(RBD_HEADER_SIGNATURE)); memcpy(&ondisk.version, RBD_HEADER_VERSION, sizeof(RBD_HEADER_VERSION)); - snprintf(ondisk.block_name, sizeof(ondisk.block_name), "rb.%x.%x", hi, lo); + snprintf(ondisk.block_name, sizeof(ondisk.block_name), "rb.%x.%x.%x", + hi, lo, extra); ondisk.image_size = size; ondisk.options.order = *order; @@ -778,26 +779,10 @@ int read_rbd_info(IoCtx& io_ctx, const string& info_oid, struct rbd_info *info) return 0; } -int touch_rbd_info(IoCtx& io_ctx, const string& info_oid) +uint64_t rbd_assign_bid(IoCtx& io_ctx) { - bufferlist bl; - int r = io_ctx.write(info_oid, bl, 0, 0); - if (r < 0) - return r; - return 0; -} - -int rbd_assign_bid(IoCtx& io_ctx, const string& info_oid, uint64_t *id) -{ - int r = touch_rbd_info(io_ctx, info_oid); - if (r < 0) - return r; - - r = cls_client::assign_bid(&io_ctx, info_oid, id); - if (r < 0) - return r; - - return 0; + Rados rados(io_ctx); + return rados.get_instance_id(); } int read_header_bl(IoCtx& io_ctx, const string& header_oid, @@ -1006,14 +991,7 @@ int create(IoCtx& io_ctx, const char *imgname, uint64_t size, return -EDOM; } - uint64_t bid; - string dir_info = RBD_INFO; - r = rbd_assign_bid(io_ctx, dir_info, &bid); - if (r < 0) { - lderr(cct) << "failed to assign a block name for image" << dendl; - return r; - } - + uint64_t bid = rbd_assign_bid(io_ctx); ldout(cct, 2) << "adding rbd image to directory..." << dendl; r = tmap_set(io_ctx, imgname); if (r < 0) { @@ -1035,7 +1013,8 @@ int create(IoCtx& io_ctx, const char *imgname, uint64_t size, r = io_ctx.write(header_oid, bl, bl.length(), 0); } else { ostringstream oss; - oss << RBD_DATA_PREFIX << std::hex << bid; + uint32_t extra = rand() % 0xFFFFFFFF; + oss << RBD_DATA_PREFIX << std::hex << bid << std::hex << extra; r = cls_client::create_image(&io_ctx, header_oid, size, *order, features, oss.str()); } diff --git a/src/librbd/cls_rbd_client.cc b/src/librbd/cls_rbd_client.cc index cb42eb7c178c3..69b3fdd8b73a2 100644 --- a/src/librbd/cls_rbd_client.cc +++ b/src/librbd/cls_rbd_client.cc @@ -246,24 +246,6 @@ namespace librbd { return 0; } - int assign_bid(librados::IoCtx *ioctx, const std::string &oid, - uint64_t *id) - { - bufferlist bl, out; - int r = ioctx->exec(oid, "rbd", "assign_bid", bl, out); - if (r < 0) - return r; - - try { - bufferlist::iterator iter = out.begin(); - ::decode(*id, iter); - } catch (const buffer::error &err) { - return -EBADMSG; - } - - return 0; - } - int old_snapshot_add(librados::IoCtx *ioctx, const std::string &oid, uint64_t snap_id, const std::string &snap_name) { diff --git a/src/librbd/cls_rbd_client.h b/src/librbd/cls_rbd_client.h index 79654480546a0..2a9da7d079a6e 100644 --- a/src/librbd/cls_rbd_client.h +++ b/src/librbd/cls_rbd_client.h @@ -46,9 +46,6 @@ namespace librbd { std::vector *names, std::vector *sizes, std::vector *features); - int assign_bid(librados::IoCtx *ioctx, const std::string &oid, - uint64_t *id); - // class operations on the old format, kept for // backwards compatability -- 2.39.5