From: Christian Brauner Date: Thu, 13 Jan 2022 17:48:15 +0000 (+0100) Subject: attach: don't pointlessly call cgroup_init() X-Git-Tag: lxc-5.0.0~40^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F4058%2Fhead;p=thirdparty%2Flxc.git attach: don't pointlessly call cgroup_init() 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 --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 23b6af1af..e82b56902 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -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; } diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h index a809b8253..108e5d84e 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -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; diff --git a/src/lxc/commands.c b/src/lxc/commands.c index 19876783b..27861f25d 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -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; }