]> git.proxmox.com Git - mirror_lxc.git/commitdiff
conf: add cgroup2, cgroup2:ro, cgroup2:force, cgroup2:ro:force options
authorChristian Brauner <christian.brauner@ubuntu.com>
Thu, 21 Oct 2021 14:17:59 +0000 (16:17 +0200)
committerChristian Brauner <christian.brauner@ubuntu.com>
Thu, 21 Oct 2021 14:40:16 +0000 (16:40 +0200)
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 <christian.brauner@ubuntu.com>
doc/api-extensions.md
src/lxc/api_extensions.h
src/lxc/cgroups/cgfsng.c
src/lxc/conf.h
src/lxc/confile.c

index 44c3abd06ab958d4b623d8ad5b8954b9ad3e14f8..0e9c724e82a58426ff3bbf32de0a4ba0a6850233 100644 (file)
@@ -153,3 +153,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.
index 90f9724637aa4dd471ceaa532f37645087f5932c..ea5011c128487c0903246ceff45778a29c1b07ce 100644 (file)
@@ -47,6 +47,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);
index f27e8e10614e56623efed67dd6323fde579c4a00..cc96339579a4ee281ffd73865d932adbaf22e2e1 100644 (file)
@@ -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,
index 0f0922d735f052e60b446e7292c750009e8066a6..ccf59b47efac0934cc646fe50be07fb4ef425190 100644 (file)
@@ -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,
 
index e706092ee1665e0811c3d224cc2c0b6002b6e647..0e87baff93d160c1a3c4c6efd079aafefc975e6a 100644 (file)
@@ -2265,6 +2265,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                                      },