2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include "alloc-util.h"
29 #include "bus-error.h"
31 #include "cgroup-show.h"
32 #include "cgroup-util.h"
35 #include "output-mode.h"
37 #include "path-util.h"
38 #include "unit-name.h"
41 static bool arg_no_pager
= false;
42 static bool arg_kernel_threads
= false;
43 static bool arg_all
= false;
44 static int arg_full
= -1;
45 static char* arg_machine
= NULL
;
47 static void help(void) {
48 printf("%s [OPTIONS...] [CGROUP...]\n\n"
49 "Recursively show control group contents.\n\n"
50 " -h --help Show this help\n"
51 " --version Show package version\n"
52 " --no-pager Do not pipe output into a pager\n"
53 " -a --all Show all groups, including empty\n"
54 " -l --full Do not ellipsize output\n"
55 " -k Include kernel threads in output\n"
56 " -M --machine= Show container\n"
57 , program_invocation_short_name
);
60 static int parse_argv(int argc
, char *argv
[]) {
67 static const struct option options
[] = {
68 { "help", no_argument
, NULL
, 'h' },
69 { "version", no_argument
, NULL
, ARG_VERSION
},
70 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
71 { "all", no_argument
, NULL
, 'a' },
72 { "full", no_argument
, NULL
, 'l' },
73 { "machine", required_argument
, NULL
, 'M' },
82 while ((c
= getopt_long(argc
, argv
, "hkalM:", options
, NULL
)) >= 0)
106 arg_kernel_threads
= true;
110 arg_machine
= optarg
;
117 assert_not_reached("Unhandled option");
123 static int get_cgroup_root(char **ret
) {
124 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
125 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
126 _cleanup_free_
char *unit
= NULL
, *path
= NULL
;
131 r
= cg_get_root_path(ret
);
133 return log_error_errno(r
, "Failed to get root control group path: No cgroup filesystem mounted on /sys/fs/cgroup");
135 return log_error_errno(r
, "Failed to get root control group path: %m");
140 m
= strjoina("/run/systemd/machines/", arg_machine
);
141 r
= parse_env_file(m
, NEWLINE
, "SCOPE", &unit
, NULL
);
143 return log_error_errno(r
, "Failed to load machine data: %m");
145 path
= unit_dbus_path_from_name(unit
);
149 r
= bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL
, NULL
, false, &bus
);
151 return log_error_errno(r
, "Failed to create bus connection: %m");
153 r
= sd_bus_get_property_string(
155 "org.freedesktop.systemd1",
157 unit_dbus_interface_from_name(unit
),
162 return log_error_errno(r
, "Failed to query unit control group path: %s", bus_error_message(&error
, r
));
167 static void show_cg_info(const char *controller
, const char *path
) {
169 if (cg_all_unified() <= 0 && controller
&& !streq(controller
, SYSTEMD_CGROUP_CONTROLLER
))
170 printf("Controller %s; ", controller
);
172 printf("Control group %s:\n", isempty(path
) ? "/" : path
);
176 int main(int argc
, char *argv
[]) {
179 log_parse_environment();
182 r
= parse_argv(argc
, argv
);
187 r
= pager_open(arg_no_pager
, false);
188 if (r
> 0 && arg_full
< 0)
193 arg_all
* OUTPUT_SHOW_ALL
|
194 (arg_full
> 0) * OUTPUT_FULL_WIDTH
|
195 arg_kernel_threads
* OUTPUT_KERNEL_THREADS
;
198 _cleanup_free_
char *root
= NULL
;
201 r
= get_cgroup_root(&root
);
205 for (i
= optind
; i
< argc
; i
++) {
208 if (path_startswith(argv
[i
], "/sys/fs/cgroup")) {
210 printf("Directory %s:\n", argv
[i
]);
213 q
= show_cgroup_by_path(argv
[i
], NULL
, 0, output_flags
);
215 _cleanup_free_
char *c
= NULL
, *p
= NULL
, *j
= NULL
;
216 const char *controller
, *path
;
218 r
= cg_split_spec(argv
[i
], &c
, &p
);
220 log_error_errno(r
, "Failed to split argument %s: %m", argv
[i
]);
224 controller
= c
?: SYSTEMD_CGROUP_CONTROLLER
;
226 j
= strjoin(root
, "/", p
);
232 path_kill_slashes(j
);
237 show_cg_info(controller
, path
);
239 q
= show_cgroup(controller
, path
, NULL
, 0, output_flags
);
250 _cleanup_free_
char *cwd
= NULL
;
252 cwd
= get_current_dir_name();
254 r
= log_error_errno(errno
, "Cannot determine current working directory: %m");
258 if (path_startswith(cwd
, "/sys/fs/cgroup")) {
259 printf("Working directory %s:\n", cwd
);
262 r
= show_cgroup_by_path(cwd
, NULL
, 0, output_flags
);
268 _cleanup_free_
char *root
= NULL
;
270 r
= get_cgroup_root(&root
);
274 show_cg_info(SYSTEMD_CGROUP_CONTROLLER
, root
);
277 r
= show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, root
, NULL
, 0, output_flags
);
282 log_error_errno(r
, "Failed to list cgroup tree: %m");
287 return r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;