]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: specify copy src image as image handle
authorSage Weil <sage@newdream.net>
Mon, 22 Aug 2011 23:02:36 +0000 (16:02 -0700)
committerSage Weil <sage@newdream.net>
Mon, 22 Aug 2011 23:02:56 +0000 (16:02 -0700)
By specifying via an image handle we can set the snapshot on the src
image.  This also makes the API cleaner.

Fixes: #1416
Signed-off-by: Sage Weil <sage@newdream.net>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd.cc
src/rbd.cc

index 71858b8768994208171421534f12e39380820513..412e290260806116c5c595aa52df1cd58c3559b1 100644 (file)
@@ -62,13 +62,13 @@ void rbd_version(int *major, int *minor, int *extra);
 int rbd_list(rados_ioctx_t io, char *names, size_t *size);
 int rbd_create(rados_ioctx_t io, const char *name, uint64_t size, int *order);
 int rbd_remove(rados_ioctx_t io, const char *name);
-int rbd_copy(rados_ioctx_t src_io_ctx, const char *srcname, rados_ioctx_t dest_io_ctx, const char *destname);
 int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname, const char *destname);
 
 int rbd_open(rados_ioctx_t io, const char *name, rbd_image_t *image, const char *snap_name);
 int rbd_close(rbd_image_t image);
 int rbd_resize(rbd_image_t image, uint64_t size);
 int rbd_stat(rbd_image_t image, rbd_image_info_t *info, size_t infosize);
+int rbd_copy(rbd_image_t image, rados_ioctx_t dest_io_ctx, const char *destname);
 
 /* snapshots */
 int rbd_snap_list(rbd_image_t image, rbd_snap_info_t *snaps, int *max_snaps);
index 74d7728b8ddd7c007e53fbb5026cecec80e4994d..01ff4f4dc885e2f6bb22e0c7f5165c761adf0f5d 100644 (file)
@@ -62,7 +62,6 @@ public:
   int list(IoCtx& io_ctx, std::vector<std::string>& names);
   int create(IoCtx& io_ctx, const char *name, uint64_t size, int *order);
   int remove(IoCtx& io_ctx, const char *name);
-  int copy(IoCtx& src_io_ctx, const char *srcname, IoCtx& dest_io_ctx, const char *destname);
   int rename(IoCtx& src_io_ctx, const char *srcname, const char *destname);
 
 private:
@@ -79,6 +78,7 @@ public:
 
   int resize(uint64_t size);
   int stat(image_info_t &info, size_t infosize);
+  int copy(IoCtx& dest_io_ctx, const char *destname);
 
   /* snapshots */
   int snap_list(std::vector<snap_info_t>& snaps);
