Skip to content

Commit c8bcf7f

Browse files
authored
HDDS-13978. OMLockDetails should not be used as the object returns a ThreadLocal Object (#9346)
1 parent cc479a8 commit c8bcf7f

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
@@ -67,8 +67,10 @@ public synchronized OMLockDetails acquireLock(Collection<UUID> ids) throws OMExc
6767
lock.acquireReadLocks(resource, keys);
6868
if (omLockDetails.isLockAcquired()) {
6969
objectLocks.addAll(keys);
70+
this.lockDetails = OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED;
71+
} else {
72+
this.lockDetails = OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
7073
}
71-
this.lockDetails = omLockDetails;
7274
return omLockDetails;
7375
}
7476

@@ -78,6 +80,8 @@ public synchronized void releaseLock() {
7880
} else {
7981
lockDetails = lock.releaseReadLocks(resource, this.objectLocks);
8082
}
83+
this.lockDetails = lockDetails.isLockAcquired() ? OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED :
84+
OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
8185
this.objectLocks.clear();
8286
}
8387

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
@@ -18,6 +18,8 @@
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.OMLockDetails.EMPTY_DETAILS_LOCK_ACQUIRED;
22+
import static org.apache.hadoop.ozone.om.lock.OMLockDetails.EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
2123
import static org.apache.ozone.rocksdiff.RocksDBCheckpointDiffer.COLUMN_FAMILIES_TO_TRACK_IN_DAG;
2224

2325
import com.google.common.annotations.VisibleForTesting;
@@ -304,13 +306,20 @@ public UncheckedAutoCloseableSupplier<OMLockDetails> lock(UUID snapshotId) {
304306
() -> cleanup(snapshotId));
305307
}
306308

309+
private OMLockDetails getEmptyOmLockDetails(OMLockDetails lockDetails) {
310+
return lockDetails.isLockAcquired() ? EMPTY_DETAILS_LOCK_ACQUIRED : EMPTY_DETAILS_LOCK_NOT_ACQUIRED;
311+
}
312+
307313
private UncheckedAutoCloseableSupplier<OMLockDetails> lock(Supplier<OMLockDetails> lockFunction,
308314
Supplier<OMLockDetails> unlockFunction, Supplier<Void> cleanupFunction) {
309-
AtomicReference<OMLockDetails> lockDetails = new AtomicReference<>(lockFunction.get());
315+
Supplier<OMLockDetails> emptyLockFunction = () -> getEmptyOmLockDetails(lockFunction.get());
316+
Supplier<OMLockDetails> emptyUnlockFunction = () -> getEmptyOmLockDetails(unlockFunction.get());
317+
318+
AtomicReference<OMLockDetails> lockDetails = new AtomicReference<>(emptyLockFunction.get());
310319
if (lockDetails.get().isLockAcquired()) {
311320
cleanupFunction.get();
312321
if (!dbMap.isEmpty()) {
313-
lockDetails.set(unlockFunction.get());
322+
lockDetails.set(emptyUnlockFunction.get());
314323
}
315324
}
316325

@@ -320,7 +329,7 @@ private UncheckedAutoCloseableSupplier<OMLockDetails> lock(Supplier<OMLockDetail
320329
public void close() {
321330
lockDetails.updateAndGet((prevLock) -> {
322331
if (prevLock != null && prevLock.isLockAcquired()) {
323-
return unlockFunction.get();
332+
return emptyUnlockFunction.get();
324333
}
325334
return prevLock;
326335
});

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;
@@ -189,6 +193,17 @@ public void testLockHoldsWriteLock(int numberOfLocks) {
189193
verify(lock, times(numberOfLocks)).acquireResourceWriteLock(eq(SNAPSHOT_DB_LOCK));
190194
}
191195

196+
@Test
197+
public void testLockSupplierReturnsLockWithAnotherLockReleased() {
198+
IOzoneManagerLock ozoneManagerLock = new OzoneManagerLock(new OzoneConfiguration());
199+
snapshotCache = new SnapshotCache(cacheLoader, CACHE_SIZE_LIMIT, omMetrics, 50, true, ozoneManagerLock);
200+
try (UncheckedAutoCloseableSupplier<OMLockDetails> lockDetails = snapshotCache.lock()) {
201+
ozoneManagerLock.acquireWriteLock(VOLUME_LOCK, "vol1");
202+
ozoneManagerLock.releaseWriteLock(VOLUME_LOCK, "vol1");
203+
assertTrue(lockDetails.get().isLockAcquired());
204+
}
205+
}
206+
192207
@ParameterizedTest
193208
@ValueSource(ints = {0, 1, 5, 10})
194209
@DisplayName("Tests lock(snapshotId) holds a write lock")

0 commit comments

Comments
 (0)