HDFS-10986. DFSAdmin should log detailed error message if any. Contributed by MingLiang Liu

This commit is contained in:
Brahma Reddy Battula 2016-10-13 21:39:50 +05:30
parent 9454dc5e80
commit 1291254042
2 changed files with 50 additions and 62 deletions

View File

@ -936,8 +936,7 @@ public int getBalancerBandwidth(String[] argv, int idx) throws IOException {
System.out.println("Balancer bandwidth is " + bandwidth System.out.println("Balancer bandwidth is " + bandwidth
+ " bytes per second."); + " bytes per second.");
} catch (IOException ioe) { } catch (IOException ioe) {
System.err.println("Datanode unreachable."); throw new IOException("Datanode unreachable. " + ioe, ioe);
return -1;
} }
return 0; return 0;
} }
@ -2207,7 +2206,7 @@ private int evictWriters(String[] argv, int i) throws IOException {
dnProxy.evictWriters(); dnProxy.evictWriters();
System.out.println("Requested writer eviction to datanode " + dn); System.out.println("Requested writer eviction to datanode " + dn);
} catch (IOException ioe) { } catch (IOException ioe) {
return -1; throw new IOException("Datanode unreachable. " + ioe, ioe);
} }
return 0; return 0;
} }
@ -2218,8 +2217,7 @@ private int getDatanodeInfo(String[] argv, int i) throws IOException {
DatanodeLocalInfo dnInfo = dnProxy.getDatanodeInfo(); DatanodeLocalInfo dnInfo = dnProxy.getDatanodeInfo();
System.out.println(dnInfo.getDatanodeLocalReport()); System.out.println(dnInfo.getDatanodeLocalReport());
} catch (IOException ioe) { } catch (IOException ioe) {
System.err.println("Datanode unreachable."); throw new IOException("Datanode unreachable. " + ioe, ioe);
return -1;
} }
return 0; return 0;
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.hdfs.tools; package org.apache.hadoop.hdfs.tools;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY;
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_DATA_DIR_KEY;
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_HEARTBEAT_INTERVAL_DEFAULT; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_HEARTBEAT_INTERVAL_DEFAULT;
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_HEARTBEAT_INTERVAL_KEY; import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_HEARTBEAT_INTERVAL_KEY;
@ -79,6 +80,7 @@ public class TestDFSAdmin {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
conf = new Configuration(); conf = new Configuration();
conf.setInt(IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 3);
restartCluster(); restartCluster();
admin = new DFSAdmin(); admin = new DFSAdmin();
@ -116,7 +118,7 @@ private void restartCluster() throws IOException {
if (cluster != null) { if (cluster != null) {
cluster.shutdown(); cluster.shutdown();
} }
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build(); cluster = new MiniDFSCluster.Builder(conf).numDataNodes(2).build();
cluster.waitActive(); cluster.waitActive();
datanode = cluster.getDataNodes().get(0); datanode = cluster.getDataNodes().get(0);
namenode = cluster.getNameNode(); namenode = cluster.getNameNode();
@ -171,70 +173,58 @@ private static void scanIntoList(
@Test(timeout = 30000) @Test(timeout = 30000)
public void testGetDatanodeInfo() throws Exception { public void testGetDatanodeInfo() throws Exception {
redirectStream(); redirectStream();
final Configuration dfsConf = new HdfsConfiguration(); final DFSAdmin dfsAdmin = new DFSAdmin(conf);
final int numDn = 2;
/* init cluster */ for (int i = 0; i < cluster.getDataNodes().size(); i++) {
try (MiniDFSCluster miniCluster = new MiniDFSCluster.Builder(dfsConf)
.numDataNodes(numDn).build()) {
miniCluster.waitActive();
assertEquals(numDn, miniCluster.getDataNodes().size());
final DFSAdmin dfsAdmin = new DFSAdmin(dfsConf);
/* init reused vars */
List<String> outs = null;
int ret;
/**
* test erroneous run
*/
resetStream(); resetStream();
outs = Lists.newArrayList(); final DataNode dn = cluster.getDataNodes().get(i);
final String addr = String.format(
/* invoke getDatanodeInfo */ "%s:%d",
ret = ToolRunner.run( dn.getXferAddress().getHostString(),
dfsAdmin, dn.getIpcPort());
new String[] {"-getDatanodeInfo", "128.0.0.1:1234"}); final int ret = ToolRunner.run(dfsAdmin,
new String[]{"-getDatanodeInfo", addr});
assertEquals(0, ret);
/* collect outputs */ /* collect outputs */
final List<String> outs = Lists.newArrayList();
scanIntoList(out, outs); scanIntoList(out, outs);
/* verify results */ /* verify results */
assertEquals(
"One line per DataNode like: Uptime: XXX, Software version: x.y.z,"
+ " Config version: core-x.y.z,hdfs-x",
1, outs.size());
assertThat(outs.get(0),
is(allOf(containsString("Uptime:"),
containsString("Software version"),
containsString("Config version"))));
}
}
/**
* Test that if datanode is not reachable, some DFSAdmin commands will fail
* elegantly with non-zero ret error code along with exception error message.
*/
@Test(timeout = 60000)
public void testDFSAdminUnreachableDatanode() throws Exception {
redirectStream();
final DFSAdmin dfsAdmin = new DFSAdmin(conf);
for (String command : new String[]{"-getDatanodeInfo",
"-evictWriters", "-getBalancerBandwidth"}) {
// Connecting to Xfer port instead of IPC port will get
// Datanode unreachable. java.io.EOFException
final String dnDataAddr = datanode.getXferAddress().getHostString() + ":"
+ datanode.getXferPort();
resetStream();
final List<String> outs = Lists.newArrayList();
final int ret = ToolRunner.run(dfsAdmin,
new String[]{command, dnDataAddr});
assertEquals(-1, ret); assertEquals(-1, ret);
assertTrue("Unexpected getDatanodeInfo stdout", outs.isEmpty());
/** scanIntoList(out, outs);
* test normal run assertTrue("Unexpected " + command + " stdout: " + out, outs.isEmpty());
*/ assertTrue("Unexpected " + command + " stderr: " + err,
for (int i = 0; i < numDn; i++) { err.toString().contains("Exception"));
resetStream();
final DataNode dn = miniCluster.getDataNodes().get(i);
/* invoke getDatanodeInfo */
final String addr = String.format(
"%s:%d",
dn.getXferAddress().getHostString(),
dn.getIpcPort());
ret = ToolRunner.run(
dfsAdmin,
new String[] {"-getDatanodeInfo", addr});
/* collect outputs */
outs = Lists.newArrayList();
scanIntoList(out, outs);
/* verify results */
assertEquals(0, ret);
assertEquals(
"One line per DataNode like: Uptime: XXX, Software version: x.y.z,"
+ " Config version: core-x.y.z,hdfs-x",
1, outs.size());
assertThat(outs.get(0),
is(allOf(containsString("Uptime:"),
containsString("Software version"),
containsString("Config version"))));
}
} }
} }