]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/cgroup-show.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / cgroup-show.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ab35fb1b
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
ab35fb1b
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.
ab35fb1b 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
ab35fb1b
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdio.h>
23#include <string.h>
fa776d8e
LP
24#include <dirent.h>
25#include <errno.h>
ab35fb1b
LP
26
27#include "util.h"
28#include "macro.h"
c6c18be3 29#include "cgroup-util.h"
ab35fb1b
LP
30#include "cgroup-show.h"
31
32static int compare(const void *a, const void *b) {
33 const pid_t *p = a, *q = b;
34
35 if (*p < *q)
36 return -1;
37 if (*p > *q)
38 return 1;
39 return 0;
40}
41
fa776d8e
LP
42static unsigned ilog10(unsigned long ul) {
43 int n = 0;
44
45 while (ul > 0) {
46 n++;
47 ul /= 10;
48 }
49
50 return n;
51}
52
1e5678d0 53static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigned n_columns, bool more, bool kernel_threads) {
ab35fb1b
LP
54 char *fn;
55 FILE *f;
56 size_t n = 0, n_allocated = 0;
57 pid_t *pids = NULL;
fa776d8e 58 char *p;
c6c18be3 59 pid_t pid, biggest = 0;
fa776d8e 60 int r;
ab35fb1b 61
fa776d8e
LP
62 if (n_columns <= 0)
63 n_columns = columns();
ab35fb1b 64
fa776d8e
LP
65 if (!prefix)
66 prefix = "";
67
35d2e7ec
LP
68 if ((r = cg_fix_path(path, &p)) < 0)
69 return r;
ab35fb1b 70
fa776d8e
LP
71 r = asprintf(&fn, "%s/cgroup.procs", p);
72 free(p);
73
74 if (r < 0)
75 return -ENOMEM;
76
77 f = fopen(fn, "re");
ab35fb1b
LP
78 free(fn);
79
80 if (!f)
fa776d8e 81 return -errno;
ab35fb1b 82
c6c18be3 83 while ((r = cg_read_pid(f, &pid)) > 0) {
ab35fb1b 84
1e5678d0
LP
85 if (!kernel_threads && is_kernel_thread(pid) > 0)
86 continue;
87
ab35fb1b
LP
88 if (n >= n_allocated) {
89 pid_t *npids;
90
91 n_allocated = MAX(16U, n*2U);
92
93 if (!(npids = realloc(pids, sizeof(pid_t) * n_allocated))) {
fa776d8e 94 r = -ENOMEM;
ab35fb1b
LP
95 goto finish;
96 }
97
98 pids = npids;
99 }
100
101 assert(n < n_allocated);
c6c18be3 102 pids[n++] = pid;
fa776d8e 103
c6c18be3
LP
104 if (pid > biggest)
105 biggest = pid;
ab35fb1b
LP
106 }
107
c6c18be3
LP
108 if (r < 0)
109 goto finish;
110
ab35fb1b
LP
111 if (n > 0) {
112 unsigned i, m;
113
114 /* Filter duplicates */
115 m = 0;
116 for (i = 0; i < n; i++) {
117 unsigned j;
118
119 for (j = i+1; j < n; j++)
120 if (pids[i] == pids[j])
121 break;
122
123 if (j >= n)
124 pids[m++] = pids[i];
125 }
126 n = m;
127
128 /* And sort */
129 qsort(pids, n, sizeof(pid_t), compare);
130
fa776d8e
LP
131 if (n_columns > 8)
132 n_columns -= 8;
ab35fb1b 133 else
fa776d8e 134 n_columns = 20;
ab35fb1b
LP
135
136 for (i = 0; i < n; i++) {
137 char *t = NULL;
138
87d2c1ff 139 get_process_cmdline(pids[i], n_columns, true, &t);
ab35fb1b 140
fa776d8e 141 printf("%s%s %*lu %s\n",
ab35fb1b 142 prefix,
fa776d8e 143 (more || i < n-1) ? "\342\224\234" : "\342\224\224",
e364ad06 144 (int) ilog10(biggest),
fa776d8e
LP
145 (unsigned long) pids[i],
146 strna(t));
ab35fb1b
LP
147
148 free(t);
149 }
150 }
151
fa776d8e
LP
152 r = 0;
153
ab35fb1b
LP
154finish:
155 free(pids);
156
157 if (f)
158 fclose(f);
fa776d8e
LP
159
160 return r;
161}
162
1e5678d0 163int show_cgroup_by_path(const char *path, const char *prefix, unsigned n_columns, bool kernel_threads) {
fa776d8e
LP
164 DIR *d;
165 char *last = NULL;
35d2e7ec 166 char *p1 = NULL, *p2 = NULL, *fn = NULL, *gn = NULL;
fa776d8e
LP
167 bool shown_pids = false;
168 int r;
169
fa776d8e
LP
170 if (n_columns <= 0)
171 n_columns = columns();
172
173 if (!prefix)
174 prefix = "";
175
35d2e7ec
LP
176 if ((r = cg_fix_path(path, &fn)) < 0)
177 return r;
fa776d8e
LP
178
179 if (!(d = opendir(fn))) {
180 free(fn);
181 return -errno;
182 }
183
35d2e7ec 184 while ((r = cg_read_subgroup(d, &gn)) > 0) {
fa776d8e
LP
185
186 if (!shown_pids) {
1e5678d0 187 show_cgroup_one_by_path(path, prefix, n_columns, true, kernel_threads);
fa776d8e
LP
188 shown_pids = true;
189 }
190
191 if (last) {
192 printf("%s\342\224\234 %s\n", prefix, file_name_from_path(last));
193
194 if (!p1)
195 if (!(p1 = strappend(prefix, "\342\224\202 "))) {
196 r = -ENOMEM;
197 goto finish;
198 }
199
1e5678d0 200 show_cgroup_by_path(last, p1, n_columns-2, kernel_threads);
fa776d8e
LP
201
202 free(last);
203 last = NULL;
204 }
205
35d2e7ec
LP
206 r = asprintf(&last, "%s/%s", fn, gn);
207 free(gn);
208
209 if (r < 0) {
e34b6159 210 r = -ENOMEM;
fa776d8e
LP
211 goto finish;
212 }
213 }
214
35d2e7ec
LP
215 if (r < 0)
216 goto finish;
217
fa776d8e 218 if (!shown_pids)
1e5678d0 219 show_cgroup_one_by_path(path, prefix, n_columns, !!last, kernel_threads);
fa776d8e
LP
220
221 if (last) {
222 printf("%s\342\224\224 %s\n", prefix, file_name_from_path(last));
223
224 if (!p2)
225 if (!(p2 = strappend(prefix, " "))) {
226 r = -ENOMEM;
227 goto finish;
228 }
229
1e5678d0 230 show_cgroup_by_path(last, p2, n_columns-2, kernel_threads);
fa776d8e
LP
231 }
232
233 r = 0;
234
235finish:
236 free(p1);
237 free(p2);
238 free(last);
239 free(fn);
240
241 closedir(d);
242
243 return r;
ab35fb1b 244}
35d2e7ec 245
1e5678d0 246int show_cgroup(const char *controller, const char *path, const char *prefix, unsigned n_columns, bool kernel_threads) {
35d2e7ec
LP
247 char *p;
248 int r;
249
250 assert(controller);
251 assert(path);
252
1e5678d0
LP
253 r = cg_get_path(controller, path, NULL, &p);
254 if (r < 0)
35d2e7ec
LP
255 return r;
256
1e5678d0 257 r = show_cgroup_by_path(p, prefix, n_columns, kernel_threads);
35d2e7ec
LP
258 free(p);
259
260 return r;
261}