diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 3f6eb646cc9..40eba1cd0b6 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -273,6 +273,8 @@ Release 2.0.3-alpha - Unreleased of it is undefined after the iteration or modifications of the map. (szetszwo) + HDFS-4231. BackupNode: Introduce BackupState. (shv) + Release 2.0.2-alpha - 2012-09-07 INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupNode.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupNode.java index 6b5f0698a62..e5137e55edb 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupNode.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupNode.java @@ -24,6 +24,7 @@ import java.net.SocketTimeoutException; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.CommonConfigurationKeys; +import org.apache.hadoop.ha.ServiceFailedException; import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.hdfs.NameNodeProxies; @@ -35,6 +36,7 @@ import org.apache.hadoop.hdfs.protocolPB.JournalProtocolPB; import org.apache.hadoop.hdfs.protocolPB.JournalProtocolServerSideTranslatorPB; import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.NamenodeRole; import org.apache.hadoop.hdfs.server.common.Storage; +import org.apache.hadoop.hdfs.server.namenode.ha.HAState; import org.apache.hadoop.hdfs.server.protocol.FenceResponse; import org.apache.hadoop.hdfs.server.protocol.JournalInfo; import org.apache.hadoop.hdfs.server.protocol.JournalProtocol; @@ -404,14 +406,23 @@ public class BackupNode extends NameNode { + HdfsConstants.LAYOUT_VERSION + " actual "+ nsInfo.getLayoutVersion(); return nsInfo; } - + @Override + protected String getNameServiceId(Configuration conf) { + return DFSUtil.getBackupNameServiceId(conf); + } + + protected HAState createHAState() { + return new BackupState(); + } + + @Override // NameNode protected NameNodeHAContext createHAContext() { return new BNHAContext(); } - + private class BNHAContext extends NameNodeHAContext { - @Override // NameNode + @Override // NameNodeHAContext public void checkOperation(OperationCategory op) throws StandbyException { if (op == OperationCategory.UNCHECKED || @@ -425,10 +436,42 @@ public class BackupNode extends NameNode { throw new StandbyException(msg); } } - } - - @Override - protected String getNameServiceId(Configuration conf) { - return DFSUtil.getBackupNameServiceId(conf); + + @Override // NameNodeHAContext + public void prepareToStopStandbyServices() throws ServiceFailedException { + } + + /** + * Start services for BackupNode. + *
+ * The following services should be muted + * (not run or not pass any control commands to DataNodes) + * on BackupNode: + * {@link LeaseManager.Monitor} protected by SafeMode. + * {@link BlockManager.ReplicationMonitor} protected by SafeMode. + * {@link HeartbeatManager.Monitor} protected by SafeMode. + * {@link DecommissionManager.Monitor} need to prohibit refreshNodes(). + * {@link PendingReplicationBlocks.PendingReplicationMonitor} harmless, + * because ReplicationMonitor is muted. + */ + @Override + public void startActiveServices() throws IOException { + try { + namesystem.startActiveServices(); + } catch (Throwable t) { + doImmediateShutdown(t); + } + } + + @Override + public void stopActiveServices() throws IOException { + try { + if (namesystem != null) { + namesystem.stopActiveServices(); + } + } catch (Throwable t) { + doImmediateShutdown(t); + } + } } } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupState.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupState.java new file mode 100644 index 00000000000..f8c79284c13 --- /dev/null +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/BackupState.java @@ -0,0 +1,51 @@ +package org.apache.hadoop.hdfs.server.namenode; + +import java.io.IOException; + +import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState; +import org.apache.hadoop.ha.ServiceFailedException; +import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory; +import org.apache.hadoop.hdfs.server.namenode.ha.HAContext; +import org.apache.hadoop.hdfs.server.namenode.ha.HAState; +import org.apache.hadoop.ipc.StandbyException; + +public class BackupState extends HAState { + + public BackupState() { + super(HAServiceState.STANDBY); + } + + @Override // HAState + public void checkOperation(HAContext context, OperationCategory op) + throws StandbyException { + context.checkOperation(op); + } + + @Override // HAState + public boolean shouldPopulateReplQueues() { + return false; + } + + @Override + public void enterState(HAContext context) throws ServiceFailedException { + try { + context.startActiveServices(); + } catch (IOException e) { + throw new ServiceFailedException("Failed to start backup services", e); + } + } + + @Override + public void exitState(HAContext context) throws ServiceFailedException { + try { + context.stopActiveServices(); + } catch (IOException e) { + throw new ServiceFailedException("Failed to stop backup services", e); + } + } + + @Override + public void prepareToExitState(HAContext context) throws ServiceFailedException { + context.prepareToStopStandbyServices(); + } +} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java index e5a3f0b3562..312501238c1 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java @@ -121,6 +121,7 @@ import org.apache.hadoop.fs.UnresolvedLinkException; import org.apache.hadoop.fs.permission.FsAction; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.permission.PermissionStatus; +import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState; import org.apache.hadoop.ha.ServiceFailedException; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.hdfs.HAUtil; @@ -161,7 +162,6 @@ import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory; import org.apache.hadoop.hdfs.server.common.Util; import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease; import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory; -import org.apache.hadoop.hdfs.server.namenode.ha.ActiveState; import org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer; import org.apache.hadoop.hdfs.server.namenode.ha.HAContext; import org.apache.hadoop.hdfs.server.namenode.ha.HAState; @@ -3413,9 +3413,9 @@ public class FSNamesystem implements Namesystem, FSClusterStats, private NNHAStatusHeartbeat createHaStatusHeartbeat() { HAState state = haContext.getState(); NNHAStatusHeartbeat.State hbState; - if (state instanceof ActiveState) { + if (state.getServiceState() == HAServiceState.ACTIVE) { hbState = NNHAStatusHeartbeat.State.ACTIVE; - } else if (state instanceof StandbyState) { + } else if (state.getServiceState() == HAServiceState.STANDBY) { hbState = NNHAStatusHeartbeat.State.STANDBY; } else { throw new AssertionError("Invalid state: " + state.getClass()); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java index af467057271..405c0a0c413 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java @@ -600,11 +600,7 @@ public class NameNode { String nsId = getNameServiceId(conf); String namenodeId = HAUtil.getNameNodeId(conf, nsId); this.haEnabled = HAUtil.isHAEnabled(conf, nsId); - if (!haEnabled) { - state = ACTIVE_STATE; - } else { - state = STANDBY_STATE; - } + state = createHAState(); this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf); this.haContext = createHAContext(); try { @@ -621,6 +617,10 @@ public class NameNode { } } + protected HAState createHAState() { + return !haEnabled ? ACTIVE_STATE : STANDBY_STATE; + } + protected HAContext createHAContext() { return new NameNodeHAContext(); } @@ -1284,7 +1284,7 @@ public class NameNode { * before exit. * @throws ExitException thrown only for testing. */ - private synchronized void doImmediateShutdown(Throwable t) + protected synchronized void doImmediateShutdown(Throwable t) throws ExitException { String message = "Error encountered requiring NN shutdown. " + "Shutting down immediately."; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestBackupNode.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestBackupNode.java index 36b092ef6ea..17192eb8044 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestBackupNode.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestBackupNode.java @@ -35,6 +35,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.fs.Path; +import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState; import org.apache.hadoop.hdfs.DFSConfigKeys; import org.apache.hadoop.hdfs.HAUtil; import org.apache.hadoop.hdfs.HdfsConfiguration; @@ -98,6 +99,9 @@ public class TestBackupNode { BackupNode bn = (BackupNode)NameNode.createNameNode( new String[]{startupOpt.getName()}, c); assertTrue(bn.getRole() + " must be in SafeMode.", bn.isInSafeMode()); + assertTrue(bn.getRole() + " must be in StandbyState", + bn.getNamesystem().getHAState() + .equalsIgnoreCase(HAServiceState.STANDBY.name())); return bn; }