Repository: hadoop Updated Branches: refs/heads/branch-3.1 fbedf8937 -> 5237bdfb5
YARN-8667. Cleanup symlinks when container restarted by NM. Contributed by Chandni Singh (cherry picked from commit d42806160eb95594f08f38bb753cf0306a191a38) Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/5237bdfb Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/5237bdfb Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/5237bdfb Branch: refs/heads/branch-3.1 Commit: 5237bdfb5a02638dd1a7207ed7f500910d97047f Parents: fbedf89 Author: Eric Yang <ey...@apache.org> Authored: Thu Aug 16 18:41:58 2018 -0400 Committer: Eric Yang <ey...@apache.org> Committed: Thu Aug 16 18:44:47 2018 -0400 ---------------------------------------------------------------------- .../server/nodemanager/ContainerExecutor.java | 62 +++++++++++++++----- .../launcher/ContainerLaunch.java | 7 +++ .../nodemanager/TestContainerExecutor.java | 31 +++++++++- 3 files changed, 85 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/5237bdfb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java index 8e335350..9714731 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/ContainerExecutor.java @@ -26,6 +26,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.LinkedHashSet; import java.util.Map; @@ -34,6 +35,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -415,20 +417,9 @@ public abstract class ContainerExecutor implements Configurable { if (resources != null) { sb.echo("Setting up job resources"); - for (Map.Entry<Path, List<String>> resourceEntry : - resources.entrySet()) { - for (String linkName : resourceEntry.getValue()) { - if (new Path(linkName).getName().equals(WILDCARD)) { - // If this is a wildcarded path, link to everything in the - // directory from the working directory - for (File wildLink : readDirAsUser(user, resourceEntry.getKey())) { - sb.symlink(new Path(wildLink.toString()), - new Path(wildLink.getName())); - } - } else { - sb.symlink(resourceEntry.getKey(), new Path(linkName)); - } - } + Map<Path, Path> symLinks = resolveSymLinks(resources, user); + for (Map.Entry<Path, Path> symLink : symLinks.entrySet()) { + sb.symlink(symLink.getKey(), symLink.getValue()); } } @@ -790,6 +781,28 @@ public abstract class ContainerExecutor implements Configurable { } /** + * Perform any cleanup before the next launch of the container. + * @param container container + */ + public void cleanupBeforeRelaunch(Container container) + throws IOException, InterruptedException { + if (container.getLocalizedResources() != null) { + + Map<Path, Path> symLinks = resolveSymLinks( + container.getLocalizedResources(), container.getUser()); + + for (Map.Entry<Path, Path> symLink : symLinks.entrySet()) { + LOG.debug("{} deleting {}", container.getContainerId(), + symLink.getValue()); + deleteAsUser(new DeletionAsUserContext.Builder() + .setUser(container.getUser()) + .setSubDir(symLink.getValue()) + .build()); + } + } + } + + /** * Get the process-identifier for the container. * * @param containerID the container ID @@ -868,4 +881,25 @@ public abstract class ContainerExecutor implements Configurable { } } } + + private Map<Path, Path> resolveSymLinks(Map<Path, + List<String>> resources, String user) { + Map<Path, Path> symLinks = new HashMap<>(); + for (Map.Entry<Path, List<String>> resourceEntry : + resources.entrySet()) { + for (String linkName : resourceEntry.getValue()) { + if (new Path(linkName).getName().equals(WILDCARD)) { + // If this is a wildcarded path, link to everything in the + // directory from the working directory + for (File wildLink : readDirAsUser(user, resourceEntry.getKey())) { + symLinks.put(new Path(wildLink.toString()), + new Path(wildLink.getName())); + } + } else { + symLinks.put(resourceEntry.getKey(), new Path(linkName)); + } + } + } + return symLinks; + } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/5237bdfb/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 ---------------------------------------------------------------------- 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 eb25ff2..9379cfb 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 @@ -1874,6 +1874,13 @@ public class ContainerLaunch implements Callable<Integer> { deleteAsUser(new Path(containerWorkDir, CONTAINER_SCRIPT)); // delete TokensPath deleteAsUser(new Path(containerWorkDir, FINAL_CONTAINER_TOKENS_FILE)); + + // delete symlinks because launch script will create symlinks again + try { + exec.cleanupBeforeRelaunch(container); + } catch (IOException | InterruptedException e) { + LOG.warn("{} exec failed to cleanup", container.getContainerId(), e); + } } private void deleteAsUser(Path path) { http://git-wip-us.apache.org/repos/asf/hadoop/blob/5237bdfb/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerExecutor.java ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerExecutor.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerExecutor.java index 3bcdc87..2890bb5 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerExecutor.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/TestContainerExecutor.java @@ -18,9 +18,17 @@ package org.apache.hadoop.yarn.server.nodemanager; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.google.common.collect.Lists; +import org.apache.commons.io.FileUtils; import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.Path; import org.apache.hadoop.util.Shell; import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -28,13 +36,13 @@ import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container; import org.apache.hadoop.yarn.server.nodemanager.executor.ContainerReapContext; import org.apache.hadoop.yarn.server.nodemanager.util.NodeManagerHardwareUtils; -import org.apache.hadoop.yarn.util.ResourceCalculatorPlugin; import org.junit.Assert; import org.junit.Test; import static org.apache.hadoop.test.PlatformAssumptions.assumeWindows; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @SuppressWarnings("deprecation") public class TestContainerExecutor { @@ -168,4 +176,25 @@ public class TestContainerExecutor { builder.setContainer(container).setUser("foo"); assertTrue(containerExecutor.reapContainer(builder.build())); } + + @Test + public void testCleanupBeforeLaunch() throws Exception { + Container container = mock(Container.class); + java.nio.file.Path linkName = Paths.get("target/linkName"); + java.nio.file.Path target = Paths.get("target"); + //deletes the link if it already exists because of previous test failures + FileUtils.deleteQuietly(linkName.toFile()); + Files.createSymbolicLink(linkName.toAbsolutePath(), + target.toAbsolutePath()); + + Map<Path, List<String>> localResources = new HashMap<>(); + localResources.put(new Path(target.toFile().getAbsolutePath()), + Lists.newArrayList(linkName.toFile().getAbsolutePath())); + + when(container.getLocalizedResources()) + .thenReturn(localResources); + when(container.getUser()).thenReturn(System.getProperty("user.name")); + containerExecutor.cleanupBeforeRelaunch(container); + Assert.assertTrue(!Files.exists(linkName)); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org