diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java index 5466182b715d4..4b19db8427514 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/launcher/ContainerLaunch.java @@ -1308,7 +1308,7 @@ public UnixShellScriptBuilder() { @Override public void command(List command) { - line("exec /bin/bash -c \"", StringUtils.join(" ", command), "\""); + line("exec /bin/bash -c \"exec ", StringUtils.join(" ", command), "\""); } @Override diff --git a/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 b/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 467381749c26e..60b9523e91550 100644 --- a/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 +++ b/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 @@ -46,6 +46,7 @@ import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; +import java.io.InputStreamReader; import java.io.PrintStream; import java.io.PrintWriter; import java.nio.ByteBuffer; @@ -1477,6 +1478,76 @@ public void testImmediateKill() throws Exception { internalKillTest(false); } + @Test + @Timeout(value = 30) + public void testNoBashParentProcess() throws Exception { + assumeNotWindows(); + containerManager.start(); + + // Construct the Container-id + ApplicationId appId = ApplicationId.newInstance(1, 1); + ApplicationAttemptId appAttemptId = + ApplicationAttemptId.newInstance(appId, 1); + ContainerId cId = ContainerId.newContainerId(appAttemptId, 0); + + ContainerLaunchContext containerLaunchContext = + recordFactory.newRecordInstance(ContainerLaunchContext.class); + + // set up the rest of the container + List commands = Arrays.asList(new String[] {"sleep 30 1>/dev/null 2>/dev/null"}); + containerLaunchContext.setCommands(commands); + Priority priority = Priority.newInstance(10); + long createTime = 1234; + Token containerToken = createContainerToken(cId, priority, createTime); + + StartContainerRequest scRequest = + StartContainerRequest.newInstance(containerLaunchContext, + containerToken); + List list = new ArrayList(); + list.add(scRequest); + StartContainersRequest allRequests = + StartContainersRequest.newInstance(list); + containerManager.startContainers(allRequests); + + NMContainerStatus nmContainerStatus = + containerManager.getContext().getContainers().get(cId) + .getNMContainerStatus(); + assertEquals(priority, nmContainerStatus.getPriority()); + + int timeoutSecs = 0; + String pid = containerManager.getContext().getContainerExecutor().getProcessId(cId); + while (pid == null && timeoutSecs++ < 20) { + Thread.sleep(1000); + pid = containerManager.getContext().getContainerExecutor().getProcessId(cId); + LOG.info("Waiting for process start-file to be created"); + } + assertNotNull(pid); + + Process proc = Runtime.getRuntime().exec(new String[] {"ps", "-o", "command=", pid}); + assertEquals(proc.waitFor(), 0); + BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream())); + + assertEquals(reader.readLine(), "sleep 30"); + + List containerIds = new ArrayList(); + containerIds.add(cId); + StopContainersRequest stopRequest = + StopContainersRequest.newInstance(containerIds); + containerManager.stopContainers(stopRequest); + + BaseContainerManagerTest.waitForContainerState(containerManager, cId, + ContainerState.COMPLETE); + + GetContainerStatusesRequest gcsRequest = + GetContainerStatusesRequest.newInstance(containerIds); + + ContainerStatus containerStatus = + containerManager.getContainerStatuses(gcsRequest) + .getContainerStatuses().get(0); + assertEquals(ContainerExitStatus.KILLED_BY_APPMASTER, + containerStatus.getExitStatus()); + } + @SuppressWarnings("rawtypes") @Test @Timeout(value = 10)