]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/cgls/cgls.c
strv: make iterator in STRV_FOREACH() declaread in the loop
[thirdparty/systemd.git] / src / cgls / cgls.c
index b55d7299cabf03529f44669af5a8d6578d01c6d2..6af95204e3ddd5f58dcb0dd04bb51c8e51c89fbc 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <errno.h>
 #include <getopt.h>
@@ -16,6 +16,7 @@
 #include "main-func.h"
 #include "output-mode.h"
 #include "pager.h"
+#include "parse-util.h"
 #include "path-util.h"
 #include "pretty-print.h"
 #include "strv.h"
@@ -23,8 +24,7 @@
 #include "util.h"
 
 static PagerFlags arg_pager_flags = 0;
-static bool arg_kernel_threads = false;
-static bool arg_all = false;
+static OutputFlags arg_output_flags = OUTPUT_CGROUP_XATTRS | OUTPUT_CGROUP_ID;
 
 static enum {
         SHOW_UNIT_NONE,
@@ -54,13 +54,14 @@ static int help(void) {
                "  -a --all            Show all groups, including empty\n"
                "  -u --unit           Show the subtrees of specified system units\n"
                "     --user-unit      Show the subtrees of specified user units\n"
+               "     --xattr=BOOL     Show cgroup extended attributes\n"
+               "     --cgroup-id=BOOL Show cgroup ID\n"
                "  -l --full           Do not ellipsize output\n"
                "  -k                  Include kernel threads in output\n"
                "  -M --machine=       Show container\n"
-               "\nSee the %s for details.\n"
-               , program_invocation_short_name
-               , link
-        );
+               "\nSee the %s for details.\n",
+               program_invocation_short_name,
+               link);
 
         return 0;
 }
@@ -71,6 +72,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_NO_PAGER = 0x100,
                 ARG_VERSION,
                 ARG_USER_UNIT,
+                ARG_XATTR,
+                ARG_CGROUP_ID,
         };
 
         static const struct option options[] = {
@@ -82,10 +85,12 @@ static int parse_argv(int argc, char *argv[]) {
                 { "machine",   required_argument, NULL, 'M'           },
                 { "unit",      optional_argument, NULL, 'u'           },
                 { "user-unit", optional_argument, NULL, ARG_USER_UNIT },
+                { "xattr",     required_argument, NULL, ARG_XATTR     },
+                { "cgroup-id", required_argument, NULL, ARG_CGROUP_ID },
                 {}
         };
 
-        int c;
+        int c, r;
 
         assert(argc >= 1);
         assert(argv);
@@ -105,7 +110,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'a':
-                        arg_all = true;
+                        arg_output_flags |= OUTPUT_SHOW_ALL;
                         break;
 
                 case 'u':
@@ -131,18 +136,34 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'k':
-                        arg_kernel_threads = true;
+                        arg_output_flags |= OUTPUT_KERNEL_THREADS;
                         break;
 
                 case 'M':
                         arg_machine = optarg;
                         break;
 
+                case ARG_XATTR:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --xattr= value: %s", optarg);
+
+                        SET_FLAG(arg_output_flags, OUTPUT_CGROUP_XATTRS, r);
+                        break;
+
+                case ARG_CGROUP_ID:
+                        r = parse_boolean(optarg);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse --cgroup-id= value: %s", optarg);
+
+                        SET_FLAG(arg_output_flags, OUTPUT_CGROUP_ID, r);
+                        break;
+
                 case '?':
                         return -EINVAL;
 
                 default:
-                        assert_not_reached("Unhandled option");
+                        assert_not_reached();
                 }
 
         if (arg_machine && arg_show_unit != SHOW_UNIT_NONE)
