Skip to content

Commit b94888d

Browse files
committed
runc update: handle duplicated devs properly
In case there's a duplicate in the device list, the latter entry overrides the former one. So, we need to modify the last entry, not the first one. To do that, use slices.Backward. Amend the test case to test the fix. Reported-by: lifubang <lifubang@acmcoder.com> Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1 parent e04ded9 commit b94888d

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

tests/integration/update.bats

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,14 @@ EOF
905905
echo "==="
906906
skip "can't get device major number from /proc/partitions (got $major)"
907907
fi
908+
# Add an entry to check that
909+
# - existing devices can be updated;
910+
# - duplicates are handled properly;
911+
# (see func upsert* in update.go).
912+
update_config ' .linux.resources.blockIO.throttleReadBpsDevice |= [
913+
{ major: '"$major"', minor: 0, rate: 485760 },
914+
{ major: '"$major"', minor: 0, rate: 485760 }
915+
]'
908916

909917
runc run -d --console-socket "$CONSOLE_SOCKET" test_update
910918
[ "$status" -eq 0 ]

update.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"os"
8+
"slices"
89
"strconv"
910

1011
"github.com/opencontainers/cgroups"
@@ -402,7 +403,9 @@ other options are ignored.
402403
}
403404

404405
func upsertWeightDevice(devices []*cgroups.WeightDevice, wd specs.LinuxWeightDevice) []*cgroups.WeightDevice {
405-
for i, dev := range devices {
406+
// Iterate backwards because in case of a duplicate
407+
// the last one will be used.
408+
for i, dev := range slices.Backward(devices) {
406409
if dev.Major != wd.Major || dev.Minor != wd.Minor {
407410
continue
408411
}
@@ -429,7 +432,9 @@ func upsertWeightDevice(devices []*cgroups.WeightDevice, wd specs.LinuxWeightDev
429432
}
430433

431434
func upsertThrottleDevice(devices []*cgroups.ThrottleDevice, td specs.LinuxThrottleDevice) []*cgroups.ThrottleDevice {
432-
for i, dev := range devices {
435+
// Iterate backwards because in case of a duplicate
436+
// the last one will be used.
437+
for i, dev := range slices.Backward(devices) {
433438
if dev.Major == td.Major && dev.Minor == td.Minor {
434439
devices[i].Rate = td.Rate
435440
return devices

0 commit comments

Comments
 (0)