X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fbasic%2Fcgroup-util.c;h=0e2f2cbc08c987e1f87a45cc3e38ffdf73d28489;hb=44d5b84ac58dd65971e3b7ed917bd532d70c704e;hp=604ce2b3169c1257efc72f9766ea34a08eb47e64;hpb=d4ce8390c5aa345602b51099e9d3ed3b74d3ec4d;p=elogind.git diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 604ce2b31..0e2f2cbc0 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -28,6 +28,7 @@ #include //#include #include +#include #include #include "alloc-util.h" @@ -37,7 +38,7 @@ #include "extract-word.h" #include "fd-util.h" #include "fileio.h" -#include "formats-util.h" +#include "format-util.h" #include "fs-util.h" //#include "log.h" #include "login-util.h" @@ -346,7 +347,7 @@ int cg_kill_recursive( while ((r = cg_read_subgroup(d, &fn)) > 0) { _cleanup_free_ char *p = NULL; - p = strjoin(path, "/", fn, NULL); + p = strjoin(path, "/", fn); free(fn); if (!p) return -ENOMEM; @@ -484,7 +485,7 @@ int cg_migrate_recursive( while ((r = cg_read_subgroup(d, &fn)) > 0) { _cleanup_free_ char *p = NULL; - p = strjoin(pfrom, "/", fn, NULL); + p = strjoin(pfrom, "/", fn); free(fn); if (!p) return -ENOMEM; @@ -567,11 +568,11 @@ static int join_path_legacy(const char *controller, const char *path, const char if (isempty(path) && isempty(suffix)) t = strappend("/sys/fs/cgroup/", dn); else if (isempty(path)) - t = strjoin("/sys/fs/cgroup/", dn, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", suffix); else if (isempty(suffix)) - t = strjoin("/sys/fs/cgroup/", dn, "/", path, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", path); else - t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", dn, "/", path, "/", suffix); if (!t) return -ENOMEM; @@ -591,7 +592,7 @@ static int join_path_unified(const char *path, const char *suffix, char **fs) { else if (isempty(suffix)) t = strappend("/sys/fs/cgroup/", path); else - t = strjoin("/sys/fs/cgroup/", path, "/", suffix, NULL); + t = strjoin("/sys/fs/cgroup/", path, "/", suffix); if (!t) return -ENOMEM; @@ -618,7 +619,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch else if (!path) t = strdup(suffix); else - t = strjoin(path, "/", suffix, NULL); + t = strjoin(path, "/", suffix); if (!t) return -ENOMEM; @@ -889,6 +890,43 @@ int cg_set_task_access( return 0; } + +int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags) { + _cleanup_free_ char *fs = NULL; + int r; + + assert(path); + assert(name); + assert(value || size <= 0); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + if (setxattr(fs, name, value, size, flags) < 0) + return -errno; + + return 0; +} + +int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size) { + _cleanup_free_ char *fs = NULL; + ssize_t n; + int r; + + assert(path); + assert(name); + + r = cg_get_path(controller, path, NULL, &fs); + if (r < 0) + return r; + + n = getxattr(fs, name, value, size); + if (n < 0) + return -errno; + + return (int) n; +} #endif // 0 int cg_pid_get_path(const char *controller, pid_t pid, char **path) { @@ -1118,7 +1156,7 @@ int cg_is_empty_recursive(const char *controller, const char *path) { while ((r = cg_read_subgroup(d, &fn)) > 0) { _cleanup_free_ char *p = NULL; - p = strjoin(path, "/", fn, NULL); + p = strjoin(path, "/", fn); free(fn); if (!p) return -ENOMEM; @@ -1292,7 +1330,11 @@ int cg_shift_path(const char *cgroup, const char *root, const char **shifted) { } p = path_startswith(cgroup, root); +#if 0 /// With other controllers, elogind might end up in /elogind, and *p is 0 if (p && p > cgroup) +#else + if (p && p[0] && (p > cgroup)) +#endif // 0 *shifted = p - 1; else *shifted = cgroup; @@ -1711,7 +1753,7 @@ int cg_path_get_slice(const char *p, char **slice) { if (!e) { char *s; - s = strdup("-.slice"); + s = strdup(SPECIAL_ROOT_SLICE); if (!s) return -ENOMEM; @@ -1868,7 +1910,7 @@ int cg_slice_to_path(const char *unit, char **ret) { assert(unit); assert(ret); - if (streq(unit, "-.slice")) { + if (streq(unit, SPECIAL_ROOT_SLICE)) { char *x; x = strdup(""); @@ -2296,14 +2338,6 @@ static int cg_update_unified(void) { if (F_TYPE_EQUAL(fs.f_type, CGROUP2_SUPER_MAGIC)) unified_cache = CGROUP_UNIFIED_ALL; else if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) { -#else - /* elogind can not support the unified hierarchy as a controller, - * so always assume a classical hierarchy. - * If, and only *if*, someone really wants to substitute systemd-login - * in an environment managed by systemd with elogind, we might have to - * add such a support. */ - if (F_TYPE_EQUAL(fs.f_type, TMPFS_MAGIC)) { -#endif // 0 if (statfs("/sys/fs/cgroup/systemd/", &fs) < 0) return -errno; @@ -2311,6 +2345,14 @@ static int cg_update_unified(void) { CGROUP_UNIFIED_SYSTEMD : CGROUP_UNIFIED_NONE; } else return -ENOMEDIUM; +#else + /* elogind can not support the unified hierarchy as a controller, + * so always assume a classical hierarchy. + * If, and only *if*, someone really wants to substitute systemd-login + * in an environment managed by systemd with elogind, we might have to + * add such a support. */ + unified_cache = CGROUP_UNIFIED_NONE; +#endif // 0 return 0; } @@ -2385,6 +2427,7 @@ int cg_enable_everywhere(CGroupMask supported, CGroupMask mask, const char *p) { bool cg_is_unified_wanted(void) { static thread_local int wanted = -1; int r, unified; + bool b; /* If the hierarchy is already mounted, then follow whatever * was chosen for it. */ @@ -2398,32 +2441,21 @@ bool cg_is_unified_wanted(void) { if (wanted >= 0) return wanted; - r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy", NULL); - if (r > 0) - return (wanted = true); - else { - _cleanup_free_ char *value = NULL; - - r = get_proc_cmdline_key("systemd.unified_cgroup_hierarchy=", &value); - if (r < 0) - return false; - if (r == 0) - return (wanted = false); + r = proc_cmdline_get_bool("systemd.unified_cgroup_hierarchy", &b); + if (r < 0) + return false; - return (wanted = parse_boolean(value) > 0); - } + return (wanted = r > 0 ? b : false); } bool cg_is_legacy_wanted(void) { return !cg_is_unified_wanted(); } -#else -bool cg_is_legacy_wanted(void) { - return true; bool cg_is_unified_systemd_controller_wanted(void) { static thread_local int wanted = -1; int r, unified; + bool b; /* If the unified hierarchy is requested in full, no need to * bother with this. */ @@ -2442,23 +2474,17 @@ bool cg_is_unified_systemd_controller_wanted(void) { if (wanted >= 0) return wanted; - r = get_proc_cmdline_key("systemd.legacy_systemd_cgroup_controller", NULL); - if (r > 0) { - wanted = false; - } else { - _cleanup_free_ char *value = NULL; - - r = get_proc_cmdline_key("systemd.legacy_systemd_cgroup_controller=", &value); - if (r < 0) - return true; - - if (r == 0) - wanted = true; - else - wanted = parse_boolean(value) <= 0; - } + r = proc_cmdline_get_bool("systemd.legacy_systemd_cgroup_controller", &b); + if (r < 0) + return false; - return wanted; +#else +bool cg_is_legacy_wanted(void) { + return true; + /* The meaning of the kernel option is reversed wrt. to the return value + * of this function, hence the negation. */ + return (wanted = r > 0 ? !b : false); + return (wanted = r > 0 ? b : false); } bool cg_is_legacy_systemd_controller_wanted(void) { @@ -2544,6 +2570,20 @@ int cg_blkio_weight_parse(const char *s, uint64_t *ret) { } #endif // 0 +bool is_cgroup_fs(const struct statfs *s) { + return is_fs_type(s, CGROUP_SUPER_MAGIC) || + is_fs_type(s, CGROUP2_SUPER_MAGIC); +} + +bool fd_is_cgroup_fs(int fd) { + struct statfs s; + + if (fstatfs(fd, &s) < 0) + return -errno; + + return is_cgroup_fs(&s); +} + static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = { [CGROUP_CONTROLLER_CPU] = "cpu", [CGROUP_CONTROLLER_CPUACCT] = "cpuacct",