Browse Source

YARN-6500. Do not mount inaccessible cgroups directories in CgroupsLCEResourcesHandler. (Miklos Szegedi via Haibo Chen)

Haibo Chen 8 years ago
parent
commit
8ac50e1322

+ 2 - 1
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/CGroupsHandlerImpl.java

@@ -232,7 +232,8 @@ class CGroupsHandlerImpl implements CGroupsHandler {
    * @param entries map of paths to mount options
    * @param entries map of paths to mount options
    * @return the first mount path that has the requested subsystem
    * @return the first mount path that has the requested subsystem
    */
    */
-  private static String findControllerInMtab(String controller,
+  @VisibleForTesting
+  static String findControllerInMtab(String controller,
       Map<String, List<String>> entries) {
       Map<String, List<String>> entries) {
     for (Map.Entry<String, List<String>> e : entries.entrySet()) {
     for (Map.Entry<String, List<String>> e : entries.entrySet()) {
       if (e.getValue().contains(controller)) {
       if (e.getValue().contains(controller)) {

+ 10 - 3
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/util/CgroupsLCEResourcesHandler.java

@@ -428,11 +428,18 @@ public class CgroupsLCEResourcesHandler implements LCEResourcesHandler {
     return ret;
     return ret;
   }
   }
 
 
-  private String findControllerInMtab(String controller,
+  @VisibleForTesting
+  String findControllerInMtab(String controller,
                                       Map<String, List<String>> entries) {
                                       Map<String, List<String>> entries) {
     for (Entry<String, List<String>> e : entries.entrySet()) {
     for (Entry<String, List<String>> e : entries.entrySet()) {
-      if (e.getValue().contains(controller))
-        return e.getKey();
+      if (e.getValue().contains(controller)) {
+        if (new File(e.getKey()).canRead()) {
+          return e.getKey();
+        } else {
+          LOG.warn(String.format(
+              "Skipping inaccessible cgroup mount point %s", e.getKey()));
+        }
+      }
     }
     }
 
 
     return null;
     return null;

+ 32 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/linux/resources/TestCGroupsHandlerImpl.java

@@ -40,6 +40,9 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Files;
 import java.security.Permission;
 import java.security.Permission;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.UUID;
 import java.util.UUID;
 
 
@@ -432,6 +435,35 @@ public class TestCGroupsHandlerImpl {
     }
     }
   }
   }
 
 
+  @Test
+  public void testSelectCgroup() throws Exception {
+    File cpu = new File(tmpPath, "cpu");
+    File cpuNoExist = new File(tmpPath, "cpuNoExist");
+    File memory = new File(tmpPath, "memory");
+    try {
+      CGroupsHandlerImpl handler = new CGroupsHandlerImpl(
+          conf,
+          privilegedOperationExecutorMock);
+      Map<String, List<String>> cgroups = new LinkedHashMap<>();
+
+      Assert.assertTrue("temp dir should be created", cpu.mkdirs());
+      Assert.assertTrue("temp dir should be created", memory.mkdirs());
+      Assert.assertFalse("temp dir should not be created", cpuNoExist.exists());
+
+      cgroups.put(
+          memory.getAbsolutePath(), Collections.singletonList("memory"));
+      cgroups.put(
+          cpuNoExist.getAbsolutePath(), Collections.singletonList("cpu"));
+      cgroups.put(cpu.getAbsolutePath(), Collections.singletonList("cpu"));
+      String selectedCPU = handler.findControllerInMtab("cpu", cgroups);
+      Assert.assertEquals("Wrong CPU mount point selected",
+          cpu.getAbsolutePath(), selectedCPU);
+    } finally {
+      FileUtils.deleteQuietly(cpu);
+      FileUtils.deleteQuietly(memory);
+    }
+  }
+
   @After
   @After
   public void teardown() {
   public void teardown() {
     FileUtil.fullyDelete(new File(tmpPath));
     FileUtil.fullyDelete(new File(tmpPath));

+ 29 - 0
hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/util/TestCgroupsLCEResourcesHandler.java

@@ -33,7 +33,10 @@ import org.junit.Before;
 import org.mockito.Mockito;
 import org.mockito.Mockito;
 
 
 import java.io.*;
 import java.io.*;
+import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 import java.util.Scanner;
 import java.util.Scanner;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.CountDownLatch;
 
 
@@ -342,4 +345,30 @@ public class TestCgroupsLCEResourcesHandler {
     FileUtils.deleteQuietly(cgroupDir);
     FileUtils.deleteQuietly(cgroupDir);
   }
   }
 
 
+  @Test
+  public void testSelectCgroup() {
+    File cpu = new File(cgroupDir, "cpu");
+    File cpuNoExist = new File(cgroupDir, "cpuNoExist");
+    File memory = new File(cgroupDir, "memory");
+    try {
+      CgroupsLCEResourcesHandler handler = new CgroupsLCEResourcesHandler();
+      Map<String, List<String>> cgroups = new LinkedHashMap<>();
+
+      Assert.assertTrue("temp dir should be created", cpu.mkdirs());
+      Assert.assertTrue("temp dir should be created", memory.mkdirs());
+      Assert.assertFalse("temp dir should not be created", cpuNoExist.exists());
+
+      cgroups.put(
+          memory.getAbsolutePath(), Collections.singletonList("memory"));
+      cgroups.put(
+          cpuNoExist.getAbsolutePath(), Collections.singletonList("cpu"));
+      cgroups.put(cpu.getAbsolutePath(), Collections.singletonList("cpu"));
+      String selectedCPU = handler.findControllerInMtab("cpu", cgroups);
+      Assert.assertEquals("Wrong CPU mount point selected",
+          cpu.getAbsolutePath(), selectedCPU);
+    } finally {
+      FileUtils.deleteQuietly(cpu);
+      FileUtils.deleteQuietly(memory);
+    }
+  }
 }
 }