From e11097bc4cf82b997ad1e8e21a8cd9400767f40d Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Thu, 30 Mar 2023 13:58:20 +0200 Subject: [PATCH] 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 --- PendingReleaseNotes | 3 +++ src/librbd/internal.cc | 1 + src/test/librbd/test_librbd.cc | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/PendingReleaseNotes b/PendingReleaseNotes index cfc8c40cac498..0c55a8972310e 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 c9c1167608ca4..3cd699b2c8142 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 c45cf989af808..8c7eb2ba4ca8b 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) { -- 2.39.5