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