Skip to content

Commit c183bd8

Browse files
swaglexiaoyuyao
authored andcommitted
HDDS-1527. HDDS Datanode start fails due to datanode.id file read error. Contributed by Siddharth Wagle.
This closes #822.
1 parent fab5b80 commit c183bd8

File tree

2 files changed

+49
-24
lines changed

2 files changed

+49
-24
lines changed

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/helpers/ContainerUtils.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.apache.hadoop.ozone.container.common.impl.ContainerData.CHARSET_ENCODING;
2525

2626
import java.io.File;
27+
import java.io.FileInputStream;
2728
import java.io.IOException;
2829
import java.nio.file.Paths;
2930
import java.security.MessageDigest;
@@ -35,6 +36,7 @@
3536
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto;
3637
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto;
3738
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Result;
39+
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
3840
import org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException;
3941
import org.apache.hadoop.ozone.OzoneConsts;
4042
import org.apache.hadoop.ozone.container.common.impl.ContainerData;
@@ -51,6 +53,9 @@
5153
*/
5254
public final class ContainerUtils {
5355

56+
private static final Logger LOG =
57+
LoggerFactory.getLogger(ContainerUtils.class);
58+
5459
private ContainerUtils() {
5560
//never constructed.
5661
}
@@ -198,7 +203,7 @@ public synchronized static void writeDatanodeDetailsTo(
198203
throw new IOException("Unable to overwrite the datanode ID file.");
199204
}
200205
} else {
201-
if(!path.getParentFile().exists() &&
206+
if (!path.getParentFile().exists() &&
202207
!path.getParentFile().mkdirs()) {
203208
throw new IOException("Unable to create datanode ID directories.");
204209
}
@@ -221,8 +226,16 @@ public synchronized static DatanodeDetails readDatanodeDetailsFrom(File path)
221226
try {
222227
return DatanodeIdYaml.readDatanodeIdFile(path);
223228
} catch (IOException e) {
224-
throw new IOException("Failed to parse DatanodeDetails from "
225-
+ path.getAbsolutePath(), e);
229+
LOG.warn("Error loading DatanodeDetails yaml from " +
230+
path.getAbsolutePath(), e);
231+
// Try to load as protobuf before giving up
232+
try (FileInputStream in = new FileInputStream(path)) {
233+
return DatanodeDetails.getFromProtoBuf(
234+
HddsProtos.DatanodeDetailsProto.parseFrom(in));
235+
} catch (IOException io) {
236+
throw new IOException("Failed to parse DatanodeDetails from "
237+
+ path.getAbsolutePath(), io);
238+
}
226239
}
227240
}
228241

hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestMiniOzoneCluster.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,38 @@
1818

1919
package org.apache.hadoop.ozone;
2020

21+
import static org.apache.hadoop.hdds.protocol.DatanodeDetails.Port;
22+
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY;
23+
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_CONTAINER_RATIS_IPC_RANDOM_PORT;
24+
import static org.junit.Assert.assertEquals;
25+
import static org.junit.Assert.assertFalse;
26+
import static org.junit.Assert.assertTrue;
27+
import static org.junit.Assert.fail;
28+
29+
import java.io.File;
30+
import java.io.FileOutputStream;
31+
import java.io.FileReader;
32+
import java.io.IOException;
33+
import java.util.ArrayList;
34+
import java.util.HashSet;
35+
import java.util.List;
36+
2137
import org.apache.commons.lang3.RandomUtils;
2238
import org.apache.hadoop.conf.Configuration;
2339
import org.apache.hadoop.hdds.HddsConfigKeys;
2440
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
2541
import org.apache.hadoop.hdds.protocol.DatanodeDetails;
42+
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
43+
import org.apache.hadoop.hdds.scm.TestUtils;
44+
import org.apache.hadoop.hdds.scm.XceiverClientGrpc;
45+
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
2646
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
2747
import org.apache.hadoop.hdds.scm.server.StorageContainerManager;
2848
import org.apache.hadoop.ozone.container.common.SCMTestUtils;
2949
import org.apache.hadoop.ozone.container.common.helpers.ContainerUtils;
30-
import org.apache.hadoop.ozone.container.common.statemachine
31-
.DatanodeStateMachine;
32-
import org.apache.hadoop.ozone.container.common.statemachine
33-
.EndpointStateMachine;
50+
import org.apache.hadoop.ozone.container.common.statemachine.DatanodeStateMachine;
51+
import org.apache.hadoop.ozone.container.common.statemachine.EndpointStateMachine;
3452
import org.apache.hadoop.ozone.container.ozoneimpl.TestOzoneContainer;
35-
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
36-
import org.apache.hadoop.hdds.scm.TestUtils;
37-
import org.apache.hadoop.hdds.scm.XceiverClientGrpc;
38-
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
3953
import org.apache.hadoop.test.PathUtils;
4054
import org.apache.hadoop.test.TestGenericTestUtils;
4155
import org.junit.AfterClass;
@@ -44,19 +58,6 @@
4458
import org.junit.Test;
4559
import org.yaml.snakeyaml.Yaml;
4660

47-
import java.io.File;
48-
import java.io.FileOutputStream;
49-
import java.io.FileReader;
50-
import java.io.IOException;
51-
import java.util.ArrayList;
52-
import java.util.HashSet;
53-
import java.util.List;
54-
55-
import static org.apache.hadoop.hdds.protocol.DatanodeDetails.Port;
56-
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY;
57-
import static org.apache.hadoop.ozone.OzoneConfigKeys.DFS_CONTAINER_RATIS_IPC_RANDOM_PORT;
58-
import static org.junit.Assert.*;
59-
6061
/**
6162
* Test cases for mini ozone cluster.
6263
*/
@@ -167,6 +168,17 @@ public void testDatanodeIDPersistent() throws Exception {
167168
} catch (Exception e) {
168169
assertTrue(e instanceof IOException);
169170
}
171+
172+
// Test upgrade scenario - protobuf file instead of yaml
173+
File protoFile = new File(WRITE_TMP, "valid-proto.id");
174+
try (FileOutputStream out = new FileOutputStream(protoFile)) {
175+
HddsProtos.DatanodeDetailsProto proto = id1.getProtoBufMessage();
176+
proto.writeTo(out);
177+
}
178+
validId = ContainerUtils.readDatanodeDetailsFrom(protoFile);
179+
assertEquals(validId.getCertSerialId(), certSerialId);
180+
assertEquals(id1, validId);
181+
assertEquals(id1.getProtoBufMessage(), validId.getProtoBufMessage());
170182
}
171183

172184
@Test

0 commit comments

Comments
 (0)