From f76df32666b555eef273ebb091f18a4aec28f7fa Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Thu, 26 Jul 2018 23:11:22 -0400 Subject: [PATCH] librbd: break composite cls rbd helpers into individual helpers With the forthcoming need to use new methods to retrieve a clone's parent, use per-method helpers to invoke the correct method within the image refresh state machine. Also used this time to merge newer cls rbd methods that should be supported by all non-EOLed OSDs. Signed-off-by: Jason Dillaman --- src/cls/rbd/cls_rbd_client.cc | 437 +++++------------- src/cls/rbd/cls_rbd_client.h | 116 ++--- src/librbd/api/Mirror.cc | 6 +- src/librbd/image/DetachChildRequest.cc | 4 +- src/librbd/image/OpenRequest.cc | 24 +- src/librbd/image/RefreshRequest.cc | 334 ++++++------- src/librbd/image/RefreshRequest.h | 28 +- src/librbd/operation/SnapshotRemoveRequest.cc | 4 +- src/test/cls_rbd/CMakeLists.txt | 1 - src/test/cls_rbd/test_cls_rbd.cc | 310 ++++--------- .../librbd/image/test_mock_RefreshRequest.cc | 42 +- 11 files changed, 424 insertions(+), 882 deletions(-) diff --git a/src/cls/rbd/cls_rbd_client.cc b/src/cls/rbd/cls_rbd_client.cc index 98221d0fa192d..0df92665591f7 100644 --- a/src/cls/rbd/cls_rbd_client.cc +++ b/src/cls/rbd/cls_rbd_client.cc @@ -13,146 +13,6 @@ namespace librbd { namespace cls_client { -void get_initial_metadata_start(librados::ObjectReadOperation *op) { - bufferlist bl, empty_bl, features_bl; - snapid_t snap = CEPH_NOSNAP; - encode(snap, bl); - op->exec("rbd", "get_size", bl); - op->exec("rbd", "get_object_prefix", empty_bl); - - encode(snap, features_bl); - encode(true, features_bl); - op->exec("rbd", "get_features", features_bl); -} - -int get_initial_metadata_finish(bufferlist::const_iterator *it, - std::string *object_prefix, - uint8_t *order, - uint64_t *features) { - try { - uint64_t size; - uint64_t incompatible_features; - // get_size - decode(*order, *it); - decode(size, *it); - // get_object_prefix - decode(*object_prefix, *it); - // get_features - decode(*features, *it); - decode(incompatible_features, *it); - } catch (const buffer::error &err) { - return -EBADMSG; - } - return 0; - -} - -int get_initial_metadata(librados::IoCtx *ioctx, const std::string &oid, - std::string *object_prefix, uint8_t *order, uint64_t *features) -{ - librados::ObjectReadOperation op; - get_initial_metadata_start(&op); - - bufferlist out_bl; - int r = ioctx->operate(oid, &op, &out_bl); - if (r < 0) { - return r; - } - - auto it = out_bl.cbegin(); - return get_initial_metadata_finish(&it, object_prefix, order, features); -} - -void get_mutable_metadata_start(librados::ObjectReadOperation *op, - bool read_only) { - snapid_t snap = CEPH_NOSNAP; - bufferlist size_bl; - encode(snap, size_bl); - op->exec("rbd", "get_size", size_bl); - - bufferlist features_bl; - encode(snap, features_bl); - encode(read_only, features_bl); - op->exec("rbd", "get_features", features_bl); - - bufferlist empty_bl; - op->exec("rbd", "get_snapcontext", empty_bl); - - get_parent_start(op, snap); - - rados::cls::lock::get_lock_info_start(op, RBD_LOCK_NAME); -} - -int get_mutable_metadata_finish(bufferlist::const_iterator *it, - uint64_t *size, uint64_t *features, - uint64_t *incompatible_features, - std::map *lockers, - bool *exclusive_lock, std::string *lock_tag, - ::SnapContext *snapc, ParentInfo *parent) { - ceph_assert(size); - ceph_assert(features); - ceph_assert(incompatible_features); - ceph_assert(lockers); - ceph_assert(exclusive_lock); - ceph_assert(snapc); - ceph_assert(parent); - - try { - uint8_t order; - // get_size - decode(order, *it); - decode(*size, *it); - // get_features - decode(*features, *it); - decode(*incompatible_features, *it); - // get_snapcontext - decode(*snapc, *it); - // get_parent - int r = get_parent_finish(it, &parent->spec, &parent->overlap); - if (r < 0) { - return r; - } - - // get_lock_info - ClsLockType lock_type = LOCK_NONE; - r = rados::cls::lock::get_lock_info_finish(it, lockers, &lock_type, - lock_tag); - if (r == 0) { - *exclusive_lock = (lock_type == LOCK_EXCLUSIVE); - } - } catch (const buffer::error &err) { - return -EBADMSG; - } - return 0; -} - -int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid, - bool read_only, uint64_t *size, uint64_t *features, - uint64_t *incompatible_features, - map *lockers, - bool *exclusive_lock, - string *lock_tag, - ::SnapContext *snapc, - ParentInfo *parent) -{ - librados::ObjectReadOperation op; - get_mutable_metadata_start(&op, read_only); - - bufferlist out_bl; - int r = ioctx->operate(oid, &op, &out_bl); - if (r < 0) { - return r; - } - - auto it = out_bl.cbegin(); - return get_mutable_metadata_finish(&it, size, features, - incompatible_features, lockers, - exclusive_lock, lock_tag, snapc, - parent); -} - void create_image(librados::ObjectWriteOperation *op, uint64_t size, uint8_t order, uint64_t features, const std::string &object_prefix, int64_t data_pool_id) @@ -177,19 +37,20 @@ int create_image(librados::IoCtx *ioctx, const std::string &oid, return ioctx->operate(oid, &op); } -int get_features(librados::IoCtx *ioctx, const std::string &oid, - snapid_t snap_id, uint64_t *features) +void get_features_start(librados::ObjectReadOperation *op, bool read_only) { - bufferlist inbl, outbl; - encode(snap_id, inbl); - - int r = ioctx->exec(oid, "rbd", "get_features", inbl, outbl); - if (r < 0) - return r; + bufferlist bl; + encode(static_cast(CEPH_NOSNAP), bl); + encode(read_only, bl); + op->exec("rbd", "get_features", bl); +} +int get_features_finish(bufferlist::const_iterator *it, uint64_t *features, + uint64_t *incompatible_features) +{ try { - auto iter = outbl.cbegin(); - decode(*features, iter); + decode(*features, *it); + decode(*incompatible_features, *it); } catch (const buffer::error &err) { return -EBADMSG; } @@ -197,6 +58,23 @@ int get_features(librados::IoCtx *ioctx, const std::string &oid, return 0; } +int get_features(librados::IoCtx *ioctx, const std::string &oid, + bool read_only, uint64_t *features, + uint64_t *incompatible_features) +{ + librados::ObjectReadOperation op; + get_features_start(&op, read_only); + + bufferlist out_bl; + int r = ioctx->operate(oid, &op, &out_bl); + if (r < 0) { + return r; + } + + auto it = out_bl.cbegin(); + return get_features_finish(&it, features, incompatible_features); +} + void set_features(librados::ObjectWriteOperation *op, uint64_t features, uint64_t mask) { @@ -216,24 +94,39 @@ int set_features(librados::IoCtx *ioctx, const std::string &oid, return ioctx->operate(oid, &op); } -int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid, - std::string *object_prefix) +void get_object_prefix_start(librados::ObjectReadOperation *op) { - bufferlist inbl, outbl; - int r = ioctx->exec(oid, "rbd", "get_object_prefix", inbl, outbl); - if (r < 0) - return r; + bufferlist bl; + op->exec("rbd", "get_object_prefix", bl); +} +int get_object_prefix_finish(bufferlist::const_iterator *it, + std::string *object_prefix) +{ try { - auto iter = outbl.cbegin(); - decode(*object_prefix, iter); + decode(*object_prefix, *it); } catch (const buffer::error &err) { return -EBADMSG; } - return 0; } +int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid, + std::string *object_prefix) +{ + librados::ObjectReadOperation op; + get_object_prefix_start(&op); + + bufferlist out_bl; + int r = ioctx->operate(oid, &op, &out_bl); + if (r < 0) { + return r; + } + + auto it = out_bl.cbegin(); + return get_object_prefix_finish(&it, object_prefix); +} + void get_data_pool_start(librados::ObjectReadOperation *op) { bufferlist bl; op->exec("rbd", "get_data_pool", bl); @@ -263,27 +156,41 @@ int get_data_pool(librados::IoCtx *ioctx, const std::string &oid, return get_data_pool_finish(&it, data_pool_id); } -int get_size(librados::IoCtx *ioctx, const std::string &oid, - snapid_t snap_id, uint64_t *size, uint8_t *order) +void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id) { - bufferlist inbl, outbl; - encode(snap_id, inbl); - - int r = ioctx->exec(oid, "rbd", "get_size", inbl, outbl); - if (r < 0) - return r; + bufferlist bl; + encode(snap_id, bl); + op->exec("rbd", "get_size", bl); +} +int get_size_finish(bufferlist::const_iterator *it, uint64_t *size, + uint8_t *order) +{ try { - auto iter = outbl.cbegin(); - decode(*order, iter); - decode(*size, iter); + decode(*order, *it); + decode(*size, *it); } catch (const buffer::error &err) { return -EBADMSG; } - return 0; } +int get_size(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, uint64_t *size, uint8_t *order) +{ + librados::ObjectReadOperation op; + get_size_start(&op, snap_id); + + bufferlist out_bl; + int r = ioctx->operate(oid, &op, &out_bl); + if (r < 0) { + return r; + } + + auto it = out_bl.cbegin(); + return get_size_finish(&it, size, order); +} + int set_size(librados::IoCtx *ioctx, const std::string &oid, uint64_t size) { @@ -356,29 +263,15 @@ void set_parent(librados::ObjectWriteOperation *op, op->exec("rbd", "set_parent", in_bl); } -void get_flags_start(librados::ObjectReadOperation *op, - const std::vector &snap_ids) { +void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id) { bufferlist in_bl; - encode(static_cast(CEPH_NOSNAP), in_bl); - + encode(static_cast(snap_id), in_bl); op->exec("rbd", "get_flags", in_bl); - for (size_t i = 0; i < snap_ids.size(); ++i) { - bufferlist snap_bl; - encode(snap_ids[i], snap_bl); - op->exec("rbd", "get_flags", snap_bl); - } - } -int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags, - const std::vector &snap_ids, - std::vector *snap_flags) { - snap_flags->resize(snap_ids.size()); +int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags) { try { decode(*flags, *it); - for (size_t i = 0; i < snap_flags->size(); ++i) { - decode((*snap_flags)[i], *it); - } } catch (const buffer::error &err) { return -EBADMSG; } @@ -386,11 +279,10 @@ int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags, } int get_flags(librados::IoCtx *ioctx, const std::string &oid, - uint64_t *flags, const std::vector &snap_ids, - vector *snap_flags) + snapid_t snap_id, uint64_t *flags) { librados::ObjectReadOperation op; - get_flags_start(&op, snap_ids); + get_flags_start(&op, snap_id); bufferlist out_bl; int r = ioctx->operate(oid, &op, &out_bl); @@ -399,7 +291,7 @@ int get_flags(librados::IoCtx *ioctx, const std::string &oid, } auto it = out_bl.cbegin(); - return get_flags_finish(&it, flags, snap_ids, snap_flags); + return get_flags_finish(&it, flags); } void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id, @@ -549,16 +441,15 @@ int get_children(librados::IoCtx *ioctx, const std::string &oid, return get_children_finish(&it, &children); } -void snapshot_info_get_start(librados::ObjectReadOperation *op, - snapid_t snap_id) +void snapshot_get_start(librados::ObjectReadOperation *op, snapid_t snap_id) { bufferlist bl; encode(snap_id, bl); op->exec("rbd", "snapshot_get", bl); } -int snapshot_info_get_finish(bufferlist::const_iterator* it, - cls::rbd::SnapshotInfo* snap_info) +int snapshot_get_finish(bufferlist::const_iterator* it, + cls::rbd::SnapshotInfo* snap_info) { try { decode(*snap_info, *it); @@ -568,60 +459,11 @@ int snapshot_info_get_finish(bufferlist::const_iterator* it, return 0; } -void snapshot_get_start(librados::ObjectReadOperation *op, - const std::vector &ids) -{ - for (auto snap_id : ids) { - snapshot_info_get_start(op, snap_id); - get_parent_start(op, snap_id); - get_protection_status_start(op, snap_id); - } -} - -int snapshot_get_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector* snaps, - std::vector *parents, - std::vector *protection_statuses) -{ - snaps->resize(ids.size()); - parents->resize(ids.size()); - protection_statuses->resize(ids.size()); - try { - for (size_t i = 0; i < snaps->size(); ++i) { - // snapshot_get - int r = snapshot_info_get_finish(it, &(*snaps)[i]); - if (r < 0) { - return r; - } - - // get_parent - r = get_parent_finish(it, &(*parents)[i].spec, - &(*parents)[i].overlap); - if (r < 0) { - return r; - } - - // get_protection_status - r = get_protection_status_finish(it, &(*protection_statuses)[i]); - if (r < 0) { - return r; - } - } - } catch (const buffer::error &err) { - return -EBADMSG; - } - return 0; -} - -int snapshot_get(librados::IoCtx* ioctx, const std::string& oid, - const std::vector& ids, - std::vector* snaps, - std::vector *parents, - std::vector *protection_statuses) +int snapshot_get(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info) { librados::ObjectReadOperation op; - snapshot_get_start(&op, ids); + snapshot_get_start(&op, snap_id); bufferlist out_bl; int r = ioctx->operate(oid, &op, &out_bl); @@ -630,7 +472,7 @@ int snapshot_get(librados::IoCtx* ioctx, const std::string& oid, } auto it = out_bl.cbegin(); - return snapshot_get_finish(&it, ids, snaps, parents, protection_statuses); + return snapshot_get_finish(&it, snap_info); } void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id, @@ -705,67 +547,30 @@ int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid, return get_snapcontext_finish(&bl_it, snapc); } -void snapshot_list_start(librados::ObjectReadOperation *op, - const std::vector &ids) { - for (auto snap_id : ids) { - bufferlist bl1, bl2; - encode(snap_id, bl1); - op->exec("rbd", "get_snapshot_name", bl1); - encode(snap_id, bl2); - op->exec("rbd", "get_size", bl2); - get_parent_start(op, snap_id); - get_protection_status_start(op, snap_id); - } +void get_snapshot_name_start(librados::ObjectReadOperation *op, + snapid_t snap_id) +{ + bufferlist bl; + encode(snap_id, bl); + op->exec("rbd", "get_snapshot_name", bl); } -int snapshot_list_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector *names, - std::vector *sizes, - std::vector *parents, - std::vector *protection_statuses) +int get_snapshot_name_finish(bufferlist::const_iterator *it, + std::string *name) { - names->resize(ids.size()); - sizes->resize(ids.size()); - parents->resize(ids.size()); - protection_statuses->resize(ids.size()); try { - for (size_t i = 0; i < names->size(); ++i) { - uint8_t order; - // get_snapshot_name - decode((*names)[i], *it); - // get_size - decode(order, *it); - decode((*sizes)[i], *it); - - // get_parent - int r = get_parent_finish(it, &(*parents)[i].spec, - &(*parents)[i].overlap); - if (r < 0) { - return r; - } - - // get_protection_status - r = get_protection_status_finish(it, &(*protection_statuses)[i]); - if (r < 0) { - return r; - } - } + decode(*name, *it); } catch (const buffer::error &err) { return -EBADMSG; } return 0; } -int snapshot_list(librados::IoCtx *ioctx, const std::string &oid, - const std::vector &ids, - std::vector *names, - std::vector *sizes, - std::vector *parents, - std::vector *protection_statuses) +int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, std::string *name) { librados::ObjectReadOperation op; - snapshot_list_start(&op, ids); + get_snapshot_name_start(&op, snap_id); bufferlist out_bl; int r = ioctx->operate(oid, &op, &out_bl); @@ -774,43 +579,33 @@ int snapshot_list(librados::IoCtx *ioctx, const std::string &oid, } auto it = out_bl.cbegin(); - return snapshot_list_finish(&it, ids, names, sizes, parents, - protection_statuses); + return get_snapshot_name_finish(&it, name); } -void snapshot_timestamp_list_start(librados::ObjectReadOperation *op, - const std::vector &ids) +void get_snapshot_timestamp_start(librados::ObjectReadOperation *op, + snapid_t snap_id) { - for (auto snap_id : ids) { - bufferlist bl; - encode(snap_id, bl); - op->exec("rbd", "get_snapshot_timestamp", bl); - } + bufferlist bl; + encode(snap_id, bl); + op->exec("rbd", "get_snapshot_timestamp", bl); } -int snapshot_timestamp_list_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector *timestamps) +int get_snapshot_timestamp_finish(bufferlist::const_iterator *it, + utime_t *timestamp) { - timestamps->resize(ids.size()); try { - for (size_t i = 0; i < timestamps->size(); ++i) { - utime_t t; - decode(t, *it); - (*timestamps)[i] = t; - } + decode(*timestamp, *it); } catch (const buffer::error &err) { return -EBADMSG; } return 0; } -int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid, - const std::vector &ids, - std::vector *timestamps) +int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, utime_t *timestamp) { librados::ObjectReadOperation op; - snapshot_timestamp_list_start(&op, ids); + get_snapshot_timestamp_start(&op, snap_id); bufferlist out_bl; int r = ioctx->operate(oid, &op, &out_bl); @@ -819,7 +614,7 @@ int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid, } auto it = out_bl.cbegin(); - return snapshot_timestamp_list_finish(&it, ids, timestamps); + return get_snapshot_timestamp_finish(&it, timestamp); } void old_snapshot_add(librados::ObjectWriteOperation *op, diff --git a/src/cls/rbd/cls_rbd_client.h b/src/cls/rbd/cls_rbd_client.h index b082e7c1c2656..e72d533d3613e 100644 --- a/src/cls/rbd/cls_rbd_client.h +++ b/src/cls/rbd/cls_rbd_client.h @@ -22,34 +22,6 @@ namespace librados { namespace librbd { namespace cls_client { -// high-level interface to the header -void get_initial_metadata_start(librados::ObjectReadOperation *op); -int get_initial_metadata_finish(bufferlist::const_iterator *it, - std::string *object_prefix, - uint8_t *order, - uint64_t *features); -int get_initial_metadata(librados::IoCtx *ioctx, const std::string &oid, - std::string *object_prefix, uint8_t *order, uint64_t *features); - -void get_mutable_metadata_start(librados::ObjectReadOperation *op, - bool read_only); -int get_mutable_metadata_finish(bufferlist::const_iterator *it, - uint64_t *size, uint64_t *features, - uint64_t *incompatible_features, - std::map *lockers, - bool *exclusive_lock, std::string *lock_tag, - ::SnapContext *snapc, ParentInfo *parent); -int get_mutable_metadata(librados::IoCtx *ioctx, const std::string &oid, - bool read_only, uint64_t *size, uint64_t *features, - uint64_t *incompatible_features, - map *lockers, - bool *exclusive_lock, - std::string *lock_tag, - ::SnapContext *snapc, - ParentInfo *parent); - // low-level interface (mainly for testing) void create_image(librados::ObjectWriteOperation *op, uint64_t size, uint8_t order, uint64_t features, @@ -57,18 +29,32 @@ void create_image(librados::ObjectWriteOperation *op, uint64_t size, int create_image(librados::IoCtx *ioctx, const std::string &oid, uint64_t size, uint8_t order, uint64_t features, const std::string &object_prefix, int64_t data_pool_id); + +void get_features_start(librados::ObjectReadOperation *op, bool read_only); +int get_features_finish(bufferlist::const_iterator *it, uint64_t *features, + uint64_t *incompatible_features); int get_features(librados::IoCtx *ioctx, const std::string &oid, - snapid_t snap_id, uint64_t *features); + bool read_only, uint64_t *features, + uint64_t *incompatible_features); void set_features(librados::ObjectWriteOperation *op, uint64_t features, uint64_t mask); int set_features(librados::IoCtx *ioctx, const std::string &oid, uint64_t features, uint64_t mask); + +void get_object_prefix_start(librados::ObjectReadOperation *op); +int get_object_prefix_finish(bufferlist::const_iterator *it, + std::string *object_prefix); int get_object_prefix(librados::IoCtx *ioctx, const std::string &oid, std::string *object_prefix); + void get_data_pool_start(librados::ObjectReadOperation *op); int get_data_pool_finish(bufferlist::const_iterator *it, int64_t *data_pool_id); int get_data_pool(librados::IoCtx *ioctx, const std::string &oid, int64_t *data_pool_id); + +void get_size_start(librados::ObjectReadOperation *op, snapid_t snap_id); +int get_size_finish(bufferlist::const_iterator *it, uint64_t *size, + uint8_t *order); int get_size(librados::IoCtx *ioctx, const std::string &oid, snapid_t snap_id, uint64_t *size, uint8_t *order); int set_size(librados::IoCtx *ioctx, const std::string &oid, @@ -86,16 +72,15 @@ int set_parent(librados::IoCtx *ioctx, const std::string &oid, const ParentSpec &pspec, uint64_t parent_overlap); void set_parent(librados::ObjectWriteOperation *op, const ParentSpec &pspec, uint64_t parent_overlap); -void get_flags_start(librados::ObjectReadOperation *op, - const std::vector &snap_ids); -int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags, - const std::vector &snap_ids, - std::vector *snap_flags); + +void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id); +int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags); int get_flags(librados::IoCtx *ioctx, const std::string &oid, - uint64_t *flags, const std::vector &snap_ids, - vector *snap_flags); + snapid_t snap_id, uint64_t *flags); + void set_flags(librados::ObjectWriteOperation *op, snapid_t snap_id, uint64_t flags, uint64_t mask); + void op_features_get_start(librados::ObjectReadOperation *op); int op_features_get_finish(bufferlist::const_iterator *it, uint64_t *op_features); int op_features_get(librados::IoCtx *ioctx, const std::string &oid, @@ -121,23 +106,12 @@ int get_children_finish(bufferlist::const_iterator *it, int get_children(librados::IoCtx *ioctx, const std::string &oid, const ParentSpec &pspec, set& children); -void snapshot_info_get_start(librados::ObjectReadOperation* op, - snapid_t snap_id); -int snapshot_info_get_finish(bufferlist::const_iterator* it, - cls::rbd::SnapshotInfo* snap_info); - -void snapshot_get_start(librados::ObjectReadOperation *op, - const std::vector &ids); -int snapshot_get_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector* snaps, - std::vector *parents, - std::vector *protection_statuses); -int snapshot_get(librados::IoCtx* ioctx, const std::string& oid, - const std::vector& ids, - std::vector* snaps, - std::vector *parents, - std::vector *protection_statuses); +void snapshot_get_start(librados::ObjectReadOperation* op, + snapid_t snap_id); +int snapshot_get_finish(bufferlist::const_iterator* it, + cls::rbd::SnapshotInfo* snap_info); +int snapshot_get(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, cls::rbd::SnapshotInfo* snap_info); void snapshot_add(librados::ObjectWriteOperation *op, snapid_t snap_id, const std::string &snap_name, @@ -156,30 +130,20 @@ int get_snapcontext(librados::IoCtx *ioctx, const std::string &oid, ::SnapContext *snapc); /// NOTE: remove after Luminous is retired -void snapshot_list_start(librados::ObjectReadOperation *op, - const std::vector &ids); -int snapshot_list_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector *names, - std::vector *sizes, - std::vector *parents, - std::vector *protection_statuses); -int snapshot_list(librados::IoCtx *ioctx, const std::string &oid, - const std::vector &ids, - std::vector *names, - std::vector *sizes, - std::vector *parents, - std::vector *protection_statuses); +void get_snapshot_name_start(librados::ObjectReadOperation *op, + snapid_t snap_id); +int get_snapshot_name_finish(bufferlist::const_iterator *it, + std::string *name); +int get_snapshot_name(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, std::string *name); /// NOTE: remove after Luminous is retired -void snapshot_timestamp_list_start(librados::ObjectReadOperation *op, - const std::vector &ids); -int snapshot_timestamp_list_finish(bufferlist::const_iterator *it, - const std::vector &ids, - std::vector *timestamps); -int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid, - const std::vector &ids, - std::vector *timestamps); +void get_snapshot_timestamp_start(librados::ObjectReadOperation *op, + snapid_t snap_id); +int get_snapshot_timestamp_finish(bufferlist::const_iterator *it, + utime_t *timestamp); +int get_snapshot_timestamp(librados::IoCtx *ioctx, const std::string &oid, + snapid_t snap_id, utime_t *timestamp); void get_all_features_start(librados::ObjectReadOperation *op); int get_all_features_finish(bufferlist::const_iterator *it, @@ -202,6 +166,7 @@ int set_protection_status(librados::IoCtx *ioctx, const std::string &oid, snapid_t snap_id, uint8_t protection_status); void set_protection_status(librados::ObjectWriteOperation *op, snapid_t snap_id, uint8_t protection_status); + int snapshot_get_limit(librados::IoCtx *ioctx, const std::string &oid, uint64_t *limit); void snapshot_set_limit(librados::ObjectWriteOperation *op, @@ -278,7 +243,6 @@ int children_list_finish(bufferlist::const_iterator *it, int children_list(librados::IoCtx *ioctx, const std::string &oid, snapid_t snap_id, cls::rbd::ChildImageSpecs *child_images); - int migration_set(librados::IoCtx *ioctx, const std::string &oid, const cls::rbd::MigrationSpec &migration_spec); void migration_set(librados::ObjectWriteOperation *op, diff --git a/src/librbd/api/Mirror.cc b/src/librbd/api/Mirror.cc index 3a2dff18cf612..b9eac8313dbf5 100644 --- a/src/librbd/api/Mirror.cc +++ b/src/librbd/api/Mirror.cc @@ -585,9 +585,9 @@ int Mirror::mode_set(librados::IoCtx& io_ctx, for (const auto& img_pair : images) { uint64_t features; - r = cls_client::get_features(&io_ctx, - util::header_name(img_pair.second), - CEPH_NOSNAP, &features); + uint64_t incompatible_features; + r = cls_client::get_features(&io_ctx, util::header_name(img_pair.second), + true, &features, &incompatible_features); if (r < 0) { lderr(cct) << "error getting features for image " << img_pair.first << ": " << cpp_strerror(r) << dendl; diff --git a/src/librbd/image/DetachChildRequest.cc b/src/librbd/image/DetachChildRequest.cc index 43922750f9236..b91cc0d19d04b 100644 --- a/src/librbd/image/DetachChildRequest.cc +++ b/src/librbd/image/DetachChildRequest.cc @@ -103,7 +103,7 @@ void DetachChildRequest::clone_v2_get_snapshot() { ldout(cct, 5) << dendl; librados::ObjectReadOperation op; - cls_client::snapshot_info_get_start(&op, m_parent_spec.snap_id); + cls_client::snapshot_get_start(&op, m_parent_spec.snap_id); m_out_bl.clear(); auto aio_comp = create_rados_callback< @@ -124,7 +124,7 @@ void DetachChildRequest::handle_clone_v2_get_snapshot(int r) { if (r == 0) { cls::rbd::SnapshotInfo snap_info; auto it = m_out_bl.cbegin(); - r = cls_client::snapshot_info_get_finish(&it, &snap_info); + r = cls_client::snapshot_get_finish(&it, &snap_info); if (r == 0) { m_parent_snap_namespace = snap_info.snapshot_namespace; m_parent_snap_name = snap_info.name; diff --git a/src/librbd/image/OpenRequest.cc b/src/librbd/image/OpenRequest.cc index 113e5d622694e..b18b512ad57f9 100644 --- a/src/librbd/image/OpenRequest.cc +++ b/src/librbd/image/OpenRequest.cc @@ -255,7 +255,9 @@ void OpenRequest::send_v2_get_initial_metadata() { m_image_ctx->header_oid = util::header_name(m_image_ctx->id); librados::ObjectReadOperation op; - cls_client::get_initial_metadata_start(&op); + cls_client::get_size_start(&op, CEPH_NOSNAP); + cls_client::get_object_prefix_start(&op); + cls_client::get_features_start(&op, true); using klass = OpenRequest; librados::AioCompletion *comp = create_rados_callback< @@ -271,11 +273,23 @@ Context *OpenRequest::handle_v2_get_initial_metadata(int *result) { CephContext *cct = m_image_ctx->cct; ldout(cct, 10) << __func__ << ": r=" << *result << dendl; - if (*result == 0) { - auto it = m_out_bl.cbegin(); - *result = cls_client::get_initial_metadata_finish( - &it, &m_image_ctx->object_prefix, &m_image_ctx->order, &m_image_ctx->features); + auto it = m_out_bl.cbegin(); + if (*result >= 0) { + uint64_t size; + *result = cls_client::get_size_finish(&it, &size, &m_image_ctx->order); + } + + if (*result >= 0) { + *result = cls_client::get_object_prefix_finish(&it, + &m_image_ctx->object_prefix); } + + if (*result >= 0) { + uint64_t incompatible_features; + *result = cls_client::get_features_finish(&it, &m_image_ctx->features, + &incompatible_features); + } + if (*result < 0) { lderr(cct) << "failed to retrieve initial metadata: " << cpp_strerror(*result) << dendl; diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc index a5289a6dc520a..6c1218b94a924 100644 --- a/src/librbd/image/RefreshRequest.cc +++ b/src/librbd/image/RefreshRequest.cc @@ -287,11 +287,7 @@ Context *RefreshRequest::handle_v1_get_locks(int *result) { ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl; - // If EOPNOTSUPP, treat image as if there are no locks (we can't - // query them). - if (*result == -EOPNOTSUPP) { - *result = 0; - } else if (*result == 0) { + if (*result == 0) { auto it = m_out_bl.cbegin(); ClsLockType lock_type; *result = rados::cls::lock::get_lock_info_finish(&it, &m_lockers, @@ -344,7 +340,11 @@ void RefreshRequest::send_v2_get_mutable_metadata() { bool read_only = m_image_ctx.read_only || snap_id != CEPH_NOSNAP; librados::ObjectReadOperation op; - cls_client::get_mutable_metadata_start(&op, read_only); + cls_client::get_size_start(&op, CEPH_NOSNAP); + cls_client::get_features_start(&op, read_only); + cls_client::get_flags_start(&op, CEPH_NOSNAP); + cls_client::get_snapcontext_start(&op); + rados::cls::lock::get_lock_info_start(&op, RBD_LOCK_NAME); using klass = RefreshRequest; librados::AioCompletion *comp = create_rados_callback< @@ -362,15 +362,34 @@ Context *RefreshRequest::handle_v2_get_mutable_metadata(int *result) { ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl; - if (*result == 0) { - auto it = m_out_bl.cbegin(); - *result = cls_client::get_mutable_metadata_finish(&it, &m_size, &m_features, - &m_incompatible_features, - &m_lockers, - &m_exclusive_locked, - &m_lock_tag, &m_snapc, - &m_parent_md); + auto it = m_out_bl.cbegin(); + if (*result >= 0) { + uint8_t order; + *result = cls_client::get_size_finish(&it, &m_size, &order); + } + + if (*result >= 0) { + *result = cls_client::get_features_finish(&it, &m_features, + &m_incompatible_features); + } + + if (*result >= 0) { + *result = cls_client::get_flags_finish(&it, &m_flags); + } + + if (*result >= 0) { + *result = cls_client::get_snapcontext_finish(&it, &m_snapc); + } + + if (*result >= 0) { + ClsLockType lock_type = LOCK_NONE; + *result = rados::cls::lock::get_lock_info_finish(&it, &m_lockers, + &lock_type, &m_lock_tag); + if (*result == 0) { + m_exclusive_locked = (lock_type == LOCK_EXCLUSIVE); + } } + if (*result < 0) { lderr(cct) << "failed to retrieve mutable metadata: " << cpp_strerror(*result) << dendl; @@ -396,6 +415,45 @@ Context *RefreshRequest::handle_v2_get_mutable_metadata(int *result) { m_incomplete_update = true; } + send_v2_get_parent(); + return nullptr; +} + +template +void RefreshRequest::send_v2_get_parent() { + // NOTE: remove support when Mimic is EOLed + CephContext *cct = m_image_ctx.cct; + ldout(cct, 10) << this << " " << __func__ << dendl; + + librados::ObjectReadOperation op; + cls_client::get_parent_start(&op, CEPH_NOSNAP); + + auto aio_comp = create_rados_callback< + RefreshRequest, &RefreshRequest::handle_v2_get_parent>(this); + m_out_bl.clear(); + m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, aio_comp, &op, + &m_out_bl); + aio_comp->release(); +} + +template +Context *RefreshRequest::handle_v2_get_parent(int *result) { + // NOTE: remove support when Mimic is EOLed + CephContext *cct = m_image_ctx.cct; + ldout(cct, 10) << this << " " << __func__ << ": r=" << *result << dendl; + + if (*result == 0) { + auto it = m_out_bl.cbegin(); + *result = cls_client::get_parent_finish(&it, &m_parent_md.spec, + &m_parent_md.overlap); + } + + if (*result < 0) { + lderr(cct) << "failed to retrieve parent: " << cpp_strerror(*result) + << dendl; + return m_on_finish; + } + if ((m_features & RBD_FEATURE_MIGRATING) != 0) { ldout(cct, 1) << "migrating feature set" << dendl; send_get_migration_header(); @@ -435,9 +493,7 @@ Context *RefreshRequest::handle_v2_get_metadata(int *result) { *result = cls_client::metadata_list_finish(&it, &metadata); } - if (*result == -EOPNOTSUPP || *result == -EIO) { - ldout(cct, 10) << "config metadata not supported by OSD" << dendl; - } else if (*result < 0) { + if (*result < 0) { lderr(cct) << "failed to retrieve metadata: " << cpp_strerror(*result) << dendl; return m_on_finish; @@ -456,61 +512,6 @@ Context *RefreshRequest::handle_v2_get_metadata(int *result) { bool thread_safe = m_image_ctx.image_watcher->is_unregistered(); m_image_ctx.apply_metadata(m_metadata, thread_safe); - send_v2_get_flags(); - return nullptr; -} - -template -void RefreshRequest::send_v2_get_flags() { - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::get_flags_start(&op, m_snapc.snaps); - - using klass = RefreshRequest; - librados::AioCompletion *comp = create_rados_callback< - klass, &klass::handle_v2_get_flags>(this); - m_out_bl.clear(); - int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op, - &m_out_bl); - ceph_assert(r == 0); - comp->release(); -} - -template -Context *RefreshRequest::handle_v2_get_flags(int *result) { - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << ": " - << "r=" << *result << dendl; - - if (*result == 0) { - /// NOTE: remove support for snap paramter after Luminous is retired - auto it = m_out_bl.cbegin(); - cls_client::get_flags_finish(&it, &m_flags, m_snapc.snaps, &m_snap_flags); - } - if (*result == -EOPNOTSUPP) { - // Older OSD doesn't support RBD flags, need to assume the worst - *result = 0; - ldout(cct, 10) << "OSD does not support RBD flags, disabling object map " - << "optimizations" << dendl; - m_flags = RBD_FLAG_OBJECT_MAP_INVALID; - if ((m_features & RBD_FEATURE_FAST_DIFF) != 0) { - m_flags |= RBD_FLAG_FAST_DIFF_INVALID; - } - - std::vector default_flags(m_snapc.snaps.size(), m_flags); - m_snap_flags = std::move(default_flags); - } else if (*result == -ENOENT) { - ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl; - send_v2_get_mutable_metadata(); - return nullptr; - } else if (*result < 0) { - lderr(cct) << "failed to retrieve flags: " << cpp_strerror(*result) - << dendl; - return m_on_finish; - } - send_v2_get_op_features(); return nullptr; } @@ -586,11 +587,7 @@ Context *RefreshRequest::handle_v2_get_group(int *result) { auto it = m_out_bl.cbegin(); cls_client::image_group_get_finish(&it, &m_group_spec); } - if (*result == -EOPNOTSUPP) { - // Older OSD doesn't support RBD groups - *result = 0; - ldout(cct, 10) << "OSD does not support groups" << dendl; - } else if (*result < 0) { + if (*result < 0) { lderr(cct) << "failed to retrieve group: " << cpp_strerror(*result) << dendl; return m_on_finish; @@ -602,10 +599,12 @@ Context *RefreshRequest::handle_v2_get_group(int *result) { template void RefreshRequest::send_v2_get_snapshots() { + m_snap_infos.resize(m_snapc.snaps.size()); + m_snap_flags.resize(m_snapc.snaps.size()); + m_snap_parents.resize(m_snapc.snaps.size()); + m_snap_protection.resize(m_snapc.snaps.size()); + if (m_snapc.snaps.empty()) { - m_snap_infos.clear(); - m_snap_parents.clear(); - m_snap_protection.clear(); send_v2_refresh_parent(); return; } @@ -614,7 +613,19 @@ void RefreshRequest::send_v2_get_snapshots() { ldout(cct, 10) << this << " " << __func__ << dendl; librados::ObjectReadOperation op; - cls_client::snapshot_get_start(&op, m_snapc.snaps); + for (auto snap_id : m_snapc.snaps) { + if (m_legacy_snapshot) { + /// NOTE: remove after Luminous is retired + cls_client::get_snapshot_name_start(&op, snap_id); + cls_client::get_size_start(&op, snap_id); + cls_client::get_snapshot_timestamp_start(&op, snap_id); + } else { + cls_client::snapshot_get_start(&op, snap_id); + } + cls_client::get_flags_start(&op, snap_id); + cls_client::get_parent_start(&op, snap_id); + cls_client::get_protection_status_start(&op, snap_id); + } using klass = RefreshRequest; librados::AioCompletion *comp = create_rados_callback< @@ -629,141 +640,76 @@ void RefreshRequest::send_v2_get_snapshots() { template Context *RefreshRequest::handle_v2_get_snapshots(int *result) { CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << ": " - << "r=" << *result << dendl; + ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl; - if (*result == 0) { - auto it = m_out_bl.cbegin(); - *result = cls_client::snapshot_get_finish(&it, m_snapc.snaps, &m_snap_infos, - &m_snap_parents, - &m_snap_protection); - } - if (*result == -ENOENT) { - ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl; - send_v2_get_mutable_metadata(); - return nullptr; - } else if (*result == -EOPNOTSUPP) { - ldout(cct, 10) << "retrying using legacy snapshot methods" << dendl; - send_v2_get_snapshots_legacy(); - return nullptr; - } else if (*result < 0) { - lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result) - << dendl; - return m_on_finish; - } + auto it = m_out_bl.cbegin(); + for (size_t i = 0; i < m_snapc.snaps.size(); ++i) { + if (m_legacy_snapshot) { + /// NOTE: remove after Luminous is retired + std::string snap_name; + if (*result >= 0) { + *result = cls_client::get_snapshot_name_finish(&it, &snap_name); + } - send_v2_refresh_parent(); - return nullptr; -} + uint64_t snap_size; + if (*result >= 0) { + uint8_t order; + *result = cls_client::get_size_finish(&it, &snap_size, &order); + } -template -void RefreshRequest::send_v2_get_snapshots_legacy() { - /// NOTE: remove after Luminous is retired - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << dendl; + utime_t snap_timestamp; + if (*result >= 0) { + *result = cls_client::get_snapshot_timestamp_finish(&it, + &snap_timestamp); + } - librados::ObjectReadOperation op; - cls_client::snapshot_list_start(&op, m_snapc.snaps); + if (*result >= 0) { + m_snap_infos[i] = {m_snapc.snaps[i], + {cls::rbd::UserSnapshotNamespace{}}, + snap_name, snap_size, snap_timestamp, 0}; + } + } else if (*result >= 0) { + *result = cls_client::snapshot_get_finish(&it, &m_snap_infos[i]); + } - using klass = RefreshRequest; - librados::AioCompletion *comp = create_rados_callback< - klass, &klass::handle_v2_get_snapshots_legacy>(this); - m_out_bl.clear(); - int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op, - &m_out_bl); - ceph_assert(r == 0); - comp->release(); -} + if (*result >= 0) { + *result = cls_client::get_flags_finish(&it, &m_snap_flags[i]); + } -template -Context *RefreshRequest::handle_v2_get_snapshots_legacy(int *result) { - /// NOTE: remove after Luminous is retired - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << ": " - << "r=" << *result << dendl; + if (*result >= 0) { + *result = cls_client::get_parent_finish(&it, &m_snap_parents[i].spec, + &m_snap_parents[i].overlap); + } - std::vector snap_names; - std::vector snap_sizes; - if (*result == 0) { - auto it = m_out_bl.cbegin(); - *result = cls_client::snapshot_list_finish(&it, m_snapc.snaps, - &snap_names, &snap_sizes, - &m_snap_parents, - &m_snap_protection); - } - if (*result == -ENOENT) { - ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl; - send_v2_get_mutable_metadata(); - return nullptr; - } else if (*result < 0) { - lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result) - << dendl; - return m_on_finish; - } + if (*result >= 0) { + *result = cls_client::get_protection_status_finish( + &it, &m_snap_protection[i]); + } - m_snap_infos.clear(); - for (size_t i = 0; i < m_snapc.snaps.size(); ++i) { - m_snap_infos.push_back({m_snapc.snaps[i], - {cls::rbd::UserSnapshotNamespace{}}, - snap_names[i], snap_sizes[i], {}, 0}); + if (*result < 0) { + break; + } } - send_v2_get_snap_timestamps(); - return nullptr; -} - -template -void RefreshRequest::send_v2_get_snap_timestamps() { - /// NOTE: remove after Luminous is retired - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << dendl; - - librados::ObjectReadOperation op; - cls_client::snapshot_timestamp_list_start(&op, m_snapc.snaps); - - using klass = RefreshRequest; - librados::AioCompletion *comp = create_rados_callback< - klass, &klass::handle_v2_get_snap_timestamps>(this); - m_out_bl.clear(); - int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid, comp, &op, - &m_out_bl); - ceph_assert(r == 0); - comp->release(); -} - -template -Context *RefreshRequest::handle_v2_get_snap_timestamps(int *result) { - /// NOTE: remove after Luminous is retired - CephContext *cct = m_image_ctx.cct; - ldout(cct, 10) << this << " " << __func__ << ": " << "r=" << *result << dendl; - - std::vector snap_timestamps; - if (*result == 0) { - auto it = m_out_bl.cbegin(); - *result = cls_client::snapshot_timestamp_list_finish(&it, m_snapc.snaps, - &snap_timestamps); - } if (*result == -ENOENT) { ldout(cct, 10) << "out-of-sync snapshot state detected" << dendl; send_v2_get_mutable_metadata(); return nullptr; - } else if (*result == -EOPNOTSUPP) { - // Ignore it means no snap timestamps are available + } else if (!m_legacy_snapshot && *result == -EOPNOTSUPP) { + ldout(cct, 10) << "retrying using legacy snapshot methods" << dendl; + m_legacy_snapshot = true; + send_v2_get_snapshots(); + return nullptr; } else if (*result < 0) { - lderr(cct) << "failed to retrieve snapshot timestamps: " - << cpp_strerror(*result) << dendl; + lderr(cct) << "failed to retrieve snapshots: " << cpp_strerror(*result) + << dendl; return m_on_finish; - } else { - for (size_t i = 0; i < m_snapc.snaps.size(); ++i) { - m_snap_infos[i].timestamp = snap_timestamps[i]; - } } send_v2_refresh_parent(); return nullptr; } - template void RefreshRequest::send_v2_refresh_parent() { { diff --git a/src/librbd/image/RefreshRequest.h b/src/librbd/image/RefreshRequest.h index 86d7ea61e28ae..1d982425dbab1 100644 --- a/src/librbd/image/RefreshRequest.h +++ b/src/librbd/image/RefreshRequest.h @@ -58,7 +58,7 @@ private: * V2_GET_METADATA * | | * v | - * V2_GET_FLAGS | + * V2_GET_PARENT | * | | * v (skip if not enabled) | * V2_GET_OP_FEATURES | @@ -66,16 +66,13 @@ private: * v | * V2_GET_GROUP | * | | - * v | + * | -EOPNOTSUPP | + * | * * * * | + * | * * | + * v v * | * V2_GET_SNAPSHOTS (skip if no snaps) | - * | . | - * | v (pre-mimic OSD) | - * | V2_GET_SNAPSHOTS_LEGACY | - * | | | - * | v | - * | V2_GET_SNAP_TIMESTAMPS | - * | | | - * v v | + * | | + * v | * V2_REFRESH_PARENT (skip if no parent or | * | refresh not needed) | * v | @@ -132,6 +129,8 @@ private: bufferlist m_out_bl; + bool m_legacy_snapshot = false; + uint8_t m_order = 0; uint64_t m_size = 0; uint64_t m_features = 0; @@ -178,12 +177,12 @@ private: void send_v2_get_mutable_metadata(); Context *handle_v2_get_mutable_metadata(int *result); + void send_v2_get_parent(); + Context *handle_v2_get_parent(int *result); + void send_v2_get_metadata(); Context *handle_v2_get_metadata(int *result); - void send_v2_get_flags(); - Context *handle_v2_get_flags(int *result); - void send_v2_get_op_features(); Context *handle_v2_get_op_features(int *result); @@ -196,9 +195,6 @@ private: void send_v2_get_snapshots_legacy(); Context *handle_v2_get_snapshots_legacy(int *result); - void send_v2_get_snap_timestamps(); - Context *handle_v2_get_snap_timestamps(int *result); - void send_v2_refresh_parent(); Context *handle_v2_refresh_parent(int *result); diff --git a/src/librbd/operation/SnapshotRemoveRequest.cc b/src/librbd/operation/SnapshotRemoveRequest.cc index dcb0661fbd1b2..51bc9ffd00469 100644 --- a/src/librbd/operation/SnapshotRemoveRequest.cc +++ b/src/librbd/operation/SnapshotRemoveRequest.cc @@ -115,7 +115,7 @@ void SnapshotRemoveRequest::get_snap() { ldout(cct, 5) << dendl; librados::ObjectReadOperation op; - cls_client::snapshot_info_get_start(&op, m_snap_id); + cls_client::snapshot_get_start(&op, m_snap_id); auto aio_comp = create_rados_callback< SnapshotRemoveRequest, @@ -136,7 +136,7 @@ void SnapshotRemoveRequest::handle_get_snap(int r) { cls::rbd::SnapshotInfo snap_info; auto it = m_out_bl.cbegin(); - r = cls_client::snapshot_info_get_finish(&it, &snap_info); + r = cls_client::snapshot_get_finish(&it, &snap_info); if (r == 0) { m_child_attached = (snap_info.child_count > 0); } diff --git a/src/test/cls_rbd/CMakeLists.txt b/src/test/cls_rbd/CMakeLists.txt index 0e1175ac3d07b..77596dd690b54 100644 --- a/src/test/cls_rbd/CMakeLists.txt +++ b/src/test/cls_rbd/CMakeLists.txt @@ -3,7 +3,6 @@ add_executable(ceph_test_cls_rbd test_cls_rbd.cc $) target_link_libraries(ceph_test_cls_rbd - librbd cls_rbd_client cls_lock_client librados diff --git a/src/test/cls_rbd/test_cls_rbd.cc b/src/test/cls_rbd/test_cls_rbd.cc index ea55689337fa8..c03c4dfd81446 100644 --- a/src/test/cls_rbd/test_cls_rbd.cc +++ b/src/test/cls_rbd/test_cls_rbd.cc @@ -403,20 +403,14 @@ TEST_F(TestClsRbd, get_features) string oid = get_temp_image_name(); uint64_t features; - ASSERT_EQ(-ENOENT, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + uint64_t incompatible_features; + ASSERT_EQ(-ENOENT, get_features(&ioctx, oid, false, &features, + &incompatible_features)); ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, false, &features, + &incompatible_features)); ASSERT_EQ(0u, features); - - int r = get_features(&ioctx, oid, 1, &features); - if (r == 0) { - ASSERT_EQ(0u, features); - } else { - // deprecated snapshot handling - ASSERT_EQ(-ENOENT, r); - } - ioctx.close(); } @@ -837,48 +831,35 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, 0, oid, -1)); - vector snaps; - vector snap_names; - vector snap_sizes; SnapContext snapc; - vector parents; - vector protection_status; - vector snap_timestamps; + cls::rbd::SnapshotInfo snap; + std::string snap_name; + uint64_t snap_size; + uint8_t snap_order; + ParentInfo parent; + uint8_t protection_status; + utime_t snap_timestamp; ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); ASSERT_EQ(0u, snapc.snaps.size()); ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps, - &parents, &protection_status)); - ASSERT_EQ(0u, snaps.size()); - ASSERT_EQ(0u, parents.size()); - ASSERT_EQ(0u, protection_status.size()); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(0u, snap_names.size()); - ASSERT_EQ(0u, snap_sizes.size()); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(0u, snap_timestamps.size()); ASSERT_EQ(0, snapshot_add(&ioctx, oid, 0, "snap1")); ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(0u, snapc.snaps[0]); ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps, - &parents, &protection_status)); - ASSERT_EQ(1u, snaps.size()); - ASSERT_EQ(1u, parents.size()); - ASSERT_EQ(1u, protection_status.size()); - ASSERT_EQ("snap1", snaps[0].name); - ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(1u, snap_names.size()); - ASSERT_EQ("snap1", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); + + ASSERT_EQ(0, snapshot_get(&ioctx, oid, 0, &snap)); + ASSERT_EQ("snap1", snap.name); + ASSERT_EQ(userSnapNamespace, snap.snapshot_namespace); + ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 0, &snap_name)); + ASSERT_EQ("snap1", snap_name); + ASSERT_EQ(0, get_size(&ioctx, oid, 0, &snap_size, &snap_order)); + ASSERT_EQ(10U, snap_size); + ASSERT_EQ(0, get_parent(&ioctx, oid, 0, &parent.spec, &parent.overlap)); + ASSERT_EQ(0, get_protection_status(&ioctx, oid, 0, &protection_status)); + ASSERT_EQ(0, get_snapshot_timestamp(&ioctx, oid, 0, &snap_timestamp)); // snap with same id and name ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 0, "snap1")); @@ -886,14 +867,6 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(0u, snapc.snaps[0]); ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(1u, snap_names.size()); - ASSERT_EQ("snap1", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); - // snap with same id, different name ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 0, "snap2")); @@ -901,13 +874,6 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(0u, snapc.snaps[0]); ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(1u, snap_names.size()); - ASSERT_EQ("snap1", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); // snap with different id, same name ASSERT_EQ(-EEXIST, snapshot_add(&ioctx, oid, 1, "snap1")); @@ -915,13 +881,6 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(0u, snapc.snaps[0]); ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(snap_names.size(), 1u); - ASSERT_EQ(snap_names[0], "snap1"); - ASSERT_EQ(snap_sizes[0], 10u); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); // snap with different id, different name ASSERT_EQ(0, snapshot_add(&ioctx, oid, 1, "snap2")); @@ -930,55 +889,29 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(1u, snapc.snaps[0]); ASSERT_EQ(0u, snapc.snaps[1]); ASSERT_EQ(1u, snapc.seq); - ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps, - &parents, &protection_status)); - ASSERT_EQ(2u, snaps.size()); - ASSERT_EQ(2u, parents.size()); - ASSERT_EQ(2u, protection_status.size()); - ASSERT_EQ("snap2", snaps[0].name); - ASSERT_EQ("snap1", snaps[1].name); - ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace); - ASSERT_EQ(userSnapNamespace, snaps[1].snapshot_namespace); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(2u, snap_names.size()); - ASSERT_EQ("snap2", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ("snap1", snap_names[1]); - ASSERT_EQ(10u, snap_sizes[1]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(2u, snap_timestamps.size()); + + ASSERT_EQ(0, snapshot_get(&ioctx, oid, 1, &snap)); + ASSERT_EQ("snap2", snap.name); + ASSERT_EQ(userSnapNamespace, snap.snapshot_namespace); + ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 1, &snap_name)); + ASSERT_EQ("snap2", snap_name); + ASSERT_EQ(0, get_size(&ioctx, oid, 1, &snap_size, &snap_order)); + ASSERT_EQ(10U, snap_size); + ASSERT_EQ(0, get_parent(&ioctx, oid, 1, &parent.spec, &parent.overlap)); + ASSERT_EQ(0, get_protection_status(&ioctx, oid, 1, &protection_status)); + ASSERT_EQ(0, get_snapshot_timestamp(&ioctx, oid, 1, &snap_timestamp)); ASSERT_EQ(0, snapshot_rename(&ioctx, oid, 0, "snap1-rename")); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(2u, snap_names.size()); - ASSERT_EQ("snap2", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ("snap1-rename", snap_names[1]); - ASSERT_EQ(10u, snap_sizes[1]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(2u, snap_timestamps.size()); + ASSERT_EQ(0, snapshot_get(&ioctx, oid, 0, &snap)); + ASSERT_EQ("snap1-rename", snap.name); + ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, 0, &snap_name)); + ASSERT_EQ("snap1-rename", snap_name); ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 0)); ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(1u, snapc.snaps[0]); ASSERT_EQ(1u, snapc.seq); - ASSERT_EQ(0, snapshot_get(&ioctx, oid, snapc.snaps, &snaps, - &parents, &protection_status)); - ASSERT_EQ(1u, snaps.size()); - ASSERT_EQ(1u, parents.size()); - ASSERT_EQ(1u, protection_status.size()); - ASSERT_EQ("snap2", snaps[0].name); - ASSERT_EQ(userSnapNamespace, snaps[0].snapshot_namespace); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(1u, snap_names.size()); - ASSERT_EQ("snap2", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); uint64_t size; uint8_t order; @@ -994,76 +927,30 @@ TEST_F(TestClsRbd, snapshots) ASSERT_EQ(large_snap_id, snapc.snaps[0]); ASSERT_EQ(1u, snapc.snaps[1]); ASSERT_EQ(large_snap_id, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(2u, snap_names.size()); - ASSERT_EQ("snap3", snap_names[0]); - ASSERT_EQ(0u, snap_sizes[0]); - ASSERT_EQ("snap2", snap_names[1]); - ASSERT_EQ(10u, snap_sizes[1]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(2u, snap_timestamps.size()); - - ASSERT_EQ(0, get_size(&ioctx, oid, large_snap_id, &size, &order)); - ASSERT_EQ(0u, size); - ASSERT_EQ(22u, order); - ASSERT_EQ(0, get_size(&ioctx, oid, 1, &size, &order)); - ASSERT_EQ(10u, size); - ASSERT_EQ(22u, order); + ASSERT_EQ(0, snapshot_get(&ioctx, oid, large_snap_id, &snap)); + ASSERT_EQ("snap3", snap.name); + ASSERT_EQ(0, get_snapshot_name(&ioctx, oid, large_snap_id, &snap_name)); + ASSERT_EQ("snap3", snap_name); + ASSERT_EQ(0, get_size(&ioctx, oid, large_snap_id, &snap_size, &snap_order)); + ASSERT_EQ(0U, snap_size); + ASSERT_EQ(22u, snap_order); + + ASSERT_EQ(0, get_size(&ioctx, oid, 1, &snap_size, &snap_order)); + ASSERT_EQ(10u, snap_size); + ASSERT_EQ(22u, snap_order); ASSERT_EQ(0, snapshot_remove(&ioctx, oid, large_snap_id)); ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); ASSERT_EQ(1u, snapc.snaps.size()); ASSERT_EQ(1u, snapc.snaps[0]); ASSERT_EQ(large_snap_id, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(1u, snap_names.size()); - ASSERT_EQ("snap2", snap_names[0]); - ASSERT_EQ(10u, snap_sizes[0]); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(1u, snap_timestamps.size()); ASSERT_EQ(-ENOENT, snapshot_remove(&ioctx, oid, large_snap_id)); ASSERT_EQ(0, snapshot_remove(&ioctx, oid, 1)); ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); ASSERT_EQ(0u, snapc.snaps.size()); ASSERT_EQ(large_snap_id, snapc.seq); - ASSERT_EQ(0, snapshot_list(&ioctx, oid, snapc.snaps, &snap_names, - &snap_sizes, &parents, &protection_status)); - ASSERT_EQ(0u, snap_names.size()); - ASSERT_EQ(0u, snap_sizes.size()); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(0u, snap_timestamps.size()); - - ioctx.close(); -} - -TEST_F(TestClsRbd, snapshots_timestamps) -{ - librados::IoCtx ioctx; - ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx)); - - string oid = get_temp_image_name(); - - ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, 0, oid, -1)); - - vector snap_timestamps; - SnapContext snapc; - - ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); - ASSERT_EQ(0u, snapc.snaps.size()); - ASSERT_EQ(0u, snapc.seq); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_EQ(0u, snap_timestamps.size()); - - ASSERT_EQ(0, snapshot_add(&ioctx, oid, 0, "snap1")); - - ASSERT_EQ(0, get_snapcontext(&ioctx, oid, &snapc)); - ASSERT_EQ(1u, snapc.snaps.size()); - ASSERT_EQ(0, snapshot_timestamp_list(&ioctx, oid, snapc.snaps, &snap_timestamps)); - ASSERT_LT(0U, snap_timestamps[0].tv.tv_sec); ioctx.close(); } @@ -1124,41 +1011,6 @@ TEST_F(TestClsRbd, stripingv2) ioctx.close(); } -TEST_F(TestClsRbd, get_mutable_metadata_features) -{ - librados::IoCtx ioctx; - ASSERT_EQ(0, _rados.ioctx_create(_pool_name.c_str(), ioctx)); - - string oid = get_temp_image_name(); - ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, RBD_FEATURE_EXCLUSIVE_LOCK, - oid, -1)); - - uint64_t size, features, incompatible_features; - std::map lockers; - bool exclusive_lock; - std::string lock_tag; - ::SnapContext snapc; - ParentInfo parent; - - ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, true, &size, &features, - &incompatible_features, &lockers, - &exclusive_lock, &lock_tag, &snapc, - &parent)); - ASSERT_EQ(static_cast(RBD_FEATURE_EXCLUSIVE_LOCK), features); - ASSERT_EQ(0U, incompatible_features); - - ASSERT_EQ(0, get_mutable_metadata(&ioctx, oid, false, &size, &features, - &incompatible_features, &lockers, - &exclusive_lock, &lock_tag, &snapc, - &parent)); - ASSERT_EQ(static_cast(RBD_FEATURE_EXCLUSIVE_LOCK), features); - ASSERT_EQ(static_cast(RBD_FEATURE_EXCLUSIVE_LOCK), - incompatible_features); - - ioctx.close(); -} - TEST_F(TestClsRbd, object_map_save) { librados::IoCtx ioctx; @@ -1381,29 +1233,24 @@ TEST_F(TestClsRbd, flags) ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1)); uint64_t flags; - std::vector snap_ids; - std::vector snap_flags; - ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags)); + ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags)); ASSERT_EQ(0U, flags); librados::ObjectWriteOperation op1; set_flags(&op1, CEPH_NOSNAP, 3, 2); ASSERT_EQ(0, ioctx.operate(oid, &op1)); - ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags)); + ASSERT_EQ(0, get_flags(&ioctx, oid, CEPH_NOSNAP, &flags)); ASSERT_EQ(2U, flags); uint64_t snap_id = 10; - snap_ids.push_back(snap_id); - ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags)); + ASSERT_EQ(-ENOENT, get_flags(&ioctx, oid, snap_id, &flags)); ASSERT_EQ(0, snapshot_add(&ioctx, oid, snap_id, "snap")); librados::ObjectWriteOperation op2; set_flags(&op2, snap_id, 31, 4); ASSERT_EQ(0, ioctx.operate(oid, &op2)); - ASSERT_EQ(0, get_flags(&ioctx, oid, &flags, snap_ids, &snap_flags)); - ASSERT_EQ(2U, flags); - ASSERT_EQ(snap_ids.size(), snap_flags.size()); - ASSERT_EQ(6U, snap_flags[0]); + ASSERT_EQ(0, get_flags(&ioctx, oid, snap_id, &flags)); + ASSERT_EQ(6U, flags); ioctx.close(); } @@ -1486,7 +1333,9 @@ TEST_F(TestClsRbd, set_features) ASSERT_EQ(0, set_features(&ioctx, oid, features, mask)); uint64_t actual_features; - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features)); + uint64_t incompatible_features; + ASSERT_EQ(0, get_features(&ioctx, oid, true, &actual_features, + &incompatible_features)); uint64_t expected_features = RBD_FEATURES_MUTABLE | base_features; ASSERT_EQ(expected_features, actual_features); @@ -1495,7 +1344,8 @@ TEST_F(TestClsRbd, set_features) mask = RBD_FEATURE_OBJECT_MAP; ASSERT_EQ(0, set_features(&ioctx, oid, features, mask)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &actual_features)); + ASSERT_EQ(0, get_features(&ioctx, oid, true, &actual_features, + &incompatible_features)); expected_features = (RBD_FEATURES_MUTABLE | base_features) & ~RBD_FEATURE_OBJECT_MAP; @@ -2606,7 +2456,9 @@ TEST_F(TestClsRbd, op_features) ASSERT_EQ(0u, actual_op_features); uint64_t features; - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + uint64_t incompatible_features; + ASSERT_EQ(0, get_features(&ioctx, oid, true, &features, + &incompatible_features)); ASSERT_EQ(0u, features); op_features = RBD_OPERATION_FEATURES_ALL; @@ -2615,7 +2467,8 @@ TEST_F(TestClsRbd, op_features) ASSERT_EQ(0, op_features_get(&ioctx, oid, &actual_op_features)); ASSERT_EQ(mask, actual_op_features); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, true, &features, + &incompatible_features)); ASSERT_EQ(RBD_FEATURE_OPERATIONS, features); op_features = 0; @@ -2629,7 +2482,8 @@ TEST_F(TestClsRbd, op_features) mask = RBD_OPERATION_FEATURES_ALL; ASSERT_EQ(0, op_features_set(&ioctx, oid, op_features, mask)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, true, &features, + &incompatible_features)); ASSERT_EQ(0u, features); } @@ -2651,13 +2505,9 @@ TEST_F(TestClsRbd, clone_parent) ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "image2"})); ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {2, "image2"})); - std::vector snaps; - std::vector parents; - std::vector protection_status; - ASSERT_EQ(0, snapshot_get(&ioctx, oid, {123}, &snaps, - &parents, &protection_status)); - ASSERT_EQ(1U, snaps.size()); - ASSERT_EQ(3U, snaps[0].child_count); + cls::rbd::SnapshotInfo snap; + ASSERT_EQ(0, snapshot_get(&ioctx, oid, 123, &snap)); + ASSERT_EQ(3U, snap.child_count); // op feature should have been enabled uint64_t op_features; @@ -2687,11 +2537,9 @@ TEST_F(TestClsRbd, clone_parent) librados::ObjectWriteOperation op3; ::librbd::cls_client::snapshot_trash_add(&op3, 123); ASSERT_EQ(0, ioctx.operate(oid, &op3)); - ASSERT_EQ(0, snapshot_get(&ioctx, oid, {123}, &snaps, - &parents, &protection_status)); - ASSERT_EQ(1U, snaps.size()); + ASSERT_EQ(0, snapshot_get(&ioctx, oid, 123, &snap)); ASSERT_EQ(cls::rbd::SNAPSHOT_NAMESPACE_TYPE_TRASH, - cls::rbd::get_snap_namespace_type(snaps[0].snapshot_namespace)); + cls::rbd::get_snap_namespace_type(snap.snapshot_namespace)); expected_op_features |= RBD_OPERATION_FEATURE_SNAP_TRASH; ASSERT_EQ(0, op_features_get(&ioctx, oid, &op_features)); @@ -2810,14 +2658,17 @@ TEST_F(TestClsRbd, migration) ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec)); uint64_t features; - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + uint64_t incompatible_features; + ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features, + &incompatible_features)); ASSERT_EQ(0U, features); ASSERT_EQ(0, migration_set(&ioctx, oid, migration_spec)); ASSERT_EQ(0, migration_get(&ioctx, oid, &read_migration_spec)); ASSERT_EQ(migration_spec, read_migration_spec); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features, + &incompatible_features)); ASSERT_EQ(RBD_FEATURE_MIGRATING, features); ASSERT_EQ(-EEXIST, migration_set(&ioctx, oid, migration_spec)); @@ -2831,7 +2682,8 @@ TEST_F(TestClsRbd, migration) ASSERT_EQ(0, migration_remove(&ioctx, oid)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features, + &incompatible_features)); ASSERT_EQ(0U, features); ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec)); @@ -2842,13 +2694,15 @@ TEST_F(TestClsRbd, migration) ASSERT_EQ(0, migration_set(&ioctx, oid, migration_spec)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features, + &incompatible_features)); ASSERT_EQ(RBD_FEATURE_MIGRATING, features); ASSERT_EQ(0, migration_remove(&ioctx, oid)); ASSERT_EQ(-EINVAL, migration_get(&ioctx, oid, &read_migration_spec)); - ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features)); + ASSERT_EQ(0, get_features(&ioctx, oid, CEPH_NOSNAP, &features, + &incompatible_features)); ASSERT_EQ(0U, features); ioctx.close(); diff --git a/src/test/librbd/image/test_mock_RefreshRequest.cc b/src/test/librbd/image/test_mock_RefreshRequest.cc index 51340526558ab..d3dcf5e0e5cf8 100644 --- a/src/test/librbd/image/test_mock_RefreshRequest.cc +++ b/src/test/librbd/image/test_mock_RefreshRequest.cc @@ -202,14 +202,15 @@ public: encode(incompatible, *out_bl); return 0; }))); + expect_get_flags(mock_image_ctx, 0); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapcontext"), _, _, _)) .WillOnce(DoDefault()); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), - exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _)) + exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _)) .WillOnce(DoDefault()); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), - exec(mock_image_ctx.header_oid, _, StrEq("lock"), StrEq("get_info"), _, _, _)) + exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _)) .WillOnce(DoDefault()); } } @@ -276,6 +277,7 @@ public: expect.WillOnce(Return(r)); } else { expect.WillOnce(DoDefault()); + expect_get_flags(mock_image_ctx, 0); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _)) .WillOnce(DoDefault()); @@ -295,6 +297,10 @@ public: EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_size"), _, _, _)) .WillOnce(DoDefault()); + EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), + exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_snapshot_timestamp"), _, _, _)) + .WillOnce(DoDefault()); + expect_get_flags(mock_image_ctx, 0); EXPECT_CALL(get_mock_io_ctx(mock_image_ctx.md_ctx), exec(mock_image_ctx.header_oid, _, StrEq("rbd"), StrEq("get_parent"), _, _, _)) .WillOnce(DoDefault()); @@ -304,16 +310,6 @@ public: } } - void expect_snap_timestamp_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_timestamp"), _, _, _)); - if (r < 0) { - expect.WillOnce(Return(r)); - } else { - expect.WillOnce(DoDefault()); - } - } - void expect_apply_metadata(MockRefreshImageCtx &mock_image_ctx, int r) { EXPECT_CALL(mock_image_ctx, apply_metadata(_, false)) @@ -513,7 +509,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessV2) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) { @@ -544,8 +539,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessSnapshotV2) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_get_snapshots(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -578,12 +571,9 @@ TEST_F(TestMockImageRefreshRequest, SuccessLegacySnapshotV2) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_get_snapshots(mock_image_ctx, -EOPNOTSUPP); expect_get_snapshots_legacy(mock_image_ctx, 0); - expect_snap_timestamp_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); @@ -617,8 +607,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessSetSnapshotV2) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_get_snapshots(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -671,7 +659,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessChild) { expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(*mock_refresh_parent_request, true); @@ -724,7 +711,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessChildDontOpenParent) { expect_get_mutable_metadata(mock_image_ctx, ictx2->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_op_features(mock_image_ctx, RBD_OPERATION_FEATURE_CLONE_CHILD, 0); expect_get_group(mock_image_ctx, 0); if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) { @@ -756,7 +742,6 @@ TEST_F(TestMockImageRefreshRequest, SuccessOpFeatures) { expect_get_mutable_metadata(mock_image_ctx, mock_image_ctx.features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_op_features(mock_image_ctx, 4096, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -826,7 +811,6 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_shut_down_exclusive_lock(mock_image_ctx, *mock_exclusive_lock, 0); @@ -881,7 +865,6 @@ TEST_F(TestMockImageRefreshRequest, DisableExclusiveLockWhileAcquiringLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -926,7 +909,6 @@ TEST_F(TestMockImageRefreshRequest, JournalDisabledByPolicy) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -976,7 +958,6 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithExclusiveLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -1025,7 +1006,6 @@ TEST_F(TestMockImageRefreshRequest, EnableJournalWithoutExclusiveLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_set_require_lock(mock_image_ctx, librbd::io::DIRECTION_BOTH, true); @@ -1072,7 +1052,6 @@ TEST_F(TestMockImageRefreshRequest, DisableJournal) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_block_writes(mock_image_ctx, 0); @@ -1119,7 +1098,6 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithExclusiveLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_open_object_map(mock_image_ctx, &mock_object_map, 0); @@ -1159,7 +1137,6 @@ TEST_F(TestMockImageRefreshRequest, EnableObjectMapWithoutExclusiveLock) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); @@ -1210,7 +1187,6 @@ TEST_F(TestMockImageRefreshRequest, DisableObjectMap) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_close_object_map(mock_image_ctx, *mock_object_map, 0); @@ -1252,7 +1228,6 @@ TEST_F(TestMockImageRefreshRequest, OpenObjectMapError) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, 0); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); expect_open_object_map(mock_image_ctx, mock_object_map, -EFBIG); @@ -1281,7 +1256,6 @@ TEST_F(TestMockImageRefreshRequest, ApplyMetadataError) { expect_get_mutable_metadata(mock_image_ctx, ictx->features, 0); expect_get_metadata(mock_image_ctx, 0); expect_apply_metadata(mock_image_ctx, -EINVAL); - expect_get_flags(mock_image_ctx, 0); expect_get_group(mock_image_ctx, 0); expect_refresh_parent_is_required(mock_refresh_parent_request, false); if (ictx->test_features(RBD_FEATURE_EXCLUSIVE_LOCK)) { -- 2.39.5