From: Ilya Dryomov Date: Thu, 30 Mar 2023 11:58:20 +0000 (+0200) Subject: librbd: clear Image::list_watchers() list before populating it X-Git-Tag: v19.0.0~1434^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e11097bc4cf82b997ad1e8e21a8cd9400767f40d;p=ceph.git librbd: clear Image::list_watchers() list before populating it The "append to the passed list" behavior is confusing and not what the corresponding C API (rbd_watchers_list) or other similar C++ APIs (e.g. list_lockers) do. Signed-off-by: Ilya Dryomov --- diff --git a/PendingReleaseNotes b/PendingReleaseNotes index cfc8c40cac4..0c55a897231 100644 --- a/PendingReleaseNotes +++ b/PendingReleaseNotes @@ -117,6 +117,9 @@ registered a RADOS client in the `name` field added to elements of the `active_clients` array. Previously, only the address of a module's RADOS client was shown in the `active_clients` array. +* RBD: list-watchers C++ API (`Image::list_watchers`) now clears the passed + `std::list` before potentially appending to it, aligning with the semantics + of the corresponding C API (`rbd_watchers_list`). >=17.2.1 diff --git a/src/librbd/internal.cc b/src/librbd/internal.cc index c9c1167608c..3cd699b2c81 100644 --- a/src/librbd/internal.cc +++ b/src/librbd/internal.cc @@ -1699,6 +1699,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) { return r; } + watchers.clear(); for (auto i = obj_watchers.begin(); i != obj_watchers.end(); ++i) { librbd::image_watcher_t watcher; watcher.addr = i->addr; diff --git a/src/test/librbd/test_librbd.cc b/src/test/librbd/test_librbd.cc index c45cf989af8..8c7eb2ba4ca 100644 --- a/src/test/librbd/test_librbd.cc +++ b/src/test/librbd/test_librbd.cc @@ -10885,7 +10885,18 @@ TEST_F(TestLibRBD, TestListWatchers) { ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), nullptr)); ASSERT_EQ(0, image.list_watchers(watchers)); ASSERT_EQ(1U, watchers.size()); + auto watcher1 = watchers.front(); ASSERT_EQ(0, image.close()); + + // (Still) one watcher + ASSERT_EQ(0, rbd.open(ioctx, image, name.c_str(), nullptr)); + ASSERT_EQ(0, image.list_watchers(watchers)); + ASSERT_EQ(1U, watchers.size()); + auto watcher2 = watchers.front(); + ASSERT_EQ(0, image.close()); + + EXPECT_EQ(watcher1.addr, watcher2.addr); + EXPECT_EQ(watcher1.id, watcher2.id); } TEST_F(TestLibRBD, TestSetSnapById) {