]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/cgls/cgls.c
Merge pull request #2921 from keszybz/do-not-report-masked-units-as-changed
[thirdparty/systemd.git] / src / cgls / cgls.c
CommitLineData
fa776d8e
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
fa776d8e
LP
9 (at your option) any later version.
10
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
5430f7f2 14 Lesser General Public License for more details.
fa776d8e 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
fa776d8e
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
fa776d8e
LP
20#include <errno.h>
21#include <getopt.h>
3f6fd1ba 22#include <stdio.h>
fa776d8e 23#include <string.h>
3f6fd1ba
LP
24#include <unistd.h>
25
26#include "sd-bus.h"
fa776d8e 27
b5efdb8a 28#include "alloc-util.h"
3f6fd1ba
LP
29#include "bus-error.h"
30#include "bus-util.h"
fa776d8e 31#include "cgroup-show.h"
c6c18be3 32#include "cgroup-util.h"
3f6fd1ba 33#include "fileio.h"
fa776d8e 34#include "log.h"
9bdbc2e2 35#include "output-mode.h"
3f6fd1ba
LP
36#include "pager.h"
37#include "path-util.h"
13be4979 38#include "unit-name.h"
3f6fd1ba 39#include "util.h"
1968a360
LP
40
41static bool arg_no_pager = false;
1e5678d0 42static bool arg_kernel_threads = false;
c3175a7f 43static bool arg_all = false;
9bdbc2e2 44static int arg_full = -1;
38158b92 45static char* arg_machine = NULL;
fa776d8e 46
601185b4 47static void help(void) {
fa776d8e
LP
48 printf("%s [OPTIONS...] [CGROUP...]\n\n"
49 "Recursively show control group contents.\n\n"
69fc152f 50 " -h --help Show this help\n"
c3175a7f 51 " --version Show package version\n"
1e5678d0 52 " --no-pager Do not pipe output into a pager\n"
c3175a7f 53 " -a --all Show all groups, including empty\n"
98a6e132 54 " -l --full Do not ellipsize output\n"
38158b92 55 " -k Include kernel threads in output\n"
e049fa16 56 " -M --machine= Show container\n"
601185b4 57 , program_invocation_short_name);
fa776d8e
LP
58}
59
60static int parse_argv(int argc, char *argv[]) {
61
1968a360 62 enum {
c3175a7f 63 ARG_NO_PAGER = 0x100,
9bdbc2e2 64 ARG_VERSION,
1968a360
LP
65 };
66
fa776d8e 67 static const struct option options[] = {
1968a360 68 { "help", no_argument, NULL, 'h' },
c3175a7f 69 { "version", no_argument, NULL, ARG_VERSION },
1968a360 70 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
c3175a7f 71 { "all", no_argument, NULL, 'a' },
98a6e132 72 { "full", no_argument, NULL, 'l' },
38158b92 73 { "machine", required_argument, NULL, 'M' },
eb9da376 74 {}
fa776d8e
LP
75 };
76
77 int c;
78
79 assert(argc >= 1);
80 assert(argv);
81
601185b4 82 while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0)
fa776d8e
LP
83
84 switch (c) {
85
86 case 'h':
601185b4
ZJS
87 help();
88 return 0;
fa776d8e 89
c3175a7f 90 case ARG_VERSION:
3f6fd1ba 91 return version();
c3175a7f 92
1968a360
LP
93 case ARG_NO_PAGER:
94 arg_no_pager = true;
95 break;
96
c3175a7f
LP
97 case 'a':
98 arg_all = true;
99 break;
100
98a6e132 101 case 'l':
9bdbc2e2
LN
102 arg_full = true;
103 break;
104
1e5678d0
LP
105 case 'k':
106 arg_kernel_threads = true;
107 break;
108
38158b92
ZJS
109 case 'M':
110 arg_machine = optarg;
111 break;
112
fa776d8e
LP
113 case '?':
114 return -EINVAL;
115
116 default:
eb9da376 117 assert_not_reached("Unhandled option");
fa776d8e 118 }
fa776d8e
LP
119
120 return 1;
121}
122
e049fa16 123static int get_cgroup_root(char **ret) {
4afd3348
LP
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;
e049fa16
LP
126 _cleanup_free_ char *unit = NULL, *path = NULL;
127 const char *m;
128 int r;
129
130 if (!arg_machine) {
131 r = cg_get_root_path(ret);
8b3aa503 132 if (r == -ENOMEDIUM)
e97a8475
MM
133 return log_error_errno(r, "Failed to get root control group path: No cgroup filesystem mounted on /sys/fs/cgroup");
134 else if (r < 0)
e049fa16
LP
135 return log_error_errno(r, "Failed to get root control group path: %m");
136
137 return 0;
138 }
139
140 m = strjoina("/run/systemd/machines/", arg_machine);
141 r = parse_env_file(m, NEWLINE, "SCOPE", &unit, NULL);
142 if (r < 0)
143 return log_error_errno(r, "Failed to load machine data: %m");
144
145 path = unit_dbus_path_from_name(unit);
146 if (!path)
147 return log_oom();
148
266f3e26 149 r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, false, &bus);
e049fa16
LP
150 if (r < 0)
151 return log_error_errno(r, "Failed to create bus connection: %m");
152
153 r = sd_bus_get_property_string(
154 bus,
155 "org.freedesktop.systemd1",
156 path,
157 unit_dbus_interface_from_name(unit),
158 "ControlGroup",
159 &error,
160 ret);
161 if (r < 0)
cb88a0a4 162 return log_error_errno(r, "Failed to query unit control group path: %s", bus_error_message(&error, r));
e049fa16
LP
163
164 return 0;
165}
166
58033c91 167static void show_cg_info(const char *controller, const char *path) {
a6a4d3c4
LP
168
169 if (cg_unified() <= 0 && controller && !streq(controller, SYSTEMD_CGROUP_CONTROLLER))
58033c91 170 printf("Controller %s; ", controller);
a6a4d3c4 171
58033c91
EV
172 printf("Control group %s:\n", isempty(path) ? "/" : path);
173 fflush(stdout);
174}
175
e049fa16
LP
176int main(int argc, char *argv[]) {
177 int r, output_flags;
fa776d8e
LP
178
179 log_parse_environment();
2396fb04 180 log_open();
fa776d8e 181
1e5678d0 182 r = parse_argv(argc, argv);
e049fa16 183 if (r <= 0)
fa776d8e 184 goto finish;
fa776d8e 185
9bdbc2e2 186 if (!arg_no_pager) {
ea4b98e6 187 r = pager_open(arg_no_pager, false);
e049fa16
LP
188 if (r > 0 && arg_full < 0)
189 arg_full = true;
9bdbc2e2
LN
190 }
191
192 output_flags =
193 arg_all * OUTPUT_SHOW_ALL |
0ff308c8
LP
194 (arg_full > 0) * OUTPUT_FULL_WIDTH |
195 arg_kernel_threads * OUTPUT_KERNEL_THREADS;
1968a360 196
fa776d8e 197 if (optind < argc) {
e049fa16 198 _cleanup_free_ char *root = NULL;
38158b92 199 int i;
fa776d8e 200
e049fa16
LP
201 r = get_cgroup_root(&root);
202 if (r < 0)
203 goto finish;
204
38158b92 205 for (i = optind; i < argc; i++) {
fa776d8e 206 int q;
baa89da4 207
e049fa16 208 if (path_startswith(argv[i], "/sys/fs/cgroup")) {
fa776d8e 209
e049fa16
LP
210 printf("Directory %s:\n", argv[i]);
211 fflush(stdout);
fa776d8e 212
0ff308c8 213 q = show_cgroup_by_path(argv[i], NULL, 0, output_flags);
e049fa16
LP
214 } else {
215 _cleanup_free_ char *c = NULL, *p = NULL, *j = NULL;
216 const char *controller, *path;
fa776d8e 217
e049fa16 218 r = cg_split_spec(argv[i], &c, &p);
13be4979 219 if (r < 0) {
e049fa16 220 log_error_errno(r, "Failed to split argument %s: %m", argv[i]);
13be4979
LN
221 goto finish;
222 }
223
e049fa16
LP
224 controller = c ?: SYSTEMD_CGROUP_CONTROLLER;
225 if (p) {
226 j = strjoin(root, "/", p, NULL);
227 if (!j) {
228 r = log_oom();
229 goto finish;
230 }
13be4979 231
e049fa16
LP
232 path_kill_slashes(j);
233 path = j;
234 } else
235 path = root;
13be4979 236
58033c91 237 show_cg_info(controller, path);
13be4979 238
0ff308c8 239 q = show_cgroup(controller, path, NULL, 0, output_flags);
e049fa16 240 }
13be4979 241
e049fa16
LP
242 if (q < 0)
243 r = q;
244 }
245
246 } else {
247 bool done = false;
13be4979 248
e049fa16
LP
249 if (!arg_machine) {
250 _cleanup_free_ char *cwd = NULL;
251
252 cwd = get_current_dir_name();
253 if (!cwd) {
254 r = log_error_errno(errno, "Cannot determine current working directory: %m");
7027ff61 255 goto finish;
b9a8e638 256 }
1f16b4a6 257
e049fa16
LP
258 if (path_startswith(cwd, "/sys/fs/cgroup")) {
259 printf("Working directory %s:\n", cwd);
260 fflush(stdout);
261
0ff308c8 262 r = show_cgroup_by_path(cwd, NULL, 0, output_flags);
e049fa16
LP
263 done = true;
264 }
265 }
266
267 if (!done) {
268 _cleanup_free_ char *root = NULL;
269
270 r = get_cgroup_root(&root);
271 if (r < 0)
272 goto finish;
273
58033c91 274 show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root);
e049fa16 275
b1f044bb 276 printf("-.slice\n");
0ff308c8 277 r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, output_flags);
1f16b4a6 278 }
fa776d8e
LP
279 }
280
e049fa16
LP
281 if (r < 0)
282 log_error_errno(r, "Failed to list cgroup tree: %m");
fa776d8e
LP
283
284finish:
1968a360 285 pager_close();
fa776d8e 286
e049fa16 287 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
fa776d8e 288}