]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/start.c
start: rework cleanup code in __lxc_start()
[mirror_lxc.git] / src / lxc / start.c
index 2e6f8c6d420c7c47161dcc5d0c6ef7ba13263c83..0d4e28949eebb3013997f3067fabf3db493dfa1d 100644 (file)
@@ -724,34 +724,28 @@ on_error:
 
 int lxc_init(const char *name, struct lxc_handler *handler)
 {
-       __do_close_prot_errno int status_fd = -EBADF;
+       __do_close int status_fd = -EBADF;
        int ret;
        const char *loglevel;
        struct lxc_conf *conf = handler->conf;
 
        handler->monitor_pid = lxc_raw_getpid();
        status_fd = open("/proc/self/status", O_RDONLY | O_CLOEXEC);
-       if (status_fd < 0) {
-               SYSERROR("Failed to open monitor status fd");
-               goto out_close_maincmd_fd;
-       }
+       if (status_fd < 0)
+               return log_error_errno(-1, errno, "Failed to open monitor status fd");
 
        lsm_init();
        TRACE("Initialized LSM");
 
        ret = lxc_read_seccomp_config(conf);
-       if (ret < 0) {
-               ERROR("Failed loading seccomp policy");
-               goto out_close_maincmd_fd;
-       }
+       if (ret < 0)
+               return log_error(-1, "Failed loading seccomp policy");
        TRACE("Read seccomp policy");
 
        /* Begin by setting the state to STARTING. */
        ret = lxc_set_state(name, handler, STARTING);
-       if (ret < 0) {
-               ERROR("Failed to set state to \"%s\"", lxc_state2str(STARTING));
-               goto out_close_maincmd_fd;
-       }
+       if (ret < 0)
+               return log_error(-1, "Failed to set state to \"%s\"", lxc_state2str(STARTING));
        TRACE("Set container state to \"STARTING\"");
 
        /* Start of environment variable setup for hooks. */
@@ -811,10 +805,8 @@ int lxc_init(const char *name, struct lxc_handler *handler)
        TRACE("Set environment variables");
 
        ret = run_lxc_hooks(name, "pre-start", conf, NULL);
-       if (ret < 0) {
-               ERROR("Failed to run lxc.hook.pre-start for container \"%s\"", name);
-               goto out_aborting;
-       }
+       if (ret < 0)
+               return log_error(-1, "Failed to run lxc.hook.pre-start for container \"%s\"", name);
        TRACE("Ran pre-start hooks");
 
        /* The signal fd has to be created before forking otherwise if the child
@@ -822,10 +814,8 @@ int lxc_init(const char *name, struct lxc_handler *handler)
         * and the command will be stuck.
         */
        handler->sigfd = setup_signal_fd(&handler->oldmask);
-       if (handler->sigfd < 0) {
-               ERROR("Failed to setup SIGCHLD fd handler.");
-               goto out_delete_tty;
-       }
+       if (handler->sigfd < 0)
+               return log_error(-1, "Failed to setup SIGCHLD fd handler.");
        TRACE("Set up signal fd");
 
        /* Do this after setting up signals since it might unblock SIGWINCH. */
@@ -867,14 +857,6 @@ out_delete_terminal:
 out_restore_sigmask:
        (void)pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL);
 
-out_delete_tty:
-       lxc_delete_tty(&conf->ttys);
-
-out_aborting:
-       (void)lxc_set_state(name, handler, ABORTING);
-
-out_close_maincmd_fd:
-       close_prot_errno_disarm(conf->maincmd_fd);
        return -1;
 }
 
@@ -1041,7 +1023,7 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
                                handler->pidfd, handler->pid);
        }
 
-       if (!ret || errno != ESRCH)
+       if ((!ret || errno != ESRCH) && handler->pid > 0)
                if (kill(handler->pid, SIGKILL))
                        SYSWARN("Failed to send SIGKILL to %d", handler->pid);
 
@@ -1053,9 +1035,9 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
 static int do_start(void *data)
 {
        struct lxc_handler *handler = data;
-       __lxc_unused __do_close_prot_errno int data_sock0 = handler->data_sock[0],
+       __lxc_unused __do_close int data_sock0 = handler->data_sock[0],
                                           data_sock1 = handler->data_sock[1];
-       __do_close_prot_errno int status_fd = -EBADF;
+       __do_close int status_fd = -EBADF;
        int ret;
        uid_t new_uid;
        gid_t new_gid;
@@ -1557,7 +1539,7 @@ static inline int do_share_ns(void *arg)
  */
 static int lxc_spawn(struct lxc_handler *handler)
 {
-       __do_close_prot_errno int data_sock0 = -EBADF, data_sock1 = -EBADF;
+       __do_close int data_sock0 = -EBADF, data_sock1 = -EBADF;
        int i, ret;
        char pidstr[20];
        bool wants_to_map_ids;
@@ -2015,19 +1997,31 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
        if (error_num)
                *error_num = handler->exit_status;
 
-out_fini:
+/* These are the goto targets you are not allowed to jump to. */
+__out_fini:
        lxc_delete_network(handler);
 
-out_detach_blockdev:
+__out_detach_blockdev:
        detach_block_device(handler->conf);
 
-out_fini_nonet:
+__out_fini_nonet:
        lxc_fini(name, handler);
+
        return ret;
 
+/* These are the goto targets you want to jump to. */
+out_fini_nonet:
+       lxc_abort(name, handler);
+       goto __out_fini_nonet;
+
+out_detach_blockdev:
+       lxc_abort(name, handler);
+       goto __out_detach_blockdev;
+
 out_abort:
        lxc_abort(name, handler);
-       goto out_fini;
+       goto __out_fini;
+
 }
 
 struct start_args {