From: xinxin shu Date: Fri, 21 Aug 2015 07:11:50 +0000 (+0800) Subject: add snapshot rename CLI X-Git-Tag: v10.0.0~10^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d139f353d343f38e6312ed3233b3ba9a7c90a7e7;p=ceph.git add snapshot rename CLI Signed-off-by: xinxin shu --- diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 690dbbd50744..2eb3aa5e9542 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -189,6 +189,8 @@ CEPH_RBD_API int rbd_snap_rollback_with_progress(rbd_image_t image, const char *snapname, librbd_progress_fn_t cb, void *cbdata); +CEPH_RBD_API int rbd_snap_rename(rbd_image_t image, const char *snapname, + const char* dstsnapsname); /** * Prevent a snapshot from being deleted until it is unprotected. * diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index e5879164f28c..0c41b8e184a6 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -165,6 +165,7 @@ public: int snap_unprotect(const char *snap_name); int snap_is_protected(const char *snap_name, bool *is_protected); int snap_set(const char *snap_name); + int snap_rename(const char *srcname, const char *dstname); /* I/O */ ssize_t read(uint64_t ofs, size_t len, ceph::bufferlist& bl); diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 3e860322c991..5682e7ec7172 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -288,6 +288,7 @@ public: plb.add_u64_counter(l_librbd_snap_create, "snap_create", "Snap creations"); plb.add_u64_counter(l_librbd_snap_remove, "snap_remove", "Snap removals"); plb.add_u64_counter(l_librbd_snap_rollback, "snap_rollback", "Snap rollbacks"); + plb.add_u64_counter(l_librbd_snap_rename, "snap_rename", "Snap rename"); plb.add_u64_counter(l_librbd_notify, "notify", "Updated header notifications"); plb.add_u64_counter(l_librbd_resize, "resize", "Resizes"); plb.add_u64_counter(l_librbd_readahead, "readahead", "Read ahead"); diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 49d6a34f90e7..5ac79f2b230f 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -496,6 +496,16 @@ int ImageWatcher::notify_snap_create(const std::string &snap_name) { return notify_lock_owner(bl); } +int ImageWatcher::notify_snap_rename(const snapid_t &src_snap_id, + const std::string &dst_snap_name) { + assert(m_image_ctx.owner_lock.is_locked()); + assert(!is_lock_owner()); + + bufferlist bl; + ::encode(NotifyMessage(SnapRenamePayload(src_snap_id, dst_snap_name)), bl); + + return notify_lock_owner(bl); +} int ImageWatcher::notify_snap_remove(const std::string &snap_name) { assert(m_image_ctx.owner_lock.is_locked()); assert(!is_lock_owner()); diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index 29645b48778f..9099e1685d02 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -50,6 +50,7 @@ namespace librbd { int notify_resize(uint64_t request_id, uint64_t size, ProgressContext &prog_ctx); int notify_snap_create(const std::string &snap_name); + int notify_snap_rename(const snapid_t &src_snap_id, const std::string &dst_snap_name); int notify_snap_remove(const std::string &snap_name); int notify_rebuild_object_map(uint64_t request_id, ProgressContext &prog_ctx); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index 9f4b2ad4a818..fce3d0608e52 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -644,6 +644,45 @@ int invoke_async_request(ImageCtx *ictx, const std::string& request_type, return 0; } + int snap_rename(ImageCtx *ictx, const char *srcname, const char *dstname) + { + ldout(ictx->cct, 20) << "snap_rename " << ictx << " from " << srcname << " to " << dstname << dendl; + + snapid_t snap_id; + if (ictx->read_only) { + return -EROFS; + } + + int r = ictx_check(ictx); + if (r < 0) + return r; + + { + RWLock::RLocker l(ictx->snap_lock); + snap_id = ictx->get_snap_id(srcname); + if (snap_id == CEPH_NOSNAP) { + return -ENOENT; + } + if (ictx->get_snap_id(dstname) != CEPH_NOSNAP) { + return -EEXIST; + } + } + + r = invoke_async_request(ictx, "snap_rename", true, + boost::bind(&snap_rename_helper, ictx, _1, + snap_id, dstname), + boost::bind(&ImageWatcher::notify_snap_rename, + ictx->image_watcher, snap_id, + dstname)); + if (r < 0 && r != -EEXIST) { + return r; + } + + ictx->perfcounter->inc(l_librbd_snap_rename); + notify_change(ictx->md_ctx, ictx->header_oid, ictx); + return 0; + } + int snap_rename_helper(ImageCtx* ictx, Context* ctx, const uint64_t src_snap_id, const char* dst_name) { diff --git a/src/librbd/internal.h b/src/librbd/internal.h index 6ce385f679ff..3d35ee0bc29a 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -34,6 +34,7 @@ enum { l_librbd_snap_create, l_librbd_snap_remove, l_librbd_snap_rollback, + l_librbd_snap_rename, l_librbd_notify, l_librbd_resize, @@ -112,6 +113,7 @@ namespace librbd { int snap_remove_helper(ImageCtx *ictx, Context* ctx, const char *snap_name); int snap_rename_helper(ImageCtx *ictx, Context* ctx, const uint64_t src_snap_id, const char *dst_name); + int snap_rename(ImageCtx *ictx, const char *srcname, const char *dstname); int snap_protect(ImageCtx *ictx, const char *snap_name); int snap_unprotect(ImageCtx *ictx, const char *snap_name); int snap_is_protected(ImageCtx *ictx, const char *snap_name, diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index e802e9ce9e57..6ccabb4dcbfa 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -685,6 +685,15 @@ namespace librbd { return r; } + int Image::snap_rename(const char *srcname, const char *dstname) + { + ImageCtx *ictx = (ImageCtx *)ctx; + tracepoint(librbd, snap_rename_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, srcname, dstname); + int r = librbd::snap_rename(ictx, srcname, dstname); + tracepoint(librbd, snap_rename_exit, r); + return r; + } + int Image::snap_rollback_with_progress(const char *snap_name, ProgressContext& prog_ctx) { @@ -1446,6 +1455,15 @@ extern "C" int rbd_snap_create(rbd_image_t image, const char *snap_name) return r; } +extern "C" int rbd_snap_rename(rbd_image_t image, const char *srcname, const char *dstname) +{ + librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; + tracepoint(librbd, snap_rename_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, srcname, dstname); + int r = librbd::snap_rename(ictx, srcname, dstname); + tracepoint(librbd, snap_rename_exit, r); + return r; +} + extern "C" int rbd_snap_remove(rbd_image_t image, const char *snap_name) { librbd::ImageCtx *ictx = (librbd::ImageCtx *)image; diff --git a/src/rbd.cc b/src/rbd.cc index f8330ff45f0c..33bee9e24942 100755 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -147,6 +147,7 @@ void usage() " snap purge deletes all snapshots\n" " snap protect prevent a snapshot from being deleted\n" " snap unprotect allow a snapshot to be deleted\n" +" snap rename rename a snapshot\n" " watch watch events on image\n" " status show the status of this image\n" " map | map image to a block device\n" @@ -768,6 +769,15 @@ static int do_rollback_snap(librbd::Image& image, const char *snapname) return 0; } +static int do_rename_snap(librbd::Image& image, const char *srcname, const char *dstname) +{ + int r = image.snap_rename(srcname, dstname); + if (r < 0) + return r; + + return 0; +} + static int do_purge_snaps(librbd::Image& image) { MyProgressContext pc("Removing all snapshots"); @@ -2884,6 +2894,7 @@ enum { OPT_SNAP_PURGE, OPT_SNAP_PROTECT, OPT_SNAP_UNPROTECT, + OPT_SNAP_RENAME, OPT_WATCH, OPT_STATUS, OPT_MAP, @@ -2979,6 +2990,8 @@ static int get_cmd(const char *cmd, CommandType command_type) return OPT_SNAP_PROTECT; if (strcmp(cmd, "unprotect") == 0) return OPT_SNAP_UNPROTECT; + if (strcmp(cmd, "rename") == 0) + return OPT_SNAP_RENAME; break; case COMMAND_TYPE_METADATA: if (strcmp(cmd, "list") == 0) @@ -3347,6 +3360,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ case OPT_COPY: case OPT_RENAME: case OPT_CLONE: + case OPT_SNAP_RENAME: SET_CONF_PARAM(v, &imgname, &destname, NULL); break; case OPT_SHOWMAPPED: @@ -3492,7 +3506,7 @@ if (!set_conf_param(v, p1, p2, p3)) { \ opt_cmd != OPT_MAP && opt_cmd != OPT_UNMAP && opt_cmd != OPT_CLONE && opt_cmd != OPT_SNAP_PROTECT && opt_cmd != OPT_SNAP_UNPROTECT && opt_cmd != OPT_CHILDREN && opt_cmd != OPT_OBJECT_MAP_REBUILD && - opt_cmd != OPT_DISK_USAGE) { + opt_cmd != OPT_DISK_USAGE && opt_cmd != OPT_SNAP_RENAME) { cerr << "rbd: snapname specified for a command that doesn't use it" << std::endl; return EXIT_FAILURE; @@ -3500,19 +3514,23 @@ if (!set_conf_param(v, p1, p2, p3)) { \ if ((opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK || opt_cmd == OPT_SNAP_REMOVE || opt_cmd == OPT_CLONE || opt_cmd == OPT_SNAP_PROTECT || opt_cmd == OPT_SNAP_UNPROTECT || - opt_cmd == OPT_CHILDREN) && !snapname) { + opt_cmd == OPT_CHILDREN || opt_cmd == OPT_SNAP_RENAME) && !snapname) { cerr << "rbd: snap name was not specified" << std::endl; return EXIT_FAILURE; } set_pool_image_name(destname, (char **)&dest_poolname, (char **)&destname, (char **)&dest_snapname); - if (dest_snapname) { + if (dest_snapname && opt_cmd != OPT_SNAP_RENAME) { // no command uses dest_snapname cerr << "rbd: destination snapname specified for a command that doesn't use it" << std::endl; return EXIT_FAILURE; } + if (opt_cmd == OPT_SNAP_RENAME && !dest_snapname) { + cerr << "rbd: destination snap name was not specified" << std::endl; + return EXIT_FAILURE; + } if (opt_cmd == OPT_IMPORT) { if (poolname && dest_poolname) { @@ -3651,7 +3669,8 @@ if (!set_conf_param(v, p1, p2, p3)) { \ opt_cmd == OPT_METADATA_SET || opt_cmd == OPT_METADATA_LIST || opt_cmd == OPT_METADATA_REMOVE || opt_cmd == OPT_METADATA_GET || opt_cmd == OPT_FEATURE_DISABLE || opt_cmd == OPT_FEATURE_ENABLE || - opt_cmd == OPT_OBJECT_MAP_REBUILD || opt_cmd == OPT_DISK_USAGE)) { + opt_cmd == OPT_OBJECT_MAP_REBUILD || opt_cmd == OPT_DISK_USAGE || + opt_cmd == OPT_SNAP_RENAME)) { if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST || opt_cmd == OPT_EXPORT || opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY || @@ -3832,6 +3851,15 @@ if (!set_conf_param(v, p1, p2, p3)) { \ } break; + case OPT_SNAP_RENAME: + r = do_rename_snap(image, snapname, dest_snapname); + if (r < 0) { + cerr << "rbd: failed to rename snapshot: " << cpp_strerror(-r) + << std::endl; + return -r; + } + break; + case OPT_SNAP_ROLLBACK: r = do_rollback_snap(image, snapname); if (r < 0) { diff --git a/src/tracing/librbd.tp b/src/tracing/librbd.tp index f9101bd92e3c..542084918e2f 100644 --- a/src/tracing/librbd.tp +++ b/src/tracing/librbd.tp @@ -966,6 +966,32 @@ TRACEPOINT_EVENT(librbd, snap_rollback_exit, ) ) +TRACEPOINT_EVENT(librbd, snap_rename_enter, + TP_ARGS( + void*, imagectx, + const char*, name, + const char*, snap_name, + char, read_only, + const char*, src_snap_name, + const char*, dst_snap_name), + TP_FIELDS( + ctf_integer_hex(void*, imagectx, imagectx) + ctf_string(name, name) + ctf_string(snap_name, snap_name) + ctf_integer(char, read_only, read_only) + ctf_string(src_snap_name, src_snap_name) + ctf_string(dst_snap_name, dst_snap_name) + ) +) + +TRACEPOINT_EVENT(librbd, snap_rename_exit, + TP_ARGS( + int, retval), + TP_FIELDS( + ctf_integer(int, retval, retval) + ) +) + TRACEPOINT_EVENT(librbd, snap_list_enter, TP_ARGS( void*, imagectx,