]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
start: fix container reboot
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 13 May 2020 10:59:59 +0000 (12:59 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 13 May 2020 10:59:59 +0000 (12:59 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/criu.c
src/lxc/lxccontainer.c
src/lxc/start.c
src/lxc/start.h

index 288f1f5157f7d98409a14612101f358212683a0b..a8af09f7b0ebd381f24529b07d4dda13b1397b1e 100644 (file)
@@ -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;
 
index 718b570d2e4085083243ed64028eebee9b612751..80f2f66d3f4d035234fd66b64c8161cd5e911b49 100644 (file)
@@ -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;
        }
index 599f08f88b4d45f8711acea56124b643a841cacd..49714e6ad39aa70066b55148dd209a4b06046cc7 100644 (file)
@@ -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)
index 3e742affa48afaafc1a6a8f6827b32c4f188055b..88afc79b1e6bd04955eb1c2be68111c1719efa15 100644 (file)
@@ -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);