diff --git a/tests/integration/cgroups.bats b/tests/integration/cgroups.bats index 29cd0978248..b21c0efc58f 100644 --- a/tests/integration/cgroups.bats +++ b/tests/integration/cgroups.bats @@ -4,6 +4,7 @@ load helpers function teardown() { teardown_bundle + teardown_loopdevs } function setup() { @@ -153,16 +154,28 @@ function setup() { @test "runc run (per-device io weight for bfq)" { requires root # to create a loop device - dd if=/dev/zero of=backing.img bs=4096 count=1 - dev=$(losetup --find --show backing.img) || skip "unable to create a loop device" + dev="$(setup_loopdev)" + + # Some distributions (like openSUSE) have udev configured to forcefully + # reset the scheduler for loopN devices to be "none", which breaks this + # test. We cannot modify the udev behaviour of the host, but since this is + # usually triggered by the "change" event from losetup, we can wait for a + # little bit before continuing the test. For more details, see + # . + sleep 2s # See if BFQ scheduler is available. if ! { grep -qw bfq "/sys/block/${dev#/dev/}/queue/scheduler" && echo bfq >"/sys/block/${dev#/dev/}/queue/scheduler"; }; then - losetup -d "$dev" skip "BFQ scheduler not available" fi + # Check that the device still has the right scheduler, in case we lost the + # race above... + if ! grep -qw '\[bfq\]' "/sys/block/${dev#/dev/}/queue/scheduler"; then + skip "udev is configured to reset loop device io scheduler" + fi + set_cgroups_path IFS=$' \t:' read -r major minor <<<"$(lsblk -nd -o MAJ:MIN "$dev")" @@ -174,28 +187,44 @@ function setup() { runc run -d --console-socket "$CONSOLE_SOCKET" test_dev_weight [ "$status" -eq 0 ] - # The loop device itself is no longer needed. - losetup -d "$dev" - if [ -v CGROUP_V2 ]; then file="io.bfq.weight" else file="blkio.bfq.weight_device" fi - weights=$(get_cgroup_value $file) - [[ "$weights" == *"default 333"* ]] - [[ "$weights" == *"$major:$minor 444"* ]] + weights1=$(get_cgroup_value $file) + + # Check that runc update works. + runc update -r - test_dev_weight <>"$LOOPBACK_DEVICE_LIST" + + unlink "$backing" + echo "$dev" +} + +function teardown_loopdevs() { + [ -s "$LOOPBACK_DEVICE_LIST" ] || return 0 + while IFS= read -r dev; do + echo "losetup -d '$dev'" >&2 + losetup -d "$dev" + done <"$LOOPBACK_DEVICE_LIST" + truncate --size=0 "$LOOPBACK_DEVICE_LIST" +} + function setup_bundle() { local image="$1" diff --git a/tests/integration/update.bats b/tests/integration/update.bats index 461fac479e3..e3d1922efba 100644 --- a/tests/integration/update.bats +++ b/tests/integration/update.bats @@ -891,3 +891,66 @@ EOF runc update test_update --memory 1024 wait_for_container 10 1 test_update stopped } + +@test "update per-device iops/bps values" { + [ $EUID -ne 0 ] && requires rootless_cgroup + + # Need major:minor for any block device (but not a partition). + dev=$(lsblk -dno MAJ:MIN | head -1 | tr -d ' \t\n') + if [ -z "$dev" ]; then + echo "=== lsblk -d ===" >&2 + lsblk -d >&2 + echo "===" >&2 + fail "can't get device from lsblk" + fi + IFS=':' read -r major minor <<<"$dev" + + # Add an entry to check that + # - existing devices can be updated; + # - duplicates are handled properly; + # (see func upsert* in update.go). + update_config ' .linux.resources.blockIO.throttleReadBpsDevice |= [ + { major: '"$major"', minor: '"$minor"', rate: 485760 }, + { major: '"$major"', minor: '"$minor"', rate: 485760 } + ]' + + runc run -d --console-socket "$CONSOLE_SOCKET" test_update + [ "$status" -eq 0 ] + + runc update -r - test_update <