]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
tools/cgget: add support for default systemd delegation slice/scope
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Fri, 10 Feb 2023 21:48:14 +0000 (14:48 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Fri, 10 Feb 2023 21:48:18 +0000 (14:48 -0700)
Enhance the cgget tool to support default systemd delegation
slice/scope, if set in the cgconfig.conf's systemd setting.
Parse the configuration file and read the systemd::delegate setting,
if any, and set it as the default systemd slice/scope in
systemd_default_cgroup. Setting it appends the slice/scope name to
the constructed default cgroup mount path.

When the user passes the relative cgroup name, its appends to the
sub-tree (delegated slice/scope) by default and if the user wishes to get
details about the cgroups in another subtree or cgroup root hierarchy,
they need to use the absolute path. For example:
  cgroup_root
 /     \
/      \
 systemd.slice[1]      cgrp1
|
 systemd.scope
|
    cgrp-d1

[1] default systemd delegation slice/scope - read from cgconfig.conf

$ sudo cgget -g cpu:cgrp-d1

will display the CPU controller information under the
cgroup_root:systemd_default_cgroup:cgrp-d1

and for viewing the CPU controller information of cgrp1, the user can
use:
$ sudo cgget -g cpu:/cgrp1

or use the newly introduced -b switch to ignore the systemd slice/scope:
$ sudo cgget -b -g cpu:cgrp

Signed-off-by: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
TJH: Fix minor typo in a comment where delegate was written instead
     of setdefault
(cherry picked from commit aa9c756add6f1ca9b61cb54ce1334d6b0be745b9)

src/tools/cgget.c

index 545288465c16a37735124d5ee5de0a4fde2feed1..b35d35450313729484cd03709af7433383958e82 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <libgen.h>
 #include <stdio.h>
 
 #define MODE_SHOW_HEADERS      1
 #define MODE_SHOW_NAMES                2
+#define MODE_SYSTEMD_DELEGATE  4
 
 #define LL_MAX                 100
 
@@ -44,6 +46,9 @@ static void usage(int status, const char *program_name)
        info("  -v, --values-only               Print only values, not ");
        info("parameter names\n");
        info("  -m                              Display the cgroup mode\n");
+#ifdef WITH_SYSTEMD
+       info("  -b                              Ignore default systemd delegate hierarchy\n");
+#endif
 }
 
 static int get_controller_from_name(const char * const name, char **controller)
@@ -398,8 +403,16 @@ static int parse_opts(int argc, char *argv[], struct cgroup **cg_list[], int * c
        int c;
 
        /* Parse arguments. */
+#ifdef WITH_SYSTEMD
+       while ((c = getopt_long(argc, argv, "r:hnvg:amb", long_options, NULL)) > 0) {
+               switch (c) {
+               case 'b':
+                       *mode = (*mode) & (INT_MAX ^ MODE_SYSTEMD_DELEGATE);
+                       break;
+#else
        while ((c = getopt_long(argc, argv, "r:hnvg:am", long_options, NULL)) > 0) {
                switch (c) {
+#endif
                case 'h':
                        usage(0, argv[0]);
                        exit(0);
@@ -563,7 +576,10 @@ static int fill_empty_controller(struct cgroup * const cg, struct cgroup_control
        struct dirent *ctrl_dir = NULL;
        bool found_mount = false;
        int i, path_len, ret = 0;
-       char path[FILENAME_MAX];
+       char path[FILENAME_MAX] = { '\0' };
+#ifdef WITH_SYSTEMD
+       char tmp[FILENAME_MAX] = { '\0' };
+#endif
        DIR *dir = NULL;
 
        pthread_rwlock_rdlock(&cg_mount_table_lock);
@@ -583,6 +599,35 @@ static int fill_empty_controller(struct cgroup * const cg, struct cgroup_control
                goto out;
 
        path_len = strlen(path);
+#ifdef WITH_SYSTEMD
+       /*
+        * If the user has set a slice/scope as setdefault in the
+        * cgconfig.conf file, every path constructed will have the
+        * systemd_default_cgroup slice/scope suffixed to it.
+        *
+        * We need to trim the slice/scope from the path, incase of
+        * user providing /<cgroup-name> as the cgroup name in the command
+        * line:
+        * cgget -g cpu:/foo
+        */
+       if (cg->name[0] == '/' && cg->name[1] != '\0' &&
+           strncmp(path + (path_len - 7), ".scope/", 7) == 0) {
+               snprintf(tmp, FILENAME_MAX, "%s", dirname(path));
+               strncpy(path, tmp, FILENAME_MAX - 1);
+               path[FILENAME_MAX - 1] = '\0';
+
+               path_len = strlen(path);
+               if (strncmp(path + (path_len - 6), ".slice", 6) == 0) {
+                       snprintf(tmp, FILENAME_MAX, "%s", dirname(path));
+                       strncpy(path, tmp, FILENAME_MAX - 1);
+                       path[FILENAME_MAX - 1] = '\0';
+               } else {
+                       cgroup_dbg("Malformed path %s (expected slice name)\n", path);
+                       ret = ECGOTHER;
+                       goto out;
+               }
+       }
+#endif
        strncat(path, cg->name, FILENAME_MAX - path_len - 1);
        path[sizeof(path) - 1] = '\0';
 
@@ -725,7 +770,7 @@ static void print_cgroups(struct cgroup *cg_list[], int cg_list_len, int mode)
 
 int main(int argc, char *argv[])
 {
-       int mode = MODE_SHOW_NAMES | MODE_SHOW_HEADERS;
+       int mode = MODE_SHOW_NAMES | MODE_SHOW_HEADERS | MODE_SYSTEMD_DELEGATE;
        struct cgroup **cg_list = NULL;
        int cg_list_len = 0;
        int ret = 0, i;
@@ -746,6 +791,10 @@ int main(int argc, char *argv[])
        if (ret)
                goto err;
 
+       /* this is false always for disable-systemd */
+       if (mode & MODE_SYSTEMD_DELEGATE)
+               cgroup_set_default_systemd_cgroup();
+
        ret = get_values(cg_list, cg_list_len);
        if (ret)
                goto err;