Commit 8323e214 authored by Tycho Andersen's avatar Tycho Andersen Committed by Pavel Emelyanov

cg: restore special cpuset properties

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: 's avatarTycho Andersen <tycho.andersen@canonical.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent d76f3ad3
...@@ -50,8 +50,12 @@ static const char *memory_props[] = { ...@@ -50,8 +50,12 @@ static const char *memory_props[] = {
static const char *cpuset_props[] = { static const char *cpuset_props[] = {
/* /*
* cpuset.cpus and cpuset.mems must be set before the process moves * 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.memory_migrate",
"cpuset.cpu_exclusive", "cpuset.cpu_exclusive",
"cpuset.mem_exclusive", "cpuset.mem_exclusive",
...@@ -856,6 +860,54 @@ static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds, ...@@ -856,6 +860,54 @@ static int ctrl_dir_and_opt(CgControllerEntry *ctl, char *dir, int ds,
return doff; 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) static int move_in_cgroup(CgSetEntry *se)
{ {
int cg, i; int cg, i;
...@@ -882,6 +934,12 @@ static int move_in_cgroup(CgSetEntry *se) ...@@ -882,6 +934,12 @@ static int move_in_cgroup(CgSetEntry *se)
} }
aux_off = ctrl_dir_and_opt(ctrl, aux, sizeof(aux), NULL, 0); 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); snprintf(aux + aux_off, sizeof(aux) - aux_off, "/%s/tasks", ce->path);
pr_debug(" `-> %s\n", aux); pr_debug(" `-> %s\n", aux);
err = fd = openat(cg, aux, O_WRONLY); err = fd = openat(cg, aux, O_WRONLY);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment