[lxc-devel] [lxc/master] cgroups: scoping for cgroup v2

brauner on Github lxc-bot at linuxcontainers.org
Tue Sep 11 09:15:56 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 431 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20180911/9b9282a3/attachment.bin>
-------------- next part --------------
From fe89c7d4976d289ee76d9cfe162f07fbc86509a3 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:12:35 +0200
Subject: [PATCH 01/11] cgroup: rename container specific cgroup functions

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 10 +++++-----
 src/lxc/cgroups/cgroup.h |  4 ++--
 src/lxc/criu.c           |  2 +-
 src/lxc/start.c          |  4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index c37456b92..c4fd6d2ec 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1229,8 +1229,8 @@ static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname)
 /* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
  * next cgroup_pattern-1, -2, ..., -999.
  */
-static inline bool cgfsng_create(struct cgroup_ops *ops,
-				 struct lxc_handler *handler)
+static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
+					 struct lxc_handler *handler)
 {
 	int i;
 	size_t len;
@@ -1305,7 +1305,7 @@ static inline bool cgfsng_create(struct cgroup_ops *ops,
 	return false;
 }
 
-static bool cgfsng_enter(struct cgroup_ops *ops, pid_t pid)
+static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
 {
 	int i, len;
 	char pidstr[25];
@@ -2583,8 +2583,8 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
 
 	cgfsng_ops->data_init = cgfsng_data_init;
 	cgfsng_ops->destroy = cgfsng_destroy;
-	cgfsng_ops->create = cgfsng_create;
-	cgfsng_ops->enter = cgfsng_enter;
+	cgfsng_ops->payload_create = cgfsng_payload_create;
+	cgfsng_ops->payload_enter = cgfsng_payload_enter;
 	cgfsng_ops->escape = cgfsng_escape;
 	cgfsng_ops->num_hierarchies = cgfsng_num_hierarchies;
 	cgfsng_ops->get_hierarchies = cgfsng_get_hierarchies;
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index 0c8b2ea88..351402127 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -124,8 +124,8 @@ struct cgroup_ops {
 
 	bool (*data_init)(struct cgroup_ops *ops);
 	void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
-	bool (*create)(struct cgroup_ops *ops, struct lxc_handler *handler);
-	bool (*enter)(struct cgroup_ops *ops, pid_t pid);
+	bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
+	bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid);
 	const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);
 	bool (*escape)(const struct cgroup_ops *ops, struct lxc_conf *conf);
 	int (*num_hierarchies)(struct cgroup_ops *ops);
diff --git a/src/lxc/criu.c b/src/lxc/criu.c
index db9101b0f..ffcb1bb0f 100644
--- a/src/lxc/criu.c
+++ b/src/lxc/criu.c
@@ -972,7 +972,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
 		goto out_fini_handler;
 	handler->cgroup_ops = cgroup_ops;
 
-	if (!cgroup_ops->create(cgroup_ops, handler)) {
+	if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
 		ERROR("failed creating groups");
 		goto out_fini_handler;
 	}
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 8d3a7ced5..675f07ff3 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1678,7 +1678,7 @@ static int lxc_spawn(struct lxc_handler *handler)
 		}
 	}
 
-	if (!cgroup_ops->create(cgroup_ops, handler)) {
+	if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
 		ERROR("Failed creating cgroups");
 		goto out_delete_net;
 	}
@@ -1772,7 +1772,7 @@ static int lxc_spawn(struct lxc_handler *handler)
 		goto out_delete_net;
 	}
 
-	if (!cgroup_ops->enter(cgroup_ops, handler->pid))
+	if (!cgroup_ops->payload_enter(cgroup_ops, handler->pid))
 		goto out_delete_net;
 
 	if (!cgroup_ops->chown(cgroup_ops, handler->conf))

