HDDS-440. Datanode loops forever if it cannot create directories.

Contributed by Bharat Viswanadham.
This commit is contained in:
Anu Engineer 2018-09-18 14:31:50 -07:00
parent e71f61ecb8
commit a968ea4897
2 changed files with 52 additions and 2 deletions

View File

@ -116,7 +116,7 @@ public DatanodeStateMachine.DatanodeStates call() throws Exception {
/**
* Persist DatanodeDetails to datanode.id file.
*/
private void persistContainerDatanodeDetails() throws IOException {
private void persistContainerDatanodeDetails() {
String dataNodeIDPath = HddsUtils.getDatanodeIdFilePath(conf);
if (Strings.isNullOrEmpty(dataNodeIDPath)) {
LOG.error("A valid file path is needed for config setting {}",
@ -128,7 +128,15 @@ private void persistContainerDatanodeDetails() throws IOException {
DatanodeDetails datanodeDetails = this.context.getParent()
.getDatanodeDetails();
if (datanodeDetails != null && !idPath.exists()) {
ContainerUtils.writeDatanodeDetailsTo(datanodeDetails, idPath);
try {
ContainerUtils.writeDatanodeDetailsTo(datanodeDetails, idPath);
} catch (IOException ex) {
// As writing DatanodeDetails in to datanodeid file failed, which is
// a critical thing, so shutting down the state machine.
LOG.error("Writing to {} failed {}", dataNodeIDPath, ex.getMessage());
this.context.setState(DatanodeStateMachine.DatanodeStates.SHUTDOWN);
return;
}
LOG.info("DatanodeDetails is persisted to {}", dataNodeIDPath);
}
}

View File

@ -311,6 +311,48 @@ public void testDatanodeStateContext() throws IOException,
}
}
@Test
public void testDatanodeStateMachineWithIdWriteFail() throws Exception {
File idPath = new File(
conf.get(ScmConfigKeys.OZONE_SCM_DATANODE_ID));
idPath.delete();
DatanodeDetails datanodeDetails = getNewDatanodeDetails();
DatanodeDetails.Port port = DatanodeDetails.newPort(
DatanodeDetails.Port.Name.STANDALONE,
OzoneConfigKeys.DFS_CONTAINER_IPC_PORT_DEFAULT);
datanodeDetails.setPort(port);
try (DatanodeStateMachine stateMachine =
new DatanodeStateMachine(datanodeDetails, conf)) {
DatanodeStateMachine.DatanodeStates currentState =
stateMachine.getContext().getState();
Assert.assertEquals(DatanodeStateMachine.DatanodeStates.INIT,
currentState);
DatanodeState<DatanodeStateMachine.DatanodeStates> task =
stateMachine.getContext().getTask();
Assert.assertEquals(InitDatanodeState.class, task.getClass());
//Set the idPath to read only, state machine will fail to write
// datanodeId file and set the state to shutdown.
idPath.getParentFile().mkdirs();
idPath.getParentFile().setReadOnly();
task.execute(executorService);
DatanodeStateMachine.DatanodeStates newState =
task.await(2, TimeUnit.SECONDS);
//As, we have changed the permission of idPath to readable, writing
// will fail and it will set the state to shutdown.
Assert.assertEquals(DatanodeStateMachine.DatanodeStates.SHUTDOWN,
newState);
//Setting back to writable.
idPath.getParentFile().setWritable(true);
}
}
/**
* Test state transition with a list of invalid scm configurations,
* and verify the state transits to SHUTDOWN each time.