]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxc_stop.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include <sys/types.h>
28 #include <lxc/lxccontainer.h>
32 #include "arguments.h"
36 #define OPT_NO_LOCK OPT_USAGE+1
37 #define OPT_NO_KILL OPT_USAGE+2
39 lxc_log_define(lxc_stop_ui
, lxc
);
41 static int my_parser(struct lxc_arguments
* args
, int c
, char* arg
)
44 case 'r': args
->reboot
= 1; break;
45 case 'W': args
->nowait
= 1; break;
46 case 't': args
->timeout
= atoi(arg
); break;
47 case 'k': args
->hardstop
= 1; break;
48 case OPT_NO_LOCK
: args
->nolock
= 1; break;
49 case OPT_NO_KILL
: args
->nokill
= 1; break;
54 static const struct option my_longopts
[] = {
55 {"reboot", no_argument
, 0, 'r'},
56 {"nowait", no_argument
, 0, 'W'},
57 {"timeout", required_argument
, 0, 't'},
58 {"kill", no_argument
, 0, 'k'},
59 {"nokill", no_argument
, 0, OPT_NO_KILL
},
60 {"nolock", no_argument
, 0, OPT_NO_LOCK
},
64 static struct lxc_arguments my_args
= {
65 .progname
= "lxc-stop",
69 lxc-stop stops a container with the identifier NAME\n\
72 -n, --name=NAME NAME of the container\n\
73 -r, --reboot reboot the container\n\
74 -W, --nowait don't wait for shutdown or reboot to complete\n\
75 -t, --timeout=T wait T seconds before hard-stopping\n\
76 -k, --kill kill container rather than request clean shutdown\n\
77 --nolock Avoid using API locks\n\
78 --nokill Only request clean shutdown, don't force kill after timeout\n",
79 .options
= my_longopts
,
85 /* returns -1 on failure, 0 on success */
86 static int do_reboot_and_check(struct lxc_arguments
*a
, struct lxc_container
*c
)
91 int timeout
= a
->timeout
;
104 /* can we use c-> wait for this, assuming it will
105 * re-enter RUNNING? For now just sleep */
106 int elapsed_time
, curtime
= 0;
109 newpid
= c
->init_pid(c
);
110 if (newpid
!= -1 && newpid
!= pid
)
114 ret
= gettimeofday(&tv
, NULL
);
122 ret
= gettimeofday(&tv
, NULL
);
125 elapsed_time
= tv
.tv_sec
- curtime
;
126 if (timeout
- elapsed_time
<= 0)
128 timeout
-= elapsed_time
;
133 newpid
= c
->init_pid(c
);
134 if (newpid
== -1 || newpid
== pid
) {
135 printf("Reboot did not complete before timeout\n");
141 int main(int argc
, char *argv
[])
143 struct lxc_container
*c
;
147 if (lxc_arguments_parse(&my_args
, argc
, argv
))
150 if (lxc_log_init(my_args
.name
, my_args
.log_file
, my_args
.log_priority
,
151 my_args
.progname
, my_args
.quiet
, my_args
.lxcpath
[0]))
153 lxc_log_options_no_override();
155 /* Set default timeout */
156 if (my_args
.timeout
== -2) {
157 if (my_args
.hardstop
) {
161 my_args
.timeout
= 60;
165 if (my_args
.nowait
) {
170 if (!my_args
.hardstop
&& my_args
.timeout
< -1) {
171 fprintf(stderr
, "invalid timeout\n");
175 if (my_args
.hardstop
&& my_args
.nokill
) {
176 fprintf(stderr
, "-k can't be used with --nokill\n");
180 if (my_args
.hardstop
&& my_args
.reboot
) {
181 fprintf(stderr
, "-k can't be used with -r\n");
185 if (my_args
.hardstop
&& my_args
.timeout
) {
186 fprintf(stderr
, "-k doesn't allow timeouts\n");
190 if (my_args
.nolock
&& !my_args
.hardstop
) {
191 fprintf(stderr
, "--nolock may only be used with -k\n");
195 /* shortcut - if locking is bogus, we should be able to kill
196 * containers at least */
198 return lxc_cmd_stop(my_args
.name
, my_args
.lxcpath
[0]);
200 c
= lxc_container_new(my_args
.name
, my_args
.lxcpath
[0]);
202 fprintf(stderr
, "Error opening container\n");
206 if (!c
->may_control(c
)) {
207 fprintf(stderr
, "Insufficent privileges to control %s\n", c
->name
);
211 if (!c
->is_running(c
)) {
212 fprintf(stderr
, "%s is not running\n", c
->name
);
218 if (my_args
.hardstop
) {
219 ret
= c
->stop(c
) ? 0 : 1;
224 if (my_args
.reboot
) {
225 ret
= do_reboot_and_check(&my_args
, c
);
230 s
= c
->shutdown(c
, my_args
.timeout
);
232 if (my_args
.timeout
== 0)
234 else if (my_args
.nokill
)
237 ret
= c
->stop(c
) ? 0 : 1;
242 lxc_container_put(c
);