]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxc_autostart.c
3 * Copyright © 2013 Stéphane Graber <stgraber@ubuntu.com>
4 * Copyright © 2013 Canonical Ltd.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <lxc/lxccontainer.h>
26 #include "arguments.h"
30 static int my_parser(struct lxc_arguments
* args
, int c
, char* arg
)
33 case 'k': args
->hardstop
= 1; break;
34 case 'L': args
->list
= 1; break;
35 case 'r': args
->reboot
= 1; break;
36 case 's': args
->shutdown
= 1; break;
37 case 'a': args
->all
= 1; break;
38 case 'g': args
->groups
= arg
; break;
39 case 't': args
->timeout
= atoi(arg
); break;
44 static const struct option my_longopts
[] = {
45 {"kill", no_argument
, 0, 'k'},
46 {"list", no_argument
, 0, 'L'},
47 {"reboot", no_argument
, 0, 'r'},
48 {"shutdown", no_argument
, 0, 's'},
49 {"all", no_argument
, 0, 'a'},
50 {"groups", required_argument
, 0, 'g'},
51 {"timeout", required_argument
, 0, 't'},
52 {"help", no_argument
, 0, 'h'},
56 static struct lxc_arguments my_args
= {
57 .progname
= "lxc-autostart",
60 lxc-autostart managed auto-started containers\n\
63 -k, --kill kill the containers instead of starting them\n\
64 -L, --list list all affected containers and wait delay\n\
65 -r, --reboot reboot the containers instead of starting them\n\
66 -s, --shutdown shutdown the containers instead of starting them\n\
68 -a, --all list all auto-started containers (ignore groups)\n\
69 -g, --groups list of groups (comma separated) to select\n\
70 -t, --timeout=T wait T seconds before hard-stopping\n",
71 .options
= my_longopts
,
77 int lists_contain_common_entry(struct lxc_list
*p1
, struct lxc_list
*p2
) {
90 lxc_list_for_each(it1
, p1
) {
91 lxc_list_for_each(it2
, p2
) {
92 if (strcmp(it1
->elem
, it2
->elem
) == 0)
100 struct lxc_list
*get_list(char *input
, char *delimiter
) {
101 char *workstr
= NULL
;
102 char *workptr
= NULL
;
105 struct lxc_list
*worklist
;
106 struct lxc_list
*workstr_list
;
108 workstr_list
= malloc(sizeof(*workstr_list
));
109 lxc_list_init(workstr_list
);
111 workstr
= strdup(input
);
117 for (workptr
= workstr
;;workptr
= NULL
) {
118 token
= strtok_r(workptr
, delimiter
, &sptr
);
123 worklist
= malloc(sizeof(*worklist
));
127 worklist
->elem
= strdup(token
);
128 if (!worklist
->elem
) {
133 lxc_list_add_tail(workstr_list
, worklist
);
141 struct lxc_list
*get_config_list(struct lxc_container
*c
, char *key
) {
144 struct lxc_list
*config_list
= NULL
;
146 len
= c
->get_config_item(c
, key
, NULL
, 0);
150 value
= (char*) malloc(sizeof(char)*len
+ 1);
154 if (c
->get_config_item(c
, key
, value
, len
+ 1) != len
) {
159 if (strlen(value
) == 0) {
164 config_list
= get_list(value
, "\n");
170 int get_config_integer(struct lxc_container
*c
, char *key
) {
175 len
= c
->get_config_item(c
, key
, NULL
, 0);
179 value
= (char*) malloc(sizeof(char)*len
+ 1);
183 if (c
->get_config_item(c
, key
, value
, len
+ 1) != len
) {
194 static int cmporder(const void *p1
, const void *p2
) {
195 struct lxc_container
*c1
= *(struct lxc_container
**)p1
;
196 struct lxc_container
*c2
= *(struct lxc_container
**)p2
;
198 int c1_order
= get_config_integer(c1
, "lxc.start.order");
199 int c2_order
= get_config_integer(c2
, "lxc.start.order");
201 if (c1_order
== c2_order
)
202 return strcmp(c1
->name
, c2
->name
);
204 return (c1_order
- c2_order
) * -1;
207 int main(int argc
, char *argv
[])
212 struct lxc_container
**containers
= NULL
;
213 struct lxc_list
*cmd_groups_list
= NULL
;
214 struct lxc_list
*c_groups_list
= NULL
;
215 struct lxc_list
*it
, *next
;
216 char *const default_start_args
[] = {
221 if (lxc_arguments_parse(&my_args
, argc
, argv
))
224 count
= list_defined_containers(NULL
, NULL
, &containers
);
229 qsort(&containers
[0], count
, sizeof(struct lxc_container
*), cmporder
);
231 if (my_args
.groups
&& !my_args
.all
)
232 cmd_groups_list
= get_list((char*)my_args
.groups
, ",");
234 for (i
= 0; i
< count
; i
++) {
235 struct lxc_container
*c
= containers
[i
];
237 if (!c
->may_control(c
)) {
238 lxc_container_put(c
);
242 if (get_config_integer(c
, "lxc.start.auto") != 1) {
243 lxc_container_put(c
);
248 /* Filter by group */
249 c_groups_list
= get_config_list(c
, "lxc.group");
251 ret
= lists_contain_common_entry(cmd_groups_list
, c_groups_list
);
254 lxc_list_for_each_safe(it
, c_groups_list
, next
) {
263 lxc_container_put(c
);
268 c
->want_daemonize(c
, 1);
270 if (my_args
.shutdown
) {
271 /* Shutdown the container */
272 if (c
->is_running(c
)) {
274 printf("%s\n", c
->name
);
277 if (!c
->shutdown(c
, my_args
.timeout
))
278 fprintf(stderr
, "Error shutting down container: %s\n", c
->name
);
282 else if (my_args
.hardstop
) {
283 /* Kill the container */
284 if (c
->is_running(c
)) {
286 printf("%s\n", c
->name
);
289 fprintf(stderr
, "Error killing container: %s\n", c
->name
);
293 else if (my_args
.reboot
) {
294 /* Reboot the container */
295 if (c
->is_running(c
)) {
297 printf("%s %d\n", c
->name
,
298 get_config_integer(c
, "lxc.start.delay"));
301 fprintf(stderr
, "Error rebooting container: %s\n", c
->name
);
303 sleep(get_config_integer(c
, "lxc.start.delay"));
308 /* Start the container */
309 if (!c
->is_running(c
)) {
311 printf("%s %d\n", c
->name
,
312 get_config_integer(c
, "lxc.start.delay"));
314 if (!c
->start(c
, 0, default_start_args
))
315 fprintf(stderr
, "Error starting container: %s\n", c
->name
);
317 sleep(get_config_integer(c
, "lxc.start.delay"));
323 lxc_container_put(c
);
326 if (cmd_groups_list
) {
327 lxc_list_for_each_safe(it
, cmd_groups_list
, next
) {
332 free(cmd_groups_list
);