From: Christian Brauner Date: Thu, 21 Oct 2021 14:17:59 +0000 (+0200) Subject: conf: add cgroup2, cgroup2:ro, cgroup2:force, cgroup2:ro:force options X-Git-Tag: lxc-4.0.12~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48728e9880f50c4e354eadb7b9836b63276e3eda;p=thirdparty%2Flxc.git conf: add cgroup2, cgroup2:ro, cgroup2:force, cgroup2:ro:force options We keep running into situations where we want to pre-mount a pure cgroup2 layout regardless of the layout of the host. Signed-off-by: Christian Brauner --- diff --git a/doc/api-extensions.md b/doc/api-extensions.md index cdf82f937..98686f9ed 100644 --- a/doc/api-extensions.md +++ b/doc/api-extensions.md @@ -144,3 +144,10 @@ Whether this LXC instance can handle idmapped mounts for the rootfs. Whether this LXC instance can handle idmapped mounts for lxc.mount.entry entries. + +## cgroup2\_auto_mounting + +This adds the new options `cgroup2`, `cgroup2:ro`, `cgroup2:force`, +`cgroup2:ro:force` for the `lxc.mount.auto` configuration key. For example, if +a user specifies `cgroup2:force` LXC will pre-mount a pure `cgroup2` layout for +the container even if the host is running with a hybrid layout. diff --git a/src/lxc/api_extensions.h b/src/lxc/api_extensions.h index c2509207d..1cf399352 100644 --- a/src/lxc/api_extensions.h +++ b/src/lxc/api_extensions.h @@ -44,6 +44,7 @@ static char *api_extensions[] = { "idmapped_mounts", "idmapped_mounts_v2", "core_scheduling", + "cgroup2_auto_mounting", }; static size_t nr_api_extensions = sizeof(api_extensions) / sizeof(*api_extensions); diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index f27e8e106..cc9633957 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -1487,7 +1487,8 @@ static int __cgroupfs_mount(int cgroup_automount_type, struct hierarchy *h, flags |= MOUNT_ATTR_RELATIME; if ((cgroup_automount_type == LXC_AUTO_CGROUP_RO) || - (cgroup_automount_type == LXC_AUTO_CGROUP_FULL_RO)) + (cgroup_automount_type == LXC_AUTO_CGROUP_FULL_RO) || + (cgroup_automount_type == LXC_AUTO_CGROUP2_RO)) flags |= MOUNT_ATTR_RDONLY; if (is_unified_hierarchy(h)) @@ -1618,6 +1619,12 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, case LXC_AUTO_CGROUP_FULL_MIXED: TRACE("Full mixed cgroup mounts requested"); break; + case LXC_AUTO_CGROUP2_RW: + TRACE("Read-write cgroup2 mount requested"); + break; + case LXC_AUTO_CGROUP2_RO: + TRACE("Read-only cgroup2 mount requested"); + break; default: return log_error_errno(false, EINVAL, "Invalid cgroup mount options specified"); } @@ -1647,9 +1654,14 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, return log_trace(true, "Mounting cgroups not requested or needed"); /* This is really the codepath that we want. */ - if (pure_unified_layout(ops)) { + if (pure_unified_layout(ops) || + (cgroup_automount_type == LXC_AUTO_CGROUP2_RW) || + (cgroup_automount_type == LXC_AUTO_CGROUP2_RO)) { __do_close int dfd_mnt_unified = -EBADF; + if (!ops->unified) + return log_error_errno(false, EINVAL, "No unified cgroup hierarchy mounted on the host"); + dfd_mnt_unified = open_at(rootfs->dfd_mnt, DEFAULT_CGROUP_MOUNTPOINT_RELATIVE, PROTECT_OPATH_DIRECTORY, PROTECT_LOOKUP_BENEATH_XDEV, 0); if (dfd_mnt_unified < 0) @@ -1684,6 +1696,11 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, * 10. cgroup-full:rw:force -> Not supported. * 11. cgroup-full:ro:force -> Not supported. * 12. cgroup-full:mixed:force -> Not supported. + * + * 13. cgroup2 -> No-op; init system responsible for mounting. + * 14. cgroup2:ro -> No-op; init system responsible for mounting. + * 15. cgroup2:force -> Mount the cgroup2 filesystem read-write + * 16. cgroup2:ro:force -> Mount the cgroup2 filesystem read-only */ ret = cgroupfs_mount(cgroup_automount_type, ops->unified, rootfs, dfd_mnt_unified, ""); if (ret < 0) @@ -1697,25 +1714,11 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, * Or the user requested to keep the cgroup namespace * of the host or another container. */ - if (wants_force_mount) { - /* - * 1. cgroup:rw:force -> Bind-mount the cgroup2 filesystem writable. - * 2. cgroup:ro:force -> Bind-mount the cgroup2 filesystem read-only. - * 3. cgroup:mixed:force -> bind-mount the cgroup2 filesystem and - * and make the parent directory of the - * container's cgroup read-only but the - * container's cgroup writable. - * - * 10. cgroup-full:rw:force -> - * 11. cgroup-full:ro:force -> - * 12. cgroup-full:mixed:force -> - */ - errno = EOPNOTSUPP; + errno = EOPNOTSUPP; + if (wants_force_mount) SYSWARN("Force-mounting the unified cgroup hierarchy without cgroup namespace support is currently not supported"); - } else { - errno = EOPNOTSUPP; + else SYSWARN("Mounting the unified cgroup hierarchy without cgroup namespace support is currently not supported"); - } } return syserror_ret(false, "Failed to mount cgroups"); @@ -1729,15 +1732,15 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, if (can_use_mount_api()) { fd_fs = fs_prepare("tmpfs", -EBADF, "", 0, 0); if (fd_fs < 0) - return log_error_errno(-errno, errno, "Failed to create new filesystem context for tmpfs"); + return log_error_errno(false, errno, "Failed to create new filesystem context for tmpfs"); ret = fs_set_property(fd_fs, "mode", "0755"); if (ret < 0) - return log_error_errno(-errno, errno, "Failed to mount tmpfs onto %d(dev)", fd_fs); + return log_error_errno(false, errno, "Failed to mount tmpfs onto %d(dev)", fd_fs); ret = fs_set_property(fd_fs, "size", "10240k"); if (ret < 0) - return log_error_errno(-errno, errno, "Failed to mount tmpfs onto %d(dev)", fd_fs); + return log_error_errno(false, errno, "Failed to mount tmpfs onto %d(dev)", fd_fs); ret = fs_attach(fd_fs, rootfs->dfd_mnt, DEFAULT_CGROUP_MOUNTPOINT_RELATIVE, PROTECT_OPATH_DIRECTORY, PROTECT_LOOKUP_BENEATH_XDEV, diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 0f0922d73..ccf59b47e 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -282,6 +282,18 @@ enum { /* /sys/fs/cgroup (full mount, parent r/o, own r/w) */ LXC_AUTO_CGROUP_FULL_MIXED = LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FULL_RW, + + /* + * Mount a pure read-write cgroup2 layout in the container independent + * of the cgroup layout used on the host. + */ + LXC_AUTO_CGROUP2_RW = BIT(8), + /* + * Mount a pure read-only cgroup2 layout in the container independent + * of the cgroup layout used on the host. + */ + LXC_AUTO_CGROUP2_RO = BIT(9), + /* * These are defined in such a way as to retain binary compatibility * with earlier versions of this code. If the previous mask is applied, @@ -293,16 +305,18 @@ enum { /* /sys/fs/cgroup (full mount, r/w or mixed, depending on caps) */ LXC_AUTO_CGROUP_FULL_NOSPEC = 0x0E0, /* mount cgroups even when cgroup namespaces are supported */ - LXC_AUTO_CGROUP_FORCE = BIT(8), + LXC_AUTO_CGROUP_FORCE = BIT(10), /* all known cgroup options */ LXC_AUTO_CGROUP_MASK = LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FULL_NOSPEC | - LXC_AUTO_CGROUP_FORCE, + LXC_AUTO_CGROUP_FORCE | + LXC_AUTO_CGROUP2_RW | + LXC_AUTO_CGROUP2_RO, /* shared mount point */ - LXC_AUTO_SHMOUNTS = BIT(9), + LXC_AUTO_SHMOUNTS = BIT(11), /* shared mount point mask */ LXC_AUTO_SHMOUNTS_MASK = LXC_AUTO_SHMOUNTS, diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 213688060..f7fe6134f 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2121,6 +2121,10 @@ static int set_config_mount_auto(const char *key, const char *value, { "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO }, { "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED }, { "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW }, + { "cgroup2", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP2_RW | LXC_AUTO_CGROUP_FORCE }, + { "cgroup2:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP2_RO | LXC_AUTO_CGROUP_FORCE }, + { "cgroup2:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP2_RW | LXC_AUTO_CGROUP_FORCE }, + { "cgroup2:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP2_RO | LXC_AUTO_CGROUP_FORCE }, { "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC }, { "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED }, { "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO },