X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcgroup-util.c;h=2167cdd6d052c2a8954747b6572f2d2e0793b095;hp=26e8f691d3ebfd1598d676cbf44e573853c804cd;hb=1104f3c1604874c2b742e761b56f4349fe3e1e58;hpb=35d2e7ec19f8d3960a14dc04642060ccee3faa43 diff --git a/src/cgroup-util.c b/src/cgroup-util.c index 26e8f691d..2167cdd6d 100644 --- a/src/cgroup-util.c +++ b/src/cgroup-util.c @@ -1,4 +1,4 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** This file is part of systemd. @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "cgroup-util.h" #include "log.h" @@ -164,12 +166,12 @@ int cg_rmdir(const char *controller, const char *path) { return r < 0 ? -errno : 0; } -int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) { +int cg_kill(const char *controller, const char *path, int sig, bool ignore_self, Set *s) { bool done = false; - Set *s; int r, ret = 0; pid_t my_pid; FILE *f = NULL; + Set *allocated_set = NULL; assert(controller); assert(path); @@ -179,8 +181,9 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) * is repeated until no further processes are added to the * tasks list, to properly handle forking processes */ - if (!(s = set_new(trivial_hash_func, trivial_compare_func))) - return -ENOMEM; + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; my_pid = getpid(); @@ -189,7 +192,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) done = true; if ((r = cg_enumerate_processes(controller, path, &f)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; goto finish; @@ -205,8 +208,8 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) /* If we haven't killed this process yet, kill * it */ - if (kill(pid, sig) < 0 && errno != ESRCH) { - if (ret >= 0) + if (kill(pid, sig) < 0) { + if (ret >= 0 && errno != ESRCH) ret = -errno; } else if (ret == 0) ret = 1; @@ -238,7 +241,8 @@ int cg_kill(const char *controller, const char *path, int sig, bool ignore_self) } while (!done); finish: - set_free(s); + if (allocated_set) + set_free(allocated_set); if (f) fclose(f); @@ -246,19 +250,24 @@ finish: return ret; } -int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool rem) { +int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool rem, Set *s) { int r, ret = 0; DIR *d = NULL; char *fn; + Set *allocated_set = NULL; assert(path); assert(controller); assert(sig >= 0); - ret = cg_kill(controller, path, sig, ignore_self); + if (!s) + if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func))) + return -ENOMEM; + + ret = cg_kill(controller, path, sig, ignore_self, s); if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; goto finish; @@ -277,7 +286,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool ig goto finish; } - r = cg_kill_recursive(controller, p, sig, ignore_self, rem); + r = cg_kill_recursive(controller, p, sig, ignore_self, rem, s); free(p); if (r != 0 && ret >= 0) @@ -289,7 +298,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool ig if (rem) if ((r = cg_rmdir(controller, path)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; } @@ -297,6 +306,9 @@ finish: if (d) closedir(d); + if (allocated_set) + set_free(allocated_set); + return ret; } @@ -321,7 +333,7 @@ int cg_kill_recursive_and_wait(const char *controller, const char *path, bool re else sig = 0; - if ((r = cg_kill_recursive(controller, path, sig, true, rem)) <= 0) + if ((r = cg_kill_recursive(controller, path, sig, true, rem, NULL)) <= 0) return r; usleep(50 * USEC_PER_MSEC); @@ -351,7 +363,7 @@ int cg_migrate(const char *controller, const char *from, const char *to, bool ig done = true; if ((r = cg_enumerate_tasks(controller, from, &f)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; goto finish; @@ -369,7 +381,7 @@ int cg_migrate(const char *controller, const char *from, const char *to, bool ig continue; if ((r = cg_attach(controller, to, pid)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ESRCH) ret = r; } else if (ret == 0) ret = 1; @@ -417,7 +429,7 @@ int cg_migrate_recursive(const char *controller, const char *from, const char *t ret = cg_migrate(controller, from, to, ignore_self); if ((r = cg_enumerate_subgroups(controller, from, &d)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; goto finish; } @@ -447,7 +459,7 @@ int cg_migrate_recursive(const char *controller, const char *from, const char *t if (rem) if ((r = cg_rmdir(controller, from)) < 0) { - if (ret >= 0) + if (ret >= 0 && r != -ENOENT) ret = r; } @@ -479,7 +491,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch else p = controller; - if (asprintf(&mp, "/cgroup/%s", p) < 0) + if (asprintf(&mp, "/sys/fs/cgroup/%s", p) < 0) return -ENOMEM; if ((r = path_is_mount_point(mp)) <= 0) { @@ -517,7 +529,7 @@ int cg_trim(const char *controller, const char *path, bool delete_root) { r = rm_rf(fs, true, delete_root); free(fs); - return r; + return r == -ENOENT ? 0 : r; } int cg_delete(const char *controller, const char *path) { @@ -533,7 +545,7 @@ int cg_delete(const char *controller, const char *path) { r = cg_migrate_recursive(controller, path, parent, false, true); free(parent); - return r; + return r == -ENOENT ? 0 : r; } int cg_create(const char *controller, const char *path) { @@ -546,7 +558,17 @@ int cg_create(const char *controller, const char *path) { if ((r = cg_get_path(controller, path, NULL, &fs)) < 0) return r; - r = mkdir_p(fs, 0755); + r = mkdir_parents(fs, 0755); + + if (r >= 0) { + if (mkdir(fs, 0755) >= 0) + r = 1; + else if (errno == EEXIST) + r = 0; + else + r = -errno; + } + free(fs); return r; @@ -577,7 +599,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { } int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { - int r; + int r, q; assert(controller); assert(path); @@ -586,8 +608,8 @@ int cg_create_and_attach(const char *controller, const char *path, pid_t pid) { if ((r = cg_create(controller, path)) < 0) return r; - if ((r = cg_attach(controller, path, pid)) < 0) - return r; + if ((q = cg_attach(controller, path, pid)) < 0) + return q; /* This does not remove the cgroup on failure */ @@ -646,6 +668,9 @@ int cg_get_by_pid(const char *controller, pid_t pid, char **path) { f = fopen(fs, "re"); free(fs); + if (!f) + return errno == ENOENT ? -ESRCH : -errno; + cs = strlen(controller); while (!feof(f)) { @@ -722,10 +747,8 @@ int cg_install_release_agent(const char *controller, const char *agent) { free(fs); fs = NULL; - if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0) { - r = -ENOMEM; + if ((r = cg_get_path(controller, NULL, "notify_on_release", &fs)) < 0) goto finish; - } free(contents); contents = NULL; @@ -763,7 +786,7 @@ int cg_is_empty(const char *controller, const char *path, bool ignore_self) { assert(path); if ((r = cg_enumerate_tasks(controller, path, &f)) < 0) - return r; + return r == -ENOENT ? 1 : r; while ((r = cg_read_pid(f, &pid)) > 0) { @@ -794,7 +817,7 @@ int cg_is_empty_recursive(const char *controller, const char *path, bool ignore_ return r; if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) - return r; + return r == -ENOENT ? 1 : r; while ((r = cg_read_subgroup(d, &fn)) > 0) { char *p = NULL; @@ -914,7 +937,7 @@ int cg_fix_path(const char *path, char **result) { /* First check if it already is a filesystem path */ if (path_is_absolute(path) && - path_startswith(path, "/cgroup") && + path_startswith(path, "/sys/fs/cgroup") && access(path, F_OK) >= 0) { if (!(t = strdup(path)))