From: Christian Brauner Date: Sun, 21 Feb 2021 00:05:39 +0000 (+0100) Subject: cgroups: split delegation checks into separate helpers X-Git-Tag: lxc-5.0.0~274^2~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0da35ac723ccf0f7c158a694b61e25efdf95bb33;p=thirdparty%2Flxc.git cgroups: split delegation checks into separate helpers Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 48de2731c..1e55d71d1 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -2942,7 +2942,42 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops * return __cgfsng_delegate_controllers(ops, ops->container_cgroup); } -static int list_unified_delegation_files(char ***delegate) +static inline bool unified_cgroup(const char *line) +{ + return *line == '0'; +} + +static inline char *current_unified_cgroup(bool relative, char *line) +{ + char *current_cgroup; + + line += STRLITERALLEN("0::"); + + if (!abspath(line)) + return ERR_PTR(-EINVAL); + + /* remove init.scope */ + if (!relative) + line = prune_init_scope(line); + + /* create a relative path */ + line = deabs(line); + + current_cgroup = strdup(line); + if (!current_cgroup) + return ERR_PTR(-ENOMEM); + + return current_cgroup; +} + +static inline const char *unprefix(const char *controllers) +{ + if (strnequal(controllers, "name=", STRLITERALLEN("name="))) + return controllers + STRLITERALLEN("name="); + return controllers; +} + +static int __list_cgroup_delegate(char ***delegate) { __do_free char **list = NULL; __do_free char *buf = NULL; @@ -2985,39 +3020,32 @@ static int list_unified_delegation_files(char ***delegate) return 0; } -static inline bool unified_cgroup(const char *line) -{ - return *line == '0'; -} - -static inline char *current_unified_cgroup(bool relative, char *line) +static bool unified_hierarchy_delegated(int dfd_base, char ***ret_files) { - char *current_cgroup; - - line += STRLITERALLEN("0::"); - - if (!abspath(line)) - return ERR_PTR(-EINVAL); + __do_free_string_list char **list = NULL; + int ret; - /* remove init.scope */ - if (!relative) - line = prune_init_scope(line); + ret = __list_cgroup_delegate(&list); + if (ret < 0) + return syserrno(ret, "Failed to determine unified cgroup delegation requirements"); - /* create a relative path */ - line = deabs(line); + for (char *const *s = list; s && *s; s++) { + if (!faccessat(dfd_base, *s, W_OK, 0) || errno == ENOENT) + continue; - current_cgroup = strdup(line); - if (!current_cgroup) - return ERR_PTR(-ENOMEM); + return sysinfo(false, "The %s file is not writable, skipping unified hierarchy", *s); + } - return current_cgroup; + *ret_files = move_ptr(list); + return true; } -static inline const char *unprefix(const char *controllers) +static bool legacy_hierarchy_delegated(int dfd_base) { - if (strnequal(controllers, "name=", STRLITERALLEN("name="))) - return controllers + STRLITERALLEN("name="); - return controllers; + if (faccessat(dfd_base, "cgroup.procs", W_OK, 0) && errno != ENOENT) + return sysinfo(false, "The cgroup.procs file is not writable, skipping legacy hierarchy"); + + return true; } static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, @@ -3082,6 +3110,9 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, dfd = dfd_base; } + if (!unified_hierarchy_delegated(dfd, &delegate)) + continue; + controller_list = unified_controllers(dfd, "cgroup.controllers"); if (!controller_list) { TRACE("No controllers are enabled for delegation in the unified hierarchy"); @@ -3090,22 +3121,6 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, return syserrno(-ENOMEM, "Failed to create empty controller list"); } - if (unprivileged) { - ret = list_unified_delegation_files(&delegate); - if (ret < 0) - return syserrno(ret, "Failed to determine delegation requirements"); - - for (char *const *d = delegate; d && *d; d++) { - if (faccessat(dfd, *d, W_OK, 0)) { - if (errno == ENOENT) - continue; - - SYSINFO("Lacking write access to %s, skipping unified cgroup", *d); - break; - } - } - } - type = CGROUP2_SUPER_MAGIC; controllers = strdup(unified_mnt); if (!controllers) @@ -3165,13 +3180,8 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, dfd = dfd_base; } - if (faccessat(dfd, "cgroup.procs", W_OK, 0)) { - if (errno == ENOENT) - continue; - - SYSINFO("Lacking write access to %s", controllers); - break; - } + if (!legacy_hierarchy_delegated(dfd)) + continue; /* * We intentionally pass __current_cgroup here and not diff --git a/src/lxc/log.h b/src/lxc/log.h index 69dee08a1..0d8a348c5 100644 --- a/src/lxc/log.h +++ b/src/lxc/log.h @@ -515,6 +515,13 @@ __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \ __internal_ret__; \ }) +#define sysinfo(__ret__, format, ...) \ + ({ \ + typeof(__ret__) __internal_ret__ = (__ret__); \ + SYSINFO(format, ##__VA_ARGS__); \ + __internal_ret__; \ + }) + #define syserrno_set(__ret__, format, ...) \ ({ \ typeof(__ret__) __internal_ret__ = (__ret__); \