]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/cgls/cgls.c
nspawn: introduce the new /machine/ tree in the cgroup tree and move containers there
[thirdparty/systemd.git] / src / cgls / cgls.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <limits.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <getopt.h>
27 #include <string.h>
28
29 #include "cgroup-show.h"
30 #include "cgroup-util.h"
31 #include "log.h"
32 #include "path-util.h"
33 #include "util.h"
34 #include "pager.h"
35 #include "build.h"
36 #include "output-mode.h"
37
38 static bool arg_no_pager = false;
39 static bool arg_kernel_threads = false;
40 static bool arg_all = false;
41 static int arg_full = -1;
42
43 static void help(void) {
44
45 printf("%s [OPTIONS...] [CGROUP...]\n\n"
46 "Recursively show control group contents.\n\n"
47 " -h --help Show this help\n"
48 " --version Show package version\n"
49 " --no-pager Do not pipe output into a pager\n"
50 " -a --all Show all groups, including empty\n"
51 " --full Do not ellipsize output\n"
52 " -k Include kernel threads in output\n",
53 program_invocation_short_name);
54 }
55
56 static int parse_argv(int argc, char *argv[]) {
57
58 enum {
59 ARG_NO_PAGER = 0x100,
60 ARG_VERSION,
61 ARG_FULL,
62 };
63
64 static const struct option options[] = {
65 { "help", no_argument, NULL, 'h' },
66 { "version", no_argument, NULL, ARG_VERSION },
67 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
68 { "all", no_argument, NULL, 'a' },
69 { "full", no_argument, NULL, ARG_FULL },
70 { NULL, 0, NULL, 0 }
71 };
72
73 int c;
74
75 assert(argc >= 1);
76 assert(argv);
77
78 while ((c = getopt_long(argc, argv, "hka", options, NULL)) >= 0) {
79
80 switch (c) {
81
82 case 'h':
83 help();
84 return 0;
85
86 case ARG_VERSION:
87 puts(PACKAGE_STRING);
88 puts(SYSTEMD_FEATURES);
89 return 0;
90
91 case ARG_NO_PAGER:
92 arg_no_pager = true;
93 break;
94
95 case 'a':
96 arg_all = true;
97 break;
98
99 case ARG_FULL:
100 arg_full = true;
101 break;
102
103 case 'k':
104 arg_kernel_threads = true;
105 break;
106
107 case '?':
108 return -EINVAL;
109
110 default:
111 log_error("Unknown option code %c", c);
112 return -EINVAL;
113 }
114 }
115
116 return 1;
117 }
118
119 int main(int argc, char *argv[]) {
120 int r = 0, retval = EXIT_FAILURE;
121 int output_flags;
122
123 log_parse_environment();
124 log_open();
125
126 r = parse_argv(argc, argv);
127 if (r < 0)
128 goto finish;
129 else if (r == 0) {
130 retval = EXIT_SUCCESS;
131 goto finish;
132 }
133
134 if (!arg_no_pager) {
135 r = pager_open(false);
136 if (r > 0) {
137 if (arg_full == -1)
138 arg_full = true;
139 }
140 }
141
142 output_flags =
143 arg_all * OUTPUT_SHOW_ALL |
144 (arg_full > 0) * OUTPUT_FULL_WIDTH;
145
146 if (optind < argc) {
147 unsigned i;
148
149 for (i = (unsigned) optind; i < (unsigned) argc; i++) {
150 int q;
151 printf("%s:\n", argv[i]);
152
153 q = show_cgroup_by_path(argv[i], NULL, 0,
154 arg_kernel_threads, output_flags);
155 if (q < 0)
156 r = q;
157 }
158
159 } else {
160 char _cleanup_free_ *p;
161
162 p = get_current_dir_name();
163 if (!p) {
164 log_error("Cannot determine current working directory: %m");
165 goto finish;
166 }
167
168 if (path_startswith(p, "/sys/fs/cgroup")) {
169 printf("Working Directory %s:\n", p);
170 r = show_cgroup_by_path(p, NULL, 0,
171 arg_kernel_threads, output_flags);
172 } else {
173 char _cleanup_free_ *root = NULL;
174
175 r = cg_get_root_path(&root);
176 if (r < 0) {
177 log_error("Failed to get root path: %s", strerror(-r));
178 goto finish;
179 }
180
181 r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0,
182 arg_kernel_threads, output_flags);
183 }
184 }
185
186 if (r < 0)
187 log_error("Failed to list cgroup tree: %s", strerror(-r));
188
189 retval = EXIT_SUCCESS;
190
191 finish:
192 pager_close();
193
194 return retval;
195 }