Commit 828695d9 by Serge Hallyn Committed by Daniel Lezcano

support proper container reboot

This patch looks for Daniel's kernel patch allowing the lxc monitor to tell container reboot from shutdown based on the exit signal. If that patch is not there, utmp monitoring is used. Otherwise, it only looks for the signal. Note that the 'conf->need_utmp_watch' is technically not necessary, as there is no harm in watching the utmp file. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@canonical.com> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 98f41f28
...@@ -203,6 +203,7 @@ struct lxc_conf { ...@@ -203,6 +203,7 @@ struct lxc_conf {
int tty; int tty;
int pts; int pts;
int reboot; int reboot;
int need_utmp_watch;
int personality; int personality;
struct utsname *utsname; struct utsname *utsname;
struct lxc_list cgroup; struct lxc_list cgroup;
......
...@@ -303,9 +303,11 @@ int lxc_poll(const char *name, struct lxc_handler *handler) ...@@ -303,9 +303,11 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
goto out_mainloop_open; goto out_mainloop_open;
} }
if (lxc_utmp_mainloop_add(&descr, handler)) { if (handler->conf->need_utmp_watch) {
ERROR("failed to add utmp handler to mainloop"); if (lxc_utmp_mainloop_add(&descr, handler)) {
goto out_mainloop_open; ERROR("failed to add utmp handler to mainloop");
goto out_mainloop_open;
}
} }
return lxc_mainloop(&descr); return lxc_mainloop(&descr);
...@@ -402,6 +404,28 @@ void lxc_abort(const char *name, struct lxc_handler *handler) ...@@ -402,6 +404,28 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
kill(handler->pid, SIGKILL); kill(handler->pid, SIGKILL);
} }
#include <sys/reboot.h>
#include <linux/reboot.h>
static int must_drop_cap_sys_boot(void)
{
FILE *f = fopen("/proc/sys/kernel/ctrl-alt-del", "r");
int ret;
int v;
if (!f)
return 1;
ret = fscanf(f, "%d", &v);
fclose(f);
if (ret != 1)
return 1;
ret = reboot(v ? LINUX_REBOOT_CMD_CAD_ON : LINUX_REBOOT_CMD_CAD_OFF);
if (ret != -1)
return 1;
return 0;
}
static int do_start(void *data) static int do_start(void *data)
{ {
struct lxc_handler *handler = data; struct lxc_handler *handler = data;
...@@ -436,10 +460,14 @@ static int do_start(void *data) ...@@ -436,10 +460,14 @@ static int do_start(void *data)
goto out_warn_father; goto out_warn_father;
} }
if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { if (must_drop_cap_sys_boot()) {
SYSERROR("failed to remove CAP_SYS_BOOT capability"); if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) {
return -1; SYSERROR("failed to remove CAP_SYS_BOOT capability");
} return -1;
}
handler->conf->need_utmp_watch = 1;
} else
handler->conf->need_utmp_watch = 0;
close(handler->sigfd); close(handler->sigfd);
...@@ -570,6 +598,24 @@ int __lxc_start(const char *name, struct lxc_conf *conf, ...@@ -570,6 +598,24 @@ int __lxc_start(const char *name, struct lxc_conf *conf,
while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR) while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
continue; continue;
if (!WIFSIGNALED(status)) {
printf("child process exited but was not signaled\n");
return -1;
}
switch(WTERMSIG(status)) {
case SIGINT: /* halt */
DEBUG("Container halting");
break;
case SIGHUP: /* reboot */
DEBUG("Container rebooting");
handler->conf->reboot = 1;
break;
default:
DEBUG("unknown exit status for init: %d\n", WTERMSIG(status));
break;
}
err = lxc_error_set_and_log(handler->pid, status); err = lxc_error_set_and_log(handler->pid, status);
out_fini: out_fini:
lxc_cgroup_destroy(name); lxc_cgroup_destroy(name);
...@@ -618,5 +664,6 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) ...@@ -618,5 +664,6 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
if (lxc_check_inherited(-1)) if (lxc_check_inherited(-1))
return -1; return -1;
conf->need_utmp_watch = 1;
return __lxc_start(name, conf, &start_ops, &start_arg); return __lxc_start(name, conf, &start_ops, &start_arg);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment