]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: replace assign_bid with client id and random number
authorJosh Durgin <josh.durgin@inktank.com>
Mon, 23 Jul 2012 21:05:53 +0000 (14:05 -0700)
committerSage Weil <sage@inktank.com>
Tue, 24 Jul 2012 00:16:01 +0000 (17:16 -0700)
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 <josh.durgin@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
src/librbd.cc
src/librbd/cls_rbd_client.cc
src/librbd/cls_rbd_client.h

index 48387f62a1574f46c4c11ed7027dee0424d98bf1..cb76fa2d9d7abd01197c0695d76756181cf8f62a 100644 (file)
@@ -637,8 +637,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);
@@ -744,13 +743,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;
@@ -862,26 +863,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,
@@ -1110,15 +1095,14 @@ int create(IoCtx& io_ctx, const char *imgname, uint64_t size,
     return -EDOM;
   }
 
-  uint64_t bid;
+  uint64_t bid = rbd_assign_bid(io_ctx);
   string dir_info = RBD_INFO;
-  r = rbd_assign_bid(io_ctx, dir_info, &bid);
+  r = rbd_assign_bid(io_ctx);
   if (r < 0) {
     lderr(cct) << "failed to assign a block name for image" << dendl;
     return r;
   }
 
-
   if (!*order)
     *order = RBD_DEFAULT_OBJ_ORDER;
 
@@ -1164,7 +1148,8 @@ int create(IoCtx& io_ctx, const char *imgname, uint64_t size,
     }
 
     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_name(id), size, *order, features,
                                 oss.str());
   }
index 63b1364cf2f6dd531d7cde3442023a0634ab0864..0ecf2f5a18bcbca7d171e46dbe855fd594b3b2f2 100644 (file)
@@ -299,24 +299,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,
                         snapid_t snap_id, const std::string &snap_name)
     {
index c7b1d5ee05f3d6374bac23295d7d6d92c4bd8e84..a30b1ad7aefe55e8179aba1bd790eabb2b6c37b0 100644 (file)
@@ -58,9 +58,6 @@ namespace librbd {
                      std::vector<string> *names,
                      std::vector<uint64_t> *sizes,
                      std::vector<uint64_t> *features);
-    int assign_bid(librados::IoCtx *ioctx, const std::string &oid,
-                  uint64_t *id);
-
     int list_locks(librados::IoCtx *ioctx, const std::string &oid,
                    std::set<std::pair<std::string, std::string> > &locks,
                    bool &exclusive);