@@ -162,36 +183,35 @@ static void show_cg_info(const char *controller, const char *path) {
 }
 
 static int run(int argc, char *argv[]) {
-        int r, output_flags;
+        int r;
 
-        log_show_color(true);
-        log_parse_environment();
-        log_open();
+        log_setup();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
                 return r;
 
-        r = pager_open(arg_pager_flags);
-        if (r > 0 && arg_full < 0)
+        pager_open(arg_pager_flags);
+        if (arg_full < 0 && pager_have())
                 arg_full = true;
 
-        output_flags =
-                arg_all * OUTPUT_SHOW_ALL |
-                (arg_full > 0) * OUTPUT_FULL_WIDTH |
-                arg_kernel_threads * OUTPUT_KERNEL_THREADS;
+        if (arg_full > 0)
+                arg_output_flags |= OUTPUT_FULL_WIDTH;
 
         if (arg_names) {
                 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
                 _cleanup_free_ char *root = NULL;
-                char **name;
 
                 STRV_FOREACH(name, arg_names) {
                         int q;
 
                         if (arg_show_unit != SHOW_UNIT_NONE) {
                                 /* Command line arguments are unit names */
-                                _cleanup_free_ char *cgroup = NULL;
+                                _cleanup_free_ char *cgroup = NULL, *unit_name = NULL;
+
+                                r = unit_name_mangle(*name, UNIT_NAME_MANGLE_WARN, &unit_name);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to mangle unit name: %m");
 
                                 if (!bus) {
                                         /* Connect to the bus only if necessary */
@@ -199,30 +219,29 @@ static int run(int argc, char *argv[]) {
                                                                           arg_show_unit == SHOW_UNIT_USER,
                                                                           &bus);
                                         if (r < 0)
-                                                return log_error_errno(r, "Failed to create bus connection: %m");
+                                                return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL);
                                 }
 
-                                q = show_cgroup_get_unit_path_and_warn(bus, *name, &cgroup);
+                                q = show_cgroup_get_unit_path_and_warn(bus, unit_name, &cgroup);
                                 if (q < 0)
                                         goto failed;
 
                                 if (isempty(cgroup)) {
-                                        log_warning("Unit %s not found.", *name);
-                                        q = -ENOENT;
+                                        q = log_warning_errno(SYNTHETIC_ERRNO(ENOENT), "Unit %s not found.", unit_name);
                                         goto failed;
                                 }
 
-                                printf("Unit %s (%s):\n", *name, cgroup);
+                                printf("Unit %s (%s):\n", unit_name, cgroup);
                                 fflush(stdout);
 
-                                q = show_cgroup_by_path(cgroup, NULL, 0, output_flags);
+                                q = show_cgroup_by_path(cgroup, NULL, 0, arg_output_flags);
 
                         } else if (path_startswith(*name, "/sys/fs/cgroup")) {
 
                                 printf("Directory %s:\n", *name);
                                 fflush(stdout);
 
-                                q = show_cgroup_by_path(*name, NULL, 0, output_flags);
+                                q = show_cgroup_by_path(*name, NULL, 0, arg_output_flags);
                         } else {
                                 _cleanup_free_ char *c = NULL, *p = NULL, *j = NULL;
                                 const char *controller, *path;
@@ -246,14 +265,14 @@ static int run(int argc, char *argv[]) {
                                         if (!j)
                                                 return log_oom();
 
-                                        path_simplify(j, false);
+                                        path_simplify(j);
                                         path = j;
                                 } else
                                         path = root;
 
                                 show_cg_info(controller, path);
 
-                                q = show_cgroup(controller, path, NULL, 0, output_flags);
+                                q = show_cgroup(controller, path, NULL, 0, arg_output_flags);
                         }
 
                 failed:
@@ -275,7 +294,7 @@ static int run(int argc, char *argv[]) {
                                 printf("Working directory %s:\n", cwd);
                                 fflush(stdout);
 
-                                r = show_cgroup_by_path(cwd, NULL, 0, output_flags);
+                                r = show_cgroup_by_path(cwd, NULL, 0, arg_output_flags);
                                 done = true;
                         }
                 }
@@ -290,7 +309,7 @@ static int run(int argc, char *argv[]) {
                         show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root);
 
                         printf("-.slice\n");
-                        r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, output_flags);
+                        r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, arg_output_flags);
                 }
         }
         if (r < 0)