selftests/bpf: Add a new cgroup helper get_cgroup_hierarchy_id()
authorYafang Shao <laoar.shao@gmail.com>
Sat, 11 Nov 2023 09:00:33 +0000 (09:00 +0000)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 14 Nov 2023 16:56:56 +0000 (08:56 -0800)
A new cgroup helper function, get_cgroup1_hierarchy_id(), has been
introduced to obtain the ID of a cgroup1 hierarchy based on the provided
cgroup name. This cgroup name can be obtained from the /proc/self/cgroup
file.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Link: https://lore.kernel.org/r/20231111090034.4248-6-laoar.shao@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/cgroup_helpers.c
tools/testing/selftests/bpf/cgroup_helpers.h

index 63bfa72..5aa133b 100644 (file)
@@ -637,3 +637,55 @@ unsigned long long get_classid_cgroup_id(void)
        format_classid_path(cgroup_workdir);
        return get_cgroup_id_from_path(cgroup_workdir);
 }
+
+/**
+ * get_cgroup1_hierarchy_id - Retrieves the ID of a cgroup1 hierarchy from the cgroup1 subsys name.
+ * @subsys_name: The cgroup1 subsys name, which can be retrieved from /proc/self/cgroup. It can be
+ * a named cgroup like "name=systemd", a controller name like "net_cls", or multi-contollers like
+ * "net_cls,net_prio".
+ */
+int get_cgroup1_hierarchy_id(const char *subsys_name)
+{
+       char *c, *c2, *c3, *c4;
+       bool found = false;
+       char line[1024];
+       FILE *file;
+       int i, id;
+
+       if (!subsys_name)
+               return -1;
+
+       file = fopen("/proc/self/cgroup", "r");
+       if (!file) {
+               log_err("fopen /proc/self/cgroup");
+               return -1;
+       }
+
+       while (fgets(line, 1024, file)) {
+               i = 0;
+               for (c = strtok_r(line, ":", &c2); c && i < 2; c = strtok_r(NULL, ":", &c2)) {
+                       if (i == 0) {
+                               id = strtol(c, NULL, 10);
+                       } else if (i == 1) {
+                               if (!strcmp(c, subsys_name)) {
+                                       found = true;
+                                       break;
+                               }
+
+                               /* Multiple subsystems may share one single mount point */
+                               for (c3 = strtok_r(c, ",", &c4); c3;
+                                    c3 = strtok_r(NULL, ",", &c4)) {
+                                       if (!strcmp(c, subsys_name)) {
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       i++;
+               }
+               if (found)
+                       break;
+       }
+       fclose(file);
+       return found ? id : -1;
+}
index e71da4e..ee05364 100644 (file)
@@ -20,6 +20,7 @@ int get_root_cgroup(void);
 int create_and_get_cgroup(const char *relative_path);
 void remove_cgroup(const char *relative_path);
 unsigned long long get_cgroup_id(const char *relative_path);
+int get_cgroup1_hierarchy_id(const char *subsys_name);
 
 int join_cgroup(const char *relative_path);
 int join_root_cgroup(void);