Skip to content

Commit de24a1a

Browse files
swamirishijojochuang
authored andcommitted
HDDS-13978. OMLockDetails should not be used as the object returns a ThreadLocal Object (#9346)
(cherry picked from commit c8bcf7f)
1 parent 163ddfa commit de24a1a

File tree

4 files changed

+52
-5
lines changed

4 files changed

+52
-5
lines changed

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/MultiSnapshotLocks.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ public synchronized OMLockDetails acquireLock(Collection<UUID> ids) throws OMExc
6161
lock.acquireReadLocks(resource, keys);
6262
if (omLockDetails.isLockAcquired()) {
6363
objectLocks.addAll(keys);
64+
this.lockDetails = OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED;
65+
} else {
66+
this.lockDetails = OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
6467
}
65-
this.lockDetails = omLockDetails;
6668
return omLockDetails;
6769
}
6870

@@ -72,6 +74,8 @@ public synchronized void releaseLock() {
7274
} else {
7375
lockDetails = lock.releaseReadLocks(resource, this.objectLocks);
7476
}
77+
this.lockDetails = lockDetails.isLockAcquired() ? OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED :
78+
OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
7579
this.objectLocks.clear();
7680
}
7781

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/SnapshotCache.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_NOT_FOUND;
2121
import static org.apache.hadoop.ozone.om.lock.FlatResource.SNAPSHOT_DB_LOCK;
22+
import static org.apache.hadoop.ozone.om.lock.OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED;
23+
import static org.apache.hadoop.ozone.om.lock.OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
2224
import static org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer.COLUMN_FAMILIES_TO_TRACK_IN_DAG;
2325

2426
import com.google.common.annotations.VisibleForTesting;
@@ -302,13 +304,20 @@ public UncheckedAutoCloseableSupplier<OMLockDetails> lock(UUID snapshotId) {
302304
() -> cleanup(snapshotId));
303305
}
304306

