]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
attach: don't pointlessly call cgroup_init() 4058/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 13 Jan 2022 17:48:15 +0000 (18:48 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 13 Jan 2022 17:51:00 +0000 (18:51 +0100)
We can let attach detect that it is running on a cgroup layout without
writable cgroup hierarchies. In that case attach can finish early and
doesn't need to run the heavy-handed cgroup parsing code.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/cgroups/cgroup.h
src/lxc/commands.c

index 23b6af1af23a588fd44d404138b8d920217c1d47..e82b5690291873e2dd54402fdf7c7e3320d675cc 100644 (file)
@@ -3116,10 +3116,14 @@ static const char *stable_order(const char *controllers)
        return unprefix(controllers);
 }
 
+#define CGFSNG_LAYOUT_LEGACY   BIT(0)
+#define CGFSNG_LAYOUT_UNIFIED  BIT(1)
+
 static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
                                bool unprivileged)
 {
        __do_free char *cgroup_info = NULL;
+       unsigned int layout_mask = 0;
        char *it;
 
        /*
@@ -3147,6 +3151,7 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
                        char *unified_mnt;
 
                        type = UNIFIED_HIERARCHY;
+                       layout_mask |= CGFSNG_LAYOUT_UNIFIED;
 
                        current_cgroup = current_unified_cgroup(relative, line);
                        if (IS_ERR(current_cgroup))
@@ -3205,6 +3210,7 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
                        char *__controllers, *__current_cgroup;
 
                        type = LEGACY_HIERARCHY;
+                       layout_mask |= CGFSNG_LAYOUT_UNIFIED;
 
                        __controllers = strchr(line, ':');
                        if (!__controllers)
@@ -3309,6 +3315,28 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative,
                }
        }
 
+       /*
+        * If we still don't know the cgroup layout at this point it means we
+        * have not found any writable cgroup hierarchies. Infer the layout
+        * from the layout bitmask we created when parsing the cgroups.
+        *
+        * Keep the ordering in the switch otherwise the bistmask-based
+        * matching won't work. 
+        */
+       if (ops->cgroup_layout == CGROUP_LAYOUT_UNKNOWN) {
+               switch (layout_mask) {
+               case (CGFSNG_LAYOUT_LEGACY | CGFSNG_LAYOUT_UNIFIED):
+                       ops->cgroup_layout = CGROUP_LAYOUT_HYBRID;
+                       break;
+               case CGFSNG_LAYOUT_LEGACY:
+                       ops->cgroup_layout = CGROUP_LAYOUT_LEGACY;
+                       break;
+               case CGFSNG_LAYOUT_UNIFIED:
+                       ops->cgroup_layout = CGROUP_LAYOUT_UNIFIED;
+                       break;
+               }
+       }
+
        if (!controllers_available(ops))
                return syserror_set(-ENOENT, "One or more requested controllers unavailable or not delegated");
 
@@ -3470,6 +3498,10 @@ static int __cgroup_attach_many(const struct lxc_conf *conf, const char *name,
        if (ret < 0)
                return ret_errno(ENOSYS);
 
+       if (ctx->fd_len == 0)
+               return log_trace(0, "Container runs with unwritable %s cgroup layout",
+                                cgroup_layout_name(ctx->layout));
+
        pidstr_len = strnprintf(pidstr, sizeof(pidstr), "%d", pid);
        if (pidstr_len < 0)
                return pidstr_len;
@@ -3487,9 +3519,6 @@ static int __cgroup_attach_many(const struct lxc_conf *conf, const char *name,
                        TRACE("Attached to cgroup fd %d", dfd_con);
        }
 
-       if (idx == 0)
-               return syserror_set(-ENOENT, "Failed to attach to cgroups");
-
        TRACE("Attached to %s cgroup layout", cgroup_layout_name(ctx->layout));
        return 0;
 }
index a809b825396f4c1b273f3af2bf77271412f40b04..108e5d84ec86c617512829b732b7466c11af52ee 100644 (file)
@@ -327,21 +327,24 @@ static inline int prepare_cgroup_ctx(struct cgroup_ops *ops,
 {
        __u32 idx;
 
-       if (!ops || !ops->hierarchies)
+       if (!ops)
                return ret_errno(ENOENT);
 
+       /* Always let the client now what cgroup layout we're dealing with. */
+       ctx->layout = ops->cgroup_layout;
+
+       /* No writable cgroup hierarchies. */
+       if (!ops->hierarchies)
+               return 0;
+
        for (idx = 0; ops->hierarchies[idx]; idx++) {
                if (idx >= CGROUP_CTX_MAX_FD)
                        return ret_errno(E2BIG);
 
                ctx->fd[idx] = ops->hierarchies[idx]->dfd_con;
        }
-
-       if (idx == 0)
-               return ret_errno(ENOENT);
-
        ctx->fd_len = idx;
-       ctx->layout = ops->cgroup_layout;
+
        if (ops->unified && ops->unified->dfd_con > 0)
                ctx->utilities = ops->unified->utilities;
 
index 19876783b69338f0f1286ad503f9303194488f63..27861f25dbe9d3e5cc00e914069ee1430bb9db9e 100644 (file)
@@ -211,7 +211,11 @@ static ssize_t lxc_cmd_rsp_recv(int sock, struct lxc_cmd_rr *cmd)
                break;
        case LXC_CMD_GET_CGROUP_CTX:
                fds->fd_count_max = CGROUP_CTX_MAX_FD;
-               fds->flags |= UNIX_FDS_ACCEPT_LESS;
+               /* 
+                * The container might run without any cgroup support at all,
+                * i.e. no writable cgroup hierarchy was found.
+                */
+               fds->flags |= UNIX_FDS_ACCEPT_LESS  | UNIX_FDS_ACCEPT_NONE ;
                break;
        default:
                fds->fd_count_max = 0;
@@ -762,9 +766,14 @@ int lxc_cmd_get_cgroup_ctx(const char *name, const char *lxcpath,
                return sysdebug("Failed to process \"%s\"",
                                lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX));
 
-       if (cmd.rsp.ret < 0)
+       if (cmd.rsp.ret < 0) {
+               /* Container does not have any writable cgroups. */
+               if (ret_ctx->fd_len == 0)
+                       return 0;
+
                return sysdebug_set(cmd.rsp.ret, "Failed to receive file descriptor for \"%s\"",
                                    lxc_cmd_str(LXC_CMD_GET_CGROUP_CTX));
+       }
 
        return 0;
 }