This is an automated email from the ASF dual-hosted git repository.

abhishek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new df4894a  Fallback to /sys/fs root when looking for cgroups (#11810)
df4894a is described below

commit df4894afff5efb31264e98f39f4f14dd934ecc3d
Author: Arun Ramani <[email protected]>
AuthorDate: Wed Oct 20 21:21:16 2021 -0700

    Fallback to /sys/fs root when looking for cgroups (#11810)
    
    ProcCgroupDiscoverer builds the cgroup directory by concatenating the proc 
mounts and proc cgroup paths together. This doesn't seem to work in Kubernetes 
if the execution context is within the container. Also this isn't consistent 
across all Linux OSes. The fix is to fallback to / as the root and it seems to 
work empirically.
---
 .../util/metrics/cgroups/ProcCgroupDiscoverer.java | 27 ++++++++++++++++++-
 .../metrics/cgroups/ProcCgroupDiscovererTest.java  | 30 ++++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)

diff --git 
a/core/src/main/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscoverer.java
 
b/core/src/main/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscoverer.java
index bb532ba..575716a 100644
--- 
a/core/src/main/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscoverer.java
+++ 
b/core/src/main/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscoverer.java
@@ -54,6 +54,22 @@ public class ProcCgroupDiscoverer implements CgroupDiscoverer
     Preconditions.checkArgument(this.procDir.isDirectory(), "Not a directory: 
[%s]", procDir);
   }
 
+  /**
+   * Gets the path in the virtual FS for the given cgroup (cpu, mem, etc.).
+   *
+   * The method first retrieves 2 paths:
+   *  - The cgroup virtual FS mount point by calling /proc/mounts. This is 
usually like '/sys/fs/cgroup/cpu'.
+   *  - The heirarchy path by calling /proc/[pid]/cgroup. In Docker this can 
look like 
'/docker/4b053f1267369a19dcdcb293e1b4d6b71fd0f26bf7711d589f19d48af92e6278'
+   *
+   * The method then tries to find the final virtual FS path by contenating 
the 2 paths first, and then falling back
+   * to the root virtual FS path. In this example, the method tries
+   * 
'/sys/fs/cgroup/cpu/docker/4b053f1267369a19dcdcb293e1b4d6b71fd0f26bf7711d589f19d48af92e6278'
 and then falls back
+   * to '/sys/fs/cgroup/cpu'.
+   *
+   * An exception is thrown if neither path exists.
+   * @param cgroup The cgroup.
+   * @return the virtual FS path.
+   */
   @Override
   public Path discover(final String cgroup)
   {
@@ -62,6 +78,7 @@ public class ProcCgroupDiscoverer implements CgroupDiscoverer
     final File pidCgroups = new File(procDir, "cgroup");
     final PidCgroupEntry pidCgroupsEntry = getCgroupEntry(pidCgroups, cgroup);
     final ProcMountsEntry procMountsEntry = getMountEntry(procMounts, cgroup);
+
     final File cgroupDir = new File(
         procMountsEntry.path.toString(),
         pidCgroupsEntry.path.toString()
@@ -69,7 +86,15 @@ public class ProcCgroupDiscoverer implements CgroupDiscoverer
     if (cgroupDir.exists() && cgroupDir.isDirectory()) {
       return cgroupDir.toPath();
     }
-    throw new RE("Invalid cgroup directory [%s]", cgroupDir);
+
+    // Check the root /sys/fs directory if there isn't a cgroup path specific 
one
+    // This happens with certain OSes
+    final File fallbackCgroupDir = procMountsEntry.path.toFile();
+    if (fallbackCgroupDir.exists() && fallbackCgroupDir.isDirectory()) {
+      return fallbackCgroupDir.toPath();
+    }
+
+    throw new RE("No cgroup directory located at [%s] or [%s]", cgroupDir, 
fallbackCgroupDir);
   }
 
   private PidCgroupEntry getCgroupEntry(final File procCgroup, final String 
cgroup)
diff --git 
a/core/src/test/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscovererTest.java
 
b/core/src/test/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscovererTest.java
index a133e18..c796dc6 100644
--- 
a/core/src/test/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscovererTest.java
+++ 
b/core/src/test/java/org/apache/druid/java/util/metrics/cgroups/ProcCgroupDiscovererTest.java
@@ -20,6 +20,7 @@
 package org.apache.druid.java.util.metrics.cgroups;
 
 import com.google.common.collect.ImmutableSet;
+import org.apache.druid.java.util.common.FileUtils;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -88,4 +89,33 @@ public class ProcCgroupDiscovererTest
     expectedException.expect(NullPointerException.class);
     Assert.assertNull(new 
ProcCgroupDiscoverer(procDir.toPath()).discover(null));
   }
+
+  @Test
+  public void testFallBack() throws Exception
+  {
+    TemporaryFolder temporaryFolder = new TemporaryFolder();
+    temporaryFolder.create();
+    File cgroupDir = temporaryFolder.newFolder();
+    File procDir = temporaryFolder.newFolder();
+    TestUtils.setUpCgroups(procDir, cgroupDir);
+
+    // Swap out the cgroup path with a default path
+    FileUtils.deleteDirectory(new File(
+        cgroupDir,
+        "cpu,cpuacct/"
+    ));
+
+    Assert.assertTrue(new File(
+        cgroupDir,
+        "cpu,cpuacct/"
+    ).mkdir());
+
+    Assert.assertEquals(
+        new File(
+            cgroupDir,
+            "cpu,cpuacct"
+        ).toPath(),
+        new ProcCgroupDiscoverer(procDir.toPath()).discover("cpu")
+    );
+  }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to