diff --git a/Vagrantfile.fedora34 b/Vagrantfile.fedora34 index 449d3b3f279..2c1f049a518 100644 --- a/Vagrantfile.fedora34 +++ b/Vagrantfile.fedora34 @@ -41,8 +41,8 @@ EOF cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF [Service] # default: Delegate=pids memory -# NOTE: delegation of cpuset requires systemd >= 244 (Fedora >= 32, Ubuntu >= 20.04). cpuset is ignored on Fedora 31. -Delegate=cpu cpuset io memory pids +# NOTE: delegation of cpuset requires systemd >= 244 (Fedora >= 32, Ubuntu >= 20.04). +Delegate=yes EOF systemctl daemon-reload SHELL diff --git a/libcontainer/cgroups/systemd/v2.go b/libcontainer/cgroups/systemd/v2.go index 99f3e450e93..8abb0feb748 100644 --- a/libcontainer/cgroups/systemd/v2.go +++ b/libcontainer/cgroups/systemd/v2.go @@ -317,6 +317,7 @@ func (m *unifiedManager) Destroy() error { } func (m *unifiedManager) Path(_ string) string { + _ = m.initPath() return m.path } diff --git a/tests/integration/cgroups.bats b/tests/integration/cgroups.bats index 50c4f9bb8ee..5875469c68c 100644 --- a/tests/integration/cgroups.bats +++ b/tests/integration/cgroups.bats @@ -16,10 +16,7 @@ function setup() { } @test "runc create (rootless + no limits + cgrouppath + no permission) fails with permission error" { - requires rootless - requires rootless_no_cgroup - # systemd controls the permission, so error does not happen - requires no_systemd + requires rootless rootless_no_cgroup set_cgroups_path @@ -29,10 +26,7 @@ function setup() { } @test "runc create (rootless + limits + no cgrouppath + no permission) fails with informative error" { - requires rootless - requires rootless_no_cgroup - # systemd controls the permission, so error does not happen - requires no_systemd + requires rootless rootless_no_cgroup set_resources_limit @@ -55,8 +49,8 @@ function setup() { if [ "$(id -u)" = "0" ]; then check_cgroup_value "cgroup.controllers" "$(cat /sys/fs/cgroup/machine.slice/cgroup.controllers)" else - # shellcheck disable=SC2046 - check_cgroup_value "cgroup.controllers" "$(cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/cgroup.controllers)" + # Filter out hugetlb as systemd is unable to delegate it. + check_cgroup_value "cgroup.controllers" "$(sed 's/ hugetlb//' = 244 (Fedora >= 32, Ubuntu >= 20.04). + if [[ "$ROOTLESS" -ne 0 && -n "$RUNC_USE_SYSTEMD" ]]; then + controllers="/sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers" + fi + # "pseudo" controllers do not appear in /sys/fs/cgroup/cgroup.controllers. # - devices (since kernel 4.15) we must assume to be supported because # it's quite hard to test. # - freezer (since kernel 5.2) we can auto-detect by looking for the # "cgroup.freeze" file a *non-root* cgroup. CGROUP_SUBSYSTEMS=$( - cat /sys/fs/cgroup/cgroup.controllers + cat "$controllers" echo devices ) CGROUP_BASE_PATH=/sys/fs/cgroup @@ -274,6 +271,11 @@ function fail() { exit 1 } +# Check whether rootless runc can use cgroups. +function rootless_cgroup() { + [[ "$ROOTLESS_FEATURES" == *"cgroup"* || -n "$RUNC_USE_SYSTEMD" ]] +} + # Allows a test to specify what things it requires. If the environment can't # support it, the test is skipped with a message. function requires() { @@ -301,12 +303,12 @@ function requires() { fi ;; rootless_cgroup) - if [[ "$ROOTLESS_FEATURES" != *"cgroup"* ]]; then + if ! rootless_cgroup; then skip_me=1 fi ;; rootless_no_cgroup) - if [[ "$ROOTLESS_FEATURES" == *"cgroup"* ]]; then + if rootless_cgroup; then skip_me=1 fi ;; @@ -315,12 +317,6 @@ function requires() { skip_me=1 fi ;; - cgroups_freezer) - init_cgroup_paths - if [[ "$CGROUP_SUBSYSTEMS" != *"freezer"* ]]; then - skip_me=1 - fi - ;; cgroups_rt) init_cgroup_paths if [ ! -e "${CGROUP_CPU_BASE_PATH}/cpu.rt_period_us" ]; then @@ -350,6 +346,13 @@ function requires() { skip_me=1 fi ;; + cgroups_*) + init_cgroup_paths + var=${var#cgroups_} + if [[ "$CGROUP_SUBSYSTEMS" != *"$var"* ]]; then + skip_me=1 + fi + ;; smp) local cpu_count=$(grep -c '^processor' /proc/cpuinfo) if [ "$cpu_count" -lt 2 ]; then diff --git a/tests/integration/update.bats b/tests/integration/update.bats index 149da63cff9..e204ea49550 100644 --- a/tests/integration/update.bats +++ b/tests/integration/update.bats @@ -14,23 +14,15 @@ function setup() { # Set some initial known values update_config ' .linux.resources.memory |= {"limit": 33554432, "reservation": 25165824} - | .linux.resources.cpu |= {"shares": 100, "quota": 500000, "period": 1000000, "cpus": "0"} + | .linux.resources.cpu |= {"shares": 100, "quota": 500000, "period": 1000000} | .linux.resources.pids |= {"limit": 20}' } # Tests whatever limits are (more or less) common between cgroup # v1 and v2: memory/swap, pids, and cpuset. @test "update cgroup v1/v2 common limits" { - [[ "$ROOTLESS" -ne 0 && -z "$RUNC_USE_SYSTEMD" ]] && requires rootless_cgroup - if [[ "$ROOTLESS" -ne 0 && -n "$RUNC_USE_SYSTEMD" ]]; then - file="/sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers" - # NOTE: delegation of cpuset requires systemd >= 244 (Fedora >= 32, Ubuntu >= 20.04). - for f in memory pids cpuset; do - if grep -qwv $f "$file"; then - skip "$f is not enabled in $file" - fi - done - fi + [[ "$ROOTLESS" -ne 0 ]] && requires rootless_cgroup + requires cgroups_memory cgroups_pids cgroups_cpuset init_cgroup_paths # run a few busyboxes detached @@ -70,11 +62,6 @@ function setup() { fi # check that initial values were properly set - check_cgroup_value "cpuset.cpus" 0 - if [[ "$CGROUP_UNIFIED" = "yes" ]] && ! grep -qw memory "$CGROUP_PATH/cgroup.controllers"; then - # This happen on containerized environment because "echo +memory > /sys/fs/cgroup/cgroup.subtree_control" fails with EINVAL - skip "memory controller not available" - fi check_cgroup_value $MEM_LIMIT 33554432 check_systemd_value $SD_MEM_LIMIT 33554432 @@ -84,7 +71,7 @@ function setup() { check_cgroup_value "pids.max" 20 check_systemd_value "TasksMax" 20 - # update cpuset if supported (i.e. we're running on a multicore cpu) + # update cpuset if possible (i.e. we're running on a multicore cpu) cpu_count=$(grep -c '^processor' /proc/cpuinfo) if [ "$cpu_count" -gt 1 ]; then runc update test_update --cpuset-cpus "1" @@ -427,7 +414,7 @@ EOF @test "update cpuset parameters via resources.CPU" { [[ "$ROOTLESS" -ne 0 ]] && requires rootless_cgroup - requires smp + requires smp cgroups_cpuset local AllowedCPUs='AllowedCPUs' AllowedMemoryNodes='AllowedMemoryNodes' # these properties require systemd >= v244 @@ -483,7 +470,7 @@ EOF @test "update cpuset parameters via v2 unified map" { # This test assumes systemd >= v244 [[ "$ROOTLESS" -ne 0 ]] && requires rootless_cgroup - requires cgroups_v2 smp + requires cgroups_v2 smp cgroups_cpuset update_config ' .linux.resources.unified |= { "cpuset.cpus": "0",