From: Christian Brauner Date: Wed, 13 May 2020 10:59:59 +0000 (+0200) Subject: start: fix container reboot X-Git-Tag: lxc-5.0.0~437^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a42abccecc79bf8b8acec4641885763fa4eddd2a;p=thirdparty%2Flxc.git start: fix container reboot Signed-off-by: Christian Brauner --- diff --git a/src/lxc/criu.c b/src/lxc/criu.c index 288f1f515..a8af09f7b 100644 --- a/src/lxc/criu.c +++ b/src/lxc/criu.c @@ -942,7 +942,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_ close(fd); } - handler = lxc_init_handler(c->name, c->lxc_conf, c->config_path, false); + handler = lxc_init_handler(NULL, c->name, c->lxc_conf, c->config_path, false); if (!handler) goto out; diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 718b570d2..80f2f66d3 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -899,7 +899,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a conf = c->lxc_conf; /* initialize handler */ - handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize); + handler = lxc_init_handler(NULL, c->name, conf, c->config_path, c->daemonize); container_mem_unlock(c); if (!handler) @@ -916,7 +916,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a if (!argv) { if (useinit) { ERROR("No valid init detected"); - lxc_free_handler(handler); + lxc_put_handler(handler); return false; } argv = default_args; @@ -934,7 +934,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a pid_first = fork(); if (pid_first < 0) { free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); return false; } @@ -951,7 +951,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a started = wait_on_daemonized_start(handler, pid_first); free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); return started; } @@ -983,7 +983,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a /* second parent */ if (pid_second != 0) { free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); _exit(EXIT_SUCCESS); } @@ -1017,7 +1017,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a } else if (!am_single_threaded()) { ERROR("Cannot start non-daemonized container when threaded"); free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); return false; } @@ -1031,7 +1031,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a w = snprintf(pidstr, sizeof(pidstr), "%d", lxc_raw_getpid()); if (w < 0 || (size_t)w >= sizeof(pidstr)) { free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); @@ -1044,7 +1044,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ret = lxc_write_to_file(c->pidfile, pidstr, w, false, 0600); if (ret < 0) { free_init_cmd(init_cmd); - lxc_free_handler(handler); + lxc_put_handler(handler); SYSERROR("Failed to write monitor pid to \"%s\"", c->pidfile); @@ -1062,7 +1062,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ret = unshare(CLONE_NEWNS); if (ret < 0) { SYSERROR("Failed to unshare mount namespace"); - lxc_free_handler(handler); + lxc_put_handler(handler); ret = 1; goto on_error; } @@ -1070,7 +1070,7 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL); if (ret < 0) { SYSERROR("Failed to make / rslave at startup"); - lxc_free_handler(handler); + lxc_put_handler(handler); ret = 1; goto on_error; } @@ -1079,19 +1079,20 @@ static bool do_lxcapi_start(struct lxc_container *c, int useinit, char * const a reboot: if (conf->reboot == REBOOT_INIT) { /* initialize handler */ - handler = lxc_init_handler(c->name, conf, c->config_path, c->daemonize); + handler = lxc_init_handler(handler, c->name, conf, c->config_path, c->daemonize); if (!handler) { ret = 1; goto on_error; } + } else { + keepfds[1] = handler->state_socket_pair[0]; + keepfds[2] = handler->state_socket_pair[1]; } keepfds[0] = handler->conf->maincmd_fd; - keepfds[1] = handler->state_socket_pair[0]; - keepfds[2] = handler->state_socket_pair[1]; ret = lxc_check_inherited(conf, c->daemonize, keepfds, ARRAY_SIZE(keepfds)); if (ret < 0) { - lxc_free_handler(handler); + lxc_put_handler(handler); ret = 1; goto on_error; } diff --git a/src/lxc/start.c b/src/lxc/start.c index 599f08f88..49714e6ad 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -605,7 +605,7 @@ out_sigfd: return ret; } -void lxc_free_handler(struct lxc_handler *handler) +void lxc_put_handler(struct lxc_handler *handler) { close_prot_errno_disarm(handler->pinfd); close_prot_errno_disarm(handler->pidfd); @@ -617,22 +617,26 @@ void lxc_free_handler(struct lxc_handler *handler) close_prot_errno_disarm(handler->state_socket_pair[0]); close_prot_errno_disarm(handler->state_socket_pair[1]); cgroup_exit(handler->cgroup_ops); - handler->conf = NULL; - free_disarm(handler); + if (handler->conf && handler->conf->reboot == REBOOT_NONE) + free_disarm(handler); + else + handler->conf = NULL; } -struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, +struct lxc_handler *lxc_init_handler(struct lxc_handler *old, + const char *name, struct lxc_conf *conf, const char *lxcpath, bool daemonize) { int ret; struct lxc_handler *handler; - handler = malloc(sizeof(*handler)); + if (!old) + handler = zalloc(sizeof(*handler)); + else + handler = old; if (!handler) return NULL; - memset(handler, 0, sizeof(*handler)); - /* Note that am_guest_unpriv() checks the effective uid. We * probably don't care if we are real root only if we are running * as root so this should be fine. @@ -692,7 +696,7 @@ struct lxc_handler *lxc_init_handler(const char *name, struct lxc_conf *conf, return handler; on_error: - lxc_free_handler(handler); + lxc_put_handler(handler); return NULL; } @@ -983,7 +987,7 @@ void lxc_end(struct lxc_handler *handler) if (handler->conf->ephemeral == 1 && handler->conf->reboot != REBOOT_REQ) lxc_destroy_container_on_signal(handler, name); - lxc_free_handler(handler); + lxc_put_handler(handler); } void lxc_abort(struct lxc_handler *handler) diff --git a/src/lxc/start.h b/src/lxc/start.h index 3e742affa..88afc79b1 100644 --- a/src/lxc/start.h +++ b/src/lxc/start.h @@ -143,11 +143,11 @@ extern int lxc_serve_state_clients(const char *name, struct lxc_handler *handler, lxc_state_t state); extern void lxc_abort(struct lxc_handler *handler); -extern struct lxc_handler *lxc_init_handler(const char *name, +extern struct lxc_handler *lxc_init_handler(struct lxc_handler *old, + const char *name, struct lxc_conf *conf, - const char *lxcpath, - bool daemonize); -extern void lxc_free_handler(struct lxc_handler *handler); + const char *lxcpath, bool daemonize); +extern void lxc_put_handler(struct lxc_handler *handler); extern int lxc_init(const char *name, struct lxc_handler *handler); extern void lxc_end(struct lxc_handler *handler);