]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_ls.c
spelling: explicitly
[mirror_lxc.git] / src / lxc / tools / lxc_ls.c
1 /*
2 *
3 * Copyright © 2016 Christian Brauner <christian.brauner@mailbox.org>.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2, as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef _GNU_SOURCE
20 #define _GNU_SOURCE 1
21 #endif
22 #include <dirent.h>
23 #include <getopt.h>
24 #include <limits.h>
25 #include <regex.h>
26 #include <stdbool.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <termios.h>
36 #include <unistd.h>
37
38 #include <lxc/lxccontainer.h>
39
40 #include "arguments.h"
41 #include "config.h"
42 #include "log.h"
43 #include "utils.h"
44
45 lxc_log_define(lxc_ls, lxc);
46
47 /* Per default we only allow five levels of recursion to protect the stack at
48 * least a little bit. */
49 #define MAX_NESTLVL 5
50
51 #define LS_FROZEN 1
52 #define LS_STOPPED 2
53 #define LS_ACTIVE 3
54 #define LS_RUNNING 4
55 #define LS_NESTING 5
56 #define LS_FILTER 6
57 #define LS_DEFINED 7
58
59 #ifndef SOCK_CLOEXEC
60 # define SOCK_CLOEXEC 02000000
61 #endif
62
63 /* Store container info. */
64 struct ls {
65 char *name;
66 char *state;
67 char *groups;
68 char *interface;
69 char *ipv4;
70 char *ipv6;
71 unsigned int nestlvl;
72 pid_t init;
73 double ram;
74 double swap;
75 bool autostart;
76 bool running;
77 bool unprivileged;
78 };
79
80 /* Keep track of field widths for printing. */
81 struct lengths {
82 unsigned int name_length;
83 unsigned int state_length;
84 unsigned int groups_length;
85 unsigned int interface_length;
86 unsigned int ipv4_length;
87 unsigned int ipv6_length;
88 unsigned int init_length;
89 unsigned int ram_length;
90 unsigned int swap_length;
91 unsigned int autostart_length;
92 unsigned int unprivileged_length;
93 };
94
95 static int ls_deserialize(int rpipefd, struct ls **m, size_t *len);
96 static void ls_field_width(const struct ls *l, const size_t size,
97 struct lengths *lht);
98 static void ls_free(struct ls *l, size_t size);
99 static void ls_free_arr(char **arr, size_t size);
100 static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
101 const char *basepath, const char *parent, unsigned int lvl,
102 char **lockpath, size_t len_lockpath, char **grps_must,
103 size_t grps_must_len);
104 static char *ls_get_cgroup_item(struct lxc_container *c, const char *item);
105 static char *ls_get_config_item(struct lxc_container *c, const char *item,
106 bool running);
107 static char *ls_get_groups(struct lxc_container *c, bool running);
108 static char *ls_get_ips(struct lxc_container *c, const char *inet);
109 static int ls_recv_str(int fd, char **buf);
110 static int ls_send_str(int fd, const char *buf);
111
112 struct wrapargs {
113 const struct lxc_arguments *args;
114 char **grps_must;
115 size_t grps_must_len;
116 int pipefd[2];
117 size_t *size;
118 const char *parent;
119 unsigned int nestlvl;
120 };
121
122 /*
123 * Takes struct wrapargs as argument.
124 */
125 static int ls_get_wrapper(void *wrap);
126
127 /*
128 * To calculate swap usage we should not simply check memory.usage_in_bytes and
129 * memory.memsw.usage_in_bytes and then do:
130 * swap = memory.memsw.usage_in_bytes - memory.usage_in_bytes;
131 * because we might receive an incorrect/negative value.
132 * Instead we check memory.stat and check the "swap" value.
133 */
134 static double ls_get_swap(struct lxc_container *c);
135 static unsigned int ls_get_term_width(void);
136 static char *ls_get_interface(struct lxc_container *c);
137 static bool ls_has_all_grps(const char *has, char **must, size_t must_len);
138 static struct ls *ls_new(struct ls **ls, size_t *size);
139
140 /*
141 * Print user-specified fancy format.
142 */
143 static void ls_print_fancy_format(struct ls *l, struct lengths *lht,
144 size_t size, const char *fancy_fmt);
145
146 /*
147 * Only print names of containers.
148 */
149 static void ls_print_names(struct ls *l, struct lengths *lht,
150 size_t ls_arr, size_t termwidth, bool list);
151
152 /*
153 * Print default fancy format.
154 */
155 static void ls_print_table(struct ls *l, struct lengths *lht,
156 size_t size);
157
158 /*
159 * id can only be 79 + \0 chars long.
160 */
161 static int ls_remove_lock(const char *path, const char *name,
162 char **lockpath, size_t *len_lockpath, bool recalc);
163 static int ls_serialize(int wpipefd, struct ls *n);
164 static int my_parser(struct lxc_arguments *args, int c, char *arg);
165
166 static const struct option my_longopts[] = {
167 {"line", no_argument, 0, '1'},
168 {"fancy", no_argument, 0, 'f'},
169 {"fancy-format", required_argument, 0, 'F'},
170 {"active", no_argument, 0, LS_ACTIVE},
171 {"running", no_argument, 0, LS_RUNNING},
172 {"frozen", no_argument, 0, LS_FROZEN},
173 {"stopped", no_argument, 0, LS_STOPPED},
174 {"defined", no_argument, 0, LS_DEFINED},
175 {"nesting", optional_argument, 0, LS_NESTING},
176 {"groups", required_argument, 0, 'g'},
177 {"filter", required_argument, 0, LS_FILTER},
178 LXC_COMMON_OPTIONS
179 };
180
181 static struct lxc_arguments my_args = {
182 .progname = "lxc-ls",
183 .help = "\n\
184 [-P lxcpath] [--active] [--running] [--frozen] [--stopped] [--nesting] [-g groups] [--filter regex]\n\
185 [-1] [-P lxcpath] [--active] [--running] [--frozen] [--stopped] [--nesting] [-g groups] [--filter regex]\n\
186 [-f] [-P lxcpath] [--active] [--running] [--frozen] [--stopped] [--nesting] [-g groups] [--filter regex]\n\
187 \n\
188 lxc-ls list containers\n\
189 \n\
190 Options :\n\
191 -1, --line show one entry per line\n\
192 -f, --fancy use a fancy, column-based output\n\
193 -F, --fancy-format comma separated list of columns to show in the fancy output\n\
194 valid columns are: NAME, STATE, PID, RAM, SWAP, AUTOSTART,\n\
195 GROUPS, INTERFACE, IPV4 and IPV6, UNPRIVILEGED\n\
196 --active list only active containers\n\
197 --running list only running containers\n\
198 --frozen list only frozen containers\n\
199 --stopped list only stopped containers\n\
200 --defined list only defined containers\n\
201 --nesting=NUM list nested containers up to NUM (default is 5) levels of nesting\n\
202 --filter=REGEX filter container names by regular expression\n\
203 -g --groups comma separated list of groups a container must have to be displayed\n",
204 .options = my_longopts,
205 .parser = my_parser,
206 .ls_nesting = 0,
207 };
208
209 int main(int argc, char *argv[])
210 {
211 int ret = EXIT_FAILURE;
212 struct lxc_log log;
213
214 /*
215 * The lxc parser requires that my_args.name is set. So let's satisfy
216 * that condition by setting a dummy name which is never used.
217 */
218 my_args.name = "";
219 if (lxc_arguments_parse(&my_args, argc, argv))
220 exit(EXIT_FAILURE);
221
222 /* Only create log if explicitly instructed */
223 if (my_args.log_file || my_args.log_priority) {
224 log.name = NULL;
225 log.file = my_args.log_file;
226 log.level = my_args.log_priority;
227 log.prefix = my_args.progname;
228 log.quiet = my_args.quiet;
229 log.lxcpath = my_args.lxcpath[0];
230
231 if (lxc_log_init(&log))
232 exit(EXIT_FAILURE);
233 }
234
235 struct lengths max_len = {
236 /* default header length */
237 .name_length = 4, /* NAME */
238 .state_length = 5, /* STATE */
239 .groups_length = 6, /* GROUPS */
240 .interface_length = 9, /* INTERFACE */
241 .ipv4_length = 4, /* IPV4 */
242 .ipv6_length = 4, /* IPV6 */
243 .init_length = 3, /* PID */
244 .ram_length = 3, /* RAM */
245 .swap_length = 4, /* SWAP */
246 .autostart_length = 9, /* AUTOSTART */
247 .unprivileged_length = 12, /* UNPRIVILEGED */
248 };
249
250 char **grps = NULL;
251 size_t ngrps = 0;
252 if (my_args.groups) {
253 grps = lxc_string_split_and_trim(my_args.groups, ',');
254 ngrps = lxc_array_len((void **)grps);
255 }
256
257 struct ls *ls_arr = NULL;
258 size_t ls_size = 0;
259
260 /* &(char *){NULL} is no magic. It's just a compound literal which
261 * avoids having a pointless variable in main() that serves no purpose
262 * here. */
263 int status = ls_get(&ls_arr, &ls_size, &my_args, "", NULL, 0, &(char *){NULL}, 0, grps, ngrps);
264 if (!ls_arr && status == 0)
265 /* We did not fail. There was just nothing to do. */
266 exit(EXIT_SUCCESS);
267 else if (!ls_arr || status == -1)
268 goto out;
269
270 ls_field_width(ls_arr, ls_size, &max_len);
271
272 if (my_args.ls_fancy && !my_args.ls_fancy_format) {
273 ls_print_table(ls_arr, &max_len, ls_size);
274 } else if (my_args.ls_fancy && my_args.ls_fancy_format) {
275 ls_print_fancy_format(ls_arr, &max_len, ls_size, my_args.ls_fancy_format);
276 } else {
277 unsigned int cols = 0;
278 if (!my_args.ls_line)
279 cols = ls_get_term_width();
280 ls_print_names(ls_arr, &max_len, ls_size, cols, my_args.ls_line);
281 }
282
283 ret = EXIT_SUCCESS;
284
285 out:
286 ls_free(ls_arr, ls_size);
287 lxc_free_array((void **)grps, free);
288
289 exit(ret);
290 }
291
292 static void ls_free(struct ls *l, size_t size)
293 {
294 size_t i;
295 struct ls *m = NULL;
296
297 for (i = 0, m = l; i < size; i++, m++) {
298 free(m->groups);
299 free(m->interface);
300 free(m->ipv4);
301 free(m->ipv6);
302 free(m->name);
303 free(m->state);
304 }
305 free(l);
306 }
307
308 static char *ls_get_config_item(struct lxc_container *c, const char *item,
309 bool running)
310 {
311 if (running)
312 return c->get_running_config_item(c, item);
313
314 int len = c->get_config_item(c, item, NULL, 0);
315 if (len <= 0)
316 return NULL;
317
318 char *val = malloc((len + 1) * sizeof(*val));
319 if (!val)
320 return NULL;
321
322 if (c->get_config_item(c, item, val, len + 1) != len) {
323 free(val);
324 val = NULL;
325 }
326
327 return val;
328 }
329
330 static void ls_free_arr(char **arr, size_t size)
331 {
332 size_t i;
333
334 for (i = 0; i < size; i++)
335 free(arr[i]);
336
337 free(arr);
338 }
339
340 static int ls_get(struct ls **m, size_t *size, const struct lxc_arguments *args,
341 const char *basepath, const char *parent, unsigned int lvl,
342 char **lockpath, size_t len_lockpath, char **grps_must,
343 size_t grps_must_len)
344 {
345 /* As ls_get() is non-tail recursive we face the inherent danger of
346 * blowing up the stack at some level of nesting. To have at least some
347 * security we define MAX_NESTLVL to be 5. That should be sufficient for
348 * most users. The argument lvl can be used to keep track of the level
349 * of nesting we are at. If lvl is greater than the allowed default
350 * level or the level the user specified on the command line we return
351 * and unwind the stack. */
352 if (lvl > args->ls_nesting)
353 return 0;
354
355 int num = 0, ret = -1;
356 char **containers = NULL;
357 /* If we, at some level of nesting, encounter a stopped container but
358 * want to retrieve nested containers we need to build an absolute path
359 * beginning from it. Initially, at nesting level 0, basepath will
360 * simply be the empty string and path will simply be whatever the
361 * default lxcpath or the path the user gave us is. Basepath will also
362 * be the empty string in case we encounter a running container since we
363 * can simply attach to its namespace to retrieve nested containers. */
364 char *path = lxc_append_paths(basepath, args->lxcpath[0]);
365 if (!path)
366 goto out;
367
368 if (!dir_exists(path)) {
369 ret = 0;
370 goto out;
371 }
372
373 /* Do not do more work than is necessary right from the start. */
374 if (args->ls_active || args->ls_frozen)
375 num = list_active_containers(path, &containers, NULL);
376 else
377 num = list_all_containers(path, &containers, NULL);
378 if (num == -1) {
379 num = 0;
380 goto out;
381 }
382
383 char *tmp = NULL;
384 int check;
385 struct ls *l = NULL;
386 struct lxc_container *c = NULL;
387 size_t i;
388
389 for (i = 0; i < (size_t)num; i++) {
390 char *name = containers[i];
391
392 /* Filter container names by regex the user gave us. */
393 if (args->ls_filter || args->argc == 1) {
394 regex_t preg;
395
396 tmp = args->ls_filter ? args->ls_filter : args->argv[0];
397 check = regcomp(&preg, tmp, REG_NOSUB | REG_EXTENDED);
398 if (check == REG_ESPACE) /* we're out of memory */
399 goto out;
400 else if (check != 0)
401 continue;
402
403 check = regexec(&preg, name, 0, NULL, 0);
404 regfree(&preg);
405 if (check != 0)
406 continue;
407 }
408
409 errno = 0;
410 c = lxc_container_new(name, path);
411 if ((errno == ENOMEM) && !c)
412 goto out;
413 else if (!c)
414 continue;
415
416 if (args->ls_defined && !c->is_defined(c))
417 goto put_and_next;
418
419 /* This does not allocate memory so no worries about freeing it
420 * when we goto next or out. */
421 const char *state_tmp = c->state(c);
422 if (!state_tmp)
423 state_tmp = "UNKNOWN";
424
425 if (args->ls_running && !c->is_running(c))
426 goto put_and_next;
427
428 if (args->ls_frozen && !args->ls_active && strcmp(state_tmp, "FROZEN"))
429 goto put_and_next;
430
431 if (args->ls_stopped && strcmp(state_tmp, "STOPPED"))
432 goto put_and_next;
433
434 bool running = c->is_running(c);
435
436 char *grp_tmp = ls_get_groups(c, running);
437 if (!ls_has_all_grps(grp_tmp, grps_must, grps_must_len)) {
438 free(grp_tmp);
439 goto put_and_next;
440 }
441
442 /* Now it makes sense to allocate memory. */
443 l = ls_new(m, size);
444 if (!l) {
445 free(grp_tmp);
446 goto put_and_next;
447 }
448
449 /* How deeply nested are we? */
450 l->nestlvl = lvl;
451
452 l->groups = grp_tmp;
453
454 l->running = running;
455
456 if (parent && args->ls_nesting && (args->ls_line || !args->ls_fancy))
457 /* Prepend the name of the container with all its parents when
458 * the user requests it. */
459 l->name = lxc_append_paths(parent, name);
460 else
461 /* Otherwise simply record the name. */
462 l->name = strdup(name);
463 if (!l->name)
464 goto put_and_next;
465
466 /* Do not record stuff the user did not explicitly request. */
467 if (args->ls_fancy) {
468 /* Maybe we should even consider the name sensitive and
469 * hide it when you're not allowed to control the
470 * container. */
471 if (!c->may_control(c))
472 goto put_and_next;
473
474 l->state = strdup(state_tmp);
475 if (!l->state)
476 goto put_and_next;
477
478 tmp = ls_get_config_item(c, "lxc.start.auto", running);
479 if (tmp) {
480 unsigned int astart = 0;
481 if (lxc_safe_uint(tmp, &astart) < 0)
482 printf("Could not parse value for 'lxc.start.auto'.\n");
483 if (astart > 1)
484 printf("Wrong value for 'lxc.start.auto = %d'.\n", astart);
485 l->autostart = astart == 1 ? true : false;
486 }
487 free(tmp);
488
489 if (running) {
490 char *val;
491
492 l->init = c->init_pid(c);
493 if (l->init <= 0)
494 goto put_and_next;
495
496 l->interface = ls_get_interface(c);
497
498 l->ipv4 = ls_get_ips(c, "inet");
499
500 l->ipv6 = ls_get_ips(c, "inet6");
501
502 tmp = ls_get_cgroup_item(c, "memory.usage_in_bytes");
503 if (tmp) {
504 l->ram = strtoull(tmp, NULL, 0);
505 l->ram = l->ram / 1024 /1024;
506 free(tmp);
507 }
508
509 l->swap = ls_get_swap(c);
510
511 val = c->get_running_config_item(c, "lxc.idmap");
512 l->unprivileged = !(val == NULL);
513 free(val);
514 } else {
515 int ret;
516
517 ret = c->get_config_item(c, "lxc.idmap", NULL, 0);
518 l->unprivileged = !(ret == 0);
519 }
520 }
521
522 /* Get nested containers: Only do this after we have gathered
523 * all other information we need. */
524 if (args->ls_nesting && running) {
525 struct wrapargs wargs = (struct wrapargs){.args = NULL};
526
527 /* Open a socket so that the child can communicate with us. */
528 check = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wargs.pipefd);
529 if (check == -1)
530 goto put_and_next;
531
532 /* Set the next nesting level. */
533 wargs.nestlvl = lvl + 1;
534 /* Send in the parent for the next nesting level. */
535 wargs.parent = l->name;
536 wargs.args = args;
537 wargs.grps_must = grps_must;
538 wargs.grps_must_len = grps_must_len;
539
540 pid_t out;
541
542 lxc_attach_options_t aopt = LXC_ATTACH_OPTIONS_DEFAULT;
543 aopt.env_policy = LXC_ATTACH_CLEAR_ENV;
544
545 /* fork(): Attach to the namespace of the container and
546 * run ls_get() in it which is called in ls_get_wrapper(). */
547 check = c->attach(c, ls_get_wrapper, &wargs, &aopt, &out);
548 /* close the socket */
549 close(wargs.pipefd[1]);
550
551 /* Retrieve all information we want from the child. */
552 if (check == 0)
553 if (ls_deserialize(wargs.pipefd[0], m, size) == -1)
554 goto put_and_next;
555
556 /* Wait for the child to finish. */
557 wait_for_pid(out);
558
559 /* We've done all the communication we need so shutdown
560 * the socket and close it. */
561 shutdown(wargs.pipefd[0], SHUT_RDWR);
562 close(wargs.pipefd[0]);
563 } else if (args->ls_nesting && !running) {
564 /* This way of extracting the rootfs is not safe since
565 * it will return very different things depending on the
566 * storage backend that is used for the container. We
567 * need a path-extractor function. We face the same
568 * problem with the ovl_mkdir() function in
569 * lxcoverlay.{c,h}. */
570 char *curr_path = ls_get_config_item(c, "lxc.rootfs.path", running);
571 if (!curr_path)
572 goto put_and_next;
573
574 /* Since the container is not running and we cannot
575 * attach to it we need another strategy to retrieve
576 * nested containers. What we do is simply create a
577 * growing path which will lead us into the rootfs of
578 * the next container where it stores its containers. */
579 char *newpath = lxc_append_paths(basepath, curr_path);
580 free(curr_path);
581 if (!newpath)
582 goto put_and_next;
583
584 /* We want to remove all locks we create under
585 * /run/lxc/lock so we create a string pointing us to
586 * the lock path for the current container. */
587 if (ls_remove_lock(path, name, lockpath, &len_lockpath, true) == -1) {
588 free(newpath);
589 goto put_and_next;
590 }
591
592 ls_get(m, size, args, newpath, l->name, lvl + 1, lockpath, len_lockpath, grps_must, grps_must_len);
593 free(newpath);
594
595 /* Remove the lock. No need to check for failure here. */
596 ls_remove_lock(path, name, lockpath, &len_lockpath, false);
597 }
598
599 put_and_next:
600 lxc_container_put(c);
601 }
602 ret = 0;
603
604 out:
605 ls_free_arr(containers, num);
606 free(path);
607
608 /* lockpath is shared amongst all non-fork()ing recursive calls to
609 * ls_get() so only free it on the uppermost level. */
610 if (lvl == 0)
611 free(*lockpath);
612
613 return ret;
614 }
615
616 static char *ls_get_cgroup_item(struct lxc_container *c, const char *item)
617 {
618 int len = c->get_cgroup_item(c, item, NULL, 0);
619 if (len <= 0)
620 return NULL;
621
622 char *val = malloc((len + 1) * sizeof(*val));
623 if (!val)
624 return NULL;
625
626 if (c->get_cgroup_item(c, item, val, len + 1) != len) {
627 free(val);
628 val = NULL;
629 }
630
631 return val;
632 }
633
634 static char *ls_get_groups(struct lxc_container *c, bool running)
635 {
636 int len = 0;
637 char *val = NULL;
638
639 if (running)
640 val = c->get_running_config_item(c, "lxc.group");
641 else
642 len = c->get_config_item(c, "lxc.group", NULL, 0);
643
644 if (!val && (len > 0)) {
645 val = malloc((len + 1) * sizeof(*val));
646 if (c->get_config_item(c, "lxc.group", val, len + 1) != len) {
647 free(val);
648 return NULL;
649 }
650 }
651
652 if (val) {
653 char *tmp;
654
655 if ((tmp = strrchr(val, '\n')))
656 *tmp = '\0';
657
658 tmp = lxc_string_replace("\n", ", ", val);
659 free(val);
660 val = tmp;
661 }
662
663 return val;
664 }
665
666 static char *ls_get_ips(struct lxc_container *c, const char *inet)
667 {
668 char *ips = NULL;
669 char **iptmp;
670
671 iptmp = c->get_ips(c, NULL, inet, 0);
672 if (iptmp)
673 ips = lxc_string_join(", ", (const char **)iptmp, false);
674
675 lxc_free_array((void **)iptmp, free);
676
677 return ips;
678 }
679
680 static char *ls_get_interface(struct lxc_container *c)
681 {
682 char **interfaces = c->get_interfaces(c);
683 if (!interfaces)
684 return NULL;
685
686 char *interface = lxc_string_join(", ", (const char **)interfaces, false);
687
688 lxc_free_array((void **)interfaces, free);
689
690 return interface;
691 }
692
693 /*
694 * To calculate swap usage we should not simply check memory.usage_in_bytes and
695 * memory.memsw.usage_in_bytes and then do:
696 * swap = memory.memsw.usage_in_bytes - memory.usage_in_bytes;
697 * because we might receive an incorrect/negative value.
698 * Instead we check memory.stat and check the "swap" value.
699 */
700 static double ls_get_swap(struct lxc_container *c)
701 {
702 char *stat, *swap, *tmp;
703 unsigned long long int num = 0;
704
705 stat = ls_get_cgroup_item(c, "memory.stat");
706 if (!stat)
707 goto out;
708
709 swap = strstr(stat, "\nswap");
710 if (!swap)
711 goto out;
712
713 /* start_of_swap_value = '\n' + strlen(swap) + ' ' */
714 swap = 1 + swap + 4 + 1;
715
716 /* find end of swap value */
717 tmp = strchr(swap, '\n');
718 if (!tmp)
719 goto out;
720
721 *tmp = '\0';
722
723 num = strtoull(swap, NULL, 0);
724 num = num / 1024 / 1024;
725
726 out:
727 free(stat);
728
729 return num;
730 }
731
732 static unsigned int ls_get_term_width(void)
733 {
734 struct winsize ws;
735
736 if (((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) &&
737 (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1) &&
738 (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)) ||
739 (ws.ws_col == 0))
740 return 0;
741
742 return ws.ws_col;
743 }
744
745 static bool ls_has_all_grps(const char *has, char **must, size_t must_len)
746 {
747 bool bret = false;
748
749 if (!has && must)
750 return false;
751 else if (!must)
752 return true;
753
754 char **tmp_has = lxc_string_split_and_trim(has, ',');
755 size_t tmp_has_len = lxc_array_len((void **)tmp_has);
756
757 /* Don't do any unnecessary work. */
758 if (must_len > tmp_has_len)
759 goto out;
760
761 size_t i, j;
762 for (i = 0; i < must_len; i++) {
763 for (j = 0; j < tmp_has_len; j++)
764 if (strcmp(must[i], tmp_has[j]) == 0)
765 break;
766 if (j == tmp_has_len)
767 break;
768 }
769
770 if (i == must_len)
771 bret = true;
772
773 out:
774 lxc_free_array((void **)tmp_has, free);
775
776 return bret;
777 }
778
779 static struct ls *ls_new(struct ls **ls, size_t *size)
780 {
781 struct ls *m, *n;
782
783 n = realloc(*ls, (*size + 1) * sizeof(struct ls));
784 if (!n)
785 return NULL;
786
787 *ls = n;
788 m = *ls + *size;
789 (*size)++;
790
791 *m = (struct ls){.name = NULL, .init = -1};
792
793 return m;
794 }
795
796 static void ls_print_names(struct ls *l, struct lengths *lht,
797 size_t size, size_t termwidth, bool list)
798 {
799 /* If list is empty do nothing. */
800 if (size == 0)
801 return;
802
803 size_t i, len = 0;
804 struct ls *m = NULL;
805
806 for (i = 0, m = l; i < size; i++, m++) {
807 if (list) {
808 printf("%s\n", m->name ? m->name : "-");
809 } else {
810 printf("%-*s", lht->name_length, m->name ? m->name : "-");
811
812 len += lht->name_length;
813 if ((len + lht->name_length) >= termwidth) {
814 printf("\n");
815 len = 0;
816 } else {
817 printf(" ");
818 len++;
819 }
820 }
821 }
822
823 if (len > 0)
824 printf("\n");
825 }
826
827 static void ls_print_fancy_format(struct ls *l, struct lengths *lht,
828 size_t size, const char *fancy_fmt)
829 {
830 /* If list is empty do nothing. */
831 if (size == 0)
832 return;
833
834 char **tmp = lxc_string_split_and_trim(fancy_fmt, ',');
835 if (!tmp)
836 return;
837
838 char **s;
839 /* Check for invalid keys. */
840 for (s = tmp; s && *s; s++) {
841 if (strcasecmp(*s, "NAME") && strcasecmp(*s, "STATE") &&
842 strcasecmp(*s, "PID") && strcasecmp(*s, "RAM") &&
843 strcasecmp(*s, "SWAP") && strcasecmp(*s, "AUTOSTART") &&
844 strcasecmp(*s, "GROUPS") && strcasecmp(*s, "INTERFACE") &&
845 strcasecmp(*s, "IPV4") && strcasecmp(*s, "IPV6") &&
846 strcasecmp(*s, "UNPRIVILEGED")) {
847 fprintf(stderr, "Invalid key: %s\n", *s);
848 lxc_free_array((void **)tmp, free);
849 return;
850 }
851 }
852
853 /* print header */
854 for (s = tmp; s && *s; s++) {
855 if (strcasecmp(*s, "NAME") == 0)
856 printf("%-*s ", lht->name_length, "NAME");
857 else if (strcasecmp(*s, "STATE") == 0)
858 printf("%-*s ", lht->state_length, "STATE");
859 else if (strcasecmp(*s, "PID") == 0)
860 printf("%-*s ", lht->init_length, "PID");
861 else if (strcasecmp(*s, "RAM") == 0)
862 printf("%-*s ", lht->ram_length + 2, "RAM");
863 else if (strcasecmp(*s, "SWAP") == 0)
864 printf("%-*s ", lht->swap_length + 2, "SWAP");
865 else if (strcasecmp(*s, "AUTOSTART") == 0)
866 printf("%-*s ", lht->autostart_length, "AUTOSTART");
867 else if (strcasecmp(*s, "GROUPS") == 0)
868 printf("%-*s ", lht->groups_length, "GROUPS");
869 else if (strcasecmp(*s, "INTERFACE") == 0)
870 printf("%-*s ", lht->interface_length, "INTERFACE");
871 else if (strcasecmp(*s, "IPV4") == 0)
872 printf("%-*s ", lht->ipv4_length, "IPV4");
873 else if (strcasecmp(*s, "IPV6") == 0)
874 printf("%-*s ", lht->ipv6_length, "IPV6");
875 else if (strcasecmp(*s, "UNPRIVILEGED") == 0)
876 printf("%-*s ", lht->unprivileged_length, "UNPRIVILEGED");
877 }
878 printf("\n");
879
880 struct ls *m = NULL;
881 size_t i;
882
883 for (i = 0, m = l; i < size; i++, m++) {
884 for (s = tmp; s && *s; s++) {
885 if (strcasecmp(*s, "NAME") == 0) {
886 if (m->nestlvl > 0) {
887 printf("%*s", m->nestlvl, "\\");
888 printf("%-*s ", lht->name_length - m->nestlvl, m->name ? m->name : "-");
889 } else {
890 printf("%-*s ", lht->name_length, m->name ? m->name : "-");
891 }
892 } else if (strcasecmp(*s, "STATE") == 0) {
893 printf("%-*s ", lht->state_length, m->state ? m->state : "-");
894 } else if (strcasecmp(*s, "PID") == 0) {
895 if (m->init > 0)
896 printf("%-*d ", lht->init_length, m->init);
897 else
898 printf("%-*s ", lht->init_length, "-");
899 } else if (strcasecmp(*s, "RAM") == 0) {
900 if ((m->ram >= 0) && m->running)
901 printf("%*.2fMB ", lht->ram_length, m->ram);
902 else
903 printf("%-*s ", lht->ram_length, "-");
904 } else if (strcasecmp(*s, "SWAP") == 0) {
905 if ((m->swap >= 0) && m->running)
906 printf("%*.2fMB ", lht->swap_length, m->swap);
907 else
908 printf("%-*s ", lht->swap_length, "-");
909 } else if (strcasecmp(*s, "AUTOSTART") == 0) {
910 printf("%-*d ", lht->autostart_length, m->autostart);
911 } else if (strcasecmp(*s, "GROUPS") == 0) {
912 printf("%-*s ", lht->groups_length, m->groups ? m->groups : "-");
913 } else if (strcasecmp(*s, "INTERFACE") == 0) {
914 printf("%-*s ", lht->interface_length, m->interface ? m->interface : "-");
915 } else if (strcasecmp(*s, "IPV4") == 0) {
916 printf("%-*s ", lht->ipv4_length, m->ipv4 ? m->ipv4 : "-");
917 } else if (strcasecmp(*s, "IPV6") == 0) {
918 printf("%-*s ", lht->ipv6_length, m->ipv6 ? m->ipv6 : "-");
919 } else if (strcasecmp(*s, "UNPRIVILEGED") == 0) {
920 printf("%-*s ", lht->unprivileged_length, m->unprivileged ? "true" : "false");
921 }
922 }
923 printf("\n");
924 }
925
926 lxc_free_array((void **)tmp, free);
927 }
928
929 static void ls_print_table(struct ls *l, struct lengths *lht,
930 size_t size)
931 {
932 size_t i;
933
934 /* If list is empty do nothing. */
935 if (size == 0)
936 return;
937
938 struct ls *m = NULL;
939
940 /* print header */
941 printf("%-*s ", lht->name_length, "NAME");
942 printf("%-*s ", lht->state_length, "STATE");
943 printf("%-*s ", lht->autostart_length, "AUTOSTART");
944 printf("%-*s ", lht->groups_length, "GROUPS");
945 printf("%-*s ", lht->ipv4_length, "IPV4");
946 printf("%-*s ", lht->ipv6_length, "IPV6");
947 printf("%-*s ", lht->unprivileged_length, "UNPRIVILEGED");
948 printf("\n");
949
950 for (i = 0, m = l; i < size; i++, m++) {
951 if (m->nestlvl > 0) {
952 printf("%*s", m->nestlvl, "\\");
953 printf("%-*s ", lht->name_length - m->nestlvl, m->name ? m->name : "-");
954 } else {
955 printf("%-*s ", lht->name_length, m->name ? m->name : "-");
956 }
957
958 printf("%-*s ", lht->state_length, m->state ? m->state : "-");
959 printf("%-*d ", lht->autostart_length, m->autostart);
960 printf("%-*s ", lht->groups_length, m->groups ? m->groups : "-");
961 printf("%-*s ", lht->ipv4_length, m->ipv4 ? m->ipv4 : "-");
962 printf("%-*s ", lht->ipv6_length, m->ipv6 ? m->ipv6 : "-");
963 printf("%-*s ", lht->unprivileged_length, m->unprivileged ? "true" : "false");
964 printf("\n");
965 }
966 }
967
968 static int my_parser(struct lxc_arguments *args, int c, char *arg)
969 {
970 char *invalid;
971 unsigned long int m, n = MAX_NESTLVL;
972
973 switch (c) {
974 case '1':
975 args->ls_line = true;
976 break;
977 case 'f':
978 args->ls_fancy = true;
979 break;
980 case LS_ACTIVE:
981 args->ls_active = true;
982 break;
983 case LS_FROZEN:
984 args->ls_frozen = true;
985 break;
986 case LS_RUNNING:
987 args->ls_running = true;
988 break;
989 case LS_STOPPED:
990 args->ls_stopped = true;
991 break;
992 case LS_DEFINED:
993 args->ls_defined = true;
994 break;
995 case LS_NESTING:
996 /* In case strtoul() receives a string that represents a
997 * negative number it will return ULONG_MAX - the number that
998 * the string represents if the number the string represents is
999 * < ULONG_MAX and ULONG_MAX otherwise. But it will consider
1000 * this valid input and not set errno. So we check manually if
1001 * the first character of num_string == '-'. Otherwise the
1002 * default level remains set. */
1003 if (arg && !(*arg == '-')) {
1004 errno = 0;
1005 m = strtoul(arg, &invalid, 0);
1006 /* ls_nesting has type unsigned int. */
1007 if (!errno && (*invalid == '\0') && (m <= UINT_MAX))
1008 n = m;
1009 }
1010 args->ls_nesting = n;
1011 break;
1012 case 'g':
1013 args->groups = arg;
1014 break;
1015 case LS_FILTER:
1016 args->ls_filter = arg;
1017 break;
1018 case 'F':
1019 args->ls_fancy_format = arg;
1020 break;
1021 }
1022
1023 return 0;
1024 }
1025
1026 static int ls_get_wrapper(void *wrap)
1027 {
1028 int ret = -1;
1029 size_t len = 0;
1030 struct wrapargs *wargs = (struct wrapargs *)wrap;
1031 struct ls *m = NULL, *n = NULL;
1032 size_t i;
1033
1034 /* close pipe */
1035 close(wargs->pipefd[0]);
1036
1037 /* &(char *){NULL} is no magic. It's just a compound literal which
1038 * allows us to avoid keeping a pointless variable around. */
1039 ls_get(&m, &len, wargs->args, "", wargs->parent, wargs->nestlvl, &(char *){NULL}, 0, wargs->grps_must, wargs->grps_must_len);
1040 if (!m)
1041 goto out;
1042
1043 /* send length */
1044 if (lxc_write_nointr(wargs->pipefd[1], &len, sizeof(len)) <= 0)
1045 goto out;
1046
1047 for (i = 0, n = m; i < len; i++, n++) {
1048 if (ls_serialize(wargs->pipefd[1], n) == -1)
1049 goto out;
1050 }
1051 ret = 0;
1052
1053 out:
1054 shutdown(wargs->pipefd[1], SHUT_RDWR);
1055 close(wargs->pipefd[1]);
1056 ls_free(m, len);
1057
1058 return ret;
1059 }
1060
1061 static int ls_remove_lock(const char *path, const char *name,
1062 char **lockpath, size_t *len_lockpath, bool recalc)
1063 {
1064 int ret = -1;
1065 char *rundir;
1066
1067 /* lockfile will be:
1068 * "/run" + "/lxc/lock/$lxcpath/$lxcname + '\0' if root
1069 * or
1070 * $XDG_RUNTIME_DIR + "/lxc/lock/$lxcpath/$lxcname + '\0' if non-root
1071 */
1072 rundir = get_rundir();
1073 if (!rundir)
1074 goto out;
1075
1076 /* Avoid doing unnecessary work if we can. */
1077 if (recalc) {
1078 size_t newlen = strlen(path) + strlen(name) + strlen(rundir) + /* / + lxc + / + lock + / + / = */ 11 + 1;
1079 if (newlen > *len_lockpath) {
1080 char *tmp = realloc(*lockpath, newlen * 2);
1081 if (!tmp)
1082 goto out;
1083 *lockpath = tmp;
1084 *len_lockpath = newlen * 2;
1085 }
1086 }
1087
1088 int check = snprintf(*lockpath, *len_lockpath, "%s/lxc/lock/%s/%s", rundir, path, name);
1089 if (check < 0 || (size_t)check >= *len_lockpath)
1090 goto out;
1091
1092 ret = recursive_destroy(*lockpath);
1093 if (ret < 0)
1094 WARN("Failed to destroy \"%s\"", *lockpath);
1095
1096 ret = 0;
1097
1098 out:
1099 free(rundir);
1100 return ret;
1101 }
1102
1103 static int ls_send_str(int fd, const char *buf)
1104 {
1105 size_t slen = 0;
1106
1107 if (buf)
1108 slen = strlen(buf);
1109
1110 if (lxc_write_nointr(fd, &slen, sizeof(slen)) != sizeof(slen))
1111 return -1;
1112
1113 if (slen > 0) {
1114 if (lxc_write_nointr(fd, buf, slen) != (ssize_t)slen)
1115 return -1;
1116 }
1117
1118 return 0;
1119 }
1120
1121 static int ls_serialize(int wpipefd, struct ls *n)
1122 {
1123 ssize_t nbytes = sizeof(n->ram);
1124 if (lxc_write_nointr(wpipefd, &n->ram, (size_t)nbytes) != nbytes)
1125 return -1;
1126
1127 nbytes = sizeof(n->swap);
1128 if (lxc_write_nointr(wpipefd, &n->swap, (size_t)nbytes) != nbytes)
1129 return -1;
1130
1131 nbytes = sizeof(n->init);
1132 if (lxc_write_nointr(wpipefd, &n->init, (size_t)nbytes) != nbytes)
1133 return -1;
1134
1135 nbytes = sizeof(n->autostart);
1136 if (lxc_write_nointr(wpipefd, &n->autostart, (size_t)nbytes) != nbytes)
1137 return -1;
1138
1139 nbytes = sizeof(n->running);
1140 if (lxc_write_nointr(wpipefd, &n->running, (size_t)nbytes) != nbytes)
1141 return -1;
1142
1143 nbytes = sizeof(n->unprivileged);
1144 if (lxc_write_nointr(wpipefd, &n->unprivileged, (size_t)nbytes) != nbytes)
1145 return -1;
1146
1147 nbytes = sizeof(n->nestlvl);
1148 if (lxc_write_nointr(wpipefd, &n->nestlvl, (size_t)nbytes) != nbytes)
1149 return -1;
1150
1151 /* NAME */
1152 if (ls_send_str(wpipefd, n->name) < 0)
1153 return -1;
1154
1155 /* STATE */
1156 if (ls_send_str(wpipefd, n->state) < 0)
1157 return -1;
1158
1159 /* GROUPS */
1160 if (ls_send_str(wpipefd, n->groups) < 0)
1161 return -1;
1162
1163 /* INTERFACE */
1164 if (ls_send_str(wpipefd, n->interface) < 0)
1165 return -1;
1166
1167 /* IPV4 */
1168 if (ls_send_str(wpipefd, n->ipv4) < 0)
1169 return -1;
1170
1171 /* IPV6 */
1172 if (ls_send_str(wpipefd, n->ipv6) < 0)
1173 return -1;
1174
1175 return 0;
1176 }
1177
1178 static int ls_recv_str(int fd, char **buf)
1179 {
1180 ssize_t ret;
1181 size_t slen = 0;
1182
1183 ret = lxc_read_nointr(fd, &slen, sizeof(slen));
1184 if (ret != sizeof(slen))
1185 return -1;
1186
1187 if (slen > 0) {
1188 *buf = malloc(sizeof(char) * (slen + 1));
1189 if (!*buf)
1190 return -1;
1191
1192 ret = lxc_read_nointr(fd, *buf, slen);
1193 if (ret != (ssize_t)slen) {
1194 free(*buf);
1195 return -1;
1196 }
1197
1198 (*buf)[slen] = '\0';
1199 }
1200
1201 return 0;
1202 }
1203
1204 static int ls_deserialize(int rpipefd, struct ls **m, size_t *len)
1205 {
1206 struct ls *n;
1207 size_t sublen = 0;
1208 ssize_t nbytes = 0;
1209
1210 /* get length */
1211 nbytes = sizeof(sublen);
1212 if (lxc_read_nointr(rpipefd, &sublen, (size_t)nbytes) != nbytes)
1213 return -1;
1214
1215 while (sublen-- > 0) {
1216 n = ls_new(m, len);
1217 if (!n)
1218 return -1;
1219
1220 nbytes = sizeof(n->ram);
1221 if (lxc_read_nointr(rpipefd, &n->ram, (size_t)nbytes) != nbytes)
1222 return -1;
1223
1224 nbytes = sizeof(n->swap);
1225 if (lxc_read_nointr(rpipefd, &n->swap, (size_t)nbytes) != nbytes)
1226 return -1;
1227
1228 nbytes = sizeof(n->init);
1229 if (lxc_read_nointr(rpipefd, &n->init, (size_t)nbytes) != nbytes)
1230 return -1;
1231
1232 nbytes = sizeof(n->autostart);
1233 if (lxc_read_nointr(rpipefd, &n->autostart, (size_t)nbytes) != nbytes)
1234 return -1;
1235
1236 nbytes = sizeof(n->running);
1237 if (lxc_read_nointr(rpipefd, &n->running, (size_t)nbytes) != nbytes)
1238 return -1;
1239
1240 nbytes = sizeof(n->unprivileged);
1241 if (lxc_read_nointr(rpipefd, &n->unprivileged, (size_t)nbytes) != nbytes)
1242 return -1;
1243
1244 nbytes = sizeof(n->nestlvl);
1245 if (lxc_read_nointr(rpipefd, &n->nestlvl, (size_t)nbytes) != nbytes)
1246 return -1;
1247
1248 /* NAME */
1249 if (ls_recv_str(rpipefd, &n->name) < 0)
1250 return -1;
1251
1252 /* STATE */
1253 if (ls_recv_str(rpipefd, &n->state) < 0)
1254 return -1;
1255
1256 /* GROUPS */
1257 if (ls_recv_str(rpipefd, &n->groups) < 0)
1258 return -1;
1259
1260 /* INTERFACE */
1261 if (ls_recv_str(rpipefd, &n->interface) < 0)
1262 return -1;
1263
1264 /* IPV4 */
1265 if (ls_recv_str(rpipefd, &n->ipv4) < 0)
1266 return -1;
1267
1268 /* IPV6 */
1269 if (ls_recv_str(rpipefd, &n->ipv6) < 0)
1270 return -1;
1271 }
1272
1273 return 0;
1274 }
1275
1276 static void ls_field_width(const struct ls *l, const size_t size,
1277 struct lengths *lht)
1278 {
1279 const struct ls *m;
1280 size_t i, len = 0;
1281
1282 for (i = 0, m = l; i < size; i++, m++) {
1283 if (m->name) {
1284 len = strlen(m->name) + m->nestlvl;
1285 if (len > lht->name_length)
1286 lht->name_length = len;
1287 }
1288
1289 if (m->state) {
1290 len = strlen(m->state);
1291 if (len > lht->state_length)
1292 lht->state_length = len;
1293 }
1294
1295 if (m->interface) {
1296 len = strlen(m->interface);
1297 if (len > lht->interface_length)
1298 lht->interface_length = len;
1299 }
1300
1301 if (m->groups) {
1302 len = strlen(m->groups);
1303 if (len > lht->groups_length)
1304 lht->groups_length = len;
1305 }
1306 if (m->ipv4) {
1307 len = strlen(m->ipv4);
1308 if (len > lht->ipv4_length)
1309 lht->ipv4_length = len;
1310 }
1311
1312 if (m->ipv6) {
1313 len = strlen(m->ipv6);
1314 if (len > lht->ipv6_length)
1315 lht->ipv6_length = len;
1316 }
1317
1318 if ((len = snprintf(NULL, 0, "%.2f", m->ram)) > lht->ram_length)
1319 lht->ram_length = len;
1320
1321 if ((len = snprintf(NULL, 0, "%.2f", m->swap)) > lht->swap_length)
1322 lht->swap_length = len;
1323
1324 if (m->init != -1) {
1325 if ((len = snprintf(NULL, 0, "%d", m->init)) > lht->init_length)
1326 lht->init_length = len;
1327 }
1328 }
1329 }