]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add snapshot trash namespace helper and remove_by_id
authorJason Dillaman <dillaman@redhat.com>
Fri, 22 Jun 2018 18:07:56 +0000 (14:07 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 23 Jul 2018 14:19:53 +0000 (10:19 -0400)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/api/Snapshot.cc
src/librbd/api/Snapshot.h
src/librbd/librbd.cc
src/test/librbd/test_librbd.cc

index 811bccb7ea825239ac34a5037b895df9db7ad704..c7b83ac1001f198018e73900efc226b5470003be 100644 (file)
@@ -486,6 +486,7 @@ CEPH_RBD_API int rbd_snap_create(rbd_image_t image, const char *snapname);
 CEPH_RBD_API int rbd_snap_remove(rbd_image_t image, const char *snapname);
 CEPH_RBD_API int rbd_snap_remove2(rbd_image_t image, const char *snap_name, uint32_t flags,
                                  librbd_progress_fn_t cb, void *cbdata);
+CEPH_RBD_API int rbd_snap_remove_by_id(rbd_image_t image, uint64_t snap_id);
 CEPH_RBD_API int rbd_snap_rollback(rbd_image_t image, const char *snapname);
 CEPH_RBD_API int rbd_snap_rollback_with_progress(rbd_image_t image,
                                                  const char *snapname,
@@ -556,6 +557,10 @@ CEPH_RBD_API int rbd_snap_get_group_namespace(rbd_image_t image,
                                               size_t group_snap_size);
 CEPH_RBD_API int rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *group_snap,
                                                   size_t group_snap_size);
+CEPH_RBD_API int rbd_snap_get_trash_namespace(rbd_image_t image,
+                                              uint64_t snap_id,
+                                              char* original_name,
+                                              size_t max_length);
 
 CEPH_RBD_API int rbd_flatten(rbd_image_t image);
 
index 5db6f44a37aa63e6511e8e05df6a36c98c42985a..bf150f47479770b374ef3f0c8d5c56219e05b7df 100644 (file)
@@ -379,6 +379,7 @@ public:
   int snap_create(const char *snapname);
   int snap_remove(const char *snapname);
   int snap_remove2(const char *snapname, uint32_t flags, ProgressContext& pctx);
+  int snap_remove_by_id(uint64_t snap_id);
   int snap_rollback(const char *snap_name);
   int snap_rollback_with_progress(const char *snap_name, ProgressContext& pctx);
   int snap_protect(const char *snap_name);
@@ -395,6 +396,7 @@ public:
   int snap_get_group_namespace(uint64_t snap_id,
                                snap_group_namespace_t *group_namespace,
                                size_t snap_group_namespace_size);
+  int snap_get_trash_namespace(uint64_t snap_id, std::string* original_name);
 
   /* I/O */
   ssize_t read(uint64_t ofs, size_t len, ceph::bufferlist& bl);
index f9f6aea5245130a6d21c5bbb6bf2c7276c64eb7b..fb5c70ba151f2344a53cf61ffb5b225faa6ea9e4 100644 (file)
@@ -5,6 +5,8 @@
 #include "cls/rbd/cls_rbd_types.h"
 #include "common/errno.h"
 #include "librbd/ImageCtx.h"
+#include "librbd/ImageState.h"
+#include "librbd/Operations.h"
 #include "librbd/Utils.h"
 #include <boost/variant.hpp>
 
@@ -73,40 +75,119 @@ public:
   }
 };
 
