]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Automatic mounting: add more ways to mount the cgroup filesystem
authorChristian Seiler <christian@iwakd.de>
Tue, 24 Sep 2013 20:45:08 +0000 (22:45 +0200)
committerSerge Hallyn <serge.hallyn@ubuntu.com>
Fri, 27 Sep 2013 15:14:14 +0000 (10:14 -0500)
This adds quite a few more ways to mount the cgroup filesystem
automatically:

 - Specify ro/rw/mixed:
       - ro: everything mounted read-only
       - rw: everything mounted read-write
       - mixed: only container's own cgroup is rw, rest ro
                (default)
 - Add cgroup-full that mounts the entire cgroup tree to the
   corresponding directories. ro/rw/mixed also apply here.

Signed-off-by: Christian Seiler <christian@iwakd.de>
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
src/lxc/cgroup.c
src/lxc/cgroup.h
src/lxc/conf.c

index e27bc03e454f6c47688952fdbb9263bdcda35f72..9e36cb17fb9384356600cc13b92f471e3425967d 100644 (file)
@@ -1256,7 +1256,7 @@ int lxc_setup_cgroup_devices(struct lxc_handler *h, struct lxc_list *cgroup_sett
        return do_setup_cgroup(h, cgroup_settings, true);
 }
 
-int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_info)
+int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_info, int type)
 {
        size_t bufsz = strlen(root) + sizeof("/sys/fs/cgroup");
        char *path = NULL;
@@ -1267,6 +1267,12 @@ int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_in
        struct cgroup_process_info *info;
        int r, saved_errno = 0;
 
+       if (type < LXC_AUTO_CGROUP_RO || type > LXC_AUTO_CGROUP_FULL_MIXED) {
+               ERROR("could not mount cgroups into container: invalid type specified internally");
+               errno = EINVAL;
+               return -1;
+       }
+
        path = calloc(1, bufsz);
        if (!path)
                return -1;
@@ -1313,27 +1319,71 @@ int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_in
                        goto out_error;
                }
 
-               /* create path for container's cgroup */
                abs_path2 = lxc_append_paths(abs_path, info->cgroup_path);
                if (!abs_path2)
                        goto out_error;
-               r = mkdir_p(abs_path2, 0755);
-               if (r < 0 && errno != EEXIST) {
-                       SYSERROR("could not create cgroup directory /sys/fs/cgroup/%s%s", dirname, info->cgroup_path);
-                       goto out_error;
-               }
 
