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..6b3e75b 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,11 @@ 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); + LOG.warn("Exception from container-launch with container ID: " + + containerId + " and exit code: " + exitCode , e); + logOutput(e.getMessage()); container.handle(new ContainerDiagnosticsUpdateEvent(containerId, - message)); + e.getMessage())); 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..ad4e438 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); } } @@ -267,10 +267,11 @@ public int launchContainer(Container container, // container-executor's output if (exitCode != ExitCode.FORCE_KILLED.getExitCode() && exitCode != ExitCode.TERMINATED.getExitCode()) { - LOG.warn("Exception from container-launch : ", e); - logOutput(shExec.getOutput()); + LOG.warn("Exception from container-launch with container ID: " + + containerId + " and exit code: " + exitCode , e); + 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 +310,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 +351,7 @@ 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()); + logOutput(e.getMessage()); } } } @@ -372,7 +373,7 @@ public void mountCgroups(List cgroupKVs, String hierarchy) shExec.execute(); } catch (IOException e) { int ret_code = shExec.getExitCode(); - logOutput(shExec.getOutput()); + logOutput(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..7789469 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,79 @@ 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 an invalid path and should throw exception because of No such file. + 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; + String message = null; + try { + shexc.execute(); + } catch(ExitCodeException e){ + catchException = true; + message = e.getMessage(); + } + Assert.assertTrue(catchException); + Assert.assertNotNull(message); + Assert.assertTrue(shexc.getExitCode() != 0); + symLinkFile = new File(tmpDir, symLink); } finally { // cleanup diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/MiniYARNCluster.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/MiniYARNCluster.java index cc52973..bdc88ee 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/MiniYARNCluster.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/MiniYARNCluster.java @@ -32,6 +32,7 @@ import org.apache.hadoop.service.AbstractService; import org.apache.hadoop.service.CompositeService; import org.apache.hadoop.util.Shell; +import org.apache.hadoop.util.Shell.ExitCodeException; import org.apache.hadoop.util.Shell.ShellCommandExecutor; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.event.Dispatcher; @@ -39,7 +40,6 @@ import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; -import org.apache.hadoop.yarn.ipc.RPCUtil; import org.apache.hadoop.yarn.server.api.ResourceTracker; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.NodeHeartbeatResponse; @@ -122,7 +122,7 @@ public MiniYARNCluster(String testName, int noOfNodeManagers, } catch (IOException e) { throw new YarnRuntimeException(String.format( "failed to create symlink from %s to %s, shell output: %s", linkPath, - targetPath, shexec.getOutput()), e); + targetPath, e.getMessage()), e); } this.testWorkDir = link;