+class GetTrashVisitor : public boost::static_visitor<int> {
+public:
+  std::string* original_name;
+
+  explicit GetTrashVisitor(std::string* original_name)
+    : original_name(original_name) {
+  }
+
+  template <typename T>
+  inline int operator()(const T&) const {
+    return -EINVAL;
+  }
+
+  inline int operator()(
+      const cls::rbd::TrashSnapshotNamespace& snap_namespace) {
+    *original_name = snap_namespace.original_name;
+    return 0;
+  }
+};
+
 } // anonymous namespace
 
 template <typename I>
 int Snapshot<I>::get_group_namespace(I *ictx, uint64_t snap_id,
                                      snap_group_namespace_t *group_snap) {
-  const SnapInfo *snap_info;
-  {
-    RWLock::RLocker snap_locker(ictx->snap_lock);
-    snap_info = ictx->get_snap_info(snap_id);
-    if (snap_info) {
-      GetGroupVisitor ggv = GetGroupVisitor(ictx->cct, &ictx->data_ctx,
-                                            group_snap);
-      int r = boost::apply_visitor(ggv, snap_info->snap_namespace);
-      if (r < 0) {
-       return r;
-      }
-    }
+  int r = ictx->state->refresh_if_required();
+  if (r < 0) {
+    return r;
+  }
+
+  RWLock::RLocker snap_locker(ictx->snap_lock);
+  auto snap_info = ictx->get_snap_info(snap_id);
+  if (snap_info == nullptr) {
+    return -ENOENT;
+  }
+
+  GetGroupVisitor ggv = GetGroupVisitor(ictx->cct, &ictx->data_ctx, group_snap);
+  r = boost::apply_visitor(ggv, snap_info->snap_namespace);
+  if (r < 0) {
+    return r;
   }
+
+  return 0;
+}
+
+template <typename I>
+int Snapshot<I>::get_trash_namespace(I *ictx, uint64_t snap_id,
+                                     std::string* original_name) {
+  int r = ictx->state->refresh_if_required();
+  if (r < 0) {
+    return r;
+  }
+
+  RWLock::RLocker snap_locker(ictx->snap_lock);
+  auto snap_info = ictx->get_snap_info(snap_id);
+  if (snap_info == nullptr) {
+    return -ENOENT;
+  }
+
+  auto visitor = GetTrashVisitor(original_name);
+  r = boost::apply_visitor(visitor, snap_info->snap_namespace);
+  if (r < 0) {
+    return r;
+  }
+
   return 0;
 }
 
 template <typename I>
 int Snapshot<I>::get_namespace_type(I *ictx, uint64_t snap_id,
                                 snap_namespace_type_t *namespace_type) {
-  const SnapInfo *snap_info;
+  int r = ictx->state->refresh_if_required();
+  if (r < 0) {
+    return r;
+  }
+
+  RWLock::RLocker l(ictx->snap_lock);
+  auto snap_info = ictx->get_snap_info(snap_id);
+  if (snap_info == nullptr) {
+    return -ENOENT;
+  }
+
+  *namespace_type = static_cast<snap_namespace_type_t>(
+    cls::rbd::get_snap_namespace_type(snap_info->snap_namespace));
+  return 0;
+}
+
+template <typename I>
+int Snapshot<I>::remove(I *ictx, uint64_t snap_id) {
+  ldout(ictx->cct, 20) << "snap_remove " << ictx << " " << snap_id << dendl;
+
+  int r = ictx->state->refresh_if_required();
+  if (r < 0) {
+    return r;
+  }
+
+  cls::rbd::SnapshotNamespace snapshot_namespace;
+  std::string snapshot_name;
   {
-    RWLock::RLocker l(ictx->snap_lock);
-    snap_info = ictx->get_snap_info(snap_id);
-    if (snap_info) {
-      *namespace_type = static_cast<snap_namespace_type_t>(
-        cls::rbd::get_snap_namespace_type(snap_info->snap_namespace));
+    RWLock::RLocker snap_locker(ictx->snap_lock);
+    auto it = ictx->snap_info.find(snap_id);
+    if (it == ictx->snap_info.end()) {
+      return -ENOENT;
     }
+
+    snapshot_namespace = it->second.snap_namespace;
+    snapshot_name = it->second.name;
   }
-  return 0;
+
+  C_SaferCond ctx;
+  ictx->operations->snap_remove(snapshot_namespace, snapshot_name, &ctx);
+  r = ctx.wait();
+  return r;
 }
 
 } // namespace api
index 6629b6973d27eb33c6f2327b9ac02e284b3658cc..453861c40088b34d680aaf917edb0dde6b7d345f 100644 (file)
@@ -5,6 +5,7 @@
 #define CEPH_LIBRBD_API_SNAPSHOT_H
 
 #include "include/rbd/librbd.hpp"
+#include <string>
 
 namespace librbd {
 
@@ -18,9 +19,14 @@ struct Snapshot {
   static int get_group_namespace(ImageCtxT *ictx, uint64_t snap_id,
                                  snap_group_namespace_t *group_snap);
 
+  static int get_trash_namespace(ImageCtxT *ictx, uint64_t snap_id,
+                                 std::string *original_name);
+
   static int get_namespace_type(ImageCtxT *ictx, uint64_t snap_id,
                                snap_namespace_type_t *namespace_type);
 
+  static int remove(ImageCtxT *ictx, uint64_t snap_id);
+
 };
 
 } // namespace api
index 68ef4303d5161589c9e0f6321928b785b5ff4554..b46ceb5002f610c9c540360624f5d3f8c9c12c4d 100644 (file)
@@ -1522,6 +1522,12 @@ namespace librbd {
     return r;
   }
 
+  int Image::snap_remove_by_id(uint64_t snap_id)
+  {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::api::Snapshot<>::remove(ictx, snap_id);
+  }
+
   int Image::snap_rollback(const char *snap_name)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -1669,6 +1675,13 @@ namespace librbd {
     return r;
   }
 
+  int Image::snap_get_trash_namespace(uint64_t snap_id,
+                                      std::string* original_name) {
+    ImageCtx *ictx = (ImageCtx *)ctx;
+    return librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
+                                                        original_name);
+  }
+
   int Image::snap_set_limit(uint64_t limit)
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
@@ -3502,6 +3515,12 @@ extern "C" int rbd_snap_remove2(rbd_image_t image, const char *snap_name, uint32
   return r;
 }
 
