]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: By default create snapshots in UserNamespace
authorVictor Denisov <denisovenator@gmail.com>
Wed, 21 Sep 2016 04:35:30 +0000 (21:35 -0700)
committerVictor Denisov <denisovenator@gmail.com>
Sat, 22 Oct 2016 03:53:24 +0000 (20:53 -0700)
Signed-off-by: Victor Denisov <denisovenator@gmail.com>
29 files changed:
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/ImageWatcher.cc
src/librbd/ImageWatcher.h
src/librbd/Operations.cc
src/librbd/Operations.h
src/librbd/SnapInfo.h
src/librbd/WatchNotifyTypes.cc
src/librbd/WatchNotifyTypes.h
src/librbd/image/RefreshRequest.cc
src/librbd/image/RefreshRequest.h
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/journal/Replay.cc
src/librbd/journal/Types.cc
src/librbd/journal/Types.h
src/librbd/librbd.cc
src/librbd/operation/SnapshotCreateRequest.cc
src/librbd/operation/SnapshotCreateRequest.h
src/test/librbd/image/test_mock_RefreshRequest.cc
src/test/librbd/journal/test_Replay.cc
src/test/librbd/journal/test_mock_Replay.cc
src/test/librbd/mock/MockImageCtx.h
src/test/librbd/mock/MockOperations.h
src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc
src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc
src/test/librbd/test_ImageWatcher.cc
src/test/librbd/test_fixture.cc
src/test/librbd/test_internal.cc

index 11422d806e9bbaba71f4c14faccf21fbdf9ce4b4..91d9ac0be4fc9a77b693f3d89b9e3c8bc584c226 100644 (file)
@@ -458,6 +458,18 @@ struct C_InvalidateCache : public Context {
     return -ENOENT;
   }
 
