HDFS-15641. DataNode could meet deadlock if invoke refreshNameNode. Contributed by Hongbing Wang.

(cherry picked from commit 12c908c827)
This commit is contained in:
Hui Fei 2020-10-26 22:12:27 +08:00
parent 8312f230eb
commit b8cc09d7c7
3 changed files with 37 additions and 1 deletions

View File

@ -206,6 +206,7 @@ String getBlockPoolId(boolean quiet) {
if (id != null) {
return id;
}
DataNodeFaultInjector.get().delayWhenOfferServiceHoldLock();
readLock();
try {
if (bpNSInfo != null) {
@ -382,6 +383,7 @@ void verifyAndSetNamespaceInfo(BPServiceActor actor, NamespaceInfo nsInfo)
}
try {
DataNodeFaultInjector.get().delayWhenOfferServiceHoldLock();
if (setNamespaceInfo(nsInfo) == null) {
boolean success = false;

View File

@ -572,11 +572,11 @@ void start() {
}
bpThread = new Thread(this);
bpThread.setDaemon(true); // needed for JUnit testing
bpThread.start();
if (lifelineSender != null) {
lifelineSender.start();
}
bpThread.start();
}
private String formatThreadName(

View File

@ -26,6 +26,8 @@
import java.util.Set;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.MiniDFSNNTopology;
import org.apache.hadoop.hdfs.MiniDFSNNTopology.NNConf;
@ -93,4 +95,36 @@ public void testRefreshNamenodes() throws IOException {
}
}
}
@Test(timeout=10000)
public void testRefreshNameNodeDeadLock() throws Exception {
Configuration conf = new HdfsConfiguration();
MiniDFSCluster cluster = null;
try {
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(3).build();
cluster.waitActive();
DataNodeFaultInjector.set(new DataNodeFaultInjector() {
@Override
public void delayWhenOfferServiceHoldLock() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
DataNode dn = cluster.getDataNodes().get(0);
Configuration dnConf = dn.getConf();
dnConf.set(DFSConfigKeys.DFS_NAMESERVICES, "ns1");
dnConf.set(DFSConfigKeys.DFS_NAMENODE_LIFELINE_RPC_ADDRESS_KEY + ".ns1",
"mock:8022");
dn.refreshNamenodes(dnConf);
} finally {
if (cluster != null) {
cluster.shutdown();
}
}
}
}