[lxc-devel] [lxc/master] cgroups: flatten hierarchy

brauner on Github lxc-bot at linuxcontainers.org
Mon Dec 9 23:05:12 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191209/ffd576fb/attachment.bin>
-------------- next part --------------
From 1e7a32990b96f515bde3bcc4c6bc7cd7dfa5e83d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 9 Dec 2019 23:14:37 +0100
Subject: [PATCH] cgroups: flatten hierarchy

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxc/cgroups/cgfsng.c | 86 ++++++++++++++++++----------------------
 src/lxc/cgroups/cgroup.h | 13 +++---
 src/lxc/initutils.c      |  2 +-
 src/lxc/lsm/apparmor.c   |  8 ++--
 src/lxc/string_utils.c   |  4 +-
 src/lxc/string_utils.h   |  2 +-
 src/lxc/utils.h          |  7 ----
 7 files changed, 55 insertions(+), 67 deletions(-)

diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 65e58b13ea..623720ac4f 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1152,10 +1152,9 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
 
 	for (int i = 0; ops->hierarchies[i]; i++) {
 		__do_free char *pivot_path = NULL;
-		int ret;
-		char *chop;
-		char pivot_cgroup[] = PIVOT_CGROUP;
+		char pivot_cgroup[] = CGROUP_PIVOT;
 		struct hierarchy *h = ops->hierarchies[i];
+		int ret;
 
 		if (!h->monitor_full_path)
 			continue;
@@ -1164,20 +1163,14 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
 			pivot_path = must_make_path(h->mountpoint,
 						    h->container_base_path,
 						    conf->cgroup_meta.dir,
-						    PIVOT_CGROUP,
-						    "cgroup.procs", NULL);
+						    CGROUP_PIVOT, NULL);
 		else
 			pivot_path = must_make_path(h->mountpoint,
 						    h->container_base_path,
-						    PIVOT_CGROUP,
-						    "cgroup.procs", NULL);
-
-		chop = strrchr(pivot_path, '/');
-		if (chop)
-			*chop = '\0';
+						    CGROUP_PIVOT, NULL);
 
 		/*
-		 * Make sure not to pass in the ro string literal PIVOT_CGROUP
+		 * Make sure not to pass in the ro string literal CGROUP_PIVOT
 		 * here.
 		 */
 		if (!cg_legacy_handle_cpuset_hierarchy(h, pivot_cgroup))
@@ -1190,13 +1183,11 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
 				       "Failed to create cgroup \"%s\"\n",
 				       pivot_path);
 
-		if (chop)
-			*chop = '/';
-
-		/* Move ourselves into the pivot cgroup to delete our own
+		/*
+		 * Move ourselves into the pivot cgroup to delete our own
 		 * cgroup.
 		 */
