[lxc-devel] [lxc/master] cgfsng: set cpuset clone_children if needed

hallyn on Github lxc-bot at linuxcontainers.org
Tue Mar 8 20:50:43 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 362 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160308/9d2140d3/attachment.bin>
-------------- next part --------------
From e3a3fecfe7a62f85a94b7976a7791010326b5c83 Mon Sep 17 00:00:00 2001
From: Serge Hallyn <serge.hallyn at ubuntu.com>
Date: Tue, 8 Mar 2016 10:49:16 -0800
Subject: [PATCH] cgfsng: set cpuset clone_children if needed

Sigh.

Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
---
 src/lxc/cgfsng.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 109 insertions(+), 8 deletions(-)

diff --git a/src/lxc/cgfsng.c b/src/lxc/cgfsng.c
index 4b2d987..913070e 100644
--- a/src/lxc/cgfsng.c
+++ b/src/lxc/cgfsng.c
@@ -259,6 +259,111 @@ struct hierarchy *get_hierarchy(struct cgfsng_handler_data *d, const char *c)
 	return NULL;
 }
 
+static char *must_make_path(const char *first, ...) __attribute__((sentinel));
+
+/* Copy contents of parent(@path)/@file to @path/@file */
+static bool copy_parent_file(char *path, char *file)
+{
+	char *lastslash, *value = NULL, *fpath, oldv;
+	int len = 0;
+	int ret;
+
+	lastslash = strrchr(path, '/');
+	if (!lastslash) { // bug...  this shouldn't be possible
+		ERROR("cgfsng:copy_parent_file: bad path %s", path);
+		return false;
+	}
+	oldv = *lastslash;
+	*lastslash = '\0';
+	fpath = must_make_path(path, file, NULL);
+	len = lxc_read_from_file(fpath, NULL, 0);
+	if (len <= 0)
+		goto bad;
+	value = must_alloc(len + 1);
+	if (lxc_read_from_file(fpath, value, len) != len)
+		goto bad;
+	free(fpath);
+	*lastslash = oldv;
+	fpath = must_make_path(path, file, NULL);
+	ret = lxc_write_to_file(fpath, value, len, false);
+	if (ret < 0)
+		SYSERROR("Unable to write %s to %s", value, fpath);
+	free(fpath);
+	free(value);
+	return ret >= 0;
+
+bad:
+	SYSERROR("Error reading '%s'", fpath);
+	free(fpath);
+	free(value);
+	return false;
+}
+
+/*
+ * Initialize the cpuset hierarchy in first directory of @gname and
+ * set cgroup.clone_children so that children inherit settings.
+ * Since the h->base_path is populated by init or ourselves, we know
+ * it is already initialized.
+ */
+bool handle_cpuset_hierarchy(struct hierarchy *h, char *cgname)
+{
+	char *cgpath, *clonechildrenpath, v, *slash;
+
+	if (!string_in_list(h->controllers, "cpuset"))
+		return true;
+
+	if (*cgname == '/')
+		cgname++;
+	slash = strchr(cgname, '/');
+	if (slash)
+		*slash = '\0';
+
+	cgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+	if (slash)
+		*slash = '/';
+	if (mkdir(cgpath, 0755) < 0 && errno != EEXIST) {
+		SYSERROR("Failed to create '%s'", cgpath);
+		free(cgpath);
+		return false;
+	}
+	clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL);
+	if (!file_exists(clonechildrenpath)) { /* unified hierarchy doesn't have clone_children */
+		free(clonechildrenpath);
+		free(cgpath);
+		return true;
+	}
+	if (lxc_read_from_file(clonechildrenpath, &v, 1) < 0) {
+		SYSERROR("Failed to read '%s'", clonechildrenpath);
+		free(clonechildrenpath);
+		free(cgpath);
+		return false;
+	}
+
+	if (v == '1') {  /* already set for us by someone else */
+		free(clonechildrenpath);
+		free(cgpath);
+		return true;
+	}
+
+	/* copy parent's settings */
+	if (!copy_parent_file(cgpath, "cpuset.cpus") ||
+			!copy_parent_file(cgpath, "cpuset.mems")) {
+		free(cgpath);
+		free(clonechildrenpath);
+		return false;
+	}
+	free(cgpath);
+
+	if (lxc_write_to_file(clonechildrenpath, "1", 1, false) < 0) {
+		/* Set clone_children so children inherit our settings */
+		SYSERROR("Failed to write 1 to %s", clonechildrenpath);
+		free(clonechildrenpath);
+		return false;
+	}
+	free(clonechildrenpath);
+	return true;
+}
+
 /*
  * Given two null-terminated lists of strings, return true if any string
  * is in both.
@@ -544,8 +649,6 @@ static char *read_file(char *fnam)
 	return buf;
 }
 
-static char *must_make_path(const char *first, ...) __attribute__((sentinel));
-
 /*
  * Given a hierarchy @mountpoint and base @path, verify that we can create
  * directories underneath it.
@@ -915,12 +1018,10 @@ struct cgroup_ops *cgfsng_ops_init(void)
 
 static bool create_path_for_hierarchy(struct hierarchy *h, char *cgname)
 {
-	char *fullpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
-	int ret;
-
-	ret = mkdir_p(fullpath, 0755);
-	h->fullcgpath = fullpath;
-	return ret == 0;
+	h->fullcgpath = must_make_path(h->mountpoint, h->base_cgroup, cgname, NULL);
+	if (!handle_cpuset_hierarchy(h, cgname))
+		return false;
+	return mkdir_p(h->fullcgpath, 0755) == 0;
 }
 
 static void remove_path_for_hierarchy(struct hierarchy *h, char *cgname)


More information about the lxc-devel mailing list