From cf9054d933f2b3068b6367cb0d4ea8a5a975e3fa Mon Sep 17 00:00:00 2001 From: NitzanMordhai Date: Mon, 4 Apr 2022 10:10:27 +0000 Subject: [PATCH] cls_lock: check expired lock before unlock Check if the lock was expired, if it is, unlock will return -ENOENT and not 0 that will cause the assert to error. Fixes: https://tracker.ceph.com/issues/38357 Signed-off-by: Nitzan Mordechai --- src/test/cls_lock/test_cls_lock.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/test/cls_lock/test_cls_lock.cc b/src/test/cls_lock/test_cls_lock.cc index bf09ec592cf..862720826c4 100644 --- a/src/test/cls_lock/test_cls_lock.cc +++ b/src/test/cls_lock/test_cls_lock.cc @@ -63,6 +63,23 @@ void lock_info(IoCtx *ioctx, string& oid, string& name, map lockers; + if (0 == get_lock_info(ioctx, oid, name, &lockers, &lock_type, &tag)) + return false; + utime_t now = ceph_clock_now(); + map::iterator liter; + for (liter = lockers.begin(); liter != lockers.end(); ++liter) { + if (liter->second.expiration > now) + return false; + } + + return true; +} + TEST(ClsLock, TestMultiLocking) { Rados cluster; std::string pool_name = get_temp_pool_name(); @@ -485,7 +502,9 @@ TEST(ClsLock, TestExclusiveEphemeralBasic) { ASSERT_EQ(0, l1.lock_exclusive_ephemeral(&ioctx, oid1)); ASSERT_EQ(0, ioctx.stat(oid1, &size, &mod_time)); sleep(2); - ASSERT_EQ(0, l1.unlock(&ioctx, oid1)); + int r1 = l1.unlock(&ioctx, oid1); + EXPECT_TRUE(r1 == 0 || ((r1 == -ENOENT) && (lock_expired(&ioctx, oid1, lock_name1)))) + << "unlock should return 0 or -ENOENT return: " << r1; ASSERT_EQ(-ENOENT, ioctx.stat(oid1, &size, &mod_time)); // *********************************************** @@ -497,7 +516,9 @@ TEST(ClsLock, TestExclusiveEphemeralBasic) { ASSERT_EQ(0, l2.lock_exclusive(&ioctx, oid2)); ASSERT_EQ(0, ioctx.stat(oid2, &size, &mod_time)); sleep(2); - ASSERT_EQ(0, l2.unlock(&ioctx, oid2)); + int r2 = l2.unlock(&ioctx, oid2); + EXPECT_TRUE(r2 == 0 || ((r2 == -ENOENT) && (lock_expired(&ioctx, oid2, lock_name2)))) + << "unlock should return 0 or -ENOENT return: " << r2; ASSERT_EQ(0, ioctx.stat(oid2, &size, &mod_time)); ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));