]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
tools/cgxget: add support for default systemd delegation slice/scope
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Fri, 10 Feb 2023 21:49:13 +0000 (14:49 -0700)
committerTom Hromatka <tom.hromatka@oracle.com>
Fri, 10 Feb 2023 21:49:17 +0000 (14:49 -0700)
Enhance the cgxget 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*      cgrp1
|
 systemd.scope
        |
    cgrp-d1

* default system delegation slice/scope - read from cgconfig.conf
$ sudo cgxget -1 -r cpu.shares 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 cgxget -1 -r cpu.shares /cgrp1

or use the newly introduced -b switch to ignore the systemd
slice/scope:
$ sudo cgxget -b -1 -r cpu.shares /cgrp1

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 36ed9afee2dfbd6b5e16df6d5f37cd05bb44eecb)

src/tools/cgxget.c

index fb7a0ccf0bde5702f2de6590282b19d989ccd913..225e3a637866f601c31293fd21c7160e8f918243 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
 
@@ -58,6 +60,9 @@ static void usage(int status, const char *program_name)
        info("  -n                              Do not print headers\n");
        info("  -r, --variable  <name>  Define parameter to display\n");
        info("  -v, --values-only               Print only values, not parameter names\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)
@@ -412,8 +417,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:a12ib", 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:a12i", long_options, NULL)) > 0) {
                switch (c) {
+#endif
                case 'h':
                        usage(0, argv[0]);
                        exit(0);
@@ -577,7 +590,10 @@ static int indent_multiline_value(struct control_value * const cv)
 static int fill_empty_controller(struct cgroup * const cg, struct cgroup_controller * const cgc)
 {
        struct dirent *ctrl_dir = NULL;
-       char path[FILENAME_MAX];
+       char path[FILENAME_MAX] = { '\0' };
+#ifdef WITH_SYSTEMD
+       char tmp[FILENAME_MAX] = { '\0' };
+#endif
        bool found_mount = false;
        int i, path_len, ret = 0;
        DIR *dir = NULL;
@@ -601,6 +617,36 @@ 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:
+                * cgxget -1  -r cpu.shares /a
+                */
+
+       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';
 
@@ -787,7 +833,7 @@ out:
 
 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;
        enum cg_version_t version = CGROUP_UNK;
        struct cgroup **cg_list = NULL;
        bool ignore_unmappable = false;
@@ -810,6 +856,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 = convert_cgroups(&cg_list, cg_list_len, version, CGROUP_DISK);
        if (ret == ECGNOVERSIONCONVERT && ignore_unmappable)
                /*