From: VinayBhaskar-V Date: Thu, 9 Jul 2026 16:00:26 +0000 (+0530) Subject: pybind/rbd: handle non-existent groups properly in list_snaps() X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=56bcf706cf91f0734899ae9de378c459a9b5af50;p=ceph.git pybind/rbd: handle non-existent groups properly in list_snaps() Calling `list_snaps()` on a non-existent group crashed the entire Python process with a `free(): invalid pointer` error. This happened because an unexpected `-ENOENT` error returned by `rbd_group_snap_list2` and the exception was raised without updating the num_group_snaps to 0 from 10. Later the Cython `__dealloc__` wrapper attempted to free garbage of uninitialized pointer spaces resulting in a crash. Fix this behavior by resetting `self.num_group_snaps` to 0 inside `GroupSnapIterator` before raising exception to prevent memory corruption and accessing uninitialized pointers during cleanup call Now `list_snaps()` consistently raise an `ObjectNotFound` error when invoked on a non-existent group. Also Extended the `TestGroups` test fixture with `self.dne_group` to validate the expected error path for `list_snaps()`. Fixes: https://tracker.ceph.com/issues/78034 Signed-off-by: VinayBhaskar-V --- diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 57a11b7dc0c..703b2f539eb 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -6143,6 +6143,7 @@ cdef class GroupSnapIterator(object): if ret >= 0: break elif ret != -errno.ERANGE: + self.num_group_snaps = 0 raise make_ex(ret, 'error listing snapshots for group %s' % group.name, group_errno_to_exception) def __iter__(self): diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index f1d4f10e391..3bcadcb8481 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -3078,6 +3078,7 @@ class TestGroups(object): create_group() snap_name = get_temp_snap_name() self.group = Group(ioctx, group_name) + self.dne_group = Group(ioctx, "group_does_not_exist") def teardown_method(self, method): remove_group() @@ -3191,6 +3192,7 @@ class TestGroups(object): def test_group_snap(self): global snap_name + assert_raises(ObjectNotFound, self.dne_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()])