[lxc-devel] [lxc/master] add force option for cgroup mount
brauner on Github
lxc-bot at linuxcontainers.org
Fri Feb 16 13:11:39 UTC 2018
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 416 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180216/7b065129/attachment.bin>
-------------- next part --------------
From f67a96275c983c82b2c5559307f51ae981364348 Mon Sep 17 00:00:00 2001
From: Shukui Yang <yangshukui at huawei.com>
Date: Thu, 15 Feb 2018 23:16:40 -0500
Subject: [PATCH] add force option for cgroup mount
Signed-off-by: Shukui Yang <yangshukui at huawei.com>
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/cgroups/cgfsng.c | 76 ++++++++++++++++++++++++++++--------------------
src/lxc/conf.c | 7 +++--
src/lxc/conf.h | 6 ++--
src/lxc/confile.c | 36 +++++++++++++----------
4 files changed, 71 insertions(+), 54 deletions(-)
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 826ea600b..c13f7fa2f 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -2043,26 +2043,31 @@ static int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
static bool cgfsng_mount(void *hdata, const char *root, int type)
{
- int i;
+ int i, ret;
char *tmpfspath = NULL;
bool retval = false;
struct lxc_handler *handler = hdata;
struct cgfsng_handler_data *d = handler->cgroup_data;
- bool has_cgns = false, has_sys_admin = true;
+ bool has_cgns = false, wants_force_mount = false;
if ((type & LXC_AUTO_CGROUP_MASK) == 0)
return true;
- has_cgns = cgns_supported();
- if (!lxc_list_empty(&handler->conf->keepcaps))
- has_sys_admin = in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps);
- else
- has_sys_admin = !in_caplist(CAP_SYS_ADMIN, &handler->conf->caps);
+ if (type & LXC_AUTO_CGROUP_FORCE) {
+ type &= ~LXC_AUTO_CGROUP_FORCE;
+ wants_force_mount = true;
+ }
- if (has_cgns && has_sys_admin)
- return true;
+ if (!wants_force_mount){
+ if (!lxc_list_empty(&handler->conf->keepcaps))
+ wants_force_mount = !in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps);
+ else
+ wants_force_mount = in_caplist(CAP_SYS_ADMIN, &handler->conf->caps);
+ }
- tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
+ has_cgns = cgns_supported();
+ if (has_cgns && !wants_force_mount)
+ return true;
if (type == LXC_AUTO_CGROUP_NOSPEC)
type = LXC_AUTO_CGROUP_MIXED;
@@ -2070,17 +2075,17 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
type = LXC_AUTO_CGROUP_FULL_MIXED;
/* Mount tmpfs */
- if (safe_mount("cgroup_root", tmpfspath, "tmpfs",
- MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME,
- "size=10240k,mode=755",
- root) < 0)
- goto bad;
+ tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
+ ret = safe_mount("cgroup_root", tmpfspath, "tmpfs",
+ MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME,
+ "size=10240k,mode=755", root);
+ if (ret < 0)
+ goto on_error;
for (i = 0; hierarchies[i]; i++) {
char *controllerpath, *path2;
struct hierarchy *h = hierarchies[i];
char *controller = strrchr(h->mountpoint, '/');
- int r;
if (!controller)
continue;
@@ -2090,49 +2095,56 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
free(controllerpath);
continue;
}
- if (mkdir(controllerpath, 0755) < 0) {
+ ret = mkdir(controllerpath, 0755);
+ if (ret < 0) {
SYSERROR("Error creating cgroup path: %s", controllerpath);
free(controllerpath);
- goto bad;
+ goto on_error;
}
- if (has_cgns && !has_sys_admin) {
+ if (has_cgns && wants_force_mount) {
/* If cgroup namespaces are supported but the container
* will not have CAP_SYS_ADMIN after it has started we
* need to mount the cgroups manually.
*/
- r = cg_mount_in_cgroup_namespace(type, h, controllerpath);
+ ret = cg_mount_in_cgroup_namespace(type, h, controllerpath);
free(controllerpath);
- if (r < 0)
- goto bad;
+ if (ret < 0)
+ goto on_error;
+
continue;
}
- if (mount_cgroup_full(type, h, controllerpath, d->container_cgroup) < 0) {
+ ret = mount_cgroup_full(type, h, controllerpath, d->container_cgroup);
+ if (ret < 0) {
free(controllerpath);
- goto bad;
+ goto on_error;
}
+
if (!cg_mount_needs_subdirs(type)) {
free(controllerpath);
continue;
}
- path2 = must_make_path(controllerpath, h->base_cgroup, d->container_cgroup, NULL);
- if (mkdir_p(path2, 0755) < 0) {
+
+ path2 = must_make_path(controllerpath, h->base_cgroup,
+ d->container_cgroup, NULL);
+ ret = mkdir_p(path2, 0755);
+ if (ret < 0) {
free(controllerpath);
free(path2);
- goto bad;
+ goto on_error;
}
- r = do_secondstage_mounts_if_needed(type, h, controllerpath, path2,
- d->container_cgroup);
+ ret = do_secondstage_mounts_if_needed(
+ type, h, controllerpath, path2, d->container_cgroup);
free(controllerpath);
free(path2);
- if (r < 0)
- goto bad;
+ if (ret < 0)
+ goto on_error;
}
retval = true;
-bad:
+on_error:
free(tmpfspath);
return retval;
}
diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 01f11422a..98d8d3871 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -715,7 +715,7 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha
if (flags & LXC_AUTO_CGROUP_MASK) {
int cg_flags;
- cg_flags = flags & LXC_AUTO_CGROUP_MASK;
+ cg_flags = flags & (LXC_AUTO_CGROUP_MASK & ~LXC_AUTO_CGROUP_FORCE);
/* If the type of cgroup mount was not specified, it depends on the
* container's capabilities as to what makes sense: if we have
* CAP_SYS_ADMIN, the read-only part can be remounted read-write
@@ -737,7 +737,8 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha
else
cg_flags = has_sys_admin ? LXC_AUTO_CGROUP_FULL_RW : LXC_AUTO_CGROUP_FULL_MIXED;
}
-
+ if (flags & LXC_AUTO_CGROUP_FORCE)
+ cg_flags |= LXC_AUTO_CGROUP_FORCE;
if (!cgroup_mount(conf->rootfs.path ? conf->rootfs.mount : "", handler, cg_flags)) {
SYSERROR("error mounting /sys/fs/cgroup");
return -1;
@@ -3343,7 +3344,7 @@ int lxc_setup(struct lxc_handler *handler)
* before, /sys could not have been mounted
* (is either mounted automatically or via fstab entries)
*/
- if (lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler) < 0) {
+ if (lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & (LXC_AUTO_CGROUP_MASK), handler) < 0) {
ERROR("failed to setup the automatic mounts for '%s'", name);
return -1;
}
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index c5f27336a..388c0518c 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -233,9 +233,9 @@ enum {
* variants, which is safe. */
LXC_AUTO_CGROUP_NOSPEC = 0x0B0, /* /sys/fs/cgroup (partial mount, r/w or mixed, depending on caps) */
LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */
- LXC_AUTO_CGROUP_MASK = 0x0F0,
-
- LXC_AUTO_ALL_MASK = 0x0FF, /* all known settings */
+ LXC_AUTO_CGROUP_FORCE = 0x100, /* mount cgroups even when cgroup namespaces are supported */
+ LXC_AUTO_CGROUP_MASK = 0x1F0, /* all known cgroup options, doe not contain LXC_AUTO_CGROUP_FORCE */
+ LXC_AUTO_ALL_MASK = 0x1FF, /* all known settings */
};
/*
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 66b7615fe..82c3b06da 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -1706,26 +1706,30 @@ 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-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 },
/* 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
*/
- { NULL, 0, 0 }
+ { NULL, 0, 0 }
};
if (lxc_config_value_empty(value)) {
More information about the lxc-devel
mailing list