HDFS-3795. QJM: validate journal dir at startup. Contributed by Todd Lipcon.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-3077@1373178 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f765fdb657
commit
160bfcd6c2
|
@ -16,3 +16,5 @@ HDFS-3741. Exhaustive failure injection test for skipped RPCs (todd)
|
||||||
HDFS-3773. TestNNWithQJM fails after HDFS-3741. (atm)
|
HDFS-3773. TestNNWithQJM fails after HDFS-3741. (atm)
|
||||||
|
|
||||||
HDFS-3793. Implement genericized format() in QJM (todd)
|
HDFS-3793. Implement genericized format() in QJM (todd)
|
||||||
|
|
||||||
|
HDFS-3795. QJM: validate journal dir at startup (todd)
|
||||||
|
|
|
@ -55,6 +55,8 @@ public class JournalNode implements Tool, Configurable {
|
||||||
private JournalNodeHttpServer httpServer;
|
private JournalNodeHttpServer httpServer;
|
||||||
private Map<String, Journal> journalsById = Maps.newHashMap();
|
private Map<String, Journal> journalsById = Maps.newHashMap();
|
||||||
|
|
||||||
|
private File localDir;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
HdfsConfiguration.init();
|
HdfsConfiguration.init();
|
||||||
}
|
}
|
||||||
|
@ -82,8 +84,32 @@ public class JournalNode implements Tool, Configurable {
|
||||||
@Override
|
@Override
|
||||||
public void setConf(Configuration conf) {
|
public void setConf(Configuration conf) {
|
||||||
this.conf = conf;
|
this.conf = conf;
|
||||||
|
this.localDir = new File(
|
||||||
|
conf.get(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY,
|
||||||
|
DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_DEFAULT).trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void validateAndCreateJournalDir(File dir) throws IOException {
|
||||||
|
if (!dir.isAbsolute()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Journal dir '" + dir + "' should be an absolute path");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dir.exists() && !dir.mkdirs()) {
|
||||||
|
throw new IOException("Could not create journal dir '" +
|
||||||
|
dir + "'");
|
||||||
|
} else if (!dir.isDirectory()) {
|
||||||
|
throw new IOException("Journal directory '" + dir + "' is not " +
|
||||||
|
"a directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dir.canWrite()) {
|
||||||
|
throw new IOException("Unable to write to journal dir '" +
|
||||||
|
dir + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Configuration getConf() {
|
public Configuration getConf() {
|
||||||
return conf;
|
return conf;
|
||||||
|
@ -101,6 +127,8 @@ public class JournalNode implements Tool, Configurable {
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
Preconditions.checkState(!isStarted(), "JN already running");
|
Preconditions.checkState(!isStarted(), "JN already running");
|
||||||
|
|
||||||
|
validateAndCreateJournalDir(localDir);
|
||||||
|
|
||||||
DefaultMetricsSystem.initialize("JournalNode");
|
DefaultMetricsSystem.initialize("JournalNode");
|
||||||
JvmMetrics.create("JournalNode",
|
JvmMetrics.create("JournalNode",
|
||||||
conf.get(DFSConfigKeys.DFS_METRICS_SESSION_ID_KEY),
|
conf.get(DFSConfigKeys.DFS_METRICS_SESSION_ID_KEY),
|
||||||
|
|
|
@ -156,7 +156,7 @@ public class MiniJournalCluster {
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getStorageDir(int idx) {
|
public File getStorageDir(int idx) {
|
||||||
return new File(baseDir, "journalnode-" + idx);
|
return new File(baseDir, "journalnode-" + idx).getAbsoluteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getCurrentDir(int idx, String jid) {
|
public File getCurrentDir(int idx, String jid) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hdfs.qjournal;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
@ -42,7 +43,9 @@ public class TestMiniJournalCluster {
|
||||||
|
|
||||||
JournalNode node = c.getJournalNode(0);
|
JournalNode node = c.getJournalNode(0);
|
||||||
String dir = node.getConf().get(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY);
|
String dir = node.getConf().get(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY);
|
||||||
assertEquals(MiniDFSCluster.getBaseDirectory() + "journalnode-0",
|
assertEquals(
|
||||||
|
new File(MiniDFSCluster.getBaseDirectory() + "journalnode-0")
|
||||||
|
.getAbsolutePath(),
|
||||||
dir);
|
dir);
|
||||||
} finally {
|
} finally {
|
||||||
c.shutdown();
|
c.shutdown();
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -234,6 +235,33 @@ public class TestJournalNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFailToStartWithBadConfig() throws Exception {
|
||||||
|
Configuration conf = new Configuration();
|
||||||
|
conf.set(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY, "non-absolute-path");
|
||||||
|
assertJNFailsToStart(conf, "should be an absolute path");
|
||||||
|
|
||||||
|
// Existing file which is not a directory
|
||||||
|
conf.set(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY, "/dev/null");
|
||||||
|
assertJNFailsToStart(conf, "is not a directory");
|
||||||
|
|
||||||
|
// Directory which cannot be created
|
||||||
|
conf.set(DFSConfigKeys.DFS_JOURNALNODE_EDITS_DIR_KEY, "/proc/does-not-exist");
|
||||||
|
assertJNFailsToStart(conf, "Could not create");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertJNFailsToStart(Configuration conf,
|
||||||
|
String errString) {
|
||||||
|
try {
|
||||||
|
JournalNode jn = new JournalNode();
|
||||||
|
jn.setConf(conf);
|
||||||
|
jn.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
GenericTestUtils.assertExceptionContains(errString, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// - add test that checks formatting behavior
|
// - add test that checks formatting behavior
|
||||||
// - add test that checks rejects newEpoch if nsinfo doesn't match
|
// - add test that checks rejects newEpoch if nsinfo doesn't match
|
||||||
|
|
Loading…
Reference in New Issue