chiark / gitweb /
fd02d52c23f0fd6e7e9b35c6a0acb604de355e0e
[elogind.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 "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 }