From: Sage Weil Date: Mon, 22 Aug 2011 23:02:36 +0000 (-0700) Subject: librbd: specify copy src image as image handle X-Git-Tag: v0.35~282 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a585c4d4fe09c1b9e7d818334b78b57b105dbb07;p=ceph.git librbd: specify copy src image as image handle 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 --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 71858b876899..412e29026080 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -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); diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index 74d7728b8ddd..01ff4f4dc885 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -62,7 +62,6 @@ public: int list(IoCtx& io_ctx, std::vector& 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& snaps); diff --git a/src/librbd.cc b/src/librbd.cc index ea3e0afd5f2e..5f3abba48cb4 100644 --- a/src/librbd.cc +++ b/src/librbd.cc @@ -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::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 m; map::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& 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) diff --git a/src/rbd.cc b/src/rbd.cc index d331ed083457..a18c0294ab9d 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -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);