[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