X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fcgroup-util.c;h=7af0c3c1243c5ddf5d3977ef4bfd70ea37771eb4;hp=1366f5865f418f7a89fdfcb0de5b1027c098fc97;hb=b043cd0b7e0e6567d9ce01bf1905337631fe0fc0;hpb=8af8afd6b3a34d1218826f55ada8ece8b4e36fed diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index 1366f5865..7af0c3c12 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -58,25 +58,6 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) return 0; } -int cg_enumerate_tasks(const char *controller, const char *path, FILE **_f) { - _cleanup_free_ char *fs = NULL; - FILE *f; - int r; - - assert(_f); - - r = cg_get_path(controller, path, "tasks", &fs); - if (r < 0) - return r; - - f = fopen(fs, "re"); - if (!f) - return -errno; - - *_f = f; - return 0; -} - int cg_read_pid(FILE *f, pid_t *_pid) { unsigned long ul; @@ -159,16 +140,28 @@ int cg_rmdir(const char *controller, const char *path, bool honour_sticky) { return r; if (honour_sticky) { - char *tasks; + char *fn; - /* If the sticky bit is set don't remove the directory */ + /* If the sticky bit is set on cgroup.procs, don't + * remove the directory */ - tasks = strappend(p, "/tasks"); - if (!tasks) + fn = strappend(p, "/cgroup.procs"); + if (!fn) return -ENOMEM; - r = file_is_priv_sticky(tasks); - free(tasks); + r = file_is_priv_sticky(fn); + free(fn); + + if (r > 0) + return 0; + + /* Compatibility ... */ + fn = strappend(p, "/tasks"); + if (!fn) + return -ENOMEM; + + r = file_is_priv_sticky(fn); + free(fn); if (r > 0) return 0; @@ -365,7 +358,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char pid_t pid = 0; done = true; - r = cg_enumerate_tasks(cfrom, pfrom, &f); + r = cg_enumerate_processes(cfrom, pfrom, &f); if (r < 0) { if (ret >= 0 && r != -ENOENT) return r; @@ -573,6 +566,19 @@ static int trim_cb(const char *path, const struct stat *sb, int typeflag, struct if (ftwbuf->level < 1) return 0; + p = strappend(path, "/cgroup.procs"); + if (!p) { + errno = ENOMEM; + return 1; + } + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + + if (is_sticky) + return 0; + + /* Compatibility */ p = strappend(path, "/tasks"); if (!p) { errno = ENOMEM; @@ -607,13 +613,22 @@ int cg_trim(const char *controller, const char *path, bool delete_root) { bool is_sticky; char *p; - p = strappend(fs, "/tasks"); + p = strappend(fs, "/cgroup.procs"); if (!p) return -ENOMEM; is_sticky = file_is_priv_sticky(p) > 0; free(p); + if (!is_sticky) { + p = strappend(fs, "/tasks"); + if (!p) + return -ENOMEM; + + is_sticky = file_is_priv_sticky(p) > 0; + free(p); + } + if (!is_sticky) if (rmdir(fs) < 0 && errno != ENOENT && r == 0) return -errno; @@ -644,7 +659,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { assert(path); assert(pid >= 0); - r = cg_get_path_and_check(controller, path, "tasks", &fs); + r = cg_get_path_and_check(controller, path, "cgroup.procs", &fs); if (r < 0) return r; @@ -697,7 +712,7 @@ int cg_set_task_access( if (mode != (mode_t) -1) mode &= 0666; - r = cg_get_path(controller, path, "tasks", &fs); + r = cg_get_path(controller, path, "cgroup.procs", &fs); if (r < 0) return r; @@ -727,8 +742,9 @@ int cg_set_task_access( if (r < 0) return r; - /* Always keep values for "cgroup.procs" in sync with "tasks" */ - r = cg_get_path(controller, path, "cgroup.procs", &procs); + /* Compatibility, Always keep values for "tasks" in sync with + * "cgroup.procs" */ + r = cg_get_path(controller, path, "tasks", &procs); if (r < 0) return r; @@ -869,7 +885,7 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) { assert(path); - r = cg_enumerate_tasks(controller, path, &f); + r = cg_enumerate_processes(controller, path, &f); if (r < 0) return r == -ENOENT ? 1 : r; @@ -1146,17 +1162,22 @@ int cg_get_user_path(char **path) { return 0; } -int cg_get_machine_path(char **path) { - _cleanup_free_ char *root = NULL; +int cg_get_machine_path(const char *machine, char **path) { + _cleanup_free_ char *root = NULL, *escaped = NULL; char *p; assert(path); - if (cg_get_root_path(&root) < 0 || streq(root, "/")) - p = strdup("/machine"); - else - p = strappend(root, "/machine"); + if (machine) { + const char *name = strappenda(machine, ".nspawn"); + + escaped = cg_escape(name); + if (!escaped) + return -ENOMEM; + } + p = strjoin(cg_get_root_path(&root) >= 0 && !streq(root, "/") ? root : "", + "/machine", machine ? "/" : "", machine ? escaped : "", NULL); if (!p) return -ENOMEM; @@ -1306,7 +1327,7 @@ int cg_pid_get_unit(pid_t pid, char **unit) { return cg_path_get_unit(cgroup, unit); } -static const char *skip_label(const char *e) { +_pure_ static const char *skip_label(const char *e) { assert(e); e = strchr(e, '/'); @@ -1522,7 +1543,12 @@ char *cg_escape(const char *p) { /* The return value of this function (unlike cg_unescape()) * needs free()! */ - if (p[0] == '_' || streq(p, "notify_on_release") || streq(p, "release_agent") || streq(p, "tasks")) + if (p[0] == 0 || + p[0] == '_' || + p[0] == '.' || + streq(p, "notify_on_release") || + streq(p, "release_agent") || + streq(p, "tasks")) need_prefix = true; else { const char *dot;