]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgfsng: enable "force" for "cgroup-full"
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 19 Feb 2018 11:30:51 +0000 (12:30 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 21 Feb 2018 17:09:54 +0000 (18:09 +0100)
This enables cgroup-full:{mixed,ro,rw}:force and reworks the mount logic.
When cgroup-full was specified we used to bind-mount the cgroups from the host.
That is pretty weird thing to do given that you can simply mount them directly
without going through bind-mounts.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/confile.c

index 801324094ed71d964f513041f78cf706526abef3..1adc1ceeb1c23edcc8182f727c3199108b32b496 100644 (file)
@@ -1971,56 +1971,6 @@ static bool cgfsng_chown(void *hdata, struct lxc_conf *conf)
        return true;
 }
 
-/* We've safe-mounted a tmpfs as parent, so we don't need to protect against
- * symlinks any more - just use mount.
- *
- * mount cgroup-full if requested
- */
-static int mount_cgroup_full(int type, struct hierarchy *h, char *dest,
-                            char *container_cgroup)
-{
-       int ret;
-       char *rwpath, *source;
-
-       if (type < LXC_AUTO_CGROUP_FULL_RO || type > LXC_AUTO_CGROUP_FULL_MIXED)
-               return 0;
-
-       ret = mount(h->mountpoint, dest, "cgroup", MS_BIND, NULL);
-       if (ret < 0) {
-               SYSERROR("Failed to bind mount cgroup \"%s\" onto \"%s\"",
-                        h->mountpoint, dest);
-               return -1;
-       }
-
-       if (type != LXC_AUTO_CGROUP_FULL_RW) {
-               unsigned long flags = MS_BIND | MS_NOSUID | MS_NOEXEC | MS_NODEV |
-                                     MS_REMOUNT | MS_RDONLY;
-
-               ret = mount(NULL, dest, "cgroup", flags, NULL);
-               if (ret < 0) {
-                       SYSERROR("Failed to remount cgroup \"%s\" read-only", dest);
-                       return -1;
-               }
-       }
-
-       INFO("Bind mounted \"%s\" onto \"%s\"", h->mountpoint, dest);
-       if (type != LXC_AUTO_CGROUP_FULL_MIXED)
-               return 0;
-
-       /* mount just the container path rw */
-       source = must_make_path(h->mountpoint, h->base_cgroup, container_cgroup, NULL);
-       rwpath = must_make_path(dest, h->base_cgroup, container_cgroup, NULL);
-       ret = mount(source, rwpath, "cgroup", MS_BIND, NULL);
-       if (ret < 0)
-               WARN("%s - Failed to mount cgroup \"%s\" read-write",
-                    strerror(errno), rwpath);
-
-       TRACE("Mounted cgroup \"%s\" read-write", rwpath);
-       free(rwpath);
-       free(source);
-       return 0;
-}
-
 /* cgroup-full:* is done, no need to create subdirs */
 static bool cg_mount_needs_subdirs(int type)
 {
@@ -2034,9 +1984,9 @@ static bool cg_mount_needs_subdirs(int type)
  * remount controller ro if needed and bindmount the cgroupfs onto
  * controll/the/cg/path.
  */
-static int do_secondstage_mounts_if_needed(int type, struct hierarchy *h,
-                                          char *controllerpath, char *cgpath,
-                                          const char *container_cgroup)
+static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
+                                      char *controllerpath, char *cgpath,
+                                      const char *container_cgroup)
 {
        int ret, remount_flags;
        char *sourcepath;
@@ -2093,8 +2043,14 @@ static int do_secondstage_mounts_if_needed(int type, struct hierarchy *h,
        return 0;
 }
 
-static int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
-                                       const char *controllerpath)
+/* __cg_mount_direct
+ *
+ * Mount cgroup hierarchies directly without using bind-mounts. The main
+ * uses-cases are mounting cgroup hierarchies in cgroup namespaces and mounting
+ * cgroups for the LXC_AUTO_CGROUP_FULL option.
+ */
+static int __cg_mount_direct(int type, struct hierarchy *h,
+                            const char *controllerpath)
 {
         int ret;
         char *controllers = NULL;
@@ -2119,14 +2075,29 @@ static int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
        ret = mount("cgroup", controllerpath, fstype, flags, controllers);
        free(controllers);
        if (ret < 0) {
-               SYSERROR("Failed to mount %s with cgroup filesystem type %s", controllerpath, fstype);
+               SYSERROR("Failed to mount \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
                return -1;
        }
 
-       DEBUG("Mounted %s with cgroup filesystem type %s", controllerpath, fstype);
+       DEBUG("Mounted \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
        return 0;
 }
 
+static inline int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
+                                              const char *controllerpath)
+{
+       return __cg_mount_direct(type, h, controllerpath);
+}
+
+static inline int cg_mount_cgroup_full(int type, struct hierarchy *h,
+                                      const char *controllerpath)
+{
+       if (type < LXC_AUTO_CGROUP_FULL_RO || type > LXC_AUTO_CGROUP_FULL_MIXED)
+               return 0;
+
+       return __cg_mount_direct(type, h, controllerpath);
+}
+
 static bool cgfsng_mount(void *hdata, const char *root, int type)
 {
        int i, ret;
@@ -2161,7 +2132,7 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
 
        /* Mount tmpfs */
        tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
-       ret = safe_mount("cgroup_root", tmpfspath, "tmpfs",
+       ret = safe_mount(NULL, tmpfspath, "tmpfs",
                         MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME,
                         "size=10240k,mode=755", root);
        if (ret < 0)
@@ -2202,7 +2173,7 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
                        continue;
                }
 
-               ret = mount_cgroup_full(type, h, controllerpath, d->container_cgroup);
+               ret = cg_mount_cgroup_full(type, h, controllerpath);
                if (ret < 0) {
                        free(controllerpath);
                        goto on_error;
@@ -2222,8 +2193,8 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
                        goto on_error;
                }
 
-               ret = do_secondstage_mounts_if_needed(type, h, controllerpath,
-                                                     path2, d->container_cgroup);
+               ret = cg_legacy_mount_controllers(type, h, controllerpath,
+                                                 path2, d->container_cgroup);
                free(controllerpath);
                free(path2);
                if (ret < 0)
index f6253114f34a748f5ace1ed2aaff8bb80acf8435..81aa5b0cd4b1249277e72343b975b52fd6673132 100644 (file)
@@ -1914,25 +1914,29 @@ static int set_config_mount_auto(const char *key, const char *value,
                int mask;
                int flag;
        } allowed_auto_mounts[] = {
-           { "proc",                    LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_MIXED                            },
-           { "proc:mixed",              LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_MIXED                            },
-           { "proc:rw",                 LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_RW                               },
-           { "sys",                     LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_MIXED                             },
-           { "sys:ro",                  LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_RO                                },
-           { "sys:mixed",               LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_MIXED                             },
-           { "sys:rw",                  LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_RW                                },
-           { "cgroup",                  LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC                         },
-           { "cgroup:mixed",            LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED                          },
-           { "cgroup:ro",               LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO                             },
-           { "cgroup:rw",               LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW                             },
-           { "cgroup:force",            LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE },
-           { "cgroup:mixed:force",      LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE  },
-           { "cgroup:ro:force",         LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE     },
-           { "cgroup:rw:force",         LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE     },
-           { "cgroup-full",             LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC                    },
-           { "cgroup-full:mixed",       LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED                     },
-           { "cgroup-full:ro",          LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO                        },
-           { "cgroup-full:rw",          LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW                        },
+           { "proc",                    LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_MIXED                                 },
+           { "proc:mixed",              LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_MIXED                                 },
+           { "proc:rw",                 LXC_AUTO_PROC_MASK,   LXC_AUTO_PROC_RW                                    },
+           { "sys",                     LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_MIXED                                  },
+           { "sys:ro",                  LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_RO                                     },
+           { "sys:mixed",               LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_MIXED                                  },
+           { "sys:rw",                  LXC_AUTO_SYS_MASK,    LXC_AUTO_SYS_RW                                     },
+           { "cgroup",                  LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC                              },
+           { "cgroup:mixed",            LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED                               },
+           { "cgroup:ro",               LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO                                  },
+           { "cgroup:rw",               LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW                                  },
+           { "cgroup:force",            LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE      },
+           { "cgroup:mixed:force",      LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE       },
+           { "cgroup:ro:force",         LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE          },
+           { "cgroup:rw:force",         LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE          },
+           { "cgroup-full",             LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC                         },
+           { "cgroup-full:mixed",       LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED                          },
+           { "cgroup-full:ro",          LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO                             },
+           { "cgroup-full:rw",          LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW                             },
+           { "cgroup-full:force",       LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC | LXC_AUTO_CGROUP_FORCE },
+           { "cgroup-full:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_FORCE  },
+           { "cgroup-full:ro:force",    LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FORCE     },
+           { "cgroup-full:rw:force",    LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW | LXC_AUTO_CGROUP_FORCE     },
            /* For adding anything that is just a single on/off, but has no
             * options: keep mask and flag identical and just define the enum
             * value as an unused bit so far