[CRIU] [PATCH 3/3] cg: restore special cpuset properties

Tycho Andersen tycho.andersen at canonical.com
Thu Aug 21 14:00:23 PDT 2014


cpuset.cpus and cpuset.mems can't be written to for the first time after they
have tasks, so the traditional mechanism of restoring properties after
restoring the tasks won't work here. Instead, we copy the parent values of the
properties into them, restore the tasks, and then restore via the traditional
mechanism the actual values of these properties.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 cgroup.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 59 insertions(+), 2 deletions(-)

diff --git a/cgroup.c b/cgroup.c
index b821762..8ffb3ea 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -50,8 +50,12 @@ static const char *memory_props[] = {
 static const char *cpuset_props[] = {
 	/*
 	 * cpuset.cpus and cpuset.mems must be set before the process moves
-	 * into its cgroup and hence can't be done here
+	 * into its cgroup; they are "initialized" below to whatever the root
+	 * values are in copy_special_cg_props so as not to cause ENOSPC when
+	 * values are restored via this code.
 	 */
+	"cpuset.cpus",
+	"cpuset.mems",
 	"cpuset.memory_migrate",
 	"cpuset.cpu_exclusive",
 	"cpuset.mem_exclusive",
@@ -302,7 +306,6 @@ static int read_cgroup_prop(struct cgroup_prop *property, const char *fullpath)
 {
 	char buf[1024];
 	FILE *f;
-	char *endptr;
 
 	f = fopen(fullpath, "r");
 	if (!f) {
@@ -853,6 +856,54 @@ static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds,
 	return doff;
 }
 
+static const char *special_cpuset_props[] = {
+	"cpuset.cpus",
+	"cpuset.mems",
+	NULL,
+};
+
+static int copy_special_cg_props(const char *controller, const char *path)
+{
+	int cg = get_service_fd(CGROUP_YARD);
+
+	pr_info("copying special cg props for %s\n", controller);
+
+	if (strstr(controller, "cpuset")) {
+		int i;
+
+		for (i = 0; special_cpuset_props[i]; i++) {
+			char fpath[PATH_MAX], buf[1024];
+			const char *prop = special_cpuset_props[i];
+			int ret;
+			FILE *f;
+
+			snprintf(fpath, PATH_MAX, "%s/%s", controller, prop);
+			f = fopenat(cg, fpath, "r");
+			if (!f)
+				return -1;
+
+			ret = fscanf(f, "%1024s", buf);
+			fclose(f);
+
+			if (ret <= 0) {
+				continue;
+			}
+
+			pr_info("copying %s for %s/%s\n", buf, controller, prop);
+
+			snprintf(fpath, PATH_MAX, "%s/%s/%s", controller, path, prop);
+			f = fopenat(cg, fpath, "w");
+			if (!f)
+				return -1;
+
+			fprintf(f, "%s", buf);
+			fclose(f);
+		}
+	}
+
+	return 0;
+}
+
 static int move_in_cgroup(CgSetEntry *se)
 {
 	int cg, i;
@@ -879,6 +930,12 @@ static int move_in_cgroup(CgSetEntry *se)
 		}
 
 		aux_off = ctrl_dir_and_opt(ctrl, aux, sizeof(aux), NULL, 0);
+
+		if (copy_special_cg_props(aux, ce->path) < 0) {
+			pr_perror("Couldn't copy special cgroup properties\n");
+			return -1;
+		}
+
 		snprintf(aux + aux_off, sizeof(aux) - aux_off, "/%s/tasks", ce->path);
 		pr_debug("  `-> %s\n", aux);
 		err = fd = openat(cg, aux, O_WRONLY);
-- 
1.9.1



More information about the CRIU mailing list