From b7039e47858399d42bab9d8e1ba33e3cefac812f Mon Sep 17 00:00:00 2001 From: S O'Donnell Date: Tue, 5 May 2026 16:31:31 +0100 Subject: [PATCH] HDDS-14670. SCM queryFinalizeStatus shouldFinalize should only be true when out of safemode --- .../scm/server/SCMClientProtocolServer.java | 2 +- .../server/TestSCMClientProtocolServer.java | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java index 5de633082c2f..806e0fed9a10 100644 --- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/server/SCMClientProtocolServer.java @@ -1213,7 +1213,7 @@ public HddsProtos.UpgradeStatus queryUpgradeStatus() throws IOException { scm.getScmNodeManager().getDatanodeFinalizationCounts(); int finalizedDatanodes = datanodeFinalizationCounts.getNumFinalizedDatanodes(); int healthyDatanodes = datanodeFinalizationCounts.getTotalHealthyDatanodes(); - boolean shouldFinalize = scmFinalized && datanodeFinalizationCounts.allNodesFinalized(); + boolean shouldFinalize = scmFinalized && datanodeFinalizationCounts.allNodesFinalized() && !scm.isInSafeMode(); HddsProtos.UpgradeStatus result = HddsProtos.UpgradeStatus.newBuilder() .setScmFinalized(scmFinalized) diff --git a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java index 184464658eee..7846c7ee5835 100644 --- a/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java +++ b/hadoop-hdds/server-scm/src/test/java/org/apache/hadoop/hdds/scm/server/TestSCMClientProtocolServer.java @@ -20,6 +20,7 @@ import static org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState.CLOSED; import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_READONLY_ADMINISTRATORS; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -46,6 +47,7 @@ import org.apache.hadoop.hdds.scm.ha.SCMNodeDetails; import org.apache.hadoop.hdds.scm.pipeline.PipelineID; import org.apache.hadoop.hdds.scm.protocol.StorageContainerLocationProtocolServerSideTranslatorPB; +import org.apache.hadoop.hdds.scm.safemode.SCMSafeModeManager; import org.apache.hadoop.hdds.utils.ProtocolMessageMetrics; import org.apache.hadoop.ozone.container.common.SCMTestUtils; import org.apache.hadoop.security.AccessControlException; @@ -63,17 +65,22 @@ public class TestSCMClientProtocolServer { private SCMClientProtocolServer server; private StorageContainerManager scm; private StorageContainerLocationProtocolServerSideTranslatorPB service; + private SCMSafeModeManager mockSafeModeManager; @BeforeEach void setUp(@TempDir File testDir) throws Exception { OzoneConfiguration config = SCMTestUtils.getConf(testDir); + + mockSafeModeManager = mock(SCMSafeModeManager.class); + when(mockSafeModeManager.getInSafeMode()).thenReturn(false); + SCMConfigurator configurator = new SCMConfigurator(); configurator.setSCMHAManager(SCMHAManagerStub.getInstance(true)); configurator.setScmContext(SCMContext.emptyContext()); + configurator.setScmSafeModeManager(mockSafeModeManager); config.set(OZONE_READONLY_ADMINISTRATORS, "testUser"); scm = HddsTestUtils.getScm(config, configurator); scm.start(); - scm.exitSafeMode(); server = scm.getClientProtocolServer(); service = new StorageContainerLocationProtocolServerSideTranslatorPB(server, @@ -186,6 +193,23 @@ public void testQueryUpgradeStatus() throws Exception { assertTrue(status.getShouldFinalize()); } + @Test + public void testQueryUpgradeStatusInSafemode() throws Exception { + // mockSafeModeManager defaults to returning true for getInSafeMode() + when(mockSafeModeManager.getInSafeMode()).thenReturn(true); + assertTrue(scm.isInSafeMode()); + + HddsProtos.UpgradeStatus status = server.queryUpgradeStatus(); + + // SCM starts already finalized in tests + assertTrue(status.getScmFinalized()); + // No datanodes registered + assertEquals(0, status.getNumDatanodesFinalized()); + assertEquals(0, status.getNumDatanodesTotal()); + // shouldFinalize is false because SCM is in safe mode + assertFalse(status.getShouldFinalize()); + } + private ContainerInfo newContainerInfoForTest() { return new ContainerInfo.Builder() .setContainerID(1)