[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