Skip to content

Commit b98ac2a

Browse files
committed
HDFS-15076. Fix tests that hold FSDirectory lock, without holding FSNamesystem lock. Contributed by Konstantin V Shvachko.
1 parent 34ff7db commit b98ac2a

3 files changed

Lines changed: 61 additions & 21 deletions

File tree

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestDiskspaceQuotaUpdate.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,16 +380,26 @@ public void testQuotaInitialization() throws Exception {
380380
HashMap<String, Long> dsMap = new HashMap<String, Long>();
381381
scanDirsWithQuota(root, nsMap, dsMap, false);
382382

383-
getFSDirectory().updateCountForQuota(1);
383+
updateCountForQuota(1);
384384
scanDirsWithQuota(root, nsMap, dsMap, true);
385385

386-
getFSDirectory().updateCountForQuota(2);
386+
updateCountForQuota(2);
387387
scanDirsWithQuota(root, nsMap, dsMap, true);
388388

389-
getFSDirectory().updateCountForQuota(4);
389+
updateCountForQuota(4);
390390
scanDirsWithQuota(root, nsMap, dsMap, true);
391391
}
392392

393+
private void updateCountForQuota(int i) {
394+
FSNamesystem fsn = cluster.getNamesystem();
395+
fsn.writeLock();
396+
try {
397+
getFSDirectory().updateCountForQuota(1);
398+
} finally {
399+
fsn.writeUnlock();
400+
}
401+
}
402+
393403
private void scanDirsWithQuota(INodeDirectory dir,
394404
HashMap<String, Long> nsMap,
395405
HashMap<String, Long> dsMap, boolean verify) {

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFSNamesystem.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void testFSNamespaceClearLeases() throws Exception {
9090
LeaseManager leaseMan = fsn.getLeaseManager();
9191
leaseMan.addLease("client1", fsn.getFSDirectory().allocateNewInodeId());
9292
assertEquals(1, leaseMan.countLease());
93-
fsn.clear();
93+
clearNamesystem(fsn);
9494
leaseMan = fsn.getLeaseManager();
9595
assertEquals(0, leaseMan.countLease());
9696
}
@@ -185,15 +185,24 @@ public void testReset() throws Exception {
185185
FSNamesystem fsn = new FSNamesystem(conf, fsImage);
186186
fsn.imageLoadComplete();
187187
assertTrue(fsn.isImageLoaded());
188-
fsn.clear();
189-
assertFalse(fsn.isImageLoaded());
188+
clearNamesystem(fsn);
190189
final INodeDirectory root = (INodeDirectory) fsn.getFSDirectory()
191190
.getINode("/");
192191
assertTrue(root.getChildrenList(Snapshot.CURRENT_STATE_ID).isEmpty());
193192
fsn.imageLoadComplete();
194193
assertTrue(fsn.isImageLoaded());
195194
}
196195

196+
private void clearNamesystem(FSNamesystem fsn) {
197+
fsn.writeLock();
198+
try {
199+
fsn.clear();
200+
assertFalse(fsn.isImageLoaded());
201+
} finally {
202+
fsn.writeUnlock();
203+
}
204+
}
205+
197206
@Test
198207
public void testGetEffectiveLayoutVersion() {
199208
assertEquals(-63,

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestGetBlockLocations.java

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.hadoop.fs.permission.PermissionStatus;
2323
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
2424
import org.apache.hadoop.hdfs.server.namenode.FSDirectory.DirOp;
25+
import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory;
2526
import org.junit.Test;
2627
import org.mockito.invocation.InvocationOnMock;
2728
import org.mockito.stubbing.Answer;
@@ -64,19 +65,28 @@ public void testGetBlockLocationsRacingWithDelete() throws IOException {
6465
FSNamesystem fsn = spy(setupFileSystem());
6566
final FSDirectory fsd = fsn.getFSDirectory();
6667
FSEditLog editlog = fsn.getEditLog();
68+
final boolean[] deleted = new boolean[]{false};
6769

6870
doAnswer(new Answer<Void>() {
6971

7072
@Override
7173
public Void answer(InvocationOnMock invocation) throws Throwable {
72-
INodesInPath iip = fsd.getINodesInPath(FILE_PATH, DirOp.READ);
73-
FSDirDeleteOp.delete(fsd, iip, new INode.BlocksMapUpdateInfo(),
74-
new ArrayList<INode>(), new ArrayList<Long>(),
75-
now());
74+
if(!deleted[0]) {
75+
fsn.writeLock();
76+
try {
77+
INodesInPath iip = fsd.getINodesInPath(FILE_PATH, DirOp.READ);
78+
FSDirDeleteOp.delete(fsd, iip, new INode.BlocksMapUpdateInfo(),
79+
new ArrayList<INode>(), new ArrayList<Long>(),
80+
now());
81+
} finally {
82+
fsn.writeUnlock();
83+
}
84+
deleted[0] = true;
85+
}
7686
invocation.callRealMethod();
7787
return null;
7888
}
79-
}).when(fsn).writeLock();
89+
}).when(fsn).checkOperation(OperationCategory.WRITE);
8090
fsn.getBlockLocations("dummy", RESERVED_PATH, 0, 1024);
8191

8292
verify(editlog, never()).logTimes(anyString(), anyLong(), anyLong());
@@ -89,22 +99,27 @@ public void testGetBlockLocationsRacingWithRename() throws IOException {
8999
final FSDirectory fsd = fsn.getFSDirectory();
90100
FSEditLog editlog = fsn.getEditLog();
91101
final String DST_PATH = "/bar";
92-
final boolean[] renamed = new boolean[1];
102+
final boolean[] renamed = new boolean[] {false};
93103

94104
doAnswer(new Answer<Void>() {
95105

96106
@Override
97107
public Void answer(InvocationOnMock invocation) throws Throwable {
98-
invocation.callRealMethod();
99108
if (!renamed[0]) {
100-
FSDirRenameOp.renameTo(fsd, fsd.getPermissionChecker(), FILE_PATH,
101-
DST_PATH, new INode.BlocksMapUpdateInfo(),
102-
false);
103-
renamed[0] = true;
109+
fsn.writeLock();
110+
try {
111+
FSDirRenameOp.renameTo(fsd, fsd.getPermissionChecker(), FILE_PATH,
112+
DST_PATH, new INode.BlocksMapUpdateInfo(),
113+
false);
114+
renamed[0] = true;
115+
} finally {
116+
fsn.writeUnlock();
117+
}
104118
}
119+
invocation.callRealMethod();
105120
return null;
106121
}
107-
}).when(fsn).writeLock();
122+
}).when(fsn).checkOperation(OperationCategory.WRITE);
108123
fsn.getBlockLocations("dummy", RESERVED_PATH, 0, 1024);
109124

110125
verify(editlog).logTimes(eq(DST_PATH), anyLong(), anyLong());
@@ -119,16 +134,22 @@ private static FSNamesystem setupFileSystem() throws IOException {
119134
when(image.getEditLog()).thenReturn(editlog);
120135
final FSNamesystem fsn = new FSNamesystem(conf, image, true);
121136

122-
final FSDirectory fsd = fsn.getFSDirectory();
123-
INodesInPath iip = fsd.getINodesInPath("/", DirOp.READ);
124137
PermissionStatus perm = new PermissionStatus(
125138
"hdfs", "supergroup",
126139
FsPermission.createImmutable((short) 0x1ff));
127140
final INodeFile file = new INodeFile(
128141
MOCK_INODE_ID, FILE_NAME.getBytes(StandardCharsets.UTF_8),
129142
perm, 1, 1, new BlockInfo[] {}, (short) 1,
130143
DFS_BLOCK_SIZE_DEFAULT);
131-
fsn.getFSDirectory().addINode(iip, file, null);
144+
145+
fsn.writeLock();
146+
try {
147+
final FSDirectory fsd = fsn.getFSDirectory();
148+
INodesInPath iip = fsd.getINodesInPath("/", DirOp.READ);
149+
fsd.addINode(iip, file, null);
150+
} finally {
151+
fsn.writeUnlock();
152+
}
132153
return fsn;
133154
}
134155

0 commit comments

Comments
 (0)