]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/cgls.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / 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 "util.h"
33 #include "pager.h"
34
35 static bool arg_no_pager = false;
36 static bool arg_kernel_threads = false;
37
38 static void help(void) {
39
40 printf("%s [OPTIONS...] [CGROUP...]\n\n"
41 "Recursively show control group contents.\n\n"
42 " -h --help Show this help\n"
43 " --no-pager Do not pipe output into a pager\n"
44 " -k Include kernel threads in output\n",
45 program_invocation_short_name);
46 }
47
48 static int parse_argv(int argc, char *argv[]) {
49
50 enum {
51 ARG_NO_PAGER = 0x100
52 };
53
54 static const struct option options[] = {
55 { "help", no_argument, NULL, 'h' },
56 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
57 { NULL, 0, NULL, 0 }
58 };
59
60 int c;
61
62 assert(argc >= 1);
63 assert(argv);
64
65 while ((c = getopt_long(argc, argv, "hk", options, NULL)) >= 0) {
66
67 switch (c) {
68
69 case 'h':
70 help();
71 return 0;
72
73 case ARG_NO_PAGER:
74 arg_no_pager = true;
75 break;
76
77 case 'k':
78 arg_kernel_threads = true;
79 break;
80
81 case '?':
82 return -EINVAL;
83
84 default:
85 log_error("Unknown option code %c", c);
86 return -EINVAL;
87 }
88 }
89
90 return 1;
91 }
92
93 int main(int argc, char *argv[]) {
94 int r = 0, retval = EXIT_FAILURE;
95
96 log_parse_environment();
97 log_open();
98
99 r = parse_argv(argc, argv);
100 if (r < 0)
101 goto finish;
102 else if (r == 0) {
103 retval = EXIT_SUCCESS;
104 goto finish;
105 }
106
107 if (!arg_no_pager)
108 pager_open();
109
110 if (optind < argc) {
111 unsigned i;
112
113 for (i = (unsigned) optind; i < (unsigned) argc; i++) {
114 int q;
115 printf("%s:\n", argv[i]);
116
117 q = show_cgroup_by_path(argv[i], NULL, 0, arg_kernel_threads);
118 if (q < 0)
119 r = q;
120 }
121
122 } else {
123 char *p;
124
125 p = get_current_dir_name();
126 if (!p) {
127 log_error("Cannot determine current working directory: %m");
128 goto finish;
129 }
130
131 if (path_startswith(p, "/sys/fs/cgroup")) {
132 printf("Working Directory %s:\n", p);
133 r = show_cgroup_by_path(p, NULL, 0, arg_kernel_threads);
134 } else {
135 char *root = NULL;
136 const char *t = NULL;
137
138 r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &root);
139 if (r < 0)
140 t = "/";
141 else {
142 if (endswith(root, "/system"))
143 root[strlen(root)-7] = 0;
144
145 t = root[0] ? root : "/";
146 }
147
148 r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, t, NULL, 0, arg_kernel_threads);
149 free(root);
150 }
151
152 free(p);
153 }
154
155 if (r < 0)
156 log_error("Failed to list cgroup tree: %s", strerror(-r));
157
158 retval = EXIT_SUCCESS;
159
160 finish:
161 pager_close();
162
163 return retval;
164 }