Skip to content

Commit 0ed4aa1

Browse files
committed
HDFS-16547. [SBN read] Namenode in safe mode should not be transfer to observer state
1 parent ec0ff1d commit 0ed4aa1

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1653,7 +1653,7 @@ && isInStartupSafeMode()) {
16531653
}
16541654
}
16551655

1656-
private SafeModeException newSafemodeException(String errorMsg) {
1656+
public SafeModeException newSafemodeException(String errorMsg) {
16571657
return new SafeModeException(errorMsg + ". Name node is in safe " +
16581658
"mode.\n" + getSafeModeTip() + " NamenodeHostName:" + nameNodeHostName);
16591659
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,6 +1899,10 @@ synchronized void transitionToStandby() throws IOException {
18991899
synchronized void transitionToObserver() throws IOException {
19001900
String operationName = "transitionToObserver";
19011901
namesystem.checkSuperuserPrivilege(operationName);
1902+
if (namesystem.isInSafeMode()) {
1903+
throw namesystem.newSafemodeException("Cannot transition to " +
1904+
OBSERVER_STATE);
1905+
}
19021906
if (!haEnabled) {
19031907
throw new ServiceFailedException("HA for namenode is not enabled");
19041908
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/DFSHAAdmin.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,13 @@ private int transitionToObserver(final CommandLine cmd)
262262
if (!checkManualStateManagementOK(target)) {
263263
return -1;
264264
}
265-
HAServiceProtocol proto = target.getProxy(getConf(), 0);
266-
HAServiceProtocolHelper.transitionToObserver(proto, createReqInfo());
265+
try {
266+
HAServiceProtocol proto = target.getProxy(getConf(), 0);
267+
HAServiceProtocolHelper.transitionToObserver(proto, createReqInfo());
268+
} catch (IOException e) {
269+
errOut.println("TransitionToObserver failed! " + e.getMessage());
270+
return -1;
271+
}
267272
return 0;
268273
}
269274

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/TestDFSZKFailoverController.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_SERVICE_RPC_BIND_HOST_KEY;
2121
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertFalse;
2223
import static org.junit.Assert.assertTrue;
2324

2425
import java.io.ByteArrayInputStream;
@@ -40,9 +41,11 @@
4041
import org.apache.hadoop.hdfs.DFSConfigKeys;
4142
import org.apache.hadoop.hdfs.MiniDFSCluster;
4243
import org.apache.hadoop.hdfs.MiniDFSNNTopology;
44+
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
4345
import org.apache.hadoop.hdfs.server.namenode.EditLogFileOutputStream;
4446
import org.apache.hadoop.hdfs.server.namenode.MockNameNodeResourceChecker;
4547
import org.apache.hadoop.hdfs.server.namenode.NameNode;
48+
import org.apache.hadoop.hdfs.server.namenode.SafeModeException;
4649
import org.apache.hadoop.hdfs.server.namenode.ha.HATestUtil;
4750
import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocols;
4851
import org.apache.hadoop.net.ServerSocketUtil;
@@ -301,6 +304,40 @@ public void testManualFailoverWithDFSHAAdmin() throws Exception {
301304
waitForHAState(1, HAServiceState.STANDBY);
302305
}
303306

307+
/**
308+
* Tests that a Namenode in safe mode should not be transfer to observer state.
309+
*/
310+
@Test
311+
public void testManualFailoverWithDFSHAAdminInSafemode() throws Exception {
312+
startCluster();
313+
NamenodeProtocols nn1 = cluster.getNameNode(1).getRpcServer();
314+
315+
// Enter safe mode.
316+
nn1.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_ENTER, false);
317+
// Test NameNodeRpcServer.
318+
LambdaTestUtils.intercept(SafeModeException.class,
319+
"Cannot transition to observer. Name node is in safe mode",
320+
() -> nn1.transitionToObserver(
321+
new StateChangeRequestInfo(RequestSource.REQUEST_BY_USER_FORCED)));
322+
323+
// Test DFSHAAdmin.
324+
DFSHAAdmin tool = new DFSHAAdmin();
325+
tool.setConf(conf);
326+
System.setIn(new ByteArrayInputStream("yes\n".getBytes()));
327+
int result = tool.run(
328+
new String[]{"-transitionToObserver", "-forcemanual", "nn2"});
329+
assertEquals("State transition returned: " + result, -1, result);
330+
331+
// Leave safe mode.
332+
nn1.setSafeMode(HdfsConstants.SafeModeAction.SAFEMODE_LEAVE, false);
333+
// Just need to test DFSHAAdmin.
334+
System.setIn(new ByteArrayInputStream("yes\n".getBytes()));
335+
int result1 = tool.run(
336+
new String[]{"-transitionToObserver", "-forcemanual", "nn2"});
337+
assertEquals("State transition returned: " + result1, 0, result1);
338+
assertFalse(cluster.getNameNode(1).isInSafeMode());
339+
}
340+
304341
@Test(timeout=30000)
305342
public void testElectionOnObserver() throws Exception{
306343
startCluster();

0 commit comments

Comments
 (0)