From 3694968a052cec3c1b5e88fec50c4444c28ca6ce Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 28 Mar 2013 21:17:21 -0700 Subject: [PATCH] librbd: implement image.snap_exists() This is a much more convenient way to tell if a snapshot already exists. Signed-off-by: Sage Weil --- src/include/rbd/librbd.hpp | 1 + src/librbd/internal.cc | 13 +++++++++++++ src/librbd/internal.h | 1 + src/librbd/librbd.cc | 6 ++++++ src/test/librbd/test_librbd.cc | 6 ++++++ 5 files changed, 27 insertions(+) diff --git a/src/include/rbd/librbd.hpp b/src/include/rbd/librbd.hpp index bf331d5e69e..d061bdbe4eb 100644 --- a/src/include/rbd/librbd.hpp +++ b/src/include/rbd/librbd.hpp @@ -142,6 +142,7 @@ public: /* snapshots */ int snap_list(std::vector& snaps); + bool snap_exists(const char *snapname); int snap_create(const char *snapname); int snap_remove(const char *snapname); int snap_rollback(const char *snap_name); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index a7812e6c611..4daa5b801db 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1462,6 +1462,19 @@ reprotect_and_return_err: return 0; } + bool snap_exists(ImageCtx *ictx, const char *snap_name) + { + ldout(ictx->cct, 20) << "snap_exists " << ictx << " " << snap_name << dendl; + + int r = ictx_check(ictx); + if (r < 0) + return r; + + RWLock::RLocker l(ictx->snap_lock); + return ictx->snaps_by_name.count(snap_name); + } + + int add_snap(ImageCtx *ictx, const char *snap_name) { uint64_t snap_id; diff --git a/src/librbd/internal.h b/src/librbd/internal.h index b78155afdae..e0ea13ba496 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -102,6 +102,7 @@ namespace librbd { int resize_helper(ImageCtx *ictx, uint64_t size, ProgressContext& prog_ctx); int snap_create(ImageCtx *ictx, const char *snap_name); int snap_list(ImageCtx *ictx, std::vector& snaps); + bool snap_list(ImageCtx *ictx, const char *snap_name); int snap_rollback(ImageCtx *ictx, const char *snap_name, ProgressContext& prog_ctx); int snap_remove(ImageCtx *ictx, const char *snap_name); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 06e4a6e23fc..b522288b6a7 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -414,6 +414,12 @@ namespace librbd { return librbd::snap_list(ictx, snaps); } + bool Image::snap_exists(const char *snap_name) + { + ImageCtx *ictx = (ImageCtx *)ctx; + return librbd::snap_exists(ictx, snap_name); + } + int Image::snap_set(const char *snap_name) { ImageCtx *ictx = (ImageCtx *)ctx; diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index 9ae72c704a2..ff083ae817f 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -566,14 +566,20 @@ TEST(LibRBD, TestCreateLsDeleteSnapPP) ASSERT_EQ(0, create_image_pp(rbd, ioctx, name, size, &order)); ASSERT_EQ(0, rbd.open(ioctx, image, name, NULL)); + ASSERT_FALSE(image.snap_exists("snap1")); ASSERT_EQ(0, image.snap_create("snap1")); + ASSERT_TRUE(image.snap_exists("snap1")); ASSERT_EQ(1, test_ls_snaps(image, 1, "snap1", size)); ASSERT_EQ(0, image.resize(size2)); + ASSERT_FALSE(image.snap_exists("snap2")); ASSERT_EQ(0, image.snap_create("snap2")); + ASSERT_TRUE(image.snap_exists("snap2")); ASSERT_EQ(2, test_ls_snaps(image, 2, "snap1", size, "snap2", size2)); ASSERT_EQ(0, image.snap_remove("snap1")); + ASSERT_FALSE(image.snap_exists("snap1")); ASSERT_EQ(1, test_ls_snaps(image, 1, "snap2", size2)); ASSERT_EQ(0, image.snap_remove("snap2")); + ASSERT_FALSE(image.snap_exists("snap2")); ASSERT_EQ(0, test_ls_snaps(image, 0)); }