]>
Commit | Line | Data |
---|---|---|
cc73685d | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
0ad19a3f | 2 | |
1160ce89 CB |
3 | #include "config.h" |
4 | ||
70952c01 | 5 | #include <libgen.h> |
576f946d | 6 | #include <stdio.h> |
70952c01 | 7 | #include <stdlib.h> |
744b1eec | 8 | #include <string.h> |
2ab8e9ba | 9 | #include <sys/types.h> |
d38dd64a | 10 | #include <unistd.h> |
2ab8e9ba | 11 | |
12ae2a33 | 12 | #include "lxc.h" |
f2363e38 | 13 | |
4237c6ca | 14 | #include "arguments.h" |
93f81bc7 | 15 | #include "log.h" |
16 | ||
17 | lxc_log_define(lxc_cgroup, lxc); | |
0ad19a3f | 18 | |
62ebeb04 | 19 | static int my_checker(const struct lxc_arguments *args); |
2ab8e9ba | 20 | |
4237c6ca MN |
21 | static const struct option my_longopts[] = { |
22 | LXC_COMMON_OPTIONS | |
23 | }; | |
2ab8e9ba | 24 | |
4237c6ca | 25 | static struct lxc_arguments my_args = { |
62ebeb04 | 26 | .progname = "lxc-cgroup", |
27 | .help = "\ | |
f10e7166 | 28 | --name=NAME state-object [value]\n\ |
4237c6ca | 29 | \n\ |
f10e7166 DW |
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\ | |
4237c6ca MN |
32 | \n\ |
33 | Options :\n\ | |
50b737a3 WB |
34 | -n, --name=NAME NAME of the container\n\ |
35 | --rcfile=FILE Load configuration file FILE\n", | |
62ebeb04 | 36 | .options = my_longopts, |
37 | .parser = NULL, | |
38 | .checker = my_checker, | |
39 | .log_priority = "ERROR", | |
40 | .log_file = "none", | |
4237c6ca | 41 | }; |
2ab8e9ba | 42 | |
62ebeb04 | 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 | ||
f4d02217 PM |
53 | int __attribute__((weak, alias("lxc_cgroup_main"))) main(int argc, char *argv[]); |
54 | int lxc_cgroup_main(int argc, char *argv[]) | |
4237c6ca | 55 | { |
f10e7166 | 56 | char *state_object = NULL, *value = NULL; |
9069513c | 57 | struct lxc_container *c; |
73b910a3 | 58 | struct lxc_log log; |
2ab8e9ba | 59 | |
272bc5af | 60 | if (lxc_arguments_parse(&my_args, argc, argv)) |
b52b0595 | 61 | exit(EXIT_FAILURE); |
2ab8e9ba | 62 | |
62ebeb04 | 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]; | |
f5abd74d | 69 | |
62ebeb04 | 70 | if (lxc_log_init(&log)) |
71 | exit(EXIT_FAILURE); | |
51cab631 | 72 | |
f10e7166 | 73 | state_object = my_args.argv[0]; |
2ab8e9ba | 74 | |
9069513c SH |
75 | c = lxc_container_new(my_args.name, my_args.lxcpath[0]); |
76 | if (!c) | |
b52b0595 | 77 | exit(EXIT_FAILURE); |
f5abd74d | 78 | |
50b737a3 WB |
79 | if (my_args.rcfile) { |
80 | c->clear_config(c); | |
93f81bc7 | 81 | |
50b737a3 | 82 | if (!c->load_config(c, my_args.rcfile)) { |
93f81bc7 | 83 | ERROR("Failed to load rcfile"); |
50b737a3 | 84 | lxc_container_put(c); |
b52b0595 | 85 | exit(EXIT_FAILURE); |
50b737a3 | 86 | } |
097268e1 | 87 | |
6118210e WB |
88 | c->configfile = strdup(my_args.rcfile); |
89 | if (!c->configfile) { | |
93f81bc7 | 90 | ERROR("Out of memory setting new config filename"); |
6118210e | 91 | lxc_container_put(c); |
b52b0595 | 92 | exit(EXIT_FAILURE); |
6118210e | 93 | } |
50b737a3 WB |
94 | } |
95 | ||
f5abd74d | 96 | if (!c->may_control(c)) { |
93f81bc7 | 97 | ERROR("Insufficent privileges to control %s:%s", my_args.lxcpath[0], my_args.name); |
f3e52710 | 98 | lxc_container_put(c); |
b52b0595 | 99 | exit(EXIT_FAILURE); |
f5abd74d SG |
100 | } |
101 | ||
9069513c | 102 | if (!c->is_running(c)) { |
93f81bc7 | 103 | ERROR("'%s:%s' is not running", my_args.lxcpath[0], my_args.name); |
9069513c | 104 | lxc_container_put(c); |
b52b0595 | 105 | exit(EXIT_FAILURE); |
9069513c | 106 | } |
2ab8e9ba | 107 | |
9069513c SH |
108 | if ((my_args.argc) > 1) { |
109 | value = my_args.argv[1]; | |
097268e1 | 110 | |
9069513c | 111 | if (!c->set_cgroup_item(c, state_object, value)) { |
93f81bc7 | 112 | ERROR("Failed to assign '%s' value to '%s' for '%s'", |
113 | value, state_object, my_args.name); | |
9069513c | 114 | lxc_container_put(c); |
b52b0595 | 115 | exit(EXIT_FAILURE); |
2ab8e9ba | 116 | } |
117 | } else { | |
3a5996ff | 118 | char buffer[PATH_MAX]; |
097268e1 | 119 | int ret; |
120 | ||
3a5996ff | 121 | ret = c->get_cgroup_item(c, state_object, buffer, PATH_MAX); |
70f7755e | 122 | if (ret < 0) { |
93f81bc7 | 123 | ERROR("Failed to retrieve value of '%s' for '%s:%s'", |
124 | state_object, my_args.lxcpath[0], my_args.name); | |
9069513c | 125 | lxc_container_put(c); |
b52b0595 | 126 | exit(EXIT_FAILURE); |
2ab8e9ba | 127 | } |
62ebeb04 | 128 | |
6a5cc560 | 129 | printf("%*s\n", ret, buffer); |
2ab8e9ba | 130 | } |
131 | ||
9069513c | 132 | lxc_container_put(c); |
93f81bc7 | 133 | |
b52b0595 | 134 | exit(EXIT_SUCCESS); |
0ad19a3f | 135 | } |