]> git.proxmox.com Git - mirror_lxc.git/blobdiff - src/lxc/start.c
coverity: #1435805
[mirror_lxc.git] / src / lxc / start.c
index b8404f99e0cc18e6ea50e412b44da31ffef48567..638e195d6356573d38738d5cd50c743e293ebf54 100644 (file)
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <poll.h>
+#include <pthread.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -314,7 +315,7 @@ static int setup_signal_fd(sigset_t *oldmask)
                        return -EBADF;
        }
 
-       ret = sigprocmask(SIG_BLOCK, &mask, oldmask);
+       ret = pthread_sigmask(SIG_BLOCK, &mask, oldmask);
        if (ret < 0) {
                SYSERROR("Failed to set signal mask");
                return -EBADF;
@@ -849,11 +850,18 @@ int lxc_init(const char *name, struct lxc_handler *handler)
        }
        TRACE("Chowned console");
 
+       handler->cgroup_ops = cgroup_init(handler);
+       if (!handler->cgroup_ops) {
+               ERROR("Failed to initialize cgroup driver");
+               goto out_restore_sigmask;
+       }
+       TRACE("Initialized cgroup driver");
+
        INFO("Container \"%s\" is initialized", name);
        return 0;
 
 out_restore_sigmask:
-       sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
+       pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL);
 out_delete_tty:
        lxc_delete_tty(&conf->ttys);
 out_aborting:
@@ -871,6 +879,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
        struct lxc_list *cur, *next;
        char *namespaces[LXC_NS_MAX + 1];
        size_t namespace_count = 0;
+       struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
 
        /* The STOPPING state is there for future cleanup code which can take
         * awhile.
@@ -935,7 +944,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
        while (namespace_count--)
                free(namespaces[namespace_count]);
 
-       cgroup_destroy(handler);
+       cgroup_ops->destroy(cgroup_ops, handler);
+       cgroup_exit(cgroup_ops);
 
        if (handler->conf->reboot == 0) {
                /* For all new state clients simply close the command socket.
@@ -977,7 +987,7 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
        }
 
        /* Reset mask set by setup_signal_fd. */
-       ret = sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
+       ret = pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL);
        if (ret < 0)
                WARN("%s - Failed to restore signal mask", strerror(errno));
 
@@ -1055,7 +1065,7 @@ static int do_start(void *data)
                goto out_warn_father;
        }
 
-       ret = sigprocmask(SIG_SETMASK, &handler->oldmask, NULL);
+       ret = pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL);
        if (ret < 0) {
                SYSERROR("Failed to set signal mask");
                goto out_warn_father;
@@ -1476,8 +1486,16 @@ static inline int do_share_ns(void *arg)
                        continue;
 
                ret = setns(handler->nsfd[i], 0);
-               if (ret < 0)
+               if (ret < 0) {
+                       /*
+                        * Note that joining a user and/or mount namespace
+                        * requires the process is not multithreaded otherwise
+                        * setns() will fail here.
+                        */
+                       SYSERROR("Failed to inherit %s namespace",
+                                ns_info[i].proc_name);
                        return -1;
+               }
 
                DEBUG("Inherited %s namespace", ns_info[i].proc_name);
        }
@@ -1506,8 +1524,9 @@ static int lxc_spawn(struct lxc_handler *handler)
        struct lxc_list *id_map;
        const char *name = handler->name;
        const char *lxcpath = handler->lxcpath;
-       bool cgroups_connected = false, share_ns = false;
+       bool share_ns = false;
        struct lxc_conf *conf = handler->conf;
+       struct cgroup_ops *cgroup_ops = handler->cgroup_ops;
 
        id_map = &conf->id_map;
        wants_to_map_ids = !lxc_list_empty(id_map);
@@ -1567,14 +1586,7 @@ static int lxc_spawn(struct lxc_handler *handler)
                }
        }
 
-       if (!cgroup_init(handler)) {
-               ERROR("Failed initializing cgroup support");
-               goto out_delete_net;
-       }
-
-       cgroups_connected = true;
-
-       if (!cgroup_create(handler)) {
+       if (!cgroup_ops->create(cgroup_ops, handler)) {
                ERROR("Failed creating cgroups");
                goto out_delete_net;
        }
@@ -1663,15 +1675,15 @@ static int lxc_spawn(struct lxc_handler *handler)
        if (ret < 0)
                goto out_delete_net;
 
-       if (!cgroup_setup_limits(handler, false)) {
+       if (!cgroup_ops->setup_limits(cgroup_ops, handler->conf, false)) {
                ERROR("Failed to setup cgroup limits for container \"%s\"", name);
                goto out_delete_net;
        }
 
-       if (!cgroup_enter(handler))
+       if (!cgroup_ops->enter(cgroup_ops, handler->pid))
                goto out_delete_net;
 
-       if (!cgroup_chown(handler))
+       if (!cgroup_ops->chown(cgroup_ops, handler->conf))
                goto out_delete_net;
 
        /* Now we're ready to preserve the network namespace */
@@ -1736,15 +1748,12 @@ static int lxc_spawn(struct lxc_handler *handler)
        if (ret < 0)
                goto out_delete_net;
 
-       if (!cgroup_setup_limits(handler, true)) {
+       if (!cgroup_ops->setup_limits(cgroup_ops, handler->conf, true)) {
                ERROR("Failed to setup legacy device cgroup controller limits");
                goto out_delete_net;
        }
        TRACE("Set up legacy device cgroup controller limits");
 
-       cgroup_disconnect();
-       cgroups_connected = false;
-
        if (handler->ns_clone_flags & CLONE_NEWCGROUP) {
                /* Now we're ready to preserve the cgroup namespace */
                ret = lxc_try_preserve_ns(handler->pid, "cgroup");
@@ -1821,9 +1830,6 @@ static int lxc_spawn(struct lxc_handler *handler)
        return 0;
 
 out_delete_net:
-       if (cgroups_connected)
-               cgroup_disconnect();
-
        if (handler->ns_clone_flags & CLONE_NEWNET)
                lxc_delete_network(handler);