From e69ca3a01ad7596570a5b5c3bd9d0d0a44721554 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 18 Jan 2018 12:16:00 -0500 Subject: [PATCH] librbd: new trash snapshot namespace Snapshots will be moved to the trash if they are still in-use by clones when deleted. Signed-off-by: Jason Dillaman --- src/cls/rbd/cls_rbd_types.cc | 34 ++++++++++++++++++++++++++++++--- src/cls/rbd/cls_rbd_types.h | 37 ++++++++++++++++++++++++++++-------- src/include/rbd/librbd.h | 5 +++-- src/pybind/rbd/rbd.pyx | 2 ++ 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/cls/rbd/cls_rbd_types.cc b/src/cls/rbd/cls_rbd_types.cc index 8d324e11c6897..a6390eb25f7fb 100644 --- a/src/cls/rbd/cls_rbd_types.cc +++ b/src/cls/rbd/cls_rbd_types.cc @@ -355,6 +355,20 @@ void GroupSnapshotNamespace::dump(Formatter *f) const { f->dump_string("group_snapshot_id", group_snapshot_id); } +void TrashSnapshotNamespace::encode(bufferlist& bl) const { + using ceph::encode; + encode(original_name, bl); +} + +void TrashSnapshotNamespace::decode(bufferlist::iterator& it) { + using ceph::decode; + decode(original_name, it); +} + +void TrashSnapshotNamespace::dump(Formatter *f) const { + f->dump_string("original_name", original_name); +} + class EncodeSnapshotNamespaceVisitor : public boost::static_visitor { public: explicit EncodeSnapshotNamespaceVisitor(bufferlist &bl) : m_bl(bl) { @@ -452,6 +466,8 @@ void SnapshotInfo::generate_test_instances(std::list &o) { o.push_back(new SnapshotInfo(2ULL, GroupSnapshotNamespace{567, "group1", "snap1"}, "snap1", 123, {123456, 0})); + o.push_back(new SnapshotInfo(3ULL, TrashSnapshotNamespace{"snap1"}, + "12345", 123, {123456, 0})); } void SnapshotNamespace::encode(bufferlist& bl) const { @@ -472,6 +488,9 @@ void SnapshotNamespace::decode(bufferlist::iterator &p) case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_GROUP: *this = GroupSnapshotNamespace(); break; + case cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH: + *this = TrashSnapshotNamespace(); + break; default: *this = UnknownSnapshotNamespace(); break; @@ -481,13 +500,17 @@ void SnapshotNamespace::decode(bufferlist::iterator &p) } void SnapshotNamespace::dump(Formatter *f) const { - boost::apply_visitor(DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this); + boost::apply_visitor( + DumpSnapshotNamespaceVisitor(f, "snapshot_namespace_type"), *this); } void SnapshotNamespace::generate_test_instances(std::list &o) { o.push_back(new SnapshotNamespace(UserSnapshotNamespace())); - o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a", "2118643c9732"))); - o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869", "33352be8933c"))); + o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(0, "10152ae8944a", + "2118643c9732"))); + o.push_back(new SnapshotNamespace(GroupSnapshotNamespace(5, "1018643c9869", + "33352be8933c"))); + o.push_back(new SnapshotNamespace(TrashSnapshotNamespace())); } std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns) { @@ -503,6 +526,11 @@ std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns) { return os; } +std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns) { + os << "[trash]"; + return os; +} + std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns) { os << "[unknown]"; return os; diff --git a/src/cls/rbd/cls_rbd_types.h b/src/cls/rbd/cls_rbd_types.h index c4a1ff496602c..78dde1a6f5eb2 100644 --- a/src/cls/rbd/cls_rbd_types.h +++ b/src/cls/rbd/cls_rbd_types.h @@ -229,8 +229,9 @@ struct GroupSpec { WRITE_CLASS_ENCODER(GroupSpec); enum SnapshotNamespaceType { - SNAPSHOT_NAMESPACE_TYPE_USER = 0, - SNAPSHOT_NAMESPACE_TYPE_GROUP = 1 + SNAPSHOT_NAMESPACE_TYPE_USER = 0, + SNAPSHOT_NAMESPACE_TYPE_GROUP = 1, + SNAPSHOT_NAMESPACE_TYPE_TRASH = 2 }; struct UserSnapshotNamespace { @@ -251,11 +252,8 @@ struct UserSnapshotNamespace { inline bool operator<(const UserSnapshotNamespace& usn) const { return false; } - }; -std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns); - struct GroupSnapshotNamespace { static const SnapshotNamespaceType SNAPSHOT_NAMESPACE_TYPE = SNAPSHOT_NAMESPACE_TYPE_GROUP; @@ -293,10 +291,29 @@ struct GroupSnapshotNamespace { } return false; } - }; -std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns); +struct TrashSnapshotNamespace { + static const SnapshotNamespaceType SNAPSHOT_NAMESPACE_TYPE = + SNAPSHOT_NAMESPACE_TYPE_TRASH; + + std::string original_name; + + TrashSnapshotNamespace() {} + TrashSnapshotNamespace(const std::string& original_name) + : original_name(original_name) {} + + void encode(bufferlist& bl) const; + void decode(bufferlist::iterator& it); + void dump(Formatter *f) const; + + inline bool operator==(const TrashSnapshotNamespace& usn) const { + return true; + } + inline bool operator<(const TrashSnapshotNamespace& usn) const { + return false; + } +}; struct UnknownSnapshotNamespace { static const SnapshotNamespaceType SNAPSHOT_NAMESPACE_TYPE = @@ -307,6 +324,7 @@ struct UnknownSnapshotNamespace { void encode(bufferlist& bl) const {} void decode(bufferlist::iterator& it) {} void dump(Formatter *f) const {} + inline bool operator==(const UnknownSnapshotNamespace& gsn) const { return true; } @@ -316,14 +334,17 @@ struct UnknownSnapshotNamespace { } }; +std::ostream& operator<<(std::ostream& os, const UserSnapshotNamespace& ns); +std::ostream& operator<<(std::ostream& os, const GroupSnapshotNamespace& ns); +std::ostream& operator<<(std::ostream& os, const TrashSnapshotNamespace& ns); std::ostream& operator<<(std::ostream& os, const UnknownSnapshotNamespace& ns); typedef boost::variant SnapshotNamespaceVariant; struct SnapshotNamespace : public SnapshotNamespaceVariant { - SnapshotNamespace() { } diff --git a/src/include/rbd/librbd.h b/src/include/rbd/librbd.h index 50949add5c114..36b93972cabee 100644 --- a/src/include/rbd/librbd.h +++ b/src/include/rbd/librbd.h @@ -176,8 +176,9 @@ typedef struct { } rbd_group_snap_info_t; typedef enum { - RBD_SNAP_NAMESPACE_TYPE_USER = 0, - RBD_SNAP_NAMESPACE_TYPE_GROUP = 1 + RBD_SNAP_NAMESPACE_TYPE_USER = 0, + RBD_SNAP_NAMESPACE_TYPE_GROUP = 1, + RBD_SNAP_NAMESPACE_TYPE_TRASH = 2 } rbd_snap_namespace_type_t; typedef struct { diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 7c4d2d864c755..8da4e65145731 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -157,6 +157,7 @@ cdef extern from "rbd/librbd.h" nogil: ctypedef enum rbd_snap_namespace_type_t: _RBD_SNAP_NAMESPACE_TYPE_USER "RBD_SNAP_NAMESPACE_TYPE_USER" _RBD_SNAP_NAMESPACE_TYPE_GROUP "RBD_SNAP_NAMESPACE_TYPE_GROUP" + _RBD_SNAP_NAMESPACE_TYPE_TRASH "RBD_SNAP_NAMESPACE_TYPE_TRASH" ctypedef enum rbd_lock_mode_t: _RBD_LOCK_MODE_EXCLUSIVE "RBD_LOCK_MODE_EXCLUSIVE" @@ -503,6 +504,7 @@ RBD_IMAGE_OPTION_DATA_POOL = _RBD_IMAGE_OPTION_DATA_POOL RBD_SNAP_NAMESPACE_TYPE_USER = _RBD_SNAP_NAMESPACE_TYPE_USER RBD_SNAP_NAMESPACE_TYPE_GROUP = _RBD_SNAP_NAMESPACE_TYPE_GROUP +RBD_SNAP_NAMESPACE_TYPE_TRASH = _RBD_SNAP_NAMESPACE_TYPE_TRASH RBD_GROUP_IMAGE_STATE_ATTACHED = _RBD_GROUP_IMAGE_STATE_ATTACHED RBD_GROUP_IMAGE_STATE_INCOMPLETE = _RBD_GROUP_IMAGE_STATE_INCOMPLETE -- 2.39.5