+  int ImageCtx::get_snap_namespace(snap_t in_snap_id,
+                                  cls::rbd::SnapshotNamespace *out_snap_namespace) const
+  {
+    assert(snap_lock.is_locked());
+    const SnapInfo *info = get_snap_info(in_snap_id);
+    if (info) {
+      *out_snap_namespace = info->snap_namespace;
+      return 0;
+    }
+    return -ENOENT;
+  }
+
   int ImageCtx::get_parent_spec(snap_t in_snap_id,
                                parent_spec *out_pspec) const
   {
@@ -527,13 +539,16 @@ struct C_InvalidateCache : public Context {
     return -ENOENT;
   }
 
-  void ImageCtx::add_snap(string in_snap_name, snap_t id, uint64_t in_size,
+  void ImageCtx::add_snap(string in_snap_name,
+                         cls::rbd::SnapshotNamespace in_snap_namespace,
+                         snap_t id, uint64_t in_size,
                          parent_info parent, uint8_t protection_status,
                           uint64_t flags)
   {
     assert(snap_lock.is_wlocked());
     snaps.push_back(id);
-    SnapInfo info(in_snap_name, in_size, parent, protection_status, flags);
+    SnapInfo info(in_snap_name, in_snap_namespace,
+                 in_size, parent, protection_status, flags);
     snap_info.insert(pair<snap_t, SnapInfo>(id, info));
     snap_ids.insert(pair<string, snap_t>(in_snap_name, id));
   }
index 1855641267ef229d11b5c93f1d9669fc28214f86..ff60498aaf7ce2a0ad0563cb33c9f77ca4f62f74 100644 (file)
@@ -23,6 +23,7 @@
 #include "include/xlist.h"
 #include "osdc/ObjectCacher.h"
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "cls/rbd/cls_rbd_client.h"
 #include "librbd/AsyncRequest.h"
 #include "librbd/SnapInfo.h"
@@ -230,6 +231,8 @@ namespace librbd {
     const SnapInfo* get_snap_info(librados::snap_t in_snap_id) const;
     int get_snap_name(librados::snap_t in_snap_id,
                      std::string *out_snap_name) const;
+    int get_snap_namespace(librados::snap_t in_snap_id,
+                          cls::rbd::SnapshotNamespace *out_snap_namespace) const;
     int get_parent_spec(librados::snap_t in_snap_id,
                        parent_spec *pspec) const;
     int is_snap_protected(librados::snap_t in_snap_id,
@@ -244,7 +247,9 @@ namespace librbd {
     uint64_t get_stripe_count() const;
     uint64_t get_stripe_period() const;
 
-    void add_snap(std::string in_snap_name, librados::snap_t id,
+    void add_snap(std::string in_snap_name,
+                 cls::rbd::SnapshotNamespace in_snap_namespace,
+                 librados::snap_t id,
                  uint64_t in_size, parent_info parent,
                   uint8_t protection_status, uint64_t flags);
     void rm_snap(std::string in_snap_name, librados::snap_t id);
index 817f4acdc4dc707f364d6b397f715e8481d033ee..12dfb0c41db294c9786a708bb9aded483050d7a9 100644 (file)
@@ -262,13 +262,14 @@ void ImageWatcher<I>::notify_resize(uint64_t request_id, uint64_t size,
 
 template <typename I>
 void ImageWatcher<I>::notify_snap_create(const std::string &snap_name,
+                                        const cls::rbd::SnapshotNamespace &snap_namespace,
                                          Context *on_finish) {
   assert(m_image_ctx.owner_lock.is_locked());
   assert(m_image_ctx.exclusive_lock &&
          !m_image_ctx.exclusive_lock->is_lock_owner());
 
   bufferlist bl;
-  ::encode(NotifyMessage(SnapCreatePayload(snap_name)), bl);
+  ::encode(NotifyMessage(SnapCreatePayload(snap_name, snap_namespace)), bl);
   notify_lock_owner(std::move(bl), on_finish);
 }
 
@@ -822,6 +823,7 @@ bool ImageWatcher<I>::handle_payload(const SnapCreatePayload &payload,
                                 << payload.snap_name << dendl;
 
       m_image_ctx.operations->execute_snap_create(payload.snap_name,
+                                                 payload.snap_namespace,
                                                   new C_ResponseMessage(ack_ctx),
                                                   0, false);
       return false;
index cac2d9d0e346e56d51f9bd6bfa1f052bdb9e5273..563fbd2653fa6715436d618e6d8b3be4ca3179a3 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_LIBRBD_IMAGE_WATCHER_H
 #define CEPH_LIBRBD_IMAGE_WATCHER_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "common/Mutex.h"
 #include "common/RWLock.h"
 #include "include/Context.h"
@@ -36,7 +37,9 @@ public:
                       Context *on_finish);
   void notify_resize(uint64_t request_id, uint64_t size, bool allow_shrink,
                      ProgressContext &prog_ctx, Context *on_finish);
-  void notify_snap_create(const std::string &snap_name, Context *on_finish);
+  void notify_snap_create(const std::string &snap_name,
+                         const cls::rbd::SnapshotNamespace &snap_namespace,
+                         Context *on_finish);
   void notify_snap_rename(const snapid_t &src_snap_id,
                           const std::string &dst_snap_name,
                           Context *on_finish);
index 933e412b8b8f0c2930e591aad25a5ed944a77e31..a3213e3864e0d9bb1050d8dc143c8b200ef02d6f 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/Operations.h"
 #include "common/dout.h"
 #include "common/errno.h"
@@ -657,7 +658,8 @@ void Operations<I>::execute_resize(uint64_t size, bool allow_shrink, ProgressCon
 }
 
 template <typename I>
-int Operations<I>::snap_create(const char *snap_name) {
+int Operations<I>::snap_create(const char *snap_name,
+                              const cls::rbd::SnapshotNamespace &snap_namespace) {
   if (m_image_ctx.read_only) {
     return -EROFS;
   }
@@ -668,7 +670,7 @@ int Operations<I>::snap_create(const char *snap_name) {
   }
 
   C_SaferCond ctx;
-  snap_create(snap_name, &ctx);
+  snap_create(snap_name, snap_namespace, &ctx);
   r = ctx.wait();
 
   if (r < 0) {
@@ -680,7 +682,9 @@ int Operations<I>::snap_create(const char *snap_name) {
 }
 
 template <typename I>
-void Operations<I>::snap_create(const char *snap_name, Context *on_finish) {
+void Operations<I>::snap_create(const char *snap_name,
+                               const cls::rbd::SnapshotNamespace &snap_namespace,
+                               Context *on_finish) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << ": snap_name=" << snap_name
                 << dendl;
@@ -700,16 +704,17 @@ void Operations<I>::snap_create(const char *snap_name, Context *on_finish) {
 
   C_InvokeAsyncRequest<I> *req = new C_InvokeAsyncRequest<I>(
     m_image_ctx, "snap_create", true,
-    boost::bind(&Operations<I>::execute_snap_create, this, snap_name, _1, 0,
-                false),
+    boost::bind(&Operations<I>::execute_snap_create, this, snap_name,
+               snap_namespace, _1, 0, false),
     boost::bind(&ImageWatcher<I>::notify_snap_create, m_image_ctx.image_watcher,
-                snap_name, _1),
+                snap_name, snap_namespace, _1),
     {-EEXIST}, on_finish);
   req->send();
 }
 
 template <typename I>
 void Operations<I>::execute_snap_create(const std::string &snap_name,
+                                       const cls::rbd::SnapshotNamespace &snap_namespace,
                                         Context *on_finish,
                                         uint64_t journal_op_tid,
                                         bool skip_object_map) {
@@ -732,7 +737,7 @@ void Operations<I>::execute_snap_create(const std::string &snap_name,
   operation::SnapshotCreateRequest<I> *req =
     new operation::SnapshotCreateRequest<I>(
       m_image_ctx, new C_NotifyUpdate<I>(m_image_ctx, on_finish), snap_name,
-      journal_op_tid, skip_object_map);
+      snap_namespace, journal_op_tid, skip_object_map);
   req->send();
 }
 
index 6790ffeac3f31c0aa9086fd0106776186d6165fe..673b61cc228a8e488e160a2b75dc67a2907fa879 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_LIBRBD_OPERATIONS_H
 #define CEPH_LIBRBD_OPERATIONS_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "include/int_types.h"
 #include "librbd/operation/ObjectMapIterate.h"
 #include <atomic>
@@ -43,9 +44,14 @@ public:
   void execute_resize(uint64_t size, bool allow_shrink, ProgressContext &prog_ctx,
                       Context *on_finish, uint64_t journal_op_tid);
 
-  int snap_create(const char *snap_name);
-  void snap_create(const char *snap_name, Context *on_finish);
-  void execute_snap_create(const std::string &snap_name, Context *on_finish,
+  int snap_create(const char *snap_name,
+                 const cls::rbd::SnapshotNamespace &snap_namespace);
+  void snap_create(const char *snap_name,
+                  const cls::rbd::SnapshotNamespace &snap_namespace,
+                  Context *on_finish);
+  void execute_snap_create(const std::string &snap_name,
+                          const cls::rbd::SnapshotNamespace &snap_namespace,
+                          Context *on_finish,
                            uint64_t journal_op_tid, bool skip_object_map);
 
   int snap_rollback(const char *snap_name, ProgressContext& prog_ctx);
index 1babee9e550f282dceb4c9aefa073a3fe5800bd7..3bd0b98a629cf5399b60e2120d78582ff42763fb 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef CEPH_LIBRBD_SNAPINFO_H
 #define CEPH_LIBRBD_SNAPINFO_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "include/int_types.h"
 
 #include "librbd/parent_types.h"
@@ -11,13 +12,15 @@ namespace librbd {
 
   struct SnapInfo {
     std::string name;
+    cls::rbd::SnapshotNamespace snap_namespace;
     uint64_t size;
     parent_info parent;
     uint8_t protection_status;
     uint64_t flags;
-    SnapInfo(std::string _name, uint64_t _size, parent_info _parent,
+    SnapInfo(std::string _name, const cls::rbd::SnapshotNamespace &_snap_namespace,
+            uint64_t _size, parent_info _parent,
              uint8_t _protection_status, uint64_t _flags)
-      : name(_name), size(_size), parent(_parent),
+      : name(_name), snap_namespace(_snap_namespace), size(_size), parent(_parent),
        protection_status(_protection_status), flags(_flags) {}
   };
 }
index 2f9d211db09eb34255039e43e6cb725eec81e62a..bbee3a100173ad2bff1534f9e02d2a864d825db1 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/WatchNotifyTypes.h"
 #include "include/assert.h"
 #include "include/stringify.h"
@@ -239,6 +240,26 @@ void SnapPayloadBase::dump(Formatter *f) const {
   f->dump_string("snap_name", snap_name);
 }
 
+void SnapCreatePayload::encode(bufferlist &bl) const {
+  SnapPayloadBase::encode(bl);
+  ::encode(cls::rbd::SnapshotNamespaceOnDisk(snap_namespace), bl);
+}
+
+void SnapCreatePayload::decode(__u8 version, bufferlist::iterator &iter) {
+  SnapPayloadBase::decode(version, iter);
+  if (version >= 5) {
+    cls::rbd::SnapshotNamespaceOnDisk sn;
+    ::decode(sn, iter);
+    snap_namespace = sn.snapshot_namespace;
+  }
+}
+
+void SnapCreatePayload::dump(Formatter *f) const {
+  SnapPayloadBase::dump(f);
+  cls::rbd::SnapshotNamespaceOnDisk sn(snap_namespace);
+  sn.dump(f);
+}
+
 void SnapRenamePayload::encode(bufferlist &bl) const {
   ::encode(snap_id, bl);
   SnapPayloadBase::encode(bl);
@@ -296,7 +317,7 @@ bool NotifyMessage::check_for_refresh() const {
 }
 
 void NotifyMessage::encode(bufferlist& bl) const {
-  ENCODE_START(4, 1, bl);
+  ENCODE_START(5, 1, bl);
   boost::apply_visitor(EncodePayloadVisitor(bl), payload);
   ENCODE_FINISH(bl);
 }
@@ -379,7 +400,8 @@ void NotifyMessage::generate_test_instances(std::list<NotifyMessage *> &o) {
   o.push_back(new NotifyMessage(AsyncCompletePayload(AsyncRequestId(ClientId(0, 1), 2), 3)));
   o.push_back(new NotifyMessage(FlattenPayload(AsyncRequestId(ClientId(0, 1), 2))));
   o.push_back(new NotifyMessage(ResizePayload(123, true, AsyncRequestId(ClientId(0, 1), 2))));
-  o.push_back(new NotifyMessage(SnapCreatePayload("foo")));
+  o.push_back(new NotifyMessage(SnapCreatePayload("foo",
+                                                 cls::rbd::UserSnapshotNamespace())));
   o.push_back(new NotifyMessage(SnapRemovePayload("foo")));
   o.push_back(new NotifyMessage(SnapProtectPayload("foo")));
   o.push_back(new NotifyMessage(SnapUnprotectPayload("foo")));
index d74747701764666f5395bc1d7c7decd321d03c92..9e91ba0f58f66181abbab02167f245e85950c668 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef LIBRBD_WATCH_NOTIFY_TYPES_H
 #define LIBRBD_WATCH_NOTIFY_TYPES_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "include/int_types.h"
 #include "include/buffer_fwd.h"
 #include "include/encoding.h"
@@ -232,7 +233,14 @@ struct SnapCreatePayload : public SnapPayloadBase {
   static const NotifyOp NOTIFY_OP = NOTIFY_OP_SNAP_CREATE;
 
   SnapCreatePayload() {}
-  SnapCreatePayload(const std::string &name) : SnapPayloadBase(name) {}
+  SnapCreatePayload(const std::string &name,
+                   const cls::rbd::SnapshotNamespace &_snap_namespace) : SnapPayloadBase(name), snap_namespace(_snap_namespace) {}
+
+  cls::rbd::SnapshotNamespace snap_namespace;
+
+  void encode(bufferlist &bl) const;
+  void decode(__u8 version, bufferlist::iterator &iter);
+  void dump(Formatter *f) const;
 };
 
 struct SnapRenamePayload : public SnapPayloadBase {
index f1a9d11045963e92c67b6054556a7c60f9d70d84..14d7e8784a6bb740ea6b3ad83b70c8c002295bf6 100644 (file)
@@ -140,6 +140,12 @@ Context *RefreshRequest<I>::handle_v1_get_snapshots(int *result) {
     return m_on_finish;
   }
 
+  //m_snap_namespaces = {m_snap_names.size(), cls::rbd::UserSnapshotNamespace()};
+  m_snap_namespaces = std::vector
+                             <cls::rbd::SnapshotNamespace>(
+                                           m_snap_names.size(),
+                                           cls::rbd::UserSnapshotNamespace());
+
   send_v1_get_locks();
   return nullptr;
 }
@@ -340,6 +346,7 @@ template <typename I>
 void RefreshRequest<I>::send_v2_get_snapshots() {
   if (m_snapc.snaps.empty()) {
     m_snap_names.clear();
+    m_snap_namespaces.clear();
     m_snap_sizes.clear();
     m_snap_parents.clear();
     m_snap_protection.clear();
@@ -372,7 +379,8 @@ Context *RefreshRequest<I>::handle_v2_get_snapshots(int *result) {
   if (*result == 0) {
     bufferlist::iterator it = m_out_bl.begin();
     *result = cls_client::snapshot_list_finish(&it, m_snapc.snaps,
-                                               &m_snap_names, &m_snap_sizes,
+                                               &m_snap_names,
+                                              &m_snap_sizes,
                                                &m_snap_parents,
                                                &m_snap_protection);
   }
@@ -386,6 +394,55 @@ Context *RefreshRequest<I>::handle_v2_get_snapshots(int *result) {
     return m_on_finish;
   }
 
+  send_v2_get_snap_namespaces();
+  return nullptr;
+}
+
+template <typename I>
+void RefreshRequest<I>::send_v2_get_snap_namespaces() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  librados::ObjectReadOperation op;
+  cls_client::snap_namespace_list_start(&op, m_snapc.snaps);
+
+  using klass = RefreshRequest<I>;
+  librados::AioCompletion *comp = create_rados_ack_callback<
+    klass, &klass::handle_v2_get_snap_namespaces>(this);
+  m_out_bl.clear();
+  int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op,
+                                         &m_out_bl);
+  assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+Context *RefreshRequest<I>::handle_v2_get_snap_namespaces(int *result) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 10) << this << " " << __func__ << ": "
+                 << "r=" << *result << dendl;
+
+  if (*result == 0) {
+    bufferlist::iterator it = m_out_bl.begin();
+    *result = cls_client::snap_namespace_list_finish(&it, m_snapc.snaps,
+                                                    &m_snap_namespaces);
+  }
+  if (*result == -ENOENT) {
+    ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl;
+    send_v2_get_mutable_metadata();
+    return nullptr;
+  } else if (*result == -EOPNOTSUPP) {
+    m_snap_namespaces = std::vector
+                               <cls::rbd::SnapshotNamespace>(
+                                            m_snap_names.size(),
+                                            cls::rbd::UserSnapshotNamespace());
+    // Ignore it means no snap namespaces are available
+  } else if (*result < 0) {
+    lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result)
+               << dendl;
+    return m_on_finish;
+  }
+
   send_v2_refresh_parent();
   return nullptr;
 }
@@ -905,7 +962,7 @@ void RefreshRequest<I>::apply() {
         parent = m_snap_parents[i];
       }
 
-      m_image_ctx.add_snap(m_snap_names[i], m_snapc.snaps[i].val,
+      m_image_ctx.add_snap(m_snap_names[i], m_snap_namespaces[i], m_snapc.snaps[i].val,
                            m_snap_sizes[i], parent, protection_status, flags);
     }
     m_image_ctx.snapc = m_snapc;
index 33e6d0bcca03196339d3e20046d55ac6b8368103..79e616ba1b6ce4152c7caf09c12ca1ed989fd16a 100644 (file)
@@ -55,6 +55,9 @@ private:
    *            V2_GET_SNAPSHOTS (skip if no snaps)           |
    *                |                                         |
    *                v                                         |
+   *            V2_GET_SNAP_NAMESPACES                        |
+   *                |                                         |
+   *                v                                         |
    *            V2_REFRESH_PARENT (skip if no parent or       |
    *                |              refresh not needed)        |
    *                v                                         |
@@ -120,6 +123,7 @@ private:
 
   ::SnapContext m_snapc;
   std::vector<std::string> m_snap_names;
+  std::vector<cls::rbd::SnapshotNamespace> m_snap_namespaces;
   std::vector<uint64_t> m_snap_sizes;
   std::vector<parent_info> m_snap_parents;
   std::vector<uint8_t> m_snap_protection;
@@ -154,6 +158,9 @@ private:
   void send_v2_get_snapshots();
   Context *handle_v2_get_snapshots(int *result);
 
+  void send_v2_get_snap_namespaces();
+  Context *handle_v2_get_snap_namespaces(int *result);
+
   void send_v2_refresh_parent();
   Context *handle_v2_refresh_parent(int *result);
 
index f08f13d911658449e99198270c49ca267fdc1f56..a48c47ba977f31ae6058775482f7b342b146b3c6 100644 (file)
@@ -810,6 +810,24 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
     return 0;
   }
 
+  int get_snap_namespace(ImageCtx *ictx,
+                        const char *snap_name,
+                        cls::rbd::SnapshotNamespace *snap_namespace) {
+    ldout(ictx->cct, 20) << "get_snap_namespace " << ictx << " " << snap_name
+                        << dendl;
+
+    int r = ictx->state->refresh_if_required();
+    if (r < 0)
+      return r;
+
+    RWLock::RLocker l(ictx->snap_lock);
+    snap_t snap_id = ictx->get_snap_id(snap_name);
+    if (snap_id == CEPH_NOSNAP)
+      return -ENOENT;
+    r = ictx->get_snap_namespace(snap_id, snap_namespace);
+    return r;
+  }
+
   int snap_is_protected(ImageCtx *ictx, const char *snap_name,
                        bool *is_protected)
   {
@@ -1699,6 +1717,15 @@ int mirror_image_disable_internal(ImageCtx *ictx, bool force,
 
     int r = 0;
 
+    cls::rbd::SnapshotNamespace snap_namespace;
+    r = get_snap_namespace(ictx, snap_name, &snap_namespace);
+    if (r < 0) {
+      return r;
+    }
+    if (boost::get<cls::rbd::UserSnapshotNamespace>(&snap_namespace) == nullptr) {
+      return -EINVAL;
+    }
+
     r = ictx->state->refresh_if_required();
     if (r < 0)
       return r;
index ddc1cb065601920d0c05bbb751c3f2786ea82a6a..50244715ca2a6ad09438931b7dfaf912ddb89816 100644 (file)
@@ -14,6 +14,7 @@
 #include "include/rbd/librbd.hpp"
 #include "include/rbd_types.h"
 #include "librbd/parent_types.h"
+#include "cls/rbd/cls_rbd_types.h"
 #include "common/WorkQueue.h"
 
 enum {
@@ -139,6 +140,9 @@ namespace librbd {
   int snap_get_limit(ImageCtx *ictx, uint64_t *limit);
   int snap_set_limit(ImageCtx *ictx, uint64_t limit);
   int snap_remove(ImageCtx *ictx, const char *snap_name, uint32_t flags, ProgressContext& pctx);
+  int get_snap_namespace(ImageCtx *ictx,
+                        const char *snap_name,
+                        cls::rbd::SnapshotNamespace *snap_namespace);
   int snap_is_protected(ImageCtx *ictx, const char *snap_name,
                        bool *is_protected);
   int copy(ImageCtx *ictx, IoCtx& dest_md_ctx, const char *destname,
index 9055e0b8974842c8921cbc17a9fe651f1cea6e18..ff52c50d0468d1c8f0254419cb3b7024d7a8e39b 100644 (file)
@@ -39,6 +39,7 @@ struct ExecuteOp : public Context {
 
   void execute(const journal::SnapCreateEvent &_) {
     image_ctx.operations->execute_snap_create(event.snap_name,
+                                             event.snap_namespace,
                                               on_op_complete,
                                               event.op_tid, false);
   }
index bdd294f467b496c0fabf1cf7664c7aa93d8c2357..8242cffbec87184facfaa4a8538a1ff777885cd8 100644 (file)
@@ -154,6 +154,25 @@ void SnapEventBase::dump(Formatter *f) const {
   f->dump_string("snap_name", snap_name);
 }
 
+void SnapCreateEvent::encode(bufferlist &bl) const {
+  SnapEventBase::encode(bl);
+  ::encode(cls::rbd::SnapshotNamespaceOnDisk(snap_namespace), bl);
+}
+
+void SnapCreateEvent::decode(__u8 version, bufferlist::iterator& it) {
+  SnapEventBase::decode(version, it);
+  if (version >= 3) {
+    cls::rbd::SnapshotNamespaceOnDisk sn;
+    ::decode(sn, it);
+    snap_namespace = sn.snapshot_namespace;
+  }
+}
+
+void SnapCreateEvent::dump(Formatter *f) const {
+  SnapEventBase::dump(f);
+  cls::rbd::SnapshotNamespaceOnDisk(snap_namespace).dump(f);
+}
+
 void SnapLimitEvent::encode(bufferlist &bl) const {
   OpEventBase::encode(bl);
   ::encode(limit, bl);
@@ -295,7 +314,7 @@ EventType EventEntry::get_event_type() const {
 }
 
 void EventEntry::encode(bufferlist& bl) const {
-  ENCODE_START(2, 1, bl);
+  ENCODE_START(3, 1, bl);
   boost::apply_visitor(EncodeVisitor(bl), event);
   ENCODE_FINISH(bl);
 }
@@ -386,7 +405,8 @@ void EventEntry::generate_test_instances(std::list<EventEntry *> &o) {
   o.push_back(new EventEntry(OpFinishEvent(123, -1)));
 
   o.push_back(new EventEntry(SnapCreateEvent()));
-  o.push_back(new EventEntry(SnapCreateEvent(234, "snap")));
+  o.push_back(new EventEntry(SnapCreateEvent(234, "snap",
+                                              cls::rbd::UserSnapshotNamespace())));
 
   o.push_back(new EventEntry(SnapRemoveEvent()));
   o.push_back(new EventEntry(SnapRemoveEvent(345, "snap")));
index 37c590556fdc7d549400cbe3db3613df53c87dd5..505822d9ffc2a9a1cee4b4edffdcec5dccbdaa92 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_LIBRBD_JOURNAL_TYPES_H
 #define CEPH_LIBRBD_JOURNAL_TYPES_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "include/int_types.h"
 #include "include/buffer.h"
 #include "include/encoding.h"
@@ -135,16 +136,17 @@ protected:
 
 struct SnapCreateEvent : public SnapEventBase {
   static const EventType TYPE = EVENT_TYPE_SNAP_CREATE;
+  cls::rbd::SnapshotNamespace snap_namespace;
 
   SnapCreateEvent() {
   }
-  SnapCreateEvent(uint64_t op_tid, const std::string &snap_name)
-    : SnapEventBase(op_tid, snap_name) {
+  SnapCreateEvent(uint64_t op_tid, const std::string &snap_name, const cls::rbd::SnapshotNamespace &_snap_namespace)
+    : SnapEventBase(op_tid, snap_name), snap_namespace(_snap_namespace) {
   }
 
-  using SnapEventBase::encode;
-  using SnapEventBase::decode;
-  using SnapEventBase::dump;
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
 };
 
 struct SnapRemoveEvent : public SnapEventBase {
index 52ee192a13e94986acb4998c093ca7a3cd5e4a98..207b7d9e80dd8891034441495f4ed7b071689393 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <errno.h>
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "common/dout.h"
 #include "common/errno.h"
 #include "common/TracepointProvider.h"
@@ -23,6 +24,7 @@
 #include "librbd/AioCompletion.h"
 #include "librbd/AioImageRequestWQ.h"
 #include "cls/rbd/cls_rbd_client.h"
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/Group.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/ImageState.h"
@@ -1026,7 +1028,8 @@ namespace librbd {
   {
     ImageCtx *ictx = (ImageCtx *)ctx;
     tracepoint(librbd, snap_create_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
-    int r = ictx->operations->snap_create(snap_name);
+    int r = ictx->operations->snap_create(snap_name,
+                                         cls::rbd::UserSnapshotNamespace());
     tracepoint(librbd, snap_create_exit, r);
     return r;
   }
@@ -2355,7 +2358,8 @@ extern "C" int rbd_snap_create(rbd_image_t image, const char *snap_name)
 {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
   tracepoint(librbd, snap_create_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, snap_name);
-  int r = ictx->operations->snap_create(snap_name);
+  int r = ictx->operations->snap_create(snap_name,
+                                       cls::rbd::UserSnapshotNamespace());
   tracepoint(librbd, snap_create_exit, r);
   return r;
 }
index 4f20ec4f977f10ad437a8f8408b379161557839c..45d1ba619f14fec6591cd07ec64760b1fffee5d0 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/operation/SnapshotCreateRequest.h"
 #include "common/dout.h"
 #include "common/errno.h"
@@ -61,9 +62,11 @@ template <typename I>
 SnapshotCreateRequest<I>::SnapshotCreateRequest(I &image_ctx,
                                                 Context *on_finish,
                                                 const std::string &snap_name,
+                                               const cls::rbd::SnapshotNamespace &snap_namespace,
                                                 uint64_t journal_op_tid,
                                                 bool skip_object_map)
   : Request<I>(image_ctx, on_finish, journal_op_tid), m_snap_name(snap_name),
+  m_snap_namespace(snap_namespace),
     m_skip_object_map(skip_object_map), m_ret_val(0), m_snap_id(CEPH_NOSNAP) {
 }
 
@@ -210,7 +213,7 @@ void SnapshotCreateRequest<I>::send_create_snap() {
     if (image_ctx.exclusive_lock != nullptr) {
       image_ctx.exclusive_lock->assert_header_locked(&op);
     }
-    cls_client::snapshot_add(&op, m_snap_id, m_snap_name);
+    cls_client::snapshot_add(&op, m_snap_id, m_snap_name, m_snap_namespace);
   }
 
   librados::AioCompletion *rados_completion = create_rados_safe_callback<
@@ -330,7 +333,7 @@ void SnapshotCreateRequest<I>::update_snap_context() {
          image_ctx.exclusive_lock->is_lock_owner());
 
   // immediately add a reference to the new snapshot
-  image_ctx.add_snap(m_snap_name, m_snap_id, m_size, m_parent_info,
+  image_ctx.add_snap(m_snap_name, m_snap_namespace, m_snap_id, m_size, m_parent_info,
                      RBD_PROTECTION_STATUS_UNPROTECTED, 0);
 
   // immediately start using the new snap context if we
index c239d601eaebb22b1d9d1c7165761598bf0728c4..164582604095b48bb3ccde89a796c9ff2acf8d4a 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_LIBRBD_OPERATION_SNAPSHOT_CREATE_REQUEST_H
 #define CEPH_LIBRBD_OPERATION_SNAPSHOT_CREATE_REQUEST_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/operation/Request.h"
 #include "librbd/parent_types.h"
 #include <string>
@@ -59,7 +60,9 @@ public:
    * (if enabled) and bubble the originating error code back to the client.
    */
   SnapshotCreateRequest(ImageCtxT &image_ctx, Context *on_finish,
-                       const std::string &snap_name, uint64_t journal_op_tid,
+                       const std::string &snap_name,
+                       const cls::rbd::SnapshotNamespace &snap_namespace,
+                       uint64_t journal_op_tid,
                         bool skip_object_map);
 
 protected:
@@ -71,11 +74,12 @@ protected:
     return true;
   }
   virtual journal::Event create_event(uint64_t op_tid) const {
-    return journal::SnapCreateEvent(op_tid, m_snap_name);
+    return journal::SnapCreateEvent(op_tid, m_snap_name, m_snap_namespace);
   }
 
 private:
   std::string m_snap_name;
+  cls::rbd::SnapshotNamespace m_snap_namespace;
   bool m_skip_object_map;
 
   int m_ret_val;
index ca634aa0db53cf6a5061633a19182794fa930a32..008fd217caeb2d8b23af433ba1400559cf1582c9 100644 (file)
@@ -189,9 +189,14 @@ public:
     }
   }
 
+  void expect_snap_namespace_list(MockRefreshImageCtx &mock_image_ctx, int r) {
+    auto &expect = EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx),
+                               exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_namespace"), _, _, _));
+  }
+
   void expect_add_snap(MockRefreshImageCtx &mock_image_ctx,
                        const std::string &snap_name, uint64_t snap_id) {
-    EXPECT_CALL(mock_image_ctx, add_snap(snap_name, snap_id, _, _, _, _));
+    EXPECT_CALL(mock_image_ctx, add_snap(snap_name, _, snap_id, _, _, _, _));
   }
 
   void expect_init_exclusive_lock(MockRefreshImageCtx &mock_image_ctx,
@@ -332,7 +337,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessV1) {
 
 TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV1) {
   REQUIRE_FORMAT_V1();
-
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, snap_create(*ictx, "snap"));
@@ -401,6 +405,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) {
   expect_get_flags(mock_image_ctx, 0);
   expect_get_flags(mock_image_ctx, 0);
   expect_get_snapshots(mock_image_ctx, 0);
+  expect_snap_namespace_list(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) {
     expect_init_exclusive_lock(mock_image_ctx, mock_exclusive_lock, 0);
@@ -433,6 +438,7 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) {
   expect_get_flags(mock_image_ctx, 0);
   expect_get_flags(mock_image_ctx, 0);
   expect_get_snapshots(mock_image_ctx, 0);
+  expect_snap_namespace_list(mock_image_ctx, 0);
   expect_refresh_parent_is_required(mock_refresh_parent_request, false);
   if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
     expect_open_object_map(mock_image_ctx, &mock_object_map, 0);
index 9abfb5e54de2eae62ca4a58b18a4341a08d48b5e..d27b7274eb42fa7ce5ddfe9b1ff0e6a61057aa5b 100644 (file)
@@ -1,8 +1,10 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "test/librbd/test_fixture.h"
 #include "test/librbd/test_support.h"
+#include "cls/rbd/cls_rbd_types.h"
 #include "cls/journal/cls_journal_types.h"
 #include "cls/journal/cls_journal_client.h"
 #include "journal/Journaler.h"
@@ -302,7 +304,8 @@ TEST_F(TestJournalReplay, SnapCreate) {
   get_journal_commit_position(ictx, &initial_tag, &initial_entry);
 
   // inject snapshot ops into journal
-  inject_into_journal(ictx, librbd::journal::SnapCreateEvent(1, "snap"));
+  inject_into_journal(ictx, librbd::journal::SnapCreateEvent(1, "snap",
+                                                              cls::rbd::UserSnapshotNamespace()));
   inject_into_journal(ictx, librbd::journal::OpFinishEvent(1, 0));
   close_image(ictx);
 
@@ -322,7 +325,8 @@ TEST_F(TestJournalReplay, SnapCreate) {
   }
 
   // verify lock ordering constraints
-  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2",
+                                            cls::rbd::UserSnapshotNamespace()));
 }
 
 TEST_F(TestJournalReplay, SnapProtect) {
@@ -333,7 +337,8 @@ TEST_F(TestJournalReplay, SnapProtect) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
 
   // get current commit position
   int64_t initial_tag;
@@ -360,7 +365,8 @@ TEST_F(TestJournalReplay, SnapProtect) {
   ASSERT_TRUE(is_protected);
 
   // verify lock ordering constraints
-  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2",
+                                            cls::rbd::UserSnapshotNamespace()));
   ASSERT_EQ(0, ictx->operations->snap_protect("snap2"));
 }
 
@@ -372,7 +378,8 @@ TEST_F(TestJournalReplay, SnapUnprotect) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
   uint64_t snap_id;
   {
     RWLock::RLocker snap_locker(ictx->snap_lock);
@@ -406,7 +413,8 @@ TEST_F(TestJournalReplay, SnapUnprotect) {
   ASSERT_FALSE(is_protected);
 
   // verify lock ordering constraints
-  ASSERT_EQ(0, ictx->operations->snap_create("snap2"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap2",
+                                            cls::rbd::UserSnapshotNamespace()));
   ASSERT_EQ(0, ictx->operations->snap_protect("snap2"));
   ASSERT_EQ(0, ictx->operations->snap_unprotect("snap2"));
 }
@@ -419,7 +427,8 @@ TEST_F(TestJournalReplay, SnapRename) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
   uint64_t snap_id;
   {
     RWLock::RLocker snap_locker(ictx->snap_lock);
@@ -467,7 +476,8 @@ TEST_F(TestJournalReplay, SnapRollback) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
 
   // get current commit position
   int64_t initial_tag;
@@ -502,7 +512,8 @@ TEST_F(TestJournalReplay, SnapRemove) {
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
   ASSERT_EQ(0, when_acquired_lock(ictx));
 
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
 
   // get current commit position
   int64_t initial_tag;
@@ -531,7 +542,8 @@ TEST_F(TestJournalReplay, SnapRemove) {
   }
 
   // verify lock ordering constraints
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
   ASSERT_EQ(0, ictx->operations->snap_remove("snap"));
 }
 
@@ -607,7 +619,8 @@ TEST_F(TestJournalReplay, Flatten) {
 
   librbd::ImageCtx *ictx;
   ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, ictx->operations->snap_create("snap"));
+  ASSERT_EQ(0, ictx->operations->snap_create("snap",
+                                            cls::rbd::UserSnapshotNamespace()));
   ASSERT_EQ(0, ictx->operations->snap_protect("snap"));
 
   std::string clone_name = get_temp_image_name();
index 92250645214c749cde2bbe12147dbc9161749844..04d2a6a81f086dc6a84e1c51272f4fe360290355 100644 (file)
@@ -155,9 +155,9 @@ public:
   void expect_snap_create(MockReplayImageCtx &mock_image_ctx,
                           Context **on_finish, const char *snap_name,
                           uint64_t op_tid) {
-    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(StrEq(snap_name), _,
+    EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(StrEq(snap_name), _, _,
                                                                 op_tid, false))
-                  .WillOnce(DoAll(SaveArg<1>(on_finish),
+                  .WillOnce(DoAll(SaveArg<2>(on_finish),
                                   NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
   }
 
@@ -557,7 +557,8 @@ TEST_F(TestMockJournalReplay, BlockedOpFinishError) {
 
   C_SaferCond on_start_ready;
   C_SaferCond on_start_safe;
-  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap",
+                                                                cls::rbd::UserSnapshotNamespace())},
                &on_start_ready, &on_start_safe);
 
   C_SaferCond on_resume;
@@ -603,7 +604,8 @@ TEST_F(TestMockJournalReplay, MissingOpFinishEvent) {
 
   C_SaferCond on_snap_create_ready;
   C_SaferCond on_snap_create_safe;
-  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap",
+                                                              cls::rbd::UserSnapshotNamespace())},
                &on_snap_create_ready, &on_snap_create_safe);
 
   C_SaferCond on_shut_down;
@@ -644,7 +646,7 @@ TEST_F(TestMockJournalReplay, MissingOpFinishEventCancelOps) {
 
   C_SaferCond on_snap_create_ready;
   C_SaferCond on_snap_create_safe;
-  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap", cls::rbd::UserSnapshotNamespace())},
                &on_snap_create_ready, &on_snap_create_safe);
 
   C_SaferCond on_resume;
@@ -729,7 +731,7 @@ TEST_F(TestMockJournalReplay, SnapCreateEvent) {
 
   C_SaferCond on_start_ready;
   C_SaferCond on_start_safe;
-  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap", cls::rbd::UserSnapshotNamespace())},
                &on_start_ready, &on_start_safe);
 
   C_SaferCond on_resume;
@@ -766,7 +768,7 @@ TEST_F(TestMockJournalReplay, SnapCreateEventExists) {
 
   C_SaferCond on_start_ready;
   C_SaferCond on_start_safe;
-  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap")},
+  when_process(mock_journal_replay, EventEntry{SnapCreateEvent(123, "snap", cls::rbd::UserSnapshotNamespace())},
                &on_start_ready, &on_start_safe);
 
   wait_for_op_invoked(&on_finish, -EEXIST);
index b17714f954d64888646a9e835327cb5530c68b2b..8fb4c6489bcf455693bc4cbbbdef2d8e5b05957e 100644 (file)
@@ -140,6 +140,8 @@ struct MockImageCtx {
   MOCK_CONST_METHOD1(get_object_count, uint64_t(librados::snap_t));
   MOCK_CONST_METHOD1(get_snap_id, librados::snap_t(std::string in_snap_name));
   MOCK_CONST_METHOD1(get_snap_info, const SnapInfo*(librados::snap_t));
+  MOCK_CONST_METHOD2(get_snap_namespace, int(librados::snap_t,
+                                            cls::rbd::SnapshotNamespace *out_snap_namespace));
   MOCK_CONST_METHOD2(get_parent_spec, int(librados::snap_t in_snap_id,
                                           parent_spec *pspec));
 
@@ -148,7 +150,9 @@ struct MockImageCtx {
   MOCK_CONST_METHOD2(is_snap_unprotected, int(librados::snap_t in_snap_id,
                                               bool *is_unprotected));
 
-  MOCK_METHOD6(add_snap, void(std::string in_snap_name, librados::snap_t id,
+  MOCK_METHOD7(add_snap, void(std::string in_snap_name,
+                             cls::rbd::SnapshotNamespace in_snap_namespace,
+                             librados::snap_t id,
                               uint64_t in_size, parent_info parent,
                               uint8_t protection_status, uint64_t flags));
   MOCK_METHOD2(rm_snap, void(std::string in_snap_name, librados::snap_t id));
index 94e39639e83329d03a9ca99e7dec433fca821589..4cc910854c4ee6926b0b47f75f0e08e507861739 100644 (file)
@@ -4,6 +4,7 @@
 #ifndef CEPH_TEST_LIBRBD_MOCK_OPERATIONS_H
 #define CEPH_TEST_LIBRBD_MOCK_OPERATIONS_H
 
+#include "cls/rbd/cls_rbd_types.h"
 #include "include/int_types.h"
 #include "include/rbd/librbd.hpp"
 #include "gmock/gmock.h"
@@ -24,9 +25,11 @@ struct MockOperations {
                                     ProgressContext &prog_ctx,
                                     Context *on_finish,
                                     uint64_t journal_op_tid));
-  MOCK_METHOD2(snap_create, void(const std::string &snap_name,
+  MOCK_METHOD3(snap_create, void(const std::string &snap_name,
+                                const cls::rbd::SnapshotNamespace &snapshot_namespace,
                                  Context *on_finish));
-  MOCK_METHOD4(execute_snap_create, void(const std::string &snap_name,
+  MOCK_METHOD5(execute_snap_create, void(const std::string &snap_name,
+                                        const cls::rbd::SnapshotNamespace &snapshot_namespace,
                                          Context *on_finish,
                                          uint64_t journal_op_tid,
                                          bool skip_object_map));
index 3dd62989f2970bc70418333278f9e5bae6775726..e8b902c0a37b6879d566ece7e44650dcd74e5f2f 100644 (file)
@@ -5,6 +5,7 @@
 #include "test/librbd/test_support.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "common/bit_vector.hpp"
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/internal.h"
 #include "librbd/ObjectMap.h"
 #include "librbd/object_map/SnapshotCreateRequest.h"
@@ -24,7 +25,9 @@ public:
   void inject_snap_info(librbd::ImageCtx *ictx, uint64_t snap_id) {
     RWLock::WLocker snap_locker(ictx->snap_lock);
     RWLock::RLocker parent_locker(ictx->parent_lock);
-    ictx->add_snap("snap name", snap_id, ictx->size, ictx->parent_md,
+    ictx->add_snap("snap name",
+         cls::rbd::UserSnapshotNamespace(), snap_id,
+                  ictx->size, ictx->parent_md,
                    RBD_PROTECTION_STATUS_UNPROTECTED, 0);
   }
 
index 1b94b7e1f9f1bf4edc8153c97cdd77f7652a7540..23398cd197f92a9c344956641a895417ab7fca3b 100644 (file)
@@ -95,7 +95,7 @@ public:
     // state machine checks to ensure a refresh hasn't already added the snap
     EXPECT_CALL(mock_image_ctx, get_snap_info(_))
                   .WillOnce(Return(reinterpret_cast<const librbd::SnapInfo*>(NULL)));
-    EXPECT_CALL(mock_image_ctx, add_snap("snap1", _, _, _, _, _));
+    EXPECT_CALL(mock_image_ctx, add_snap("snap1", _, _, _, _, _, _));
   }
 
   void expect_unblock_writes(MockImageCtx &mock_image_ctx) {
@@ -138,7 +138,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, Success) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, false);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, false);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
@@ -167,7 +168,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, AllocateSnapIdError) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, false);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, false);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
@@ -205,7 +207,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, CreateSnapStale) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, false);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, false);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
@@ -235,7 +238,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, CreateSnapError) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, false);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, false);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
@@ -265,7 +269,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, ReleaseSnapIdError) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, false);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, false);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
@@ -301,7 +306,8 @@ TEST_F(TestMockOperationSnapshotCreateRequest, SkipObjectMap) {
 
   C_SaferCond cond_ctx;
   MockSnapshotCreateRequest *req = new MockSnapshotCreateRequest(
-    mock_image_ctx, &cond_ctx, "snap1", 0, true);
+    mock_image_ctx, &cond_ctx, "snap1",
+      cls::rbd::UserSnapshotNamespace(), 0, true);
   {
     RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
     req->send();
index f51595a66d32df9b0fbf00b57dcdbc7d2ae396b4..52f52f2bd7c8d8f2ad06bb990ed4f278201703c4 100644 (file)
@@ -488,7 +488,8 @@ TEST_F(TestImageWatcher, NotifySnapCreate) {
 
   RWLock::RLocker l(ictx->owner_lock);
   C_SaferCond notify_ctx;
-  ictx->image_watcher->notify_snap_create("snap", &notify_ctx);
+  ictx->image_watcher->notify_snap_create("snap",
+       cls::rbd::UserSnapshotNamespace(), &notify_ctx);
   ASSERT_EQ(0, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
@@ -510,7 +511,8 @@ TEST_F(TestImageWatcher, NotifySnapCreateError) {
 
   RWLock::RLocker l(ictx->owner_lock);
   C_SaferCond notify_ctx;
-  ictx->image_watcher->notify_snap_create("snap", &notify_ctx);
+  ictx->image_watcher->notify_snap_create("snap",
+       cls::rbd::UserSnapshotNamespace(), &notify_ctx);
   ASSERT_EQ(-EEXIST, notify_ctx.wait());
 
   NotifyOps expected_notify_ops;
index a521a79deee86afc172538a3502f44ea3b547e3b..82e7408ff88979030ff72616435fc6d0ffb92425 100644 (file)
@@ -10,6 +10,7 @@
 #include "librbd/Operations.h"
 #include "cls/lock/cls_lock_client.h"
 #include "cls/lock/cls_lock_types.h"
+#include "cls/rbd/cls_rbd_types.h"
 #include "librbd/internal.h"
 #include "test/librados/test.h"
 #include <iostream>
@@ -65,7 +66,8 @@ int TestFixture::open_image(const std::string &image_name,
 
 int TestFixture::snap_create(librbd::ImageCtx &ictx,
                              const std::string &snap_name) {
-  return ictx.operations->snap_create(snap_name.c_str());
+  return ictx.operations->snap_create(snap_name.c_str(),
+                                     cls::rbd::UserSnapshotNamespace());
 }
 
 int TestFixture::snap_protect(librbd::ImageCtx &ictx,
index 32de41a7efa8e94527d862a0ea204d5ad08020c3..1a754b49980e9f535567ff729d406fa2288ec779 100644 (file)
@@ -1,5 +1,6 @@
 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
+#include "cls/rbd/cls_rbd_types.h"
 #include "test/librbd/test_fixture.h"
 #include "test/librbd/test_support.h"
 #include "librbd/AioCompletion.h"
@@ -812,7 +813,8 @@ TEST_F(TestInternal, WriteFullCopyup) {
   } BOOST_SCOPE_EXIT_END;
 
   ASSERT_EQ(0, open_image(clone_name, &ictx2));
-  ASSERT_EQ(0, ictx2->operations->snap_create("snap1"));
+  ASSERT_EQ(0, ictx2->operations->snap_create("snap1",
+                                             cls::rbd::UserSnapshotNamespace()));
 
   bufferlist write_full_bl;
   write_full_bl.append(std::string(1 << ictx2->order, '2'));