index ea3e0afd5f2eb41a8979dd46e3bba8d7b04790bc..5f3abba48cb4a17fca1d73cb0b6c263b93ab9b91 100644 (file)
@@ -246,7 +246,7 @@ namespace librbd {
   int rm_snap(ImageCtx *ictx, const char *snap_name);
   int ictx_check(ImageCtx *ictx);
   int ictx_refresh(ImageCtx *ictx, const char *snap_name);
-  int copy(IoCtx& src_md_ctx, const char *srcname, IoCtx& dest_md_ctx, const char *destname);
+  int copy(ImageCtx& srci, IoCtx& dest_md_ctx, const char *destname);
 
   int open_image(IoCtx& io_ctx, ImageCtx *ictx, const char *name, const char *snap_name);
   void close_image(ImageCtx *ictx);
@@ -265,6 +265,7 @@ namespace librbd {
   int rollback_image(ImageCtx *ictx, uint64_t snapid);
   void image_info(const rbd_obj_header_ondisk& header, image_info_t& info, size_t info_size);
   string get_block_oid(const rbd_obj_header_ondisk &header, uint64_t num);
+  uint64_t get_max_block(uint64_t size, int obj_order);
   uint64_t get_max_block(const rbd_obj_header_ondisk &header);
   uint64_t get_block_size(const rbd_obj_header_ondisk &header);
   uint64_t get_block_num(const rbd_obj_header_ondisk &header, uint64_t ofs);
@@ -364,16 +365,18 @@ string get_block_oid(const rbd_obj_header_ondisk &header, uint64_t num)
   return o;
 }
 
-uint64_t get_max_block(const rbd_obj_header_ondisk &header)
+uint64_t get_max_block(uint64_t size, int obj_order)
 {
-  uint64_t size = header.image_size;
-  int obj_order = header.options.order;
   uint64_t block_size = 1 << obj_order;
   uint64_t numseg = (size + block_size - 1) >> obj_order;
-
   return numseg;
 }
 
+uint64_t get_max_block(const rbd_obj_header_ondisk &header)
+{
+  return get_max_block(header.image_size, header.options.order);
+}
+
 uint64_t get_block_ofs(const rbd_obj_header_ondisk &header, uint64_t ofs)
 {
   int obj_order = header.options.order;
@@ -999,54 +1002,38 @@ int snap_rollback(ImageCtx *ictx, const char *snap_name)
   return 0;
 }
 
-int copy(IoCtx& src_md_ctx, const char *srcname, IoCtx& dest_md_ctx, const char *destname)
+int copy(ImageCtx& ictx, IoCtx& dest_md_ctx, const char *destname)
 {
-  CephContext *cct = src_md_ctx.cct();
-  struct rbd_obj_header_ondisk header, dest_header;
-  int64_t ret;
-  int r;
-  IoCtx src_data_ctx(src_md_ctx);
-  IoCtx dest_data_ctx(dest_md_ctx);
-  string md_oid, dest_md_oid;
-  md_oid = srcname;
-  md_oid += RBD_SUFFIX;
-
-  dest_md_oid = destname;
-  dest_md_oid += RBD_SUFFIX;
-
-  ret = read_header(src_md_ctx, md_oid, &header, NULL);
-  if (ret < 0)
-    return ret;
-
-  uint64_t numseg = get_max_block(header);
-  uint64_t block_size = get_block_size(header);
-  int order = header.options.order;
+  CephContext *cct = dest_md_ctx.cct();
+  struct rbd_obj_header_ondisk dest_header;
 
-  r = create(dest_md_ctx, destname, header.image_size, &order);
+  int order = ictx.header.options.order;
+  int r = create(dest_md_ctx, destname, ictx.header.image_size, &order);
   if (r < 0) {
     lderr(cct) << "header creation failed" << dendl;
     return r;
   }
 
-  ret = read_header(dest_md_ctx, dest_md_oid, &dest_header, NULL);
-  if (ret < 0) {
-    lderr(cct) << "failed to read newly created header" << dendl;
-    return ret;
+  uint64_t numseg = get_max_block(ictx.header);
+  if (ictx.snapname.length()) {
+    map<std::string,SnapInfo>::iterator p = ictx.snaps_by_name.find(ictx.snapname);
+    assert(p != ictx.snaps_by_name.end());
+    numseg = get_max_block(p->second.size, ictx.header.options.order);
   }
+  uint64_t block_size = get_block_size(ictx.header);
 
   for (uint64_t i = 0; i < numseg; i++) {
     bufferlist bl;
-    string oid = get_block_oid(header, i);
+    string oid = get_block_oid(ictx.header, i);
     string dest_oid = get_block_oid(dest_header, i);
     map<uint64_t, uint64_t> m;
     map<uint64_t, uint64_t>::iterator iter;
-    r = src_data_ctx.sparse_read(oid, m, bl, block_size, 0);
+    r = ictx.data_ctx.sparse_read(oid, m, bl, block_size, 0);
     if (r < 0 && r == -ENOENT)
       r = 0;
     if (r < 0)
       return r;
 
-
     for (iter = m.begin(); iter != m.end(); ++iter) {
       uint64_t extent_ofs = iter->first;
       size_t extent_len = iter->second;
@@ -1056,7 +1043,7 @@ int copy(IoCtx& src_md_ctx, const char *srcname, IoCtx& dest_md_ctx, const char
        return -EIO;
       }
       bl.copy(extent_ofs, extent_len, wrbl);
-      r = dest_data_ctx.write(dest_oid, wrbl, extent_len, extent_ofs);
+      r = dest_md_ctx.write(dest_oid, wrbl, extent_len, extent_ofs);
       if (r < 0)
        goto done;
     }
@@ -1064,7 +1051,7 @@ int copy(IoCtx& src_md_ctx, const char *srcname, IoCtx& dest_md_ctx, const char
   }
   r = 0;
 
-done:
+ done:
   return r;
 }
 
@@ -1514,12 +1501,6 @@ int RBD::list(IoCtx& io_ctx, std::vector<std::string>& names)
   return r;
 }
 
-int RBD::copy(IoCtx& src_io_ctx, const char *srcname, IoCtx& dest_io_ctx, const char *destname)
-{
-  int r = librbd::copy(src_io_ctx, srcname, dest_io_ctx, destname);
-  return r;
-}
-
 int RBD::rename(IoCtx& src_io_ctx, const char *srcname, const char *destname)
 {
   int r = librbd::rename(src_io_ctx, srcname, destname);
@@ -1582,6 +1563,12 @@ int Image::stat(image_info_t& info, size_t infosize)
   return r;
 }
 
+int Image::copy(IoCtx& dest_io_ctx, const char *destname)
+{
+  ImageCtx *ictx = (ImageCtx *)ctx;
+  int r = librbd::copy(*ictx, dest_io_ctx, destname);
+  return r;
+}
 
 int Image::snap_create(const char *snap_name)
 {
@@ -1712,12 +1699,12 @@ extern "C" int rbd_remove(rados_ioctx_t p, const char *name)
   return librbd::remove(io_ctx, name);
 }
 
-extern "C" int rbd_copy(rados_ioctx_t src_p, const char *srcname, rados_ioctx_t dest_p, const char *destname)
+extern "C" int rbd_copy(rbd_image_t image, rados_ioctx_t dest_p, const char *destname)
 {
-  librados::IoCtx src_io_ctx, dest_io_ctx;
-  librados::IoCtx::from_rados_ioctx_t(src_p, src_io_ctx);
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  librados::IoCtx dest_io_ctx;
   librados::IoCtx::from_rados_ioctx_t(dest_p, dest_io_ctx);
-  return librbd::copy(src_io_ctx, srcname, dest_io_ctx, destname);
+  return librbd::copy(*ictx, dest_io_ctx, destname);
 }
 
 extern "C" int rbd_rename(rados_ioctx_t src_p, const char *srcname, const char *destname)
index d331ed083457aa1de1d0fbc8ffbdf6222a4c13c1..a18c0294ab9dc115951814ccc6df0c49ea3f4c71 100644 (file)
@@ -463,11 +463,10 @@ done:
   return r;
 }
 
-static int do_copy(librbd::RBD &rbd, librados::IoCtx& pp,
-          const char *imgname, librados::IoCtx& dest_pp,
-          const char *destname)
+static int do_copy(librbd::Image &src, librados::IoCtx& dest_pp,
+                  const char *destname)
 {
-  int r = rbd.copy(pp, imgname, dest_pp, destname);
+  int r = src.copy(dest_pp, destname);
   if (r < 0)
     return r;
   return 0;
@@ -966,7 +965,8 @@ int main(int argc, const char **argv)
   if (imgname &&
       (opt_cmd == OPT_RESIZE || opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST ||
        opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK ||
-       opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_EXPORT || opt_cmd == OPT_WATCH)) {
+       opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_EXPORT || opt_cmd == OPT_WATCH ||
+       opt_cmd == OPT_COPY)) {
     r = rbd.open(io_ctx, image, imgname);
     if (r < 0) {
       cerr << "error opening image " << imgname << ": " << strerror(r) << std::endl;
@@ -1128,7 +1128,7 @@ int main(int argc, const char **argv)
     break;
 
   case OPT_COPY:
-    r = do_copy(rbd, io_ctx, imgname, dest_io_ctx, destname);
+    r = do_copy(image, dest_io_ctx, destname);
     if (r < 0) {
       cerr << "copy failed: " << strerror(-r) << std::endl;
       exit(1);