From 217475194604e96d153aafbc934f1c5241638cfb Mon Sep 17 00:00:00 2001 From: Victor Denisov Date: Tue, 20 Sep 2016 21:35:30 -0700 Subject: [PATCH] librbd: By default create snapshots in UserNamespace Signed-off-by: Victor Denisov --- src/librbd/ImageCtx.cc | 19 +++++- src/librbd/ImageCtx.h | 7 ++- src/librbd/ImageWatcher.cc | 4 +- src/librbd/ImageWatcher.h | 5 +- src/librbd/Operations.cc | 19 +++--- src/librbd/Operations.h | 12 +++- src/librbd/SnapInfo.h | 7 ++- src/librbd/WatchNotifyTypes.cc | 26 +++++++- src/librbd/WatchNotifyTypes.h | 10 ++- src/librbd/image/RefreshRequest.cc | 61 ++++++++++++++++++- src/librbd/image/RefreshRequest.h | 7 +++ src/librbd/internal.cc | 27 ++++++++ src/librbd/internal.h | 4 ++ src/librbd/journal/Replay.cc | 1 + src/librbd/journal/Types.cc | 24 +++++++- src/librbd/journal/Types.h | 12 ++-- src/librbd/librbd.cc | 8 ++- src/librbd/operation/SnapshotCreateRequest.cc | 7 ++- src/librbd/operation/SnapshotCreateRequest.h | 8 ++- .../librbd/image/test_mock_RefreshRequest.cc | 10 ++- src/test/librbd/journal/test_Replay.cc | 35 +++++++---- src/test/librbd/journal/test_mock_Replay.cc | 16 ++--- src/test/librbd/mock/MockImageCtx.h | 6 +- src/test/librbd/mock/MockOperations.h | 7 ++- .../test_mock_SnapshotCreateRequest.cc | 5 +- .../test_mock_SnapshotCreateRequest.cc | 20 +++--- src/test/librbd/test_ImageWatcher.cc | 6 +- src/test/librbd/test_fixture.cc | 4 +- src/test/librbd/test_internal.cc | 4 +- 29 files changed, 311 insertions(+), 70 deletions(-) diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 11422d806e9..91d9ac0be4f 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -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(id, info)); snap_ids.insert(pair(in_snap_name, id)); } diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 1855641267e..ff60498aaf7 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -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); diff --git a/src/librbd/ImageWatcher.cc b/src/librbd/ImageWatcher.cc index 817f4acdc4d..12dfb0c41db 100644 --- a/src/librbd/ImageWatcher.cc +++ b/src/librbd/ImageWatcher.cc @@ -262,13 +262,14 @@ void ImageWatcher::notify_resize(uint64_t request_id, uint64_t size, template void ImageWatcher::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::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; diff --git a/src/librbd/ImageWatcher.h b/src/librbd/ImageWatcher.h index cac2d9d0e34..563fbd2653f 100644 --- a/src/librbd/ImageWatcher.h +++ b/src/librbd/ImageWatcher.h @@ -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); diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index 933e412b8b8..a3213e3864e 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -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::execute_resize(uint64_t size, bool allow_shrink, ProgressCon } template -int Operations::snap_create(const char *snap_name) { +int Operations::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::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::snap_create(const char *snap_name) { } template -void Operations::snap_create(const char *snap_name, Context *on_finish) { +void Operations::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::snap_create(const char *snap_name, Context *on_finish) { C_InvokeAsyncRequest *req = new C_InvokeAsyncRequest( m_image_ctx, "snap_create", true, - boost::bind(&Operations::execute_snap_create, this, snap_name, _1, 0, - false), + boost::bind(&Operations::execute_snap_create, this, snap_name, + snap_namespace, _1, 0, false), boost::bind(&ImageWatcher::notify_snap_create, m_image_ctx.image_watcher, - snap_name, _1), + snap_name, snap_namespace, _1), {-EEXIST}, on_finish); req->send(); } template void Operations::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::execute_snap_create(const std::string &snap_name, operation::SnapshotCreateRequest *req = new operation::SnapshotCreateRequest( m_image_ctx, new C_NotifyUpdate(m_image_ctx, on_finish), snap_name, - journal_op_tid, skip_object_map); + snap_namespace, journal_op_tid, skip_object_map); req->send(); } diff --git a/src/librbd/Operations.h b/src/librbd/Operations.h index 6790ffeac3f..673b61cc228 100644 --- a/src/librbd/Operations.h +++ b/src/librbd/Operations.h @@ -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 @@ -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); diff --git a/src/librbd/SnapInfo.h b/src/librbd/SnapInfo.h index 1babee9e550..3bd0b98a629 100644 --- a/src/librbd/SnapInfo.h +++ b/src/librbd/SnapInfo.h @@ -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) {} }; } diff --git a/src/librbd/WatchNotifyTypes.cc b/src/librbd/WatchNotifyTypes.cc index 2f9d211db09..bbee3a10017 100644 --- a/src/librbd/WatchNotifyTypes.cc +++ b/src/librbd/WatchNotifyTypes.cc @@ -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 &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"))); diff --git a/src/librbd/WatchNotifyTypes.h b/src/librbd/WatchNotifyTypes.h index d7474770176..9e91ba0f58f 100644 --- a/src/librbd/WatchNotifyTypes.h +++ b/src/librbd/WatchNotifyTypes.h @@ -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 { diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc index f1a9d110459..14d7e8784a6 100644 --- a/src/librbd/image/RefreshRequest.cc +++ b/src/librbd/image/RefreshRequest.cc @@ -140,6 +140,12 @@ Context *RefreshRequest::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 + ( + m_snap_names.size(), + cls::rbd::UserSnapshotNamespace()); + send_v1_get_locks(); return nullptr; } @@ -340,6 +346,7 @@ template void RefreshRequest::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::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::handle_v2_get_snapshots(int *result) { return m_on_finish; } + send_v2_get_snap_namespaces(); + return nullptr; +} + +template +void RefreshRequest::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; + 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 +Context *RefreshRequest::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 + ( + 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::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; diff --git a/src/librbd/image/RefreshRequest.h b/src/librbd/image/RefreshRequest.h index 33e6d0bcca0..79e616ba1b6 100644 --- a/src/librbd/image/RefreshRequest.h +++ b/src/librbd/image/RefreshRequest.h @@ -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 m_snap_names; + std::vector m_snap_namespaces; std::vector m_snap_sizes; std::vector m_snap_parents; std::vector 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); diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index f08f13d9116..a48c47ba977 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -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(&snap_namespace) == nullptr) { + return -EINVAL; + } + r = ictx->state->refresh_if_required(); if (r < 0) return r; diff --git a/src/librbd/internal.h b/src/librbd/internal.h index ddc1cb06560..50244715ca2 100644 --- a/src/librbd/internal.h +++ b/src/librbd/internal.h @@ -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, diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc index 9055e0b8974..ff52c50d046 100644 --- a/src/librbd/journal/Replay.cc +++ b/src/librbd/journal/Replay.cc @@ -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); } diff --git a/src/librbd/journal/Types.cc b/src/librbd/journal/Types.cc index bdd294f467b..8242cffbec8 100644 --- a/src/librbd/journal/Types.cc +++ b/src/librbd/journal/Types.cc @@ -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 &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"))); diff --git a/src/librbd/journal/Types.h b/src/librbd/journal/Types.h index 37c590556fd..505822d9ffc 100644 --- a/src/librbd/journal/Types.h +++ b/src/librbd/journal/Types.h @@ -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 { diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 52ee192a13e..207b7d9e80d 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -15,6 +15,7 @@ #include +#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; } diff --git a/src/librbd/operation/SnapshotCreateRequest.cc b/src/librbd/operation/SnapshotCreateRequest.cc index 4f20ec4f977..45d1ba619f1 100644 --- a/src/librbd/operation/SnapshotCreateRequest.cc +++ b/src/librbd/operation/SnapshotCreateRequest.cc @@ -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 SnapshotCreateRequest::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(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::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::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 diff --git a/src/librbd/operation/SnapshotCreateRequest.h b/src/librbd/operation/SnapshotCreateRequest.h index c239d601eae..16458260409 100644 --- a/src/librbd/operation/SnapshotCreateRequest.h +++ b/src/librbd/operation/SnapshotCreateRequest.h @@ -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 @@ -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; diff --git a/src/test/librbd/image/test_mock_RefreshRequest.cc b/src/test/librbd/image/test_mock_RefreshRequest.cc index ca634aa0db5..008fd217cae 100644 --- a/src/test/librbd/image/test_mock_RefreshRequest.cc +++ b/src/test/librbd/image/test_mock_RefreshRequest.cc @@ -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); diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc index 9abfb5e54de..d27b7274eb4 100644 --- a/src/test/librbd/journal/test_Replay.cc +++ b/src/test/librbd/journal/test_Replay.cc @@ -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(); diff --git a/src/test/librbd/journal/test_mock_Replay.cc b/src/test/librbd/journal/test_mock_Replay.cc index 92250645214..04d2a6a81f0 100644 --- a/src/test/librbd/journal/test_mock_Replay.cc +++ b/src/test/librbd/journal/test_mock_Replay.cc @@ -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); diff --git a/src/test/librbd/mock/MockImageCtx.h b/src/test/librbd/mock/MockImageCtx.h index b17714f954d..8fb4c6489bc 100644 --- a/src/test/librbd/mock/MockImageCtx.h +++ b/src/test/librbd/mock/MockImageCtx.h @@ -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)); diff --git a/src/test/librbd/mock/MockOperations.h b/src/test/librbd/mock/MockOperations.h index 94e39639e83..4cc910854c4 100644 --- a/src/test/librbd/mock/MockOperations.h +++ b/src/test/librbd/mock/MockOperations.h @@ -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)); diff --git a/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc b/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc index 3dd62989f29..e8b902c0a37 100644 --- a/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc +++ b/src/test/librbd/object_map/test_mock_SnapshotCreateRequest.cc @@ -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); } diff --git a/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc b/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc index 1b94b7e1f9f..23398cd197f 100644 --- a/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc +++ b/src/test/librbd/operation/test_mock_SnapshotCreateRequest.cc @@ -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(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(); diff --git a/src/test/librbd/test_ImageWatcher.cc b/src/test/librbd/test_ImageWatcher.cc index f51595a66d3..52f52f2bd7c 100644 --- a/src/test/librbd/test_ImageWatcher.cc +++ b/src/test/librbd/test_ImageWatcher.cc @@ -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", ¬ify_ctx); + ictx->image_watcher->notify_snap_create("snap", + cls::rbd::UserSnapshotNamespace(), ¬ify_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", ¬ify_ctx); + ictx->image_watcher->notify_snap_create("snap", + cls::rbd::UserSnapshotNamespace(), ¬ify_ctx); ASSERT_EQ(-EEXIST, notify_ctx.wait()); NotifyOps expected_notify_ops; diff --git a/src/test/librbd/test_fixture.cc b/src/test/librbd/test_fixture.cc index a521a79deee..82e7408ff88 100644 --- a/src/test/librbd/test_fixture.cc +++ b/src/test/librbd/test_fixture.cc @@ -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 @@ -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, diff --git a/src/test/librbd/test_internal.cc b/src/test/librbd/test_internal.cc index 32de41a7efa..1a754b49980 100644 --- a/src/test/librbd/test_internal.cc +++ b/src/test/librbd/test_internal.cc @@ -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')); -- 2.39.5