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

Reply via email to