diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java index 5b534ba..f79498a 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/DefaultContainerExecutor.java @@ -203,11 +203,13 @@ public int launchContainer(Container container, return -1; } int exitCode = shExec.getExitCode(); - LOG.warn("Exit code from task is : " + exitCode); - String message = shExec.getOutput(); - logOutput(message); - container.handle(new ContainerDiagnosticsUpdateEvent(containerId, + LOG.error("Exit code from task is : " + exitCode); + if( e instanceof ExitCodeException) { + String message = ((ExitCodeException)e).getMessage(); + logOutput(message); + container.handle(new ContainerDiagnosticsUpdateEvent(containerId, message)); + } return exitCode; } finally { ; // diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java index 4e6cdcb..96707a8 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/LinuxContainerExecutor.java @@ -147,7 +147,7 @@ public void init() throws IOException { } catch (ExitCodeException e) { int exitCode = shExec.getExitCode(); LOG.warn("Exit code from container is : " + exitCode); - logOutput(shExec.getOutput()); + logOutput(e.getMessage()); throw new IOException("Linux container executor not configured properly" + " (error=" + exitCode + ")", e); } @@ -204,9 +204,9 @@ public void startLocalizer(Path nmPrivateContainerTokensPath, } catch (ExitCodeException e) { int exitCode = shExec.getExitCode(); LOG.warn("Exit code from container is : " + exitCode); - logOutput(shExec.getOutput()); + logOutput(e.getMessage()); throw new IOException("App initialization failed (" + exitCode + - ") with output: " + shExec.getOutput(), e); + ") with output: " + e.getMessage(), e); } } @@ -268,9 +268,9 @@ public int launchContainer(Container container, if (exitCode != ExitCode.FORCE_KILLED.getExitCode() && exitCode != ExitCode.TERMINATED.getExitCode()) { LOG.warn("Exception from container-launch : ", e); - logOutput(shExec.getOutput()); + logOutput(e.getMessage()); String diagnostics = "Exception from container-launch: \n" - + StringUtils.stringifyException(e) + "\n" + shExec.getOutput(); + + StringUtils.stringifyException(e) + "\n" + e.getMessage(); container.handle(new ContainerDiagnosticsUpdateEvent(containerId, diagnostics)); } else { @@ -309,7 +309,7 @@ public boolean signalContainer(String user, String pid, Signal signal) if (ret_code == ResultCode.INVALID_CONTAINER_PID.getValue()) { return false; } - logOutput(shExec.getOutput()); + logOutput(e.getMessage()); throw new IOException("Problem signalling container " + pid + " with " + signal + "; exit = " + ret_code); } @@ -350,7 +350,9 @@ public void deleteAsUser(String user, Path dir, Path... baseDirs) { LOG.error("DeleteAsUser for " + dir.toUri().getPath() + " returned with non-zero exit code" + exitCode); LOG.error("Output from LinuxContainerExecutor's deleteAsUser follows:"); - logOutput(shExec.getOutput()); + if( e instanceof ExitCodeException) { + logOutput(((ExitCodeException)e).getMessage()); + } } } } @@ -372,7 +374,9 @@ public void mountCgroups(List cgroupKVs, String hierarchy) shExec.execute(); } catch (IOException e) { int ret_code = shExec.getExitCode(); - logOutput(shExec.getOutput()); + if( e instanceof ExitCodeException) { + logOutput(((ExitCodeException)e).getMessage()); + } throw new IOException("Problem mounting cgroups " + cgroupKVs + "; exit code = " + ret_code, e); } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java index 231e2fa..3353f03 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/TestContainerLaunch.java @@ -39,6 +39,7 @@ import org.apache.hadoop.fs.UnsupportedFileSystemException; import org.apache.hadoop.security.token.SecretManager.InvalidToken; import org.apache.hadoop.util.Shell; +import org.apache.hadoop.util.Shell.ExitCodeException; import org.apache.hadoop.util.StringUtils; import org.apache.hadoop.yarn.api.ApplicationConstants.Environment; import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusRequest; @@ -98,7 +99,7 @@ public void testSpecialCharSymlinks() throws IOException { tempFile = Shell.appendScriptExtension(tmpDir, "temp"); String timeoutCommand = Shell.WINDOWS ? "@echo \"hello\"" : "echo \"hello\""; - PrintWriter writer = new PrintWriter(new FileOutputStream(shellFile)); + PrintWriter writer = new PrintWriter(new FileOutputStream(shellFile)); FileUtil.setExecutable(shellFile, true); writer.println(timeoutCommand); writer.close(); @@ -132,7 +133,78 @@ public void testSpecialCharSymlinks() throws IOException { assertEquals(shexc.getExitCode(), 0); assert(shexc.getOutput().contains("hello")); - symLinkFile = new File(tmpDir, badSymlink); + symLinkFile = new File(tmpDir, badSymlink); + } + finally { + // cleanup + if (shellFile != null + && shellFile.exists()) { + shellFile.delete(); + } + if (tempFile != null + && tempFile.exists()) { + tempFile.delete(); + } + if (symLinkFile != null + && symLinkFile.exists()) { + symLinkFile.delete(); + } + } + } + + @Test (timeout = 20000) + public void testInvalidSymlinkDiagnostics() throws IOException { + + File shellFile = null; + File tempFile = null; + String symLink = Shell.WINDOWS ? "test.cmd" : + "test"; + File symLinkFile = null; + + try { + shellFile = Shell.appendScriptExtension(tmpDir, "hello"); + tempFile = Shell.appendScriptExtension(tmpDir, "temp"); + String timeoutCommand = Shell.WINDOWS ? "@echo \"hello\"" : + "echo \"hello\""; + PrintWriter writer = new PrintWriter(new FileOutputStream(shellFile)); + FileUtil.setExecutable(shellFile, true); + writer.println(timeoutCommand); + writer.close(); + + Map> resources = + new HashMap>(); + //This is a invalid path, should throw exception:"No such file or directory" + Path invalidPath = new Path(shellFile.getAbsolutePath()+"randomPath"); + resources.put(invalidPath, Arrays.asList(symLink)); + FileOutputStream fos = new FileOutputStream(tempFile); + + Map env = new HashMap(); + List commands = new ArrayList(); + if (Shell.WINDOWS) { + commands.add("cmd"); + commands.add("/c"); + commands.add("\"" + symLink + "\""); + } else { + commands.add("/bin/sh ./\\\"" + symLink + "\\\""); + } + ContainerLaunch.writeLaunchEnv(fos, env, resources, commands); + fos.flush(); + fos.close(); + FileUtil.setExecutable(tempFile, true); + + Shell.ShellCommandExecutor shexc + = new Shell.ShellCommandExecutor(new String[]{tempFile.getAbsolutePath()}, tmpDir); + boolean catchException = false; + try { + shexc.execute(); + } catch(ExitCodeException e){ + catchException = true; + Assert.assertTrue(e.getMessage().contains("No such file or directory")); + } + Assert.assertTrue(catchException); + Assert.assertFalse(shexc.getExitCode() == 0); + + symLinkFile = new File(tmpDir, symLink); } finally { // cleanup