Add support to get the current cgroup(s) of a running process.
Works with both cgroup v1 and cgroup v2.

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 ftests/process.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/ftests/process.py b/ftests/process.py
index 5e07bbf65402..6de43a019cc9 100644
--- a/ftests/process.py
+++ b/ftests/process.py
@@ -20,6 +20,7 @@
 #
 
 from cgroup import Cgroup
+from cgroup import CgroupVersion
 import multiprocessing as mp
 from run import Run
 from run import RunError
@@ -105,3 +106,81 @@ class Process(object):
                 # ignore any errors during the kill command.  this is belt
                 # and suspenders code
                 pass
+
+    @staticmethod
+    def __get_cgroup_v1(config, pid, controller):
+        cmd = list()
+
+        cmd.append('cat')
+        cmd.append('/proc/{}/cgroup'.format(pid))
+
+        if config.args.container:
+            ret = config.container.run(cmd)
+        else:
+            ret = Run.run(cmd).decode('ascii')
+
+        for line in ret.splitlines():
+            # cgroup v1 appears in /proc/{pid}/cgroup like the following:
+            # $ cat /proc/1/cgroup
+            # 12:memory:/
+            # 11:hugetlb:/
+            # 10:perf_event:/
+            # 9:rdma:/
+            # 8:devices:/
+            # 7:cpuset:/
+            # 6:blkio:/
+            # 5:cpu,cpuacct:/
+            # 4:pids:/
+            # 3:freezer:/
+            # 2:net_cls,net_prio:/
+            # 1:name=systemd:/init.scope
+            # 0::/init.scope
+            proc_controllers = line.split(':')[1]
+            if proc_controllers.find(',') >= 0:
+                for proc_controller in proc_controllers.split(','):
+                    if controller == proc_controller:
+                        return line.split(':')[2]
+            else:
+                if controller == proc_controllers:
+                    return line.split(':')[2]
+
+        raise ValueError("Could not get cgroup for pid {} and controller {}".
+                         format(pid, controller))
+
+    @staticmethod
+    def __get_cgroup_v2(config, pid, controller):
+        cmd = list()
+
+        cmd.append('cat')
+        cmd.append('/proc/{}/cgroup'.format(pid))
+
+        if config.args.container:
+            ret = config.container.run(cmd)
+        else:
+            ret = Run.run(cmd).decode('ascii')
+
+        for line in ret.splitlines():
+            # cgroup v2 appears in /proc/{pid}/cgroup like the following:
+            # $ cat /proc/1/cgroup
+            # 0::/init.scope
+            if line.find('::') < 0:
+                # we have identified this controller is cgroup v2,
+                # ignore any cgroup v1 controllers
+                continue
+
+            return line.split(':')[2]
+
+        raise ValueError("Could not get cgroup for pid {} and controller {}".
+                         format(pid, controller))
+
+    # given a PID and a cgroup controller, what cgroup is this PID a member of
+    @staticmethod
+    def get_cgroup(config, pid, controller):
+        version = CgroupVersion.get_version(controller)
+
+        if version == CgroupVersion.CGROUP_V1:
+            return Process.__get_cgroup_v1(config, pid, controller)
+        elif version == CgroupVersion.CGROUP_V2:
+            return Process.__get_cgroup_v2(config, pid, controller)
+
+        raise ValueError("get_cgroup() shouldn't reach this point")
-- 
2.26.2



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to