From 1e22ed12d039335aa2538cb2a8437092bd5808c7 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:24:21 +0200
Subject: [PATCH 02/11] cgroups: switch to lxc.payload as default pattern

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 configure.ac        | 2 +-
 src/lxc/initutils.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 502b9ae1d..ad151f23f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -483,7 +483,7 @@ AC_ARG_WITH([cgroup-pattern],
 	[AC_HELP_STRING(
 		[--with-cgroup-pattern=pattern],
 		[pattern for container cgroups]
-	)], [], [with_cgroup_pattern=['lxc/%n']])
+	)], [], [with_cgroup_pattern=['lxc.payload/%n']])
 
 # The path for the apparmor_parser's cache for generated apparmor profiles
 AC_ARG_WITH([apparmor-cache-dir],
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
index 467d3f0bc..4257ffeaa 100644
--- a/src/lxc/initutils.c
+++ b/src/lxc/initutils.c
@@ -101,7 +101,7 @@ const char *lxc_global_config_value(const char *option_name)
 		sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
 		sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
 		sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
-		user_cgroup_pattern = strdup("lxc/%n");
+		user_cgroup_pattern = strdup("lxc.payload/%n");
 	}
 	else {
 		user_config_path = strdup(LXC_GLOBAL_CONF);

From 3ac680476db6eaa9a9eef4ce83587183bb85f0f6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:41:11 +0200
Subject: [PATCH 03/11] cgroups: s/fullcgpath/container_full_path/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 50 ++++++++++++++++++++--------------------
 src/lxc/cgroups/cgroup.c |  2 +-
 src/lxc/cgroups/cgroup.h |  4 ++--
 3 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index c4fd6d2ec..588ab40ec 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -817,7 +817,7 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
 	new->controllers = clist;
 	new->mountpoint = mountpoint;
 	new->base_cgroup = base_cgroup;
-	new->fullcgpath = NULL;
+	new->container_full_path = NULL;
 	new->version = type;
 
 	newentry = append_null_to_list((void ***)h);
@@ -1049,15 +1049,15 @@ static int cgroup_rmdir(struct hierarchy **hierarchies,
 		int ret;
 		struct hierarchy *h = hierarchies[i];
 
-		if (!h->fullcgpath)
+		if (!h->container_full_path)
 			continue;
 
-		ret = recursive_destroy(h->fullcgpath);
+		ret = recursive_destroy(h->container_full_path);
 		if (ret < 0)
-			WARN("Failed to destroy \"%s\"", h->fullcgpath);
+			WARN("Failed to destroy \"%s\"", h->container_full_path);
 
-		free(h->fullcgpath);
-		h->fullcgpath = NULL;
+		free(h->container_full_path);
+		h->container_full_path = NULL;
 	}
 
 	return 0;
@@ -1194,9 +1194,9 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 {
 	int ret;
 
-	h->fullcgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
-	if (dir_exists(h->fullcgpath)) {
-		ERROR("The cgroup \"%s\" already existed", h->fullcgpath);
+	h->container_full_path = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+	if (dir_exists(h->container_full_path)) {
+		ERROR("The cgroup \"%s\" already existed", h->container_full_path);
 		return false;
 	}
 
@@ -1205,9 +1205,9 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 		return false;
 	}
 
-	ret = mkdir_p(h->fullcgpath, 0755);
+	ret = mkdir_p(h->container_full_path, 0755);
 	if (ret < 0) {
-		ERROR("Failed to create cgroup \"%s\"", h->fullcgpath);
+		ERROR("Failed to create cgroup \"%s\"", h->container_full_path);
 		return false;
 	}
 
@@ -1218,12 +1218,12 @@ static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname)
 {
 	int ret;
 
-	ret = rmdir(h->fullcgpath);
+	ret = rmdir(h->container_full_path);
 	if (ret < 0)
-		SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->fullcgpath);
+		SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->container_full_path);
 