-		ret = lxc_write_to_file(pivot_path, pidstr, len, false, 0666);
+		ret = lxc_write_openat(pivot_path, "cgroup.procs", pidstr, len);
 		if (ret != 0)
 			log_warn_errno(continue, errno,
 				       "Failed to move monitor %s to \"%s\"\n",
@@ -1305,9 +1296,10 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
 						      struct lxc_handler *handler)
 {
 	__do_free char *monitor_cgroup = NULL;
-	char *offset, *tmp;
-	int i, idx = 0;
+	int idx = 0;
+	int i;
 	size_t len;
+	char *suffix;
 	struct lxc_conf *conf;
 
 	if (!ops)
@@ -1325,24 +1317,22 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
 	conf = handler->conf;
 
 	if (conf->cgroup_meta.dir)
-		tmp = lxc_string_join("/",
-				      (const char *[]){conf->cgroup_meta.dir,
-						       ops->monitor_pattern,
-						       handler->name, NULL},
-				      false);
+		monitor_cgroup = must_concat(&len, conf->cgroup_meta.dir, "/",
+					     DEFAULT_MONITOR_CGROUP_PREFIX,
+					     handler->name,
+					     CGROUP_CREATE_RETRY, NULL);
 	else
-		tmp = must_make_path(ops->monitor_pattern, handler->name, NULL);
-	if (!tmp)
+		monitor_cgroup = must_concat(&len, DEFAULT_MONITOR_CGROUP_PREFIX,
+					     handler->name,
+					     CGROUP_CREATE_RETRY, NULL);
+	if (!monitor_cgroup)
 		return ret_set_errno(false, ENOMEM);
 
-	len = strlen(tmp) + 5; /* leave room for -NNN\0 */
-	monitor_cgroup = must_realloc(tmp, len);
-	offset = monitor_cgroup + len - 5;
-	*offset = 0;
-
+	suffix = monitor_cgroup + len - CGROUP_CREATE_RETRY_LEN;
+	*suffix = '\0';
 	do {
 		if (idx)
-			sprintf(offset, "-%d", idx);
+			sprintf(suffix, "-%d", idx);
 
 		for (i = 0; ops->hierarchies[i]; i++) {
 			if (!monitor_create_path_for_hierarchy(ops->hierarchies[i],
@@ -1373,11 +1363,11 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
 __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 						      struct lxc_handler *handler)
 {
-	__do_free char *container_cgroup = NULL, *tmp = NULL;
+	__do_free char *container_cgroup = NULL;
 	int idx = 0;
-	int i, ret;
+	int i;
 	size_t len;
-	char *offset;
+	char *suffix;
 	struct lxc_conf *conf;
 
 	if (!ops)
@@ -1395,21 +1385,22 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 	conf = handler->conf;
 
 	if (conf->cgroup_meta.dir)
-		tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false);
+		container_cgroup = must_concat(&len, conf->cgroup_meta.dir, "/",
+					     DEFAULT_PAYLOAD_CGROUP_PREFIX,
+					     handler->name,
+					     CGROUP_CREATE_RETRY, NULL);
 	else
-		tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern);
-	if (!tmp)
-		return log_error_errno(false, ENOMEM,
-				       "Failed expanding cgroup name pattern");
-
-	len = strlen(tmp) + 5; /* leave room for -NNN\0 */
-	container_cgroup = must_realloc(NULL, len);
-	(void)strlcpy(container_cgroup, tmp, len);
-	offset = container_cgroup + len - 5;
+		container_cgroup = must_concat(&len, DEFAULT_PAYLOAD_CGROUP_PREFIX,
+					     handler->name,
+					     CGROUP_CREATE_RETRY, NULL);
+	if (!container_cgroup)
+		return ret_set_errno(false, ENOMEM);
 
+	suffix = container_cgroup + len - CGROUP_CREATE_RETRY_LEN;
+	*suffix = '\0';
 	do {
 		if (idx)
-			sprintf(offset, "-%d", idx);
+			sprintf(suffix, "-%d", idx);
 
 		for (i = 0; ops->hierarchies[i]; i++) {
 			if (!container_create_path_for_hierarchy(ops->hierarchies[i],
@@ -1433,6 +1424,8 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
 	ops->container_cgroup = move_ptr(container_cgroup);
 
 	if (ops->unified && ops->unified->container_full_path) {
+		int ret;
+
 		ret = open(ops->unified->container_full_path,
 			   O_DIRECTORY | O_RDONLY | O_CLOEXEC);
 		if (ret < 0)
@@ -3300,7 +3293,6 @@ __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops)
 		return ret_set_errno(-1, ENOMEM);
 	}
 	ops->cgroup_pattern = must_copy_string(cgroup_pattern);
-	ops->monitor_pattern = MONITOR_CGROUP;
 
 	return 0;
 }
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index dce506aa20..ea33223570 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -7,10 +7,14 @@
 #include <stddef.h>
 #include <sys/types.h>
 
+#include "macro.h"
+
 #define DEFAULT_CGROUP_MOUNTPOINT "/sys/fs/cgroup"
-#define PAYLOAD_CGROUP "lxc.payload"
-#define MONITOR_CGROUP "lxc.monitor"
-#define PIVOT_CGROUP "lxc.pivot"
+#define DEFAULT_PAYLOAD_CGROUP_PREFIX "lxc.payload."
+#define DEFAULT_MONITOR_CGROUP_PREFIX "lxc.monitor."
+#define CGROUP_CREATE_RETRY "-NNNN"
+#define CGROUP_CREATE_RETRY_LEN STRLITERALLEN(CGROUP_CREATE_RETRY)
+#define CGROUP_PIVOT "lxc.pivot"
 
 struct lxc_handler;
 struct lxc_conf;
@@ -90,9 +94,6 @@ struct cgroup_ops {
 	char *container_cgroup;
 	char *monitor_cgroup;
 
-	/* Static memory, do not free.*/
-	const char *monitor_pattern;
-
 	/* @hierarchies
 	 * - A NULL-terminated array of struct hierarchy, one per legacy
 	 *   hierarchy. No duplicates. First sufficient, writeable mounted
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
index 9751954013..41ed9e9425 100644
--- a/src/lxc/initutils.c
+++ b/src/lxc/initutils.c
@@ -84,7 +84,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.payload/%n");
+		user_cgroup_pattern = strdup("%n");
 	}
 	else {
 		user_config_path = strdup(LXC_GLOBAL_CONF);
diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c
index 33b3343cea..e34d999a19 100644
--- a/src/lxc/lsm/apparmor.c
+++ b/src/lxc/lsm/apparmor.c
@@ -510,7 +510,7 @@ static inline char *apparmor_dir(const char *ctname, const char *lxcpath)
 
 static inline char *apparmor_profile_full(const char *ctname, const char *lxcpath)
 {
-	return shorten_apparmor_name(must_concat("lxc-", ctname, "_<", lxcpath, ">", NULL));
+	return shorten_apparmor_name(must_concat(NULL, "lxc-", ctname, "_<", lxcpath, ">", NULL));
 }
 
 /* Like apparmor_profile_full() but with slashes replaced by hyphens */
@@ -639,7 +639,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
 
 	profile_name_full = apparmor_profile_full(conf->name, lxcpath);
 
-	profile = must_concat(
+	profile = must_concat(NULL,
 "#include <tunables/global>\n"
 "profile \"", profile_name_full, "\" flags=(attach_disconnected,mediate_deleted) {\n",
 	                      NULL);
@@ -663,7 +663,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
 		                  STRARRAYLEN(AA_PROFILE_STACKING_BASE));
 
 		namespace = apparmor_namespace(conf->name, lxcpath);
-		temp = must_concat("  change_profile -> \":", namespace, ":*\",\n"
+		temp = must_concat(NULL, "  change_profile -> \":", namespace, ":*\",\n"
 		                   "  change_profile -> \":", namespace, "://*\",\n",
 		                   NULL);
 		free(namespace);
@@ -682,7 +682,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
 		if (!aa_can_stack || aa_is_stacked) {
 			char *temp;
 
-			temp = must_concat("  change_profile -> \"",
+			temp = must_concat(NULL, "  change_profile -> \"",
 			                   profile_name_full, "\",\n", NULL);
 			must_append_sized(&profile, &size, temp, strlen(temp));
 			free(temp);
diff --git a/src/lxc/string_utils.c b/src/lxc/string_utils.c
index 4e8fc21811..dcb1160e4c 100644
--- a/src/lxc/string_utils.c
+++ b/src/lxc/string_utils.c
@@ -730,7 +730,7 @@ int lxc_safe_long_long(const char *numstr, long long int *converted)
 	return 0;
 }
 
-char *must_concat(const char *first, ...)
+char *must_concat(size_t *len, const char *first, ...)
 {
 	va_list args;
 	char *cur, *dest;
@@ -751,6 +751,8 @@ char *must_concat(const char *first, ...)
 	va_end(args);
 
 	dest[cur_len] = '\0';
+	if (len)
+		*len = cur_len;
 	return dest;
 }
 
diff --git a/src/lxc/string_utils.h b/src/lxc/string_utils.h
index f55d9ee019..ec0c1acef7 100644
--- a/src/lxc/string_utils.h
+++ b/src/lxc/string_utils.h
@@ -79,7 +79,7 @@ extern int parse_byte_size_string(const char *s, int64_t *converted);
  * Concatenate all passed-in strings into one path. Do not fail. If any piece
  * is not prefixed with '/', add a '/'.
  */
-__attribute__((sentinel)) extern char *must_concat(const char *first, ...);
+__attribute__((sentinel)) extern char *must_concat(size_t *len, const char *first, ...);
 __attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
 __attribute__((sentinel)) extern char *must_append_path(char *first, ...);
 
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 2382038fea..5f07150dbc 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -199,13 +199,6 @@ extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *),
 extern int run_command_status(char *buf, size_t buf_size, int (*child_fn)(void *),
 		       void *args);
 
-/* Concatenate all passed-in strings into one path. Do not fail. If any piece
- * is not prefixed with '/', add a '/'.
- */
-__attribute__((sentinel)) extern char *must_concat(const char *first, ...);
-__attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
-__attribute__((sentinel)) extern char *must_append_path(char *first, ...);
-
 /* return copy of string @entry;  do not fail. */
 extern char *must_copy_string(const char *entry);
 


More information about the lxc-devel mailing list