X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fcgroup-util.c;h=05c3125aec79ca0ba2fafb2c27eb94ec65ccc085;hb=d8d5781c1eb031477670facc132e198f8fddd56c;hp=da8e8852260a106248e1e1955152fe3e350ca069;hpb=d5099efc47d4e6ac60816b5381a5f607ab03f06e;p=elogind.git diff --git a/src/shared/cgroup-util.c b/src/shared/cgroup-util.c index da8e88522..05c3125ae 100644 --- a/src/shared/cgroup-util.c +++ b/src/shared/cgroup-util.c @@ -30,12 +30,10 @@ #include #include "cgroup-util.h" -#include "log.h" #include "set.h" #include "macro.h" #include "util.h" #include "path-util.h" -#include "strv.h" #include "unit-name.h" #include "fileio.h" #include "special.h" @@ -195,7 +193,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) @@ -502,14 +500,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 = strjoina("/sys/fs/cgroup/", p); + if (laccess(cc, F_OK) < 0) return -errno; return 0; @@ -682,7 +682,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 +704,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); @@ -1249,17 +1249,15 @@ int cg_path_get_user_unit(const char *path, char **unit) { /* Skip slices, if there are any */ e = skip_slices(path); - /* Skip the session scope... */ + /* Skip the session scope or user manager... */ t = skip_session(e); - if (t) - /* ... and skip more slices if there's one */ - e = skip_slices(t); - else { - /* ... or require a user manager unit to be there */ - e = skip_user_manager(e); - if (!e) - return -ENOENT; - } + if (!t) + t = skip_user_manager(e); + if (!t) + return -ENOENT; + + /* ... and skip more slices if there are any */ + e = skip_slices(t); return cg_path_decode_unit(e, unit); } @@ -1590,6 +1588,17 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri 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[] = "cpu\0" "cpuacct\0" @@ -1624,7 +1633,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; @@ -1634,8 +1643,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; } @@ -1643,7 +1662,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; @@ -1652,7 +1671,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; } @@ -1722,3 +1741,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; +}