]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/cgls/cgls.c
question: drop dns_question_is_superset() which we don't use anymore
[thirdparty/systemd.git] / src / cgls / cgls.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
fa776d8e
LP
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
fa776d8e
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
fa776d8e 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
fa776d8e
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
fa776d8e
LP
22#include <errno.h>
23#include <getopt.h>
3f6fd1ba 24#include <stdio.h>
fa776d8e 25#include <string.h>
3f6fd1ba
LP
26#include <unistd.h>
27
28#include "sd-bus.h"
fa776d8e 29
b5efdb8a 30#include "alloc-util.h"
3f6fd1ba
LP
31#include "bus-error.h"
32#include "bus-util.h"
fa776d8e 33#include "cgroup-show.h"
c6c18be3 34#include "cgroup-util.h"
3f6fd1ba 35#include "fileio.h"
fa776d8e 36#include "log.h"
9bdbc2e2 37#include "output-mode.h"
3f6fd1ba
LP
38#include "pager.h"
39#include "path-util.h"
13be4979 40#include "unit-name.h"
3f6fd1ba 41#include "util.h"
1968a360
LP
42
43static bool arg_no_pager = false;
1e5678d0 44static bool arg_kernel_threads = false;
c3175a7f 45static bool arg_all = false;
9bdbc2e2 46static int arg_full = -1;
38158b92 47static char* arg_machine = NULL;
fa776d8e 48
601185b4 49static void help(void) {
fa776d8e
LP
50 printf("%s [OPTIONS...] [CGROUP...]\n\n"
51 "Recursively show control group contents.\n\n"
69fc152f 52 " -h --help Show this help\n"
c3175a7f 53 " --version Show package version\n"
1e5678d0 54 " --no-pager Do not pipe output into a pager\n"
c3175a7f 55 " -a --all Show all groups, including empty\n"
98a6e132 56 " -l --full Do not ellipsize output\n"
38158b92 57 " -k Include kernel threads in output\n"
e049fa16 58 " -M --machine= Show container\n"
601185b4 59 , program_invocation_short_name);
fa776d8e
LP
60}
61
62static int parse_argv(int argc, char *argv[]) {
63
1968a360 64 enum {
c3175a7f 65 ARG_NO_PAGER = 0x100,
9bdbc2e2 66 ARG_VERSION,
1968a360
LP
67 };
68
fa776d8e 69 static const struct option options[] = {
1968a360 70 { "help", no_argument, NULL, 'h' },
c3175a7f 71 { "version", no_argument, NULL, ARG_VERSION },
1968a360 72 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
c3175a7f 73 { "all", no_argument, NULL, 'a' },
98a6e132 74 { "full", no_argument, NULL, 'l' },
38158b92 75 { "machine", required_argument, NULL, 'M' },
eb9da376 76 {}
fa776d8e
LP
77 };
78
79 int c;
80
81 assert(argc >= 1);
82 assert(argv);
83
601185b4 84 while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0)
fa776d8e
LP
85
86 switch (c) {
87
88 case 'h':
601185b4
ZJS
89 help();
90 return 0;
fa776d8e 91
c3175a7f 92 case ARG_VERSION:
3f6fd1ba 93 return version();
c3175a7f 94
1968a360
LP
95 case ARG_NO_PAGER:
96 arg_no_pager = true;
97 break;
98
c3175a7f
LP
99 case 'a':
100 arg_all = true;
101 break;
102
98a6e132 103 case 'l':
9bdbc2e2
LN
104 arg_full = true;
105 break;
106
1e5678d0
LP
107 case 'k':
108 arg_kernel_threads = true;
109 break;
110
38158b92
ZJS
111 case 'M':
112 arg_machine = optarg;
113 break;
114
fa776d8e
LP
115 case '?':
116 return -EINVAL;
117
118 default:
eb9da376 119 assert_not_reached("Unhandled option");
fa776d8e 120 }
fa776d8e
LP
121
122 return 1;
123}
124
e049fa16
LP
125static int get_cgroup_root(char **ret) {
126 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
03976f7b 127 _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
e049fa16
LP
128 _cleanup_free_ char *unit = NULL, *path = NULL;
129 const char *m;
130 int r;
131
132 if (!arg_machine) {
133 r = cg_get_root_path(ret);
134 if (r < 0)
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) {
1b12a7b5 187 r = pager_open(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 |
194 (arg_full > 0) * OUTPUT_FULL_WIDTH;
1968a360 195
fa776d8e 196 if (optind < argc) {
e049fa16 197 _cleanup_free_ char *root = NULL;
38158b92 198 int i;
fa776d8e 199
e049fa16
LP
200 r = get_cgroup_root(&root);
201 if (r < 0)
202 goto finish;
203
38158b92 204 for (i = optind; i < argc; i++) {
fa776d8e 205 int q;
baa89da4 206
e049fa16 207 if (path_startswith(argv[i], "/sys/fs/cgroup")) {
fa776d8e 208
e049fa16
LP
209 printf("Directory %s:\n", argv[i]);
210 fflush(stdout);
fa776d8e 211
e049fa16
LP
212 q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads, output_flags);
213 } else {
214 _cleanup_free_ char *c = NULL, *p = NULL, *j = NULL;
215 const char *controller, *path;
fa776d8e 216
e049fa16 217 r = cg_split_spec(argv[i], &c, &p);
13be4979 218 if (r < 0) {
e049fa16 219 log_error_errno(r, "Failed to split argument %s: %m", argv[i]);
13be4979
LN
220 goto finish;
221 }
222
e049fa16
LP
223 controller = c ?: SYSTEMD_CGROUP_CONTROLLER;
224 if (p) {
225 j = strjoin(root, "/", p, NULL);
226 if (!j) {
227 r = log_oom();
228 goto finish;
229 }
13be4979 230
e049fa16
LP
231 path_kill_slashes(j);
232 path = j;
233 } else
234 path = root;
13be4979 235
58033c91 236 show_cg_info(controller, path);
13be4979 237
e049fa16
LP
238 q = show_cgroup(controller, path, NULL, 0, arg_kernel_threads, output_flags);
239 }
13be4979 240
e049fa16
LP
241 if (q < 0)
242 r = q;
243 }
244
245 } else {
246 bool done = false;
13be4979 247
e049fa16
LP
248 if (!arg_machine) {
249 _cleanup_free_ char *cwd = NULL;
250
251 cwd = get_current_dir_name();
252 if (!cwd) {
253 r = log_error_errno(errno, "Cannot determine current working directory: %m");
7027ff61 254 goto finish;
b9a8e638 255 }
1f16b4a6 256
e049fa16
LP
257 if (path_startswith(cwd, "/sys/fs/cgroup")) {
258 printf("Working directory %s:\n", cwd);
259 fflush(stdout);
260
261 r = show_cgroup_by_path(cwd, NULL, 0, arg_kernel_threads, output_flags);
262 done = true;
263 }
264 }
265
266 if (!done) {
267 _cleanup_free_ char *root = NULL;
268
269 r = get_cgroup_root(&root);
270 if (r < 0)
271 goto finish;
272
58033c91 273 show_cg_info(SYSTEMD_CGROUP_CONTROLLER, root);
e049fa16 274
b1f044bb 275 printf("-.slice\n");
e049fa16 276 r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0, arg_kernel_threads, output_flags);
1f16b4a6 277 }
fa776d8e
LP
278 }
279
e049fa16
LP
280 if (r < 0)
281 log_error_errno(r, "Failed to list cgroup tree: %m");
fa776d8e
LP
282
283finish:
1968a360 284 pager_close();
fa776d8e 285
e049fa16 286 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
fa776d8e 287}