]> git.proxmox.com Git - mirror_lxc.git/commitdiff
setup cgroups from parent
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Mon, 14 Jan 2013 23:32:44 +0000 (23:32 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Tue, 15 Jan 2013 16:57:02 +0000 (11:57 -0500)
This is a first step to enabling user namespaces.  When starting a
container in a new user namespace, the child will not have the
rights to write to the cgroup fs.  (We can give it that right, but
don't always want to have to).

At the parent, we don't want to setup_cgroups() before the child
has set itself up.  But we also don't want to wait until it has
started running it's init, since that is racy.

Therefore introduce a new sync point.  The child will let the
parent know when it is ready to be confined, and wait for the
parent to respond that it has done so.  Then the child will finish
constraining itself with LSM and seccomp and execute init.

Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Acked-by: Stéphane Graber <stgraber@ubuntu.com>
src/lxc/conf.c
src/lxc/start.c
src/lxc/sync.h

index d448d59f5f99bfa9dae8b99d45579729e1ea0387..b516d7d871d093a10a45fb590d50449ac15b5a4a 100644 (file)
@@ -2594,11 +2594,6 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf)
                }
        }
 
-       if (setup_cgroup(name, &lxc_conf->cgroup)) {
-               ERROR("failed to setup the cgroups for '%s'", name);
-               return -1;
-       }
-
        if (setup_console(&lxc_conf->rootfs, &lxc_conf->console, lxc_conf->ttydir)) {
                ERROR("failed to setup the console for '%s'", name);
                return -1;
index 2eb17d8a629b9ee08b9716fb436c227047624a12..e1dca7bdb23333fb9a372e770fddc3f1d7fa4f78 100644 (file)
@@ -597,6 +597,10 @@ static int do_start(void *data)
                goto out_warn_father;
        }
 
+       /* ask father to setup cgroups and wait for him to finish */
+       if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP))
+               return -1;
+
        if (apparmor_load(handler) < 0)
                goto out_warn_father;
 
@@ -630,6 +634,8 @@ static int do_start(void *data)
        handler->ops->start(handler, handler->data);
 
 out_warn_father:
+       /* we want the parent to know something went wrong, so any
+        * value other than what it expects is ok. */
        lxc_sync_wake_parent(handler, LXC_SYNC_POST_CONFIGURE);
        return -1;
 }
@@ -741,10 +747,26 @@ int lxc_spawn(struct lxc_handler *handler)
                }
        }
 
-       /* Tell the child to continue its initialization and wait for
-        * it to exec or return an error
+       /* Tell the child to continue its initialization.  we'll get
+        * LXC_SYNC_CGROUP when it is ready for us to setup cgroups
         */
        if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CONFIGURE))
+               goto out_delete_net;
+
+       if (setup_cgroup(name, &handler->conf->cgroup)) {
+               ERROR("failed to setup the cgroups for '%s'", name);
+               goto out_delete_net;
+       }
+
+
+       /* Tell the child to complete its initialization and wait for
+        * it to exec or return an error.  (the child will never
+        * return LXC_SYNC_POST_CGROUP+1.  It will either close the
+        * sync pipe, causing lxc_sync_barrier_child to return
+        * success, or return a different value, causing us to error
+        * out).
+        */
+       if (lxc_sync_barrier_child(handler, LXC_SYNC_POST_CGROUP))
                return -1;
 
        if (detect_shared_rootfs())
index a733d2e585d94a51bbffbc7432f35b14339b6afc..fbf126e572d265cc6060ff150941627e07a9b8f7 100644 (file)
@@ -28,6 +28,8 @@ struct lxc_handler;
 enum {
        LXC_SYNC_CONFIGURE,
        LXC_SYNC_POST_CONFIGURE,
+       LXC_SYNC_CGROUP,
+       LXC_SYNC_POST_CGROUP,
        LXC_SYNC_RESTART,
        LXC_SYNC_POST_RESTART,
 };