-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include <getopt.h>
#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"
#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,
" -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;
}
ARG_NO_PAGER = 0x100,
ARG_VERSION,
ARG_USER_UNIT,
+ ARG_XATTR,
+ ARG_CGROUP_ID,
};
static const struct option options[] = {
{ "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);
break;
case 'a':
- arg_all = true;
+ arg_output_flags |= OUTPUT_SHOW_ALL;
break;
case 'u':
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)
}
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 */
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;
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:
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;
}
}
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)