-	free(h->fullcgpath);
-	h->fullcgpath = NULL;
+	free(h->container_full_path);
+	h->container_full_path = NULL;
 }
 
 /* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
@@ -1285,9 +1285,9 @@ static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 	for (i = 0; ops->hierarchies[i]; i++) {
 		if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
 			int j;
-			ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->fullcgpath);
-			free(ops->hierarchies[i]->fullcgpath);
-			ops->hierarchies[i]->fullcgpath = NULL;
+			ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->container_full_path);
+			free(ops->hierarchies[i]->container_full_path);
+			ops->hierarchies[i]->container_full_path = NULL;
 			for (j = 0; j < i; j++)
 				remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup);
 			idx++;
@@ -1318,7 +1318,7 @@ static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
 		int ret;
 		char *fullpath;
 
-		fullpath = must_make_path(ops->hierarchies[i]->fullcgpath,
+		fullpath = must_make_path(ops->hierarchies[i]->container_full_path,
 					  "cgroup.procs", NULL);
 		ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666);
 		if (ret != 0) {
@@ -1393,7 +1393,7 @@ static int chown_cgroup_wrapper(void *data)
 
 	for (i = 0; arg->hierarchies[i]; i++) {
 		char *fullpath;
-		char *path = arg->hierarchies[i]->fullcgpath;
+		char *path = arg->hierarchies[i]->container_full_path;
 
 		ret = chowmod(path, destuid, nsgid, 0775);
 		if (ret < 0)
@@ -1738,7 +1738,7 @@ static int cgfsng_nrtasks(struct cgroup_ops *ops)
 	if (!ops->container_cgroup || !ops->hierarchies)
 		return -1;
 
-	path = must_make_path(ops->hierarchies[0]->fullcgpath, NULL);
+	path = must_make_path(ops->hierarchies[0]->container_full_path, NULL);
 	count = recursive_count_nrtasks(path);
 	free(path);
 	return count;
@@ -1811,7 +1811,7 @@ static bool cgfsng_unfreeze(struct cgroup_ops *ops)
 	if (!h)
 		return false;
 
-	fullpath = must_make_path(h->fullcgpath, "freezer.state", NULL);
+	fullpath = must_make_path(h->container_full_path, "freezer.state", NULL);
 	ret = lxc_write_to_file(fullpath, THAWED, THAWED_LEN, false, 0666);
 	free(fullpath);
 	if (ret < 0)
@@ -1832,7 +1832,7 @@ static const char *cgfsng_get_cgroup(struct cgroup_ops *ops,
 		return NULL;
 	}
 
-	return h->fullcgpath ? h->fullcgpath + strlen(h->mountpoint) : NULL;
+	return h->container_full_path ? h->container_full_path + strlen(h->mountpoint) : NULL;
 }
 
 /* Given a cgroup path returned from lxc_cmd_get_cgroup_path, build a full path,
@@ -2155,7 +2155,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename,
 		return -ENOENT;
 	}
 
-	fullpath = must_make_path(h->fullcgpath, filename, NULL);
+	fullpath = must_make_path(h->container_full_path, filename, NULL);
 	ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666);
 	free(fullpath);
 	return ret;
@@ -2223,7 +2223,7 @@ static bool __cg_unified_setup_limits(struct cgroup_ops *ops,
 		char *fullpath;
 		struct lxc_cgroup *cg = iterator->elem;
 
-		fullpath = must_make_path(h->fullcgpath, cg->subsystem, NULL);
+		fullpath = must_make_path(h->container_full_path, cg->subsystem, NULL);
 		ret = lxc_write_to_file(fullpath, cg->value, strlen(cg->value), false, 0666);
 		free(fullpath);
 		if (ret < 0) {
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 7dffeb0cc..f9a33cb3c 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -85,7 +85,7 @@ void cgroup_exit(struct cgroup_ops *ops)
 
 		free((*it)->mountpoint);
 		free((*it)->base_cgroup);
-		free((*it)->fullcgpath);
+		free((*it)->container_full_path);
 		free(*it);
 	}
 	free(ops->hierarchies);
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index 351402127..4c1e94c23 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -62,7 +62,7 @@ typedef enum {
  *   is created. This will be either the caller's cgroup (if not root), or
  *   init's cgroup (if root).
  *
- * @fullcgpath
+ * @container_full_path
  * - The full path to the containers cgroup.
  *
  * @version
@@ -77,7 +77,7 @@ struct hierarchy {
 	char **controllers;
 	char *mountpoint;
 	char *base_cgroup;
-	char *fullcgpath;
+	char *container_full_path;
 	int version;
 };
 

From 47dbf45667a9fb9f879bbf605b0c56cde083055d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:42:02 +0200
Subject: [PATCH 04/11] cgroups: add missing string.h include

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgroup.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index f9a33cb3c..5c6523bc9 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -22,6 +22,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 

From 5966066b06070fe0377a238d7b72771c89bb1334 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:47:59 +0200
Subject: [PATCH 05/11] cgroups: s/base_cgroup/container_base_path/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 18 +++++++++---------
 src/lxc/cgroups/cgroup.c |  2 +-
 src/lxc/cgroups/cgroup.h |  4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 588ab40ec..26da28e5b 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -571,7 +571,7 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
 	if (slash)
 		*slash = '\0';
 
-	cgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+	cgpath = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
 	if (slash)
 		*slash = '/';
 
@@ -808,7 +808,7 @@ static char **cg_unified_get_controllers(const char *file)
 }
 
 static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char *mountpoint,
-				       char *base_cgroup, int type)
+				       char *container_base_path, int type)
 {
 	struct hierarchy *new;
 	int newentry;
@@ -816,7 +816,7 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
 	new = must_alloc(sizeof(*new));
 	new->controllers = clist;
 	new->mountpoint = mountpoint;
-	new->base_cgroup = base_cgroup;
+	new->container_base_path = container_base_path;
 	new->container_full_path = NULL;
 	new->version = type;
 
@@ -1013,7 +1013,7 @@ static void lxc_cgfsng_print_hierarchies(struct cgroup_ops *ops)
 		int j;
 		char **cit;
 
-		TRACE("  %d: base_cgroup: %s", i, (*it)->base_cgroup ? (*it)->base_cgroup : "(null)");
+		TRACE("  %d: base_cgroup: %s", i, (*it)->container_base_path ? (*it)->container_base_path : "(null)");
 		TRACE("      mountpoint:  %s", (*it)->mountpoint ? (*it)->mountpoint : "(null)");
 		TRACE("      controllers:");
 		for (j = 0, cit = (*it)->controllers; cit && *cit; cit++, j++)
@@ -1165,7 +1165,7 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
 	if (parts_len > 0)
 		parts_len--;
 
-	cgroup = must_make_path(h->mountpoint, h->base_cgroup, NULL);
+	cgroup = must_make_path(h->mountpoint, h->container_base_path, NULL);
 	for (i = 0; i < parts_len; i++) {
 		int ret;
 		char *target;
@@ -1194,7 +1194,7 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 {
 	int ret;
 
-	h->container_full_path = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+	h->container_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
 	if (dir_exists(h->container_full_path)) {
 		ERROR("The cgroup \"%s\" already existed", h->container_full_path);
 		return false;
@@ -1495,7 +1495,7 @@ static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
 		INFO("Remounted %s read-only", controllerpath);
 	}
 
-	sourcepath = must_make_path(h->mountpoint, h->base_cgroup,
+	sourcepath = must_make_path(h->mountpoint, h->container_base_path,
 				    container_cgroup, NULL);
 	if (type == LXC_AUTO_CGROUP_RO)
 		flags |= MS_RDONLY;
@@ -1665,7 +1665,7 @@ static bool cgfsng_mount(struct cgroup_ops *ops, struct lxc_handler *handler,
 			continue;
 		}
 
-		path2 = must_make_path(controllerpath, h->base_cgroup,
+		path2 = must_make_path(controllerpath, h->container_base_path,
 				       ops->container_cgroup, NULL);
 		ret = mkdir_p(path2, 0755);
 		if (ret < 0) {
@@ -1757,7 +1757,7 @@ static bool cgfsng_escape(const struct cgroup_ops *ops, struct lxc_conf *conf)
 		char *fullpath;
 
 		fullpath = must_make_path(ops->hierarchies[i]->mountpoint,
-					  ops->hierarchies[i]->base_cgroup,
+					  ops->hierarchies[i]->container_base_path,
 					  "cgroup.procs", NULL);
 		ret = lxc_write_to_file(fullpath, "0", 2, false, 0666);
 		if (ret != 0) {
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 5c6523bc9..517bb4b3c 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -85,7 +85,7 @@ void cgroup_exit(struct cgroup_ops *ops)
 		free((*it)->controllers);
 
 		free((*it)->mountpoint);
-		free((*it)->base_cgroup);
+		free((*it)->container_base_path);
 		free((*it)->container_full_path);
 		free(*it);
 	}
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index 4c1e94c23..9aba1842b 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -57,7 +57,7 @@ typedef enum {
  *   depending on whether this is a hybrid cgroup layout (mix of legacy and
  *   unified hierarchies) or a pure unified cgroup layout.
  *
- * @base_cgroup
+ * @container_base_path
  * - The cgroup under which the container cgroup path
  *   is created. This will be either the caller's cgroup (if not root), or
  *   init's cgroup (if root).
@@ -76,7 +76,7 @@ typedef enum {
 struct hierarchy {
 	char **controllers;
 	char *mountpoint;
-	char *base_cgroup;
+	char *container_base_path;
 	char *container_full_path;
 	int version;
 };

From 7cb0d3b198401bab2ae5eb178be43b454f980863 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:42:51 +0200
Subject: [PATCH 06/11] cgroups: add monitor_cgroup member

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 1 +
 src/lxc/cgroups/cgroup.c | 1 +
 src/lxc/cgroups/cgroup.h | 1 +
 3 files changed, 3 insertions(+)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 26da28e5b..f67195230 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -2561,6 +2561,7 @@ static bool cgfsng_data_init(struct cgroup_ops *ops)
 		return false;
 	}
 	ops->cgroup_pattern = must_copy_string(cgroup_pattern);
+	ops->monitor_pattern = must_copy_string("lxc.monitor");
 
 	return true;
 }
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index 517bb4b3c..de602d04e 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -76,6 +76,7 @@ void cgroup_exit(struct cgroup_ops *ops)
 
 	free(ops->cgroup_pattern);
 	free(ops->container_cgroup);
+	free(ops->monitor_pattern);
 
 	for (it = ops->hierarchies; it && *it; it++) {
 		char **ctrlr;
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index 9aba1842b..d79508362 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -92,6 +92,7 @@ struct cgroup_ops {
 	char **cgroup_use;
 	char *cgroup_pattern;
 	char *container_cgroup;
+	char *monitor_pattern;
 
 	/* @hierarchies
 	 * - A NULL-terminated array of struct hierarchy, one per legacy

From 8228109dd9ea87c8bb894675ac77679b133dadb9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 15:51:38 +0200
Subject: [PATCH 07/11] cgroups: add monitor_full_path member

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 1 +
 src/lxc/cgroups/cgroup.c | 1 +
 src/lxc/cgroups/cgroup.h | 4 ++++
 3 files changed, 6 insertions(+)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index f67195230..052978158 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -818,6 +818,7 @@ static struct hierarchy *add_hierarchy(struct hierarchy ***h, char **clist, char
 	new->mountpoint = mountpoint;
 	new->container_base_path = container_base_path;
 	new->container_full_path = NULL;
+	new->monitor_full_path = NULL;
 	new->version = type;
 
 	newentry = append_null_to_list((void ***)h);
diff --git a/src/lxc/cgroups/cgroup.c b/src/lxc/cgroups/cgroup.c
index de602d04e..cf81f3edb 100644
--- a/src/lxc/cgroups/cgroup.c
+++ b/src/lxc/cgroups/cgroup.c
@@ -88,6 +88,7 @@ void cgroup_exit(struct cgroup_ops *ops)
 		free((*it)->mountpoint);
 		free((*it)->container_base_path);
 		free((*it)->container_full_path);
+		free((*it)->monitor_full_path);
 		free(*it);
 	}
 	free(ops->hierarchies);
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index d79508362..d3f834c4c 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -65,6 +65,9 @@ typedef enum {
  * @container_full_path
  * - The full path to the containers cgroup.
  *
+ * @monitor_full_path
+ * - The full path to the monitor's cgroup.
+ *
  * @version
  * - legacy hierarchy
  *   If the hierarchy is a legacy hierarchy this will be set to
@@ -78,6 +81,7 @@ struct hierarchy {
 	char *mountpoint;
 	char *container_base_path;
 	char *container_full_path;
+	char *monitor_full_path;
 	int version;
 };
 

From d5d04f624c451ebf03cde91e03634e02b14abd49 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 16:27:18 +0200
Subject: [PATCH 08/11] cgroups: add monitor_create()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgroup.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index d3f834c4c..ae701122f 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -129,6 +129,7 @@ struct cgroup_ops {
 
 	bool (*data_init)(struct cgroup_ops *ops);
 	void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
+	bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
 	bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
 	bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid);
 	const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);

From 3516a996372327186c8cb5d064197ba48535a544 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 16:27:35 +0200
Subject: [PATCH 09/11] cgfsng: add cgfsng_monitor_create()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 83 +++++++++++++++++++++++++++++++++++-----
 src/lxc/start.c          |  7 ++++
 2 files changed, 80 insertions(+), 10 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 052978158..f756018c3 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1191,7 +1191,24 @@ static bool cg_unified_create_cgroup(struct hierarchy *h, char *cgname)
 	return bret;
 }
 
-static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
+static bool monitor_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
+{
+	int ret;
+
+	h->monitor_full_path = must_make_path(h->mountpoint, h->container_base_path, cgname, NULL);
+	if (dir_exists(h->monitor_full_path))
+		return true;
+
+	ret = mkdir_p(h->monitor_full_path, 0755);
+	if (ret < 0) {
+		ERROR("Failed to create cgroup \"%s\"", h->monitor_full_path);
+		return false;
+	}
+
+	return cg_unified_create_cgroup(h, cgname);
+}
+
+static bool container_create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 {
 	int ret;
 
@@ -1215,16 +1232,62 @@ static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 	return cg_unified_create_cgroup(h, cgname);
 }
 
-static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname)
+static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname, bool monitor)
 {
 	int ret;
+	char *full_path;
+
+	if (monitor)
+		full_path = h->monitor_full_path;
+	else
+		full_path = h->container_full_path;
 
-	ret = rmdir(h->container_full_path);
+	ret = rmdir(full_path);
 	if (ret < 0)
-		SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", h->container_full_path);
+		SYSERROR("Failed to rmdir(\"%s\") from failed creation attempt", full_path);
 
-	free(h->container_full_path);
-	h->container_full_path = NULL;
+	free(full_path);
+
+	if (monitor)
+		h->monitor_full_path = NULL;
+	else
+		h->container_full_path = NULL;
+}
+
+static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
+					 struct lxc_handler *handler)
+{
+	char *monitor_cgroup;
+	bool bret = false;
+	struct lxc_conf *conf = handler->conf;
+
+	if (!conf)
+		return bret;
+
+	if (conf->cgroup_meta.dir)
+		monitor_cgroup = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, ops->monitor_pattern, handler->name, NULL}, false);
+	else
+		monitor_cgroup = must_make_path(ops->monitor_pattern, handler->name, NULL);
+	if (!monitor_cgroup)
+		return bret;
+
+	for (int i = 0; ops->hierarchies[i]; i++) {
+		if (!monitor_create_path_for_hierarchy(ops->hierarchies[i], monitor_cgroup)) {
+			ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->monitor_full_path);
+			free(ops->hierarchies[i]->container_full_path);
+			ops->hierarchies[i]->container_full_path = NULL;
+			for (int j = 0; j < i; j++)
+				remove_path_for_hierarchy(ops->hierarchies[j], monitor_cgroup, true);
+			goto on_error;
+		}
+	}
+
+	bret = true;
+
+on_error:
+	free(monitor_cgroup);
+
+	return bret;
 }
 
 /* Try to create the same cgroup in all hierarchies. Start with cgroup_pattern;
@@ -1284,13 +1347,12 @@ static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 	}
 
 	for (i = 0; ops->hierarchies[i]; i++) {
-		if (!create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
-			int j;
+		if (!container_create_path_for_hierarchy(ops->hierarchies[i], container_cgroup)) {
 			ERROR("Failed to create cgroup \"%s\"", ops->hierarchies[i]->container_full_path);
 			free(ops->hierarchies[i]->container_full_path);
 			ops->hierarchies[i]->container_full_path = NULL;
-			for (j = 0; j < i; j++)
-				remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup);
+			for (int j = 0; j < i; j++)
+				remove_path_for_hierarchy(ops->hierarchies[j], container_cgroup, false);
 			idx++;
 			goto again;
 		}
@@ -2585,6 +2647,7 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
 
 	cgfsng_ops->data_init = cgfsng_data_init;
 	cgfsng_ops->destroy = cgfsng_destroy;
+	cgfsng_ops->monitor_create = cgfsng_monitor_create;
 	cgfsng_ops->payload_create = cgfsng_payload_create;
 	cgfsng_ops->payload_enter = cgfsng_payload_enter;
 	cgfsng_ops->escape = cgfsng_escape;
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 675f07ff3..3139431f0 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1949,6 +1949,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
 {
 	int ret, status;
 	struct lxc_conf *conf = handler->conf;
+	struct cgroup_ops *cgroup_ops;
 
 	ret = lxc_init(name, handler);
 	if (ret < 0) {
@@ -1958,12 +1959,18 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
 	handler->ops = ops;
 	handler->data = data;
 	handler->backgrounded = backgrounded;
+	cgroup_ops = handler->cgroup_ops;
 
 	if (!attach_block_device(handler->conf)) {
 		ERROR("Failed to attach block device");
 		goto out_fini_nonet;
 	}
 
+	if (!cgroup_ops->monitor_create(cgroup_ops, handler)) {
+		ERROR("Failed to create monitor cgroup");
+		goto out_fini_nonet;
+	}
+
 	if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) {
 		/* If the backing store is a device, mount it here and now. */
 		if (rootfs_is_blockdev(conf)) {

From 1080c19d595889399088b81db32de32a0359a39c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 16:28:13 +0200
Subject: [PATCH 10/11] cgroups: add monitor_enter()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgroup.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index ae701122f..16b880942 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -130,6 +130,7 @@ struct cgroup_ops {
 	bool (*data_init)(struct cgroup_ops *ops);
 	void (*destroy)(struct cgroup_ops *ops, struct lxc_handler *handler);
 	bool (*monitor_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
+	bool (*monitor_enter)(struct cgroup_ops *ops, pid_t pid);
 	bool (*payload_create)(struct cgroup_ops *ops, struct lxc_handler *handler);
 	bool (*payload_enter)(struct cgroup_ops *ops, pid_t pid);
 	const char *(*get_cgroup)(struct cgroup_ops *ops, const char *controller);

From 8860155a9eef1cc999d738acaf29f79e943d70c9 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 10 Sep 2018 16:40:18 +0200
Subject: [PATCH 11/11] cgfsng: cgfsng_monitor_enter()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

brauner at wittgenstein|~
> sudo systemctl status lxc at c1
lxc at c1.service - LXC Container: c1
   Loaded: loaded (/lib/systemd/system/lxc at .service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-09-11 10:42:22 CEST; 38s ago
     Docs: man:lxc-start
           man:lxc
  Process: 29855 ExecStart=/usr/bin/lxc-start -n c1 -p /run/lxc/c1.pid (code=exited, status=0/SUCCESS)
    Tasks: 18 (limit: 4915)
   Memory: 32.1M
   CGroup: /system.slice/system-lxc.slice/lxc at c1.service
           ├─lxc.monitor
           │ └─c1
           │   └─29870 [lxc monitor] /var/lib/lxc c1
           └─lxc.payload
             └─c1
               ├─init.scope
               │ └─29878 /sbin/init
               └─system.slice
                 ├─console-getty.service
                 │ └─30028 /sbin/agetty -o -p -- \u --noclear --keep-baud console 115200,38400,9600 linux
                 ├─cron.service
                 │ └─30019 /usr/sbin/cron -f
                 ├─dbus.service
                 │ └─30020 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
                 ├─networkd-dispatcher.service
                 │ └─30016 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
                 ├─rsyslog.service
                 │ └─30017 /usr/sbin/rsyslogd -n
                 ├─system-container\x2dgetty.slice
                 │ ├─container-getty at 0.service
                 │ │ └─30027 /sbin/agetty -o -p -- \u --noclear --keep-baud pts/0 115200,38400,9600 vt220
                 │ ├─container-getty at 1.service
                 │ │ └─30030 /sbin/agetty -o -p -- \u --noclear --keep-baud pts/1 115200,38400,9600 vt220
                 │ ├─container-getty at 2.service
                 │ │ └─30026 /sbin/agetty -o -p -- \u --noclear --keep-baud pts/2 115200,38400,9600 vt220
                 │ └─container-getty at 3.service
                 │   └─30029 /sbin/agetty -o -p -- \u --noclear --keep-baud pts/3 115200,38400,9600 vt220
                 ├─systemd-journald.service
                 │ └─29976 /lib/systemd/systemd-journald
                 ├─systemd-logind.service
                 │ └─30018 /lib/systemd/systemd-logind
                 ├─systemd-networkd.service
                 │ └─29996 /lib/systemd/systemd-networkd
                 ├─systemd-resolved.service
                 │ └─30014 /lib/systemd/systemd-resolved
                 └─systemd-udevd.service
                   └─29986 /lib/systemd/systemd-udevd

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 35 +++++++++++++++++++++++++----------
 src/lxc/start.c          |  5 +++++
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index f756018c3..9230c292e 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1368,33 +1368,47 @@ static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 	return false;
 }
 
-static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
+static bool __do_cgroup_enter(struct cgroup_ops *ops, pid_t pid, bool monitor)
 {
-	int i, len;
+	int len;
 	char pidstr[25];
 
 	len = snprintf(pidstr, 25, "%d", pid);
 	if (len < 0 || len >= 25)
 		return false;
 
-	for (i = 0; ops->hierarchies[i]; i++) {
+	for (int i = 0; ops->hierarchies[i]; i++) {
 		int ret;
-		char *fullpath;
+		char *path;
 
-		fullpath = must_make_path(ops->hierarchies[i]->container_full_path,
-					  "cgroup.procs", NULL);
-		ret = lxc_write_to_file(fullpath, pidstr, len, false, 0666);
+		if (monitor)
+			path = must_make_path(ops->hierarchies[i]->monitor_full_path,
+					      "cgroup.procs", NULL);
+		else
+			path = must_make_path(ops->hierarchies[i]->container_full_path,
+					      "cgroup.procs", NULL);
+		ret = lxc_write_to_file(path, pidstr, len, false, 0666);
 		if (ret != 0) {
-			SYSERROR("Failed to enter cgroup \"%s\"", fullpath);
-			free(fullpath);
+			SYSERROR("Failed to enter cgroup \"%s\"", path);
+			free(path);
 			return false;
 		}
-		free(fullpath);
+		free(path);
 	}
 
 	return true;
 }
 
+static bool cgfsng_monitor_enter(struct cgroup_ops *ops, pid_t pid)
+{
+	return __do_cgroup_enter(ops, pid, true);
+}
+
+static bool cgfsng_payload_enter(struct cgroup_ops *ops, pid_t pid)
+{
+	return __do_cgroup_enter(ops, pid, false);
+}
+
 static int chowmod(char *path, uid_t chown_uid, gid_t chown_gid,
 		   mode_t chmod_mode)
 {
@@ -2648,6 +2662,7 @@ struct cgroup_ops *cgfsng_ops_init(struct lxc_conf *conf)
 	cgfsng_ops->data_init = cgfsng_data_init;
 	cgfsng_ops->destroy = cgfsng_destroy;
 	cgfsng_ops->monitor_create = cgfsng_monitor_create;
+	cgfsng_ops->monitor_enter = cgfsng_monitor_enter;
 	cgfsng_ops->payload_create = cgfsng_payload_create;
 	cgfsng_ops->payload_enter = cgfsng_payload_enter;
 	cgfsng_ops->escape = cgfsng_escape;
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 3139431f0..a8c284136 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -1971,6 +1971,11 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
 		goto out_fini_nonet;
 	}
 
+	if (!cgroup_ops->monitor_enter(cgroup_ops, lxc_raw_getpid())) {
+		ERROR("Failed to enter monitor cgroup");
+		goto out_fini_nonet;
+	}
+
 	if (geteuid() == 0 && !lxc_list_empty(&conf->id_map)) {
 		/* If the backing store is a device, mount it here and now. */
 		if (rootfs_is_blockdev(conf)) {


More information about the lxc-devel mailing list