From: Christian Seiler Date: Tue, 24 Sep 2013 20:45:08 +0000 (+0200) Subject: Automatic mounting: add more ways to mount the cgroup filesystem X-Git-Tag: lxc-1.0.0.alpha2~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7997d7da4dfcaad50a0dcbcae8e0681bc5613f46;p=thirdparty%2Flxc.git Automatic mounting: add more ways to mount the cgroup filesystem 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 Signed-off-by: Serge Hallyn --- diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index e27bc03e4..9e36cb17f 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -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); diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h index 5f517f666..0c0a67899 100644 --- a/src/lxc/cgroup.h +++ b/src/lxc/cgroup.h @@ -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); diff --git a/src/lxc/conf.c b/src/lxc/conf.c index a8d2cad96..ecbcf41a7 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -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;