X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fsystemd.git;a=blobdiff_plain;f=src%2Fbasic%2Fcgroup-util.c;h=232d6e8fe24ebfb45e5c90eef537f31b55ce038b;hp=218de0b376f598aad81f5a06319b44149de7a521;hb=6bedfcbb2970e06a4d3280c8fb62083d252ede73;hpb=efdb02375beb0a940c3320865572913780b4d7de diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 218de0b376f..232d6e8fe24 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -19,28 +19,33 @@ along with systemd; If not, see . ***/ +#include #include -#include +#include #include -#include #include -#include +#include #include #include -#include +#include -#include "set.h" -#include "macro.h" -#include "util.h" +#include "cgroup-util.h" +#include "extract-word.h" +#include "fd-util.h" +#include "fileio.h" #include "formats-util.h" -#include "process-util.h" +#include "login-util.h" +#include "macro.h" +#include "mkdir.h" +#include "parse-util.h" #include "path-util.h" -#include "unit-name.h" -#include "fileio.h" +#include "process-util.h" +#include "set.h" #include "special.h" -#include "mkdir.h" -#include "login-util.h" -#include "cgroup-util.h" +#include "string-util.h" +#include "unit-name.h" +#include "user-util.h" +#include "util.h" int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { _cleanup_free_ char *fs = NULL; @@ -187,7 +192,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo if (ignore_self && pid == my_pid) continue; - if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid)) continue; /* If we haven't killed this process yet, kill @@ -205,7 +210,7 @@ int cg_kill(const char *controller, const char *path, int sig, bool sigcont, boo done = false; - r = set_put(s, LONG_TO_PTR(pid)); + r = set_put(s, PID_TO_PTR(pid)); if (r < 0) { if (ret >= 0) return r; @@ -318,7 +323,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char if (ignore_self && pid == my_pid) continue; - if (set_get(s, LONG_TO_PTR(pid)) == LONG_TO_PTR(pid)) + if (set_get(s, PID_TO_PTR(pid)) == PID_TO_PTR(pid)) continue; /* Ignore kernel threads. Since they can only @@ -338,7 +343,7 @@ int cg_migrate(const char *cfrom, const char *pfrom, const char *cto, const char done = false; - r = set_put(s, LONG_TO_PTR(pid)); + r = set_put(s, PID_TO_PTR(pid)); if (r < 0) { if (ret >= 0) return r; @@ -460,20 +465,23 @@ static const char *controller_to_dirname(const char *controller) { return controller; } -static int join_path_legacy(const char *controller_dn, const char *path, const char *suffix, char **fs) { +static int join_path_legacy(const char *controller, const char *path, const char *suffix, char **fs) { + const char *dn; char *t = NULL; assert(fs); - assert(controller_dn); + assert(controller); + + dn = controller_to_dirname(controller); if (isempty(path) && isempty(suffix)) - t = strappend("/sys/fs/cgroup/", controller_dn); + t = strappend("/sys/fs/cgroup/", dn); else if (isempty(path)) - t = strjoin("/sys/fs/cgroup/", controller_dn, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", suffix, NULL); else if (isempty(suffix)) - t = strjoin("/sys/fs/cgroup/", controller_dn, "/", path, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", path, NULL); else - t = strjoin("/sys/fs/cgroup/", controller_dn, "/", path, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix, NULL); if (!t) return -ENOMEM; @@ -509,15 +517,15 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch if (!controller) { char *t; - /* If no controller is specified, we assume only the - * path below the controller matters */ + /* If no controller is specified, we return the path + * *below* the controllers, without any prefix. */ if (!path && !suffix) return -EINVAL; - if (isempty(suffix)) + if (!suffix) t = strdup(path); - else if (isempty(path)) + else if (!path) t = strdup(suffix); else t = strjoin(path, "/", suffix, NULL); @@ -537,17 +545,8 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch if (unified > 0) r = join_path_unified(path, suffix, fs); - else { - const char *dn; - - if (controller) - dn = controller_to_dirname(controller); - else - dn = NULL; - - r = join_path_legacy(dn, path, suffix, fs); - } - + else + r = join_path_legacy(controller, path, suffix, fs); if (r < 0) return r; @@ -876,7 +875,7 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **path) { return 0; } - return -ENOENT; + return -ENODATA; } int cg_install_release_agent(const char *controller, const char *agent) { @@ -905,7 +904,7 @@ int cg_install_release_agent(const char *controller, const char *agent) { r = write_string_file(fs, agent, 0); if (r < 0) return r; - } else if (!streq(sc, agent)) + } else if (!path_equal(sc, agent)) return -EEXIST; fs = mfree(fs); @@ -1008,6 +1007,8 @@ int cg_is_empty_recursive(const char *controller, const char *path) { return r; r = read_one_line_file(populated, &t); + if (r == -ENOENT) + return 1; if (r < 0) return r; @@ -1901,7 +1902,7 @@ int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids, int r = 0; SET_FOREACH(pidp, pids, i) { - pid_t pid = PTR_TO_LONG(pidp); + pid_t pid = PTR_TO_PID(pidp); int q; q = cg_attach_everywhere(supported, path, pid, path_callback, userdata); @@ -1913,8 +1914,8 @@ int cg_attach_many_everywhere(CGroupMask supported, const char *path, Set* pids, } int cg_migrate_everywhere(CGroupMask supported, const char *from, const char *to, cg_migrate_callback_t to_callback, void *userdata) { - CGroupController c; - int r, unified; + CGroupController c; + int r = 0, unified; if (!path_equal(from, to)) { r = cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, from, SYSTEMD_CGROUP_CONTROLLER, to, false, true); @@ -1985,14 +1986,22 @@ int cg_mask_supported(CGroupMask *ret) { if (unified < 0) return unified; if (unified > 0) { - _cleanup_free_ char *controllers = NULL; + _cleanup_free_ char *root = NULL, *controllers = NULL, *path = NULL; const char *c; /* In the unified hierarchy we can read the supported * and accessible controllers from a the top-level * cgroup attribute */ - r = read_one_line_file("/sys/fs/cgroup/cgroup.controllers", &controllers); + r = cg_get_root_path(&root); + if (r < 0) + return r; + + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, root, "cgroup.controllers", &path); + if (r < 0) + return r; + + r = read_one_line_file(path, &controllers); if (r < 0) return r; @@ -2014,9 +2023,10 @@ int cg_mask_supported(CGroupMask *ret) { mask |= CGROUP_CONTROLLER_TO_MASK(v); } - /* Currently, we only support the memory controller in - * the unified hierarchy, mask everything else off. */ - mask &= CGROUP_MASK_MEMORY; + /* Currently, we only support the memory and pids + * controller in the unified hierarchy, mask + * everything else off. */ + mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_PIDS; } else { CGroupController c; @@ -2159,7 +2169,7 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) { r = write_string_file(fs, s, 0); if (r < 0) - log_warning_errno(r, "Failed to enable controller %s for %s (%s): %m", n, p, fs); + log_debug_errno(r, "Failed to enable controller %s for %s (%s): %m", n, p, fs); } } @@ -2202,12 +2212,54 @@ bool cg_is_legacy_wanted(void) { return !cg_is_unified_wanted(); } +int cg_cpu_shares_parse(const char *s, uint64_t *ret) { + uint64_t u; + int r; + + if (isempty(s)) { + *ret = CGROUP_CPU_SHARES_INVALID; + return 0; + } + + r = safe_atou64(s, &u); + if (r < 0) + return r; + + if (u < CGROUP_CPU_SHARES_MIN || u > CGROUP_CPU_SHARES_MAX) + return -ERANGE; + + *ret = u; + return 0; +} + +int cg_blkio_weight_parse(const char *s, uint64_t *ret) { + uint64_t u; + int r; + + if (isempty(s)) { + *ret = CGROUP_BLKIO_WEIGHT_INVALID; + return 0; + } + + r = safe_atou64(s, &u); + if (r < 0) + return r; + + if (u < CGROUP_BLKIO_WEIGHT_MIN || u > CGROUP_BLKIO_WEIGHT_MAX) + return -ERANGE; + + *ret = u; + return 0; +} + static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = { [CGROUP_CONTROLLER_CPU] = "cpu", [CGROUP_CONTROLLER_CPUACCT] = "cpuacct", [CGROUP_CONTROLLER_BLKIO] = "blkio", [CGROUP_CONTROLLER_MEMORY] = "memory", - [CGROUP_CONTROLLER_DEVICE] = "device", + [CGROUP_CONTROLLER_DEVICES] = "devices", + [CGROUP_CONTROLLER_PIDS] = "pids", + [CGROUP_CONTROLLER_NET_CLS] = "net_cls", }; DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);