]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
cls_lock: check expired lock before unlock
authorNitzanMordhai <nmordech@redhat.com>
Mon, 4 Apr 2022 10:10:27 +0000 (10:10 +0000)
committerNitzanMordhai <nmordech@redhat.com>
Wed, 13 Apr 2022 04:20:23 +0000 (04:20 +0000)
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 <nmordec@redhat.com>
src/test/cls_lock/test_cls_lock.cc

index bf09ec592cff0f85520dc7f74156fd35b9532f04..862720826c42abf87728ff342f48bcb293f72b98 100644 (file)
@@ -63,6 +63,23 @@ void lock_info(IoCtx *ioctx, string& oid, string& name, map<locker_id_t, locker_
   lock_info(ioctx, oid, name, lockers, NULL, NULL);
 }
 
+bool lock_expired(IoCtx *ioctx, string& oid, string& name)
+{
+  ClsLockType lock_type = ClsLockType::NONE;
+  string tag;
+  map<locker_id_t, locker_info_t> lockers;
+  if (0 == get_lock_info(ioctx, oid, name, &lockers, &lock_type, &tag))
+    return false;
+  utime_t now = ceph_clock_now();
+  map<locker_id_t, locker_info_t>::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));