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