]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/tools/lxc_cgroup.c
tools: Provide multicall lxc binary
[mirror_lxc.git] / src / lxc / tools / lxc_cgroup.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "config.h"
4
5 #include <libgen.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11
12 #include "lxc.h"
13
14 #include "arguments.h"
15 #include "log.h"
16
17 lxc_log_define(lxc_cgroup, lxc);
18
19 static int my_checker(const struct lxc_arguments *args);
20
21 static const struct option my_longopts[] = {
22 LXC_COMMON_OPTIONS
23 };
24
25 static struct lxc_arguments my_args = {
26 .progname = "lxc-cgroup",
27 .help = "\
28 --name=NAME state-object [value]\n\
29 \n\
30 Get or set the value of a state object (for example, 'cpuset.cpus')\n\
31 in the container's cgroup for the corresponding subsystem.\n\
32 \n\
33 Options :\n\
34 -n, --name=NAME NAME of the container\n\
35 --rcfile=FILE Load configuration file FILE\n",
36 .options = my_longopts,
37 .parser = NULL,
38 .checker = my_checker,
39 .log_priority = "ERROR",
40 .log_file = "none",
41 };
42
43 static int my_checker(const struct lxc_arguments *args)
44 {
45 if (!args->argc) {
46 ERROR("Missing state object");
47 return -1;
48 }
49
50 return 0;
51 }
52
53 int __attribute__((weak, alias("lxc_cgroup_main"))) main(int argc, char *argv[]);
54 int lxc_cgroup_main(int argc, char *argv[])
55 {
56 char *state_object = NULL, *value = NULL;
57 struct lxc_container *c;
58 struct lxc_log log;
59
60 if (lxc_arguments_parse(&my_args, argc, argv))
61 exit(EXIT_FAILURE);
62
63 log.name = my_args.name;
64 log.file = my_args.log_file;
65 log.level = my_args.log_priority;
66 log.prefix = my_args.progname;
67 log.quiet = my_args.quiet;
68 log.lxcpath = my_args.lxcpath[0];
69
70 if (lxc_log_init(&log))
71 exit(EXIT_FAILURE);
72
73 state_object = my_args.argv[0];
74
75 c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
76 if (!c)
77 exit(EXIT_FAILURE);
78
79 if (my_args.rcfile) {
80 c->clear_config(c);
81
82 if (!c->load_config(c, my_args.rcfile)) {
83 ERROR("Failed to load rcfile");
84 lxc_container_put(c);
85 exit(EXIT_FAILURE);
86 }
87
88 c->configfile = strdup(my_args.rcfile);
89 if (!c->configfile) {
90 ERROR("Out of memory setting new config filename");
91 lxc_container_put(c);
92 exit(EXIT_FAILURE);
93 }
94 }
95
96 if (!c->may_control(c)) {
97 ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name);
98 lxc_container_put(c);
99 exit(EXIT_FAILURE);
100 }
101
102 if (!c->is_running(c)) {
103 ERROR("'%s:%s' is not running", my_args.lxcpath[0], my_args.name);
104 lxc_container_put(c);
105 exit(EXIT_FAILURE);
106 }
107
108 if ((my_args.argc) > 1) {
109 value = my_args.argv[1];
110
111 if (!c->set_cgroup_item(c, state_object, value)) {
112 ERROR("Failed to assign '%s' value to '%s' for '%s'",
113 value, state_object, my_args.name);
114 lxc_container_put(c);
115 exit(EXIT_FAILURE);
116 }
117 } else {
118 char buffer[PATH_MAX];
119 int ret;
120
121 ret = c->get_cgroup_item(c, state_object, buffer, PATH_MAX);
122 if (ret < 0) {
123 ERROR("Failed to retrieve value of '%s' for '%s:%s'",
124 state_object, my_args.lxcpath[0], my_args.name);
125 lxc_container_put(c);
126 exit(EXIT_FAILURE);
127 }
128
129 printf("%*s\n", ret, buffer);
130 }
131
132 lxc_container_put(c);
133
134 exit(EXIT_SUCCESS);
135 }