cgroups: split delegation checks into separate helpers

parent 63ba9eaf
...@@ -2942,7 +2942,42 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops * ...@@ -2942,7 +2942,42 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops *
return __cgfsng_delegate_controllers(ops, ops->container_cgroup); 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 **list = NULL;
__do_free char *buf = NULL; __do_free char *buf = NULL;
...@@ -2985,39 +3020,32 @@ static int list_unified_delegation_files(char ***delegate) ...@@ -2985,39 +3020,32 @@ static int list_unified_delegation_files(char ***delegate)
return 0; return 0;
} }
static inline bool unified_cgroup(const char *line) static bool unified_hierarchy_delegated(int dfd_base, char ***ret_files)
{
return *line == '0';
}
static inline char *current_unified_cgroup(bool relative, char *line)
{ {
char *current_cgroup; __do_free_string_list char **list = NULL;
int ret;
line += STRLITERALLEN("0::");
if (!abspath(line))
return ERR_PTR(-EINVAL);
/* remove init.scope */ ret = __list_cgroup_delegate(&list);
if (!relative) if (ret < 0)
line = prune_init_scope(line); return syserrno(ret, "Failed to determine unified cgroup delegation requirements");
/* create a relative path */ for (char *const *s = list; s && *s; s++) {
line = deabs(line); if (!faccessat(dfd_base, *s, W_OK, 0) || errno == ENOENT)
continue;
current_cgroup = strdup(line); return sysinfo(false, "The %s file is not writable, skipping unified hierarchy", *s);
if (!current_cgroup) }
return ERR_PTR(-ENOMEM);
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="))) if (faccessat(dfd_base, "cgroup.procs", W_OK, 0) && errno != ENOENT)
return controllers + STRLITERALLEN("name="); return sysinfo(false, "The cgroup.procs file is not writable, skipping legacy hierarchy");
return controllers;
return true;
} }
static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
...@@ -3082,6 +3110,9 @@ 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; dfd = dfd_base;
} }
if (!unified_hierarchy_delegated(dfd, &delegate))
continue;
controller_list = unified_controllers(dfd, "cgroup.controllers"); controller_list = unified_controllers(dfd, "cgroup.controllers");
if (!controller_list) { if (!controller_list) {
TRACE("No controllers are enabled for delegation in the unified hierarchy"); 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, ...@@ -3090,22 +3121,6 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
return syserrno(-ENOMEM, "Failed to create empty controller list"); 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; type = CGROUP2_SUPER_MAGIC;
controllers = strdup(unified_mnt); controllers = strdup(unified_mnt);
if (!controllers) if (!controllers)
...@@ -3165,13 +3180,8 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, ...@@ -3165,13 +3180,8 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
dfd = dfd_base; dfd = dfd_base;
} }
if (faccessat(dfd, "cgroup.procs", W_OK, 0)) { if (!legacy_hierarchy_delegated(dfd))
if (errno == ENOENT) continue;
continue;
SYSINFO("Lacking write access to %s", controllers);
break;
}
/* /*
* We intentionally pass __current_cgroup here and not * We intentionally pass __current_cgroup here and not
......
...@@ -515,6 +515,13 @@ __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \ ...@@ -515,6 +515,13 @@ __lxc_unused static inline void LXC_##LEVEL(struct lxc_log_locinfo* locinfo, \
__internal_ret__; \ __internal_ret__; \
}) })
#define sysinfo(__ret__, format, ...) \
({ \
typeof(__ret__) __internal_ret__ = (__ret__); \
SYSINFO(format, ##__VA_ARGS__); \
__internal_ret__; \
})
#define syserrno_set(__ret__, format, ...) \ #define syserrno_set(__ret__, format, ...) \
({ \ ({ \
typeof(__ret__) __internal_ret__ = (__ret__); \ typeof(__ret__) __internal_ret__ = (__ret__); \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment