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<rados::cls::lock::locker_id_t,
- rados::cls::lock::locker_info_t> *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<rados::cls::lock::locker_id_t,
- rados::cls::lock::locker_info_t> *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)
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<uint64_t>(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;
}
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)
{
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);
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)
{
op->exec("rbd", "set_parent", in_bl);
}
-void get_flags_start(librados::ObjectReadOperation *op,
- const std::vector<snapid_t> &snap_ids) {
+void get_flags_start(librados::ObjectReadOperation *op, snapid_t snap_id) {
bufferlist in_bl;
- encode(static_cast<snapid_t>(CEPH_NOSNAP), in_bl);
-
+ encode(static_cast<snapid_t>(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<snapid_t> &snap_ids,
- std::vector<uint64_t> *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;
}
}
int get_flags(librados::IoCtx *ioctx, const std::string &oid,
- uint64_t *flags, const std::vector<snapid_t> &snap_ids,
- vector<uint64_t> *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);
}
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,
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);
return 0;
}
-void snapshot_get_start(librados::ObjectReadOperation *op,
- const std::vector<snapid_t> &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<snapid_t> &ids,
- std::vector<cls::rbd::SnapshotInfo>* snaps,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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<snapid_t>& ids,
- std::vector<cls::rbd::SnapshotInfo>* snaps,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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);
}
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,
return get_snapcontext_finish(&bl_it, snapc);
}
-void snapshot_list_start(librados::ObjectReadOperation *op,
- const std::vector<snapid_t> &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<snapid_t> &ids,
- std::vector<string> *names,
- std::vector<uint64_t> *sizes,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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<snapid_t> &ids,
- std::vector<string> *names,
- std::vector<uint64_t> *sizes,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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);
}
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<snapid_t> &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<snapid_t> &ids,
- std::vector<utime_t> *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<snapid_t> &ids,
- std::vector<utime_t> *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);
}
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,
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<rados::cls::lock::locker_id_t,
- rados::cls::lock::locker_info_t> *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<rados::cls::lock::locker_id_t,
- rados::cls::lock::locker_info_t> *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,
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,
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<snapid_t> &snap_ids);
-int get_flags_finish(bufferlist::const_iterator *it, uint64_t *flags,
- const std::vector<snapid_t> &snap_ids,
- std::vector<uint64_t> *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<snapid_t> &snap_ids,
- vector<uint64_t> *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,
int get_children(librados::IoCtx *ioctx, const std::string &oid,
const ParentSpec &pspec, set<string>& 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<snapid_t> &ids);
-int snapshot_get_finish(bufferlist::const_iterator *it,
- const std::vector<snapid_t> &ids,
- std::vector<cls::rbd::SnapshotInfo>* snaps,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *protection_statuses);
-int snapshot_get(librados::IoCtx* ioctx, const std::string& oid,
- const std::vector<snapid_t>& ids,
- std::vector<cls::rbd::SnapshotInfo>* snaps,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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,
::SnapContext *snapc);
/// NOTE: remove after Luminous is retired
-void snapshot_list_start(librados::ObjectReadOperation *op,
- const std::vector<snapid_t> &ids);
-int snapshot_list_finish(bufferlist::const_iterator *it,
- const std::vector<snapid_t> &ids,
- std::vector<string> *names,
- std::vector<uint64_t> *sizes,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *protection_statuses);
-int snapshot_list(librados::IoCtx *ioctx, const std::string &oid,
- const std::vector<snapid_t> &ids,
- std::vector<string> *names,
- std::vector<uint64_t> *sizes,
- std::vector<ParentInfo> *parents,
- std::vector<uint8_t> *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<snapid_t> &ids);
-int snapshot_timestamp_list_finish(bufferlist::const_iterator *it,
- const std::vector<snapid_t> &ids,
- std::vector<utime_t> *timestamps);
-int snapshot_timestamp_list(librados::IoCtx *ioctx, const std::string &oid,
- const std::vector<snapid_t> &ids,
- std::vector<utime_t> *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,
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,
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,
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;
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<
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;
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<I>;
librados::AioCompletion *comp = create_rados_callback<
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;
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,
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<I>;
librados::AioCompletion *comp = create_rados_callback<
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;
m_incomplete_update = true;
}
+ send_v2_get_parent();
+ return nullptr;
+}
+
+template <typename I>
+void RefreshRequest<I>::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<I>, &RefreshRequest<I>::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 <typename I>
+Context *RefreshRequest<I>::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();
*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;
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 <typename I>
-void RefreshRequest<I>::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<I>;
- 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 <typename I>
-Context *RefreshRequest<I>::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<uint64_t> 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;
}
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;
template <typename I>
void RefreshRequest<I>::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;
}
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<I>;
librados::AioCompletion *comp = create_rados_callback<
template <typename I>
Context *RefreshRequest<I>::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 <typename I>
-void RefreshRequest<I>::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<I>;
- 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 <typename I>
-Context *RefreshRequest<I>::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<std::string> snap_names;
- std::vector<uint64_t> 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 <typename I>
-void RefreshRequest<I>::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<I>;
- 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 <typename I>
-Context *RefreshRequest<I>::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<utime_t> 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 <typename I>
void RefreshRequest<I>::send_v2_refresh_parent() {
{
* V2_GET_METADATA <apply>
* | |
* v |
- * V2_GET_FLAGS |
+ * V2_GET_PARENT |
* | |
* v (skip if not enabled) |
* V2_GET_OP_FEATURES |
* 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 |
bufferlist m_out_bl;
+ bool m_legacy_snapshot = false;
+
uint8_t m_order = 0;
uint64_t m_size = 0;
uint64_t m_features = 0;
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);
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);
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<I>,
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);
}
test_cls_rbd.cc
$<TARGET_OBJECTS:common_texttable_obj>)
target_link_libraries(ceph_test_cls_rbd
- librbd
cls_rbd_client
cls_lock_client
librados
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();
}
ASSERT_EQ(0, create_image(&ioctx, oid, 10, 22, 0, oid, -1));
- vector<cls::rbd::SnapshotInfo> snaps;
- vector<string> snap_names;
- vector<uint64_t> snap_sizes;
SnapContext snapc;
- vector<ParentInfo> parents;
- vector<uint8_t> protection_status;
- vector<utime_t> 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"));
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"));
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"));
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"));
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;
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<utime_t> 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();
}
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<rados::cls::lock::locker_id_t,
- rados::cls::lock::locker_info_t> 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<uint64_t>(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<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK), features);
- ASSERT_EQ(static_cast<uint64_t>(RBD_FEATURE_EXCLUSIVE_LOCK),
- incompatible_features);
-
- ioctx.close();
-}
-
TEST_F(TestClsRbd, object_map_save)
{
librados::IoCtx ioctx;
ASSERT_EQ(0, create_image(&ioctx, oid, 0, 22, 0, oid, -1));
uint64_t flags;
- std::vector<snapid_t> snap_ids;
- std::vector<uint64_t> 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();
}
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);
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;
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;
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;
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);
}
ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {1, "image2"}));
ASSERT_EQ(0, child_attach(&ioctx, oid, 123, {2, "image2"}));
- std::vector<cls::rbd::SnapshotInfo> snaps;
- std::vector<ParentInfo> parents;
- std::vector<uint8_t> 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;
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));
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));
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));
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();
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());
}
}
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());
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());
}
}
- 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))
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)) {
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);
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);
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);
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);
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)) {
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);
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);
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_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_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_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);
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);
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);
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_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);
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);
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)) {