+extern "C" int rbd_snap_remove_by_id(rbd_image_t image, uint64_t snap_id)
+{
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+  return librbd::api::Snapshot<>::remove(ictx, snap_id);
+}
+
 extern "C" int rbd_snap_rollback(rbd_image_t image, const char *snap_name)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
@@ -4967,6 +4986,25 @@ extern "C" int rbd_snap_group_namespace_cleanup(rbd_snap_group_namespace_t *grou
   return 0;
 }
 
+extern "C" int rbd_snap_get_trash_namespace(rbd_image_t image, uint64_t snap_id,
+                                            char *original_name,
+                                            size_t max_length) {
+  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
+
+  std::string cpp_original_name;
+  int r = librbd::api::Snapshot<>::get_trash_namespace(ictx, snap_id,
+                                                       &cpp_original_name);
+  if (r < 0) {
+    return r;
+  }
+
+  if (cpp_original_name.length() >= max_length) {
+    return -ERANGE;
+  }
+
+  strcpy(original_name, cpp_original_name.c_str());
+  return 0;
+}
 extern "C" int rbd_watchers_list(rbd_image_t image,
                                 rbd_image_watcher_t *watchers,
                                 size_t *max_watchers) {
index aac06e3a597930510031a8069e3d0196262ccb04..cde5e85096faf1badaa1cb2f238d0cf0d2241d5b 100644 (file)
@@ -3168,6 +3168,24 @@ TEST_F(TestLibRBD, TestClone2)
   ASSERT_PASSED(validate_object_map, child);
   ASSERT_PASSED(validate_object_map, parent);
 
+  rbd_snap_info_t snaps[2];
+  int max_snaps = 2;
+  ASSERT_EQ(1, rbd_snap_list(parent, snaps, &max_snaps));
+  rbd_snap_list_end(snaps);
+
+  ASSERT_EQ(0, rbd_snap_remove_by_id(parent, snaps[0].id));
+
+  rbd_snap_namespace_type_t snap_namespace_type;
+  ASSERT_EQ(0, rbd_snap_get_namespace_type(parent, snaps[0].id,
+                                           &snap_namespace_type));
+  ASSERT_EQ(RBD_SNAP_NAMESPACE_TYPE_TRASH, snap_namespace_type);
+
+  char original_name[32];
+  ASSERT_EQ(0, rbd_snap_get_trash_namespace(parent, snaps[0].id,
+                                            original_name,
+                                            sizeof(original_name)));
+  ASSERT_EQ(0, strcmp("parent_snap", original_name));
+
   ASSERT_EQ(0, rbd_close(child));
   ASSERT_EQ(0, rbd_close(parent));
   rados_ioctx_destroy(ioctx);