307+
private OMLockDetails getEmptyOmLockDetails(OMLockDetails lockDetails) {
308+
return lockDetails.isLockAcquired() ? EMPTY_DETAILS_LOCK_ACQUIRED : EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
309+
}
310+
305311
private UncheckedAutoCloseableSupplier<OMLockDetails> lock(Supplier<OMLockDetails> lockFunction,
306312
Supplier<OMLockDetails> unlockFunction, Supplier<Void> cleanupFunction) {
307-
AtomicReference<OMLockDetails> lockDetails = new AtomicReference<>(lockFunction.get());
313+
Supplier<OMLockDetails> emptyLockFunction = () -> getEmptyOmLockDetails(lockFunction.get());
314+
Supplier<OMLockDetails> emptyUnlockFunction = () -> getEmptyOmLockDetails(unlockFunction.get());
315+
316+
AtomicReference<OMLockDetails> lockDetails = new AtomicReference<>(emptyLockFunction.get());
308317
if (lockDetails.get().isLockAcquired()) {
309318
cleanupFunction.get();
310319
if (!dbMap.isEmpty()) {
311-
lockDetails.set(unlockFunction.get());
320+
lockDetails.set(emptyUnlockFunction.get());
312321
}
313322
}
314323

@@ -318,7 +327,7 @@ private UncheckedAutoCloseableSupplier<OMLockDetails> lock(Supplier<OMLockDetail
318327
public void close() {
319328
lockDetails.updateAndGet((prevLock) -> {
320329
if (prevLock != null && prevLock.isLockAcquired()) {
321-
return unlockFunction.get();
330+
return emptyUnlockFunction.get();
322331
}
323332
return prevLock;
324333
});

hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestMultiSnapshotLocks.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package org.apache.hadoop.ozone.om.snapshot;
1919

20+
import static org.apache.hadoop.ozone.om.lock.FlatResource.SNAPSHOT_GC_LOCK;
2021
import static org.junit.jupiter.api.Assertions.assertEquals;
2122
import static org.junit.jupiter.api.Assertions.assertFalse;
2223
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -31,9 +32,11 @@
3132
import static org.mockito.Mockito.when;
3233

3334
import java.util.Arrays;
35+
import java.util.Collection;
3436
import java.util.Collections;
3537
import java.util.List;
3638
import java.util.UUID;
39+
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
3740
import org.apache.hadoop.ozone.om.exceptions.OMException;
3841
import org.apache.hadoop.ozone.om.lock.IOzoneManagerLock;
3942
import org.apache.hadoop.ozone.om.lock.OMLockDetails;
@@ -66,6 +69,21 @@ void setUp() {
6669
multiSnapshotLocks = new MultiSnapshotLocks(mockLock, mockResource, true);
6770
}
6871

72+
@Test
73+
public void testMultiSnapshotLocksWithMultipleResourceLocksMultipleTimes() throws OMException {
74+
OzoneManagerLock omLock = new OzoneManagerLock(new OzoneConfiguration());
75+
MultiSnapshotLocks multiSnapshotLocks1 = new MultiSnapshotLocks(omLock, SNAPSHOT_GC_LOCK, true);
76+
MultiSnapshotLocks multiSnapshotLocks2 = new MultiSnapshotLocks(omLock, SNAPSHOT_GC_LOCK, true);
77+
Collection<UUID> uuid1 = Collections.singleton(UUID.randomUUID());
78+
Collection<UUID> uuid2 = Collections.singleton(UUID.randomUUID());
79+
for (int i = 0; i < 10; i++) {
80+
assertTrue(multiSnapshotLocks1.acquireLock(uuid1).isLockAcquired());
81+
assertTrue(multiSnapshotLocks2.acquireLock(uuid2).isLockAcquired());
82+
multiSnapshotLocks1.releaseLock();
83+
multiSnapshotLocks2.releaseLock();
84+
}
85+
}
86+
6987
@Test
7088
void testAcquireLockSuccess() throws Exception {
7189
List<UUID> objects = Arrays.asList(obj1, obj2);
@@ -107,7 +125,8 @@ void testReleaseLock() throws Exception {
107125
when(mockLock.acquireWriteLocks(eq(mockResource), anyCollection())).thenReturn(mockLockDetails);
108126
multiSnapshotLocks.acquireLock(objects);
109127
assertFalse(multiSnapshotLocks.getObjectLocks().isEmpty());
110-
128+
when(mockLockDetails.isLockAcquired()).thenReturn(false);
129+
when(mockLock.releaseWriteLocks(eq(mockResource), anyCollection())).thenReturn(mockLockDetails);
111130
// Now release locks
112131
multiSnapshotLocks.releaseLock();
113132

hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestSnapshotCache.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
package org.apache.hadoop.ozone.om.snapshot;
1919

2020
import static org.apache.hadoop.ozone.om.lock.FlatResource.SNAPSHOT_DB_LOCK;
21+
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.LeveledResource.VOLUME_LOCK;
2122
import static org.junit.jupiter.api.Assertions.assertEquals;
2223
import static org.junit.jupiter.api.Assertions.assertFalse;
2324
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
2425
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2526
import static org.junit.jupiter.api.Assertions.assertNotNull;
2627
import static org.junit.jupiter.api.Assertions.assertThrows;
28+
import static org.junit.jupiter.api.Assertions.assertTrue;
2729
import static org.junit.jupiter.api.Assertions.fail;
2830
import static org.mockito.ArgumentMatchers.any;
2931
import static org.mockito.ArgumentMatchers.eq;
@@ -43,6 +45,7 @@
4345
import java.util.concurrent.Semaphore;
4446
import java.util.concurrent.TimeoutException;
4547
import java.util.concurrent.atomic.AtomicBoolean;
48+
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
4649
import org.apache.hadoop.hdds.utils.db.Table;
4750
import org.apache.hadoop.ozone.om.OMMetadataManager;
4851
import org.apache.hadoop.ozone.om.OMMetrics;
@@ -51,6 +54,7 @@
5154
import org.apache.hadoop.ozone.om.lock.IOzoneManagerLock;
5255
import org.apache.hadoop.ozone.om.lock.OMLockDetails;
5356
import org.apache.hadoop.ozone.om.lock.OmReadOnlyLock;
57+
import org.apache.hadoop.ozone.om.lock.OzoneManagerLock;
5458
import org.apache.ozone.test.GenericTestUtils;
5559
import org.apache.ratis.util.function.UncheckedAutoCloseableSupplier;
5660
import org.junit.jupiter.api.AfterEach;
@@ -181,6 +185,17 @@ public void testLockHoldsWriteLock(int numberOfLocks) {
181185
verify(lock, times(numberOfLocks)).acquireResourceWriteLock(eq(SNAPSHOT_DB_LOCK));
182186
}
183187

188+
@Test
189+
public void testLockSupplierReturnsLockWithAnotherLockReleased() {
190+
IOzoneManagerLock ozoneManagerLock = new OzoneManagerLock(new OzoneConfiguration());
191+
snapshotCache = new SnapshotCache(cacheLoader, CACHE_SIZE_LIMIT, omMetrics, 50, true, ozoneManagerLock);
192+
try (UncheckedAutoCloseableSupplier<OMLockDetails> lockDetails = snapshotCache.lock()) {
193+
ozoneManagerLock.acquireWriteLock(VOLUME_LOCK, "vol1");
194+
ozoneManagerLock.releaseWriteLock(VOLUME_LOCK, "vol1");
195+
assertTrue(lockDetails.get().isLockAcquired());
196+
}
197+
}
198+
184199
@ParameterizedTest
185200
@ValueSource(ints = {0, 1, 5, 10})
186201
@DisplayName("Tests lock(snapshotId) holds a write lock")

0 commit comments

Comments
 (0)