X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fcgroup-util.c;h=0d3cc53517de07b7ef779ea5c219f7a052cd566d;hp=c1c4d409ae5ee6bcc30d5d743473417861dbc6e4;hb=7d328b544621d4b1bec936dec612947ad8bfb65a;hpb=de0671ee7fe465e108f62dcbbbe9366f81dd9e9a diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index c1c4d409a..0d3cc5351 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -161,7 +161,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo * tasks list, to properly handle forking processes */ if (!s) { - s = allocated_set = set_new(trivial_hash_func, trivial_compare_func); + s = allocated_set = set_new(NULL); if (!s) return -ENOMEM; } @@ -195,7 +195,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo if (ret >= 0 && errno != ESRCH) ret = -errno; } else { - if (sigcont) + if (sigcont && sig != SIGKILL) kill(pid, SIGCONT); if (ret == 0) @@ -239,7 +239,7 @@ int cg_kill_recursive(const char *controller, const char *path, int sig, bool si assert(sig >= 0); if (!s) { - s = allocated_set = set_new(trivial_hash_func, trivial_compare_func); + s = allocated_set = set_new(NULL); if (!s) return -ENOMEM; } @@ -290,7 +290,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char assert(cto); assert(pto); - s = set_new(trivial_hash_func, trivial_compare_func); + s = set_new(NULL); if (!s) return -ENOMEM; @@ -502,14 +502,16 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch } static int check_hierarchy(const char *p) { - char *cc; + const char *cc; assert(p); + if (!filename_is_valid(p)) + return 0; + /* Check if this controller actually really exists */ - cc = alloca(strlen("/sys/fs/cgroup/") + strlen(p) + 1); - strcpy(stpcpy(cc, "/sys/fs/cgroup/"), p); - if (access(cc, F_OK) < 0) + cc = strappenda("/sys/fs/cgroup/", p); + if (laccess(cc, F_OK) < 0) return -errno; return 0; @@ -643,7 +645,7 @@ int cg_attach(const char *controller, const char *path, pid_t pid) { snprintf(c, sizeof(c), PID_FMT"\n", pid); - return write_string_file(fs, c); + return write_string_file_no_create(fs, c); } int cg_attach_fallback(const char *controller, const char *path, pid_t pid) { @@ -682,7 +684,7 @@ int cg_set_group_access( assert(path); - if (mode != (mode_t) -1) + if (mode != MODE_INVALID) mode &= 0777; r = cg_get_path(controller, path, NULL, &fs); @@ -704,10 +706,10 @@ int cg_set_task_access( assert(path); - if (mode == (mode_t) -1 && uid == (uid_t) -1 && gid == (gid_t) -1) + if (mode == MODE_INVALID && uid == UID_INVALID && gid == GID_INVALID) return 0; - if (mode != (mode_t) -1) + if (mode != MODE_INVALID) mode &= 0666; r = cg_get_path(controller, path, "cgroup.procs", &fs); @@ -753,9 +755,9 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { cs = strlen(controller); FOREACH_LINE(line, f, return -errno) { - char *l, *p, *w, *e; + char *l, *p, *e; size_t k; - char *state; + const char *word, *state; bool found = false; truncate_nl(line); @@ -771,16 +773,16 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { *e = 0; - FOREACH_WORD_SEPARATOR(w, k, l, ",", state) { + FOREACH_WORD_SEPARATOR(word, k, l, ",", state) { - if (k == cs && memcmp(w, controller, cs) == 0) { + if (k == cs && memcmp(word, controller, cs) == 0) { found = true; break; } if (k == 5 + cs && - memcmp(w, "name=", 5) == 0 && - memcmp(w+5, controller, cs) == 0) { + memcmp(word, "name=", 5) == 0 && + memcmp(word+5, controller, cs) == 0) { found = true; break; } @@ -817,7 +819,7 @@ int cg_install_release_agent(const char *controller, const char *agent) { sc = strstrip(contents); if (sc[0] == 0) { - r = write_string_file(fs, agent); + r = write_string_file_no_create(fs, agent); if (r < 0) return r; } else if (!streq(sc, agent)) @@ -837,7 +839,7 @@ int cg_install_release_agent(const char *controller, const char *agent) { sc = strstrip(contents); if (streq(sc, "0")) { - r = write_string_file(fs, "1"); + r = write_string_file_no_create(fs, "1"); if (r < 0) return r; @@ -858,7 +860,7 @@ int cg_uninstall_release_agent(const char *controller) { if (r < 0) return r; - r = write_string_file(fs, "0"); + r = write_string_file_no_create(fs, "0"); if (r < 0) return r; @@ -869,7 +871,7 @@ int cg_uninstall_release_agent(const char *controller) { if (r < 0) return r; - r = write_string_file(fs, ""); + r = write_string_file_no_create(fs, ""); if (r < 0) return r; @@ -1306,9 +1308,8 @@ int cg_pid_get_machine_name(pid_t pid, char **machine) { } int cg_path_get_session(const char *path, char **session) { - const char *e, *n, *x; + const char *e, *n, *x, *y; char *s; - size_t l; assert(path); @@ -1325,17 +1326,14 @@ int cg_path_get_session(const char *path, char **session) { x = startswith(s, "session-"); if (!x) return -ENOENT; - if (!endswith(x, ".scope")) - return -ENOENT; - - l = strlen(x); - if (l <= 6) + y = endswith(x, ".scope"); + if (!y || x == y) return -ENOENT; if (session) { char *r; - r = strndup(x, l - 6); + r = strndup(x, y - x); if (!r) return -ENOMEM; @@ -1591,7 +1589,18 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri if (r < 0) return r; - return write_string_file(p, value); + return write_string_file_no_create(p, value); +} + +int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret) { + _cleanup_free_ char *p = NULL; + int r; + + r = cg_get_path(controller, path, attribute, &p); + if (r < 0) + return r; + + return read_one_line_file(p, ret); } static const char mask_names[] = @@ -1628,7 +1637,7 @@ int cg_create_everywhere(CGroupControllerMask supported, CGroupControllerMask ma return 0; } -int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid) { +int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t pid, cg_migrate_callback_t path_callback, void *userdata) { CGroupControllerMask bit = 1; const char *n; int r; @@ -1638,8 +1647,18 @@ int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t return r; NULSTR_FOREACH(n, mask_names) { - if (supported & bit) + + if (supported & bit) { + const char *p = NULL; + + if (path_callback) + p = path_callback(bit, userdata); + + if (!p) + p = path; + cg_attach_fallback(n, path, pid); + } bit <<= 1; } @@ -1647,7 +1666,7 @@ int cg_attach_everywhere(CGroupControllerMask supported, const char *path, pid_t return 0; } -int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids) { +int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, Set* pids, cg_migrate_callback_t path_callback, void *userdata) { Iterator i; void *pidp; int r = 0; @@ -1656,7 +1675,7 @@ int cg_attach_many_everywhere(CGroupControllerMask supported, const char *path, pid_t pid = PTR_TO_LONG(pidp); int q; - q = cg_attach_everywhere(supported, path, pid); + q = cg_attach_everywhere(supported, path, pid, path_callback, userdata); if (q < 0) r = q; } @@ -1726,3 +1745,54 @@ CGroupControllerMask cg_mask_supported(void) { return mask; } + +int cg_kernel_controllers(Set *controllers) { + _cleanup_fclose_ FILE *f = NULL; + char buf[LINE_MAX]; + int r; + + assert(controllers); + + f = fopen("/proc/cgroups", "re"); + if (!f) { + if (errno == ENOENT) + return 0; + return -errno; + } + + /* Ignore the header line */ + (void) fgets(buf, sizeof(buf), f); + + for (;;) { + char *controller; + int enabled = 0; + + errno = 0; + if (fscanf(f, "%ms %*i %*i %i", &controller, &enabled) != 2) { + + if (feof(f)) + break; + + if (ferror(f) && errno) + return -errno; + + return -EBADMSG; + } + + if (!enabled) { + free(controller); + continue; + } + + if (!filename_is_valid(controller)) { + free(controller); + return -EBADMSG; + } + + r = set_consume(controllers, controller); + if (r < 0) + return r; + } + + return 0; +}