]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxc: cgfs: handle lxcfs 831/head
authorUbuntu <ubuntu@localhost.localdomain>
Sat, 20 Feb 2016 02:25:55 +0000 (02:25 +0000)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Sat, 20 Feb 2016 02:45:40 +0000 (18:45 -0800)
When containers have lxcfs mounted instead of cgroupfs, we have to
process /proc/self/mountinfo a bit differently.  In particular, we
should look for fuse.lxcfs fstype, we need to look elsewhere for the
list of comounted controllers, and the mount_prefix is not a cgroup path
which was bind mounted, so we should ignore it, and named subsystems
show up without the 'name=' prefix.

With this patchset I can start containers inside a privileged lxd
container with lxcfs mounted (i.e. without cgroup namespaces).

Closes #830

Signed-off-by: Ubuntu <ubuntu@localhost.localdomain>
src/lxc/cgfs.c

index 603d63af2ccc7512b9a1fe244f89dfac7ddc5a41..d41e74c96257c002188ddf2d3295fdc9c5055f93 100644 (file)
@@ -433,6 +433,7 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char **
                struct cgroup_mount_point *mount_point;
                struct cgroup_hierarchy *h;
                char **subsystems;
+               bool is_lxcfs = false;
 
                if (line[0] && line[strlen(line) - 1] == '\n')
                        line[strlen(line) - 1] = '\0';
@@ -471,10 +472,18 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char **
                        continue;
 
                /* not a cgroup filesystem */
-               if (strcmp(tokens[j + 1], "cgroup") != 0)
-                       continue;
-
-               subsystems = subsystems_from_mount_options(tokens[j + 3], kernel_subsystems);
+               if (strcmp(tokens[j + 1], "cgroup") != 0) {
+                       if (strcmp(tokens[j + 1], "fuse.lxcfs") != 0)
+                               continue;
+                       if (strncmp(tokens[4], "/sys/fs/cgroup/", 15) != 0)
+                               continue;
+                       is_lxcfs = true;
+                       char *curtok = tokens[4] + 15;
+                       subsystems = subsystems_from_mount_options(curtok,
+                                                        kernel_subsystems);
+               } else
+                       subsystems = subsystems_from_mount_options(tokens[j + 3],
+                                                        kernel_subsystems);
                if (!subsystems)
                        goto out;
 
@@ -503,8 +512,11 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char **
                meta_data->mount_points[mount_point_count++] = mount_point;
 
                mount_point->hierarchy = h;
+               if (is_lxcfs)
+                       mount_point->mount_prefix = strdup("/");
+               else
+                       mount_point->mount_prefix = strdup(tokens[3]);
                mount_point->mount_point = strdup(tokens[4]);
-               mount_point->mount_prefix = strdup(tokens[3]);
                if (!mount_point->mount_point || !mount_point->mount_prefix)
                        goto out;
                mount_point->read_only = !lxc_string_in_list("rw", tokens[5], ',');
@@ -1704,16 +1716,20 @@ static char **subsystems_from_mount_options(const char *mount_options,
                 * subsystems provided by the kernel OR if it starts
                 * with name= for named hierarchies
                 */
-               if (!strncmp(token, "name=", 5) || lxc_string_in_array(token, (const char **)kernel_list)) {
-                       r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 12);
-                       if (r < 0)
-                               goto out_free;
-                       result[result_count + 1] = NULL;
+               r = lxc_grow_array((void ***)&result, &result_capacity, result_count + 1, 12);
+               if (r < 0)
+                       goto out_free;
+               result[result_count + 1] = NULL;
+               if (strncmp(token, "name=", 5) && !lxc_string_in_array(token, (const char **)kernel_list)) {
+                       // this is eg 'systemd' but the mount will be 'name=systemd'
+                       result[result_count] = malloc(strlen(token) + 6);
+                       if (result[result_count])
+                               sprintf(result[result_count], "name=%s", token);
+               } else
                        result[result_count] = strdup(token);
-                       if (!result[result_count])
-                               goto out_free;
-                       result_count++;
-               }
+               if (!result[result_count])
+                       goto out_free;
+               result_count++;
        }
 
        return result;