Sfoglia il codice sorgente

Handle existence of cgroup version 2 hierarchy

When parsing the control groups to which the Elasticsearch process
belongs, we extract a map from subsystems to paths by parsing
/proc/self/cgroup. This file contains colon-delimited entries of the
form hierarchy-ID:subsystem-list:cgroup-path. For control group version
1 hierarchies, the subsystem-list is a comma-delimited list of the
subsystems for that hierarchy. For control group version 2 hierarchies
(which can only exist on Linux kernels since version 4.5), the
subsystem-list is an empty string. The previous parsing of
/proc/self/cgroup incorrectly accounted for this possibility (a +
instead of a * in a regular expression). This commit addresses this
issue, adds a test case that covers this possibility, and simplifies the
code that parses /proc/self/cgroup.

Relates #23493
Jason Tedor 8 anni fa
parent
commit
ae6331f27e

+ 14 - 11
core/src/main/java/org/elasticsearch/monitor/os/OsProbe.java

@@ -187,9 +187,6 @@ public class OsProbe {
         return lines.get(0);
     }
 
-    // pattern for lines in /proc/self/cgroup
-    private static final Pattern CONTROL_GROUP_PATTERN = Pattern.compile("\\d+:([^:]+):(/.*)");
-
     // this property is to support a hack to workaround an issue with Docker containers mounting the cgroups hierarchy inconsistently with
     // respect to /proc/self/cgroup; for Docker containers this should be set to "/"
     private static final String CONTROL_GROUPS_HIERARCHY_OVERRIDE = System.getProperty("es.cgroups.hierarchy.override");
@@ -205,23 +202,29 @@ public class OsProbe {
         final List<String> lines = readProcSelfCgroup();
         final Map<String, String> controllerMap = new HashMap<>();
         for (final String line : lines) {
-            final Matcher matcher = CONTROL_GROUP_PATTERN.matcher(line);
-            // Matcher#matches must be invoked as matching is lazy; this can not happen in an assert as assertions might not be enabled
-            final boolean matches = matcher.matches();
-            assert matches : line;
-            // at this point we have captured the subsystems and the control group
-            final String[] controllers = matcher.group(1).split(",");
+            /*
+             * The virtual file /proc/self/cgroup lists the control groups that the Elasticsearch process is a member of. Each line contains
+             * three colon-separated fields of the form hierarchy-ID:subsystem-list:cgroup-path. For cgroups version 1 hierarchies, the
+             * subsystem-list is a comma-separated list of subsystems. The subsystem-list can be empty if the hierarchy represents a cgroups
+             * version 2 hierarchy. For cgroups version 1
+             */
+            final String[] fields = line.split(":");
+            assert fields.length == 3;
+            final String[] controllers = fields[1].split(",");
             for (final String controller : controllers) {
+                final String controlGroupPath;
                 if (CONTROL_GROUPS_HIERARCHY_OVERRIDE != null) {
                     /*
                      * Docker violates the relationship between /proc/self/cgroup and the /sys/fs/cgroup hierarchy. It's possible that this
                      * will be fixed in future versions of Docker with cgroup namespaces, but this requires modern kernels. Thus, we provide
                      * an undocumented hack for overriding the control group path. Do not rely on this hack, it will be removed.
                      */
-                    controllerMap.put(controller, CONTROL_GROUPS_HIERARCHY_OVERRIDE);
+                    controlGroupPath = CONTROL_GROUPS_HIERARCHY_OVERRIDE;
                 } else {
-                    controllerMap.put(controller, matcher.group(2));
+                    controlGroupPath = fields[2];
                 }
+                final String previous = controllerMap.put(controller, controlGroupPath);
+                assert previous == null;
             }
         }
         return controllerMap;

+ 11 - 10
core/src/test/java/org/elasticsearch/monitor/os/OsProbeTests.java

@@ -155,16 +155,17 @@ public class OsProbeTests extends ESTestCase {
             @Override
             List<String> readProcSelfCgroup() {
                 return Arrays.asList(
-                    "10:freezer:/",
-                    "9:net_cls,net_prio:/",
-                    "8:pids:/",
-                    "7:blkio:/",
-                    "6:memory:/",
-                    "5:devices:/user.slice",
-                    "4:hugetlb:/",
-                    "3:perf_event:/",
-                    "2:cpu,cpuacct,cpuset:/" + hierarchy,
-                    "1:name=systemd:/user.slice/user-1000.slice/session-2359.scope");
+                        "10:freezer:/",
+                        "9:net_cls,net_prio:/",
+                        "8:pids:/",
+                        "7:blkio:/",
+                        "6:memory:/",
+                        "5:devices:/user.slice",
+                        "4:hugetlb:/",
+                        "3:perf_event:/",
+                        "2:cpu,cpuacct,cpuset:/" + hierarchy,
+                        "1:name=systemd:/user.slice/user-1000.slice/session-2359.scope",
+                        "0::/cgroup2");
             }
 
             @Override