-               free(abs_path);
-               abs_path = NULL;
+               if (type == LXC_AUTO_CGROUP_FULL_RO || type == LXC_AUTO_CGROUP_FULL_RW || type == LXC_AUTO_CGROUP_FULL_MIXED) {
+                       /* bind-mount the cgroup entire filesystem there */
+                       if (strcmp(mp->mount_prefix, "/") != 0) {
+                               /* FIXME: maybe we should just try to remount the entire hierarchy
+                                *        with a regular mount command? may that works? */
+                               ERROR("could not automatically mount cgroup-full to /sys/fs/cgroup/%s: host has no mount point for this cgroup filesystem that has access to the root cgroup", dirname);
+                               goto out_error;
+                       }
+                       r = mount(mp->mount_point, abs_path, "none", MS_BIND, 0);
+                       if (r < 0) {
+                               SYSERROR("error bind-mounting %s to %s", mp->mount_point, abs_path);
+                               goto out_error;
+                       }
+                       /* main cgroup path should be read-only */
+                       if (type == LXC_AUTO_CGROUP_FULL_RO || type == LXC_AUTO_CGROUP_FULL_MIXED) {
+                               r = mount(NULL, abs_path, NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL);
+                               if (r < 0) {
+                                       SYSERROR("error re-mounting %s readonly", abs_path);
+                                       goto out_error;
+                               }
+                       }
+                       /* own cgroup should be read-write */
+                       if (type == LXC_AUTO_CGROUP_FULL_MIXED) {
+                               r = mount(abs_path2, abs_path2, NULL, MS_BIND, NULL);
+                               if (r < 0) {
+                                       SYSERROR("error bind-mounting %s onto itself", abs_path2);
+                                       goto out_error;
+                               }
+                               r = mount(NULL, abs_path2, NULL, MS_REMOUNT|MS_BIND, NULL);
+                               if (r < 0) {
+                                       SYSERROR("error re-mounting %s readwrite", abs_path2);
+                                       goto out_error;
+                               }
+                       }
+               } else {
+                       /* create path for container's cgroup */
+                       r = mkdir_p(abs_path2, 0755);
+                       if (r < 0 && errno != EEXIST) {
+                               SYSERROR("could not create cgroup directory /sys/fs/cgroup/%s%s", dirname, info->cgroup_path);
+                               goto out_error;
+                       }
 
-               /* bind-mount container's cgroup to that directory */
-               abs_path = cgroup_to_absolute_path(mp, info->cgroup_path, NULL);
-               if (!abs_path)
-                       goto out_error;
-               r = mount(abs_path, abs_path2, "none", MS_BIND, 0);
-               if (r < 0) {
-                       SYSERROR("error bind-mounting %s to %s", abs_path, abs_path2);
-                       goto out_error;
+                       free(abs_path);
+                       abs_path = NULL;
+
+                       /* bind-mount container's cgroup to that directory */
+                       abs_path = cgroup_to_absolute_path(mp, info->cgroup_path, NULL);
+                       if (!abs_path)
+                               goto out_error;
+                       r = mount(abs_path, abs_path2, "none", MS_BIND, 0);
+                       if (r < 0) {
+                               SYSERROR("error bind-mounting %s to %s", abs_path, abs_path2);
+                               goto out_error;
+                       }
+                       if (type == LXC_AUTO_CGROUP_RO) {
+                               r = mount(NULL, abs_path2, NULL, MS_REMOUNT|MS_BIND|MS_RDONLY, NULL);
+                               if (r < 0) {
+                                       SYSERROR("error re-mounting %s readonly", abs_path2);
+                                       goto out_error;
+                               }
+                       }
                }
 
                free(abs_path);
@@ -1365,7 +1415,8 @@ int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_in
         * new cgroups outside the allowed area fails with an error instead
         * of simply causing this to create directories in the tmpfs itself)
         */
-       mount(NULL, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
+       if (type != LXC_AUTO_CGROUP_RW && type != LXC_AUTO_CGROUP_FULL_RW)
+               mount(NULL, path, NULL, MS_REMOUNT|MS_RDONLY, NULL);
 
        free(path);
 
index 5f517f6660e4355867b18bdc91077ab54912ca9a..0c0a678991b68d82e7d133dab57ff852b096178e 100644 (file)
@@ -160,7 +160,7 @@ struct lxc_list;
 extern int lxc_setup_cgroup_without_devices(struct lxc_handler *h, struct lxc_list *cgroup_settings);
 extern int lxc_setup_cgroup_devices(struct lxc_handler *h, struct lxc_list *cgroup_settings);
 
-extern int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_info);
+extern int lxc_setup_mount_cgroup(const char *root, struct cgroup_process_info *base_info, int type);
 
 extern int lxc_cgroup_nrtasks_handler(struct lxc_handler *handler);
 
index a8d2cad961ddb3d4c1f1e05b83c063fd4306d89b..ecbcf41a75f9cfc56df16ac63acb37f33655df8c 100644 (file)
@@ -811,7 +811,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct cgroup
        }
 
        if (flags & LXC_AUTO_CGROUP_MASK) {
-               r = lxc_setup_mount_cgroup(conf->rootfs.mount, cgroup_info);
+               r = lxc_setup_mount_cgroup(conf->rootfs.mount, cgroup_info, flags & LXC_AUTO_CGROUP_MASK);
                if (r < 0) {
                        SYSERROR("error mounting /sys/fs/cgroup");
                        return -1;