]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgmanager: fix 'attach' with "all" controller support
authorSerge Hallyn <serge.hallyn@ubuntu.com>
Sun, 2 Nov 2014 14:01:18 +0000 (14:01 +0000)
committerStéphane Graber <stgraber@ubuntu.com>
Sun, 2 Nov 2014 21:59:26 +0000 (16:59 -0500)
"all" is not a supported keyword for cgmanager's get_pid_cgroup.
Pass the first mounted cgroup subsystem instead of passing "all" when
getting the container's cgorup to attach to.

Also, make sure that the target cgroup is in fact in all identical
cgroups before attaching with 'all".  If not, then we must attach to
each cgroup separately, or else we will not be in all the same cgroups
as the target container.

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

index e1840cebcb65ac25d3a5c4f0a8e893116ed7b987..c61d2de9b0e6239c920c73bdeb0132ad4fdc4752 100644 (file)
@@ -189,11 +189,22 @@ static bool cgm_supports_multiple_controllers;
  */
 static bool cgm_all_controllers_same;
 
-static void check_supports_multiple_controllers(void)
+/*
+ * Check whether we can use "all" when talking to cgmanager.
+ * We check two things:
+ * 1. whether cgmanager is new enough to support this.
+ * 2. whether the task we are interested in is in the same
+ *    cgroup for all controllers.
+ * In cgm_init (before an lxc-start) we care about our own
+ * cgroup.  In cgm_attach, we care about the target task's
+ * cgroup.
+ */
+static void check_supports_multiple_controllers(pid_t pid)
 {
        FILE *f;
        char *line = NULL, *prevpath = NULL;
        size_t sz = 0;
+       char path[100];
 
        cgm_supports_multiple_controllers = false;
        cgm_all_controllers_same = false;
@@ -205,7 +216,11 @@ static void check_supports_multiple_controllers(void)
 
        cgm_supports_multiple_controllers = true;
 
-       f = fopen("/proc/self/cgroup", "r");
+       if (pid == -1)
+               sprintf(path, "/proc/self/cgroup");
+       else
+               sprintf(path, "/proc/%d/cgroup", pid);
+       f = fopen(path, "r");
        if (!f)
                return;
 
@@ -517,7 +532,7 @@ static void *cgm_init(const char *name)
                return NULL;
        }
 
-       check_supports_multiple_controllers();
+       check_supports_multiple_controllers(-1);
 
        d = malloc(sizeof(*d));
        if (!d) {
@@ -1282,13 +1297,16 @@ static bool cgm_attach(const char *name, const char *lxcpath, pid_t pid)
                return false;
        }
 
-       check_supports_multiple_controllers();
+       check_supports_multiple_controllers(pid);
 
        if (cgm_all_controllers_same)
                slist = subsystems_inone;
 
        for (i = 0; slist[i]; i++) {
-               cgroup = try_get_abs_cgroup(name, lxcpath, slist[i]);
+               if (slist == subsystems_inone)
+                       cgroup = try_get_abs_cgroup(name, lxcpath, subsystems[0]);
+               else
+                       cgroup = try_get_abs_cgroup(name, lxcpath, slist[i]);
                if (!cgroup) {
                        ERROR("Failed to get cgroup for controller %s", slist[i]);
                        cgm_dbus_disconnect();