The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxc/pull/882
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) === Sigh. Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
From e3a3fecfe7a62f85a94b7976a7791010326b5c83 Mon Sep 17 00:00:00 2001 From: Serge Hallyn <serge.hal...@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.hal...@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)
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel