]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgroups: split delegation checks into separate helpers
authorChristian Brauner <christian.brauner@ubuntu.com>
Sun, 21 Feb 2021 00:05:39 +0000 (01:05 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 21 Feb 2021 00:07:12 +0000 (01:07 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/log.h

index 48de2731cb887f639270b4503d0ef2a75f9cd20b..1e55d71d1edcd9d047c79e6ec79015648b00ebf6 100644 (file)
@@ -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
index 69dee08a1bdcbc60c1f5683c0f6f4b2caf96ced8..0d8a348c5454a09d91baea9f191c397deee36d5f 100644 (file)
@@ -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__); \