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]