rather rigid and also challenging to disseminate in some environments. The
key can be embedded in the migration spec or just referenced from there while
stored in the MON config-key store.
+* RBD: `Group::list_images` python API will now correctly raise an ObjectNotFound
+ error when invoked on a non-existent group. The C APIs `rbd_group_image_list`,
+ `rbd_snap_list`, `rbd_group_snap_list` and C++ API `group_image_list` will now
+ return ENOENT instead of masking the error and returning 0.
* BlueStore: The experimental PMEM device backend has been removed, together
with the ``pmem`` value of the ``bdev_type`` option and the DML/DSA offload
path. The hardware it targeted, Intel Optane DC persistent memory, was
std::vector<cls::rbd::GroupImageStatus> image_ids;
- group_image_list(group_ioctx, group_name, &image_ids);
+ int r = group_image_list(group_ioctx, group_name, &image_ids);
+ if (r < 0) {
+ return r;
+ }
for (auto image_id : image_ids) {
IoCtx ioctx;
memset(snaps, 0, sizeof(*snaps) * *max_snaps);
int r = librbd::api::Snapshot<>::list(ictx, cpp_snaps);
- if (r == -ENOENT) {
- tracepoint(librbd, snap_list_exit, 0, *max_snaps);
- return 0;
- }
if (r < 0) {
tracepoint(librbd, snap_list_exit, r, *max_snaps);
return r;
int r = librbd::api::Group<>::image_list(group_ioctx, group_name,
&cpp_images);
- if (r == -ENOENT) {
- tracepoint(librbd, group_image_list_exit, 0);
- *image_size = 0;
- return 0;
- }
-
if (r < 0) {
tracepoint(librbd, group_image_list_exit, r);
return r;
int r = librbd::api::Group<>::snap_list(group_ioctx, group_name, true, false,
&cpp_snaps);
- if (r == -ENOENT) {
- *snaps_size = 0;
- tracepoint(librbd, group_snap_list_exit, 0);
- return 0;
- }
-
if (r < 0) {
tracepoint(librbd, group_snap_list_exit, r);
return r;
ASSERT_EQ(1U, num_images);
rbd_group_image_info_t images[1];
+ ASSERT_EQ(-ENOENT, rbd_group_image_list(ioctx, "group_does_not_exist",
+ images,
+ sizeof(rbd_group_image_info_t),
+ &num_images));
ASSERT_EQ(1, rbd_group_image_list(ioctx, group_name, images,
sizeof(rbd_group_image_info_t),
&num_images));
RBD_OPERATION_FEATURE_GROUP);
std::vector<librbd::group_image_info_t> images;
+ ASSERT_EQ(-ENOENT, rbd.group_image_list(ioctx, "group_does_not_exist",
+ &images,
+ sizeof(librbd::group_image_info_t)));
ASSERT_EQ(0, rbd.group_image_list(ioctx, group_name, &images,
sizeof(librbd::group_image_info_t)));
ASSERT_EQ(1U, images.size());
ASSERT_EQ(1U, num_snaps);
rbd_group_snap_info_t snaps[1];
+ ASSERT_EQ(-ENOENT, rbd_group_snap_list(ioctx, "group_does_not_exist", snaps,
+ sizeof(rbd_group_snap_info_t),
+ &num_snaps));
ASSERT_EQ(1, rbd_group_snap_list(ioctx, group_name, snaps,
sizeof(rbd_group_snap_info_t),
&num_snaps));
ASSERT_EQ(0, rbd.group_snap_create(ioctx, group_name, snap_name));
std::vector<librbd::group_snap_info_t> snaps;
+ ASSERT_EQ(-ENOENT, rbd.group_snap_list(ioctx, "group_does_not_exist", &snaps,
+ sizeof(librbd::group_snap_info_t)));
ASSERT_EQ(0, rbd.group_snap_list(ioctx, group_name, &snaps,
sizeof(librbd::group_snap_info_t)));
ASSERT_EQ(1U, snaps.size());
RBD().remove(ioctx, name)
def test_group_image_add(self):
+ assert_raises(ObjectNotFound, self.dne_group.add_image, ioctx, image_name)
self.group.add_image(ioctx, image_name)
- def test_group_image_list_empty(self):
- eq([], list(self.group.list_images()))
-
def test_group_image_list(self):
+ assert_raises(ObjectNotFound, self.dne_group.list_images)
eq([], list(self.group.list_images()))
self.group.add_image(ioctx, image_name)
eq([image_name], [img['name'] for img in self.group.list_images()])
eq([image_name], [img['name'] for img in self.group.list_images()])
def test_group_get_id(self):
+ assert_raises(ObjectNotFound, self.dne_group.id)
id = self.group.id()
assert isinstance(id, str)
assert len(id) > 0
eq(group_name, group['name'])
eq([image_name], [img['name'] for img in self.group.list_images()])
+ assert_raises(ObjectNotFound, self.dne_group.remove_image, ioctx, image_name)
self.group.remove_image(ioctx, image_name)
eq([], list(self.group.list_images()))
with Image(ioctx, image_name) as image:
assert_raises(ObjectNotFound, self.group.get_snap_info, "")
self.group.create_snap(snap_name)
+ assert_raises(ObjectNotFound, self.dne_group.get_snap_info, snap_name)
snap_info_dict = self.group.get_snap_info(snap_name)
image_names = []
assert sorted(snap_info_dict.keys()) == self.gp_snap_keys
global snap_name
assert_raises(ObjectNotFound, self.dne_group.list_snaps)
eq([], list(self.group.list_snaps()))
+ assert_raises(ObjectNotFound, self.dne_group.create_snap, snap_name)
self.group.create_snap(snap_name)
eq([snap_name], [snap['name'] for snap in self.group.list_snaps()])
eq(group_name, info['group_name'])
eq(snap_name, info['group_snap_name'])
+ assert_raises(ObjectNotFound, self.dne_group.remove_snap, snap_name)
self.group.remove_snap(snap_name)
eq([], list(self.group.list_snaps()))
eq([], list(self.group.list_snaps()))
self.group.create_snap(snap_name)
eq([snap_name], [snap['name'] for snap in self.group.list_snaps()])
+ assert_raises(ObjectNotFound, self.dne_group.rename_snap, snap_name, new_snap_name)
self.group.rename_snap(snap_name, new_snap_name)
eq([new_snap_name], [snap['name'] for snap in self.group.list_snaps()])
self.group.remove_snap(new_snap_name)
image_snaps = list(image.list_snaps())
assert [s['namespace'] for s in image_snaps] == [RBD_SNAP_NAMESPACE_TYPE_GROUP]
+ # no group exists
+ assert_raises(ObjectNotFound, self.dne_group.rollback_to_snap, snap_name1)
+
# group = []
assert_raises(InvalidArgument, self.group.rollback_to_snap, snap_name1)
assert_raises(InvalidArgument, self.group.rollback_to_snap, snap_name2)