mirror of https://github.com/containers/podman.git
Implement 'podman run --blkio-weight-device'
`--blkio-weight-device` is not fully implemented and this causes an unexpected panic when specified because an entry is put into an uninitialized map at parsing. This fix implements the `--blkio-weight-device` and adds a system test. When creating a spec generator on a client, a major number and a minor number of a device cannot be set. So, these numbers are inspected on a server and set to a runtime spec. Signed-off-by: Hironori Shiina <shiina.hironori@jp.fujitsu.com>
This commit is contained in:
parent
8de68b1707
commit
5a56f40948
|
@ -329,6 +329,14 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
|
||||||
g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access)
|
g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for k, v := range s.WeightDevice {
|
||||||
|
statT := unix.Stat_t{}
|
||||||
|
if err := unix.Stat(k, &statT); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to inspect '%s' in --blkio-weight-device", k)
|
||||||
|
}
|
||||||
|
g.AddLinuxResourcesBlockIOWeightDevice((int64(unix.Major(uint64(statT.Rdev)))), (int64(unix.Minor(uint64(statT.Rdev)))), *v.Weight)
|
||||||
|
}
|
||||||
|
|
||||||
BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), s.Mask, s.Unmask, &g)
|
BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), s.Mask, s.Unmask, &g)
|
||||||
|
|
||||||
g.ClearProcessEnv()
|
g.ClearProcessEnv()
|
||||||
|
|
|
@ -85,7 +85,7 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.BlkIOWeightDevice) > 0 {
|
if len(c.BlkIOWeightDevice) > 0 {
|
||||||
if err := parseWeightDevices(s, c.BlkIOWeightDevice); err != nil {
|
if s.WeightDevice, err = parseWeightDevices(c.BlkIOWeightDevice); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hasLimits = true
|
hasLimits = true
|
||||||
|
@ -791,29 +791,30 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
|
||||||
return &hc, nil
|
return &hc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseWeightDevices(s *specgen.SpecGenerator, weightDevs []string) error {
|
func parseWeightDevices(weightDevs []string) (map[string]specs.LinuxWeightDevice, error) {
|
||||||
|
wd := make(map[string]specs.LinuxWeightDevice)
|
||||||
for _, val := range weightDevs {
|
for _, val := range weightDevs {
|
||||||
split := strings.SplitN(val, ":", 2)
|
split := strings.SplitN(val, ":", 2)
|
||||||
if len(split) != 2 {
|
if len(split) != 2 {
|
||||||
return fmt.Errorf("bad format: %s", val)
|
return nil, fmt.Errorf("bad format: %s", val)
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(split[0], "/dev/") {
|
if !strings.HasPrefix(split[0], "/dev/") {
|
||||||
return fmt.Errorf("bad format for device path: %s", val)
|
return nil, fmt.Errorf("bad format for device path: %s", val)
|
||||||
}
|
}
|
||||||
weight, err := strconv.ParseUint(split[1], 10, 0)
|
weight, err := strconv.ParseUint(split[1], 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid weight for device: %s", val)
|
return nil, fmt.Errorf("invalid weight for device: %s", val)
|
||||||
}
|
}
|
||||||
if weight > 0 && (weight < 10 || weight > 1000) {
|
if weight > 0 && (weight < 10 || weight > 1000) {
|
||||||
return fmt.Errorf("invalid weight for device: %s", val)
|
return nil, fmt.Errorf("invalid weight for device: %s", val)
|
||||||
}
|
}
|
||||||
w := uint16(weight)
|
w := uint16(weight)
|
||||||
s.WeightDevice[split[0]] = specs.LinuxWeightDevice{
|
wd[split[0]] = specs.LinuxWeightDevice{
|
||||||
Weight: &w,
|
Weight: &w,
|
||||||
LeafWeight: nil,
|
LeafWeight: nil,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return wd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseThrottleBPSDevices(bpsDevices []string) (map[string]specs.LinuxThrottleDevice, error) {
|
func parseThrottleBPSDevices(bpsDevices []string) (map[string]specs.LinuxThrottleDevice, error) {
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/env bats -*- bats -*-
|
||||||
|
#
|
||||||
|
# podman blkio-related tests
|
||||||
|
#
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
lofile=${PODMAN_TMPDIR}/disk.img
|
||||||
|
if [ -f ${lofile} ]; then
|
||||||
|
run_podman '?' rm -t 0 --all --force
|
||||||
|
|
||||||
|
while read path dev; do
|
||||||
|
if [[ "$path" == "$lofile" ]]; then
|
||||||
|
losetup -d $dev
|
||||||
|
fi
|
||||||
|
done < <(losetup -l --noheadings --output BACK-FILE,NAME)
|
||||||
|
|
||||||
|
rm ${lofile}
|
||||||
|
fi
|
||||||
|
basic_teardown
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "podman run --blkio-weight-device" {
|
||||||
|
|
||||||
|
skip_if_rootless "cannot create devices in rootless mode"
|
||||||
|
|
||||||
|
# create loopback device
|
||||||
|
lofile=${PODMAN_TMPDIR}/disk.img
|
||||||
|
fallocate -l 1k ${lofile}
|
||||||
|
losetup -f ${lofile}
|
||||||
|
|
||||||
|
run losetup -l --noheadings --output BACK-FILE,NAME,MAJ:MIN
|
||||||
|
is "$output" ".\+" "Empty output from losetup"
|
||||||
|
|
||||||
|
lodevice=$(awk "\$1 == \"$lofile\" { print \$2 }" <<<"$output")
|
||||||
|
lomajmin=$(awk "\$1 == \"$lofile\" { print \$3 }" <<<"$output")
|
||||||
|
|
||||||
|
is "$lodevice" ".\+" "Could not determine device for $lofile"
|
||||||
|
is "$lomajmin" ".\+" "Could not determine major/minor for $lofile"
|
||||||
|
|
||||||
|
# use bfq io scheduler
|
||||||
|
run grep -w bfq /sys/block/$(basename ${lodevice})/queue/scheduler
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
skip "BFQ scheduler is not supported on the system"
|
||||||
|
fi
|
||||||
|
echo bfq > /sys/block/$(basename ${lodevice})/queue/scheduler
|
||||||
|
|
||||||
|
# run podman
|
||||||
|
if is_cgroupsv2; then
|
||||||
|
if [ ! -f /sys/fs/cgroup/system.slice/io.bfq.weight ]; then
|
||||||
|
skip "Kernel does not support BFQ IO scheduler"
|
||||||
|
fi
|
||||||
|
run_podman run --device ${lodevice}:${lodevice} --blkio-weight-device ${lodevice}:123 --rm $IMAGE \
|
||||||
|
/bin/sh -c "cat /sys/fs/cgroup/\$(sed -e 's/0:://' < /proc/self/cgroup)/io.bfq.weight"
|
||||||
|
is "${lines[1]}" "${lomajmin}\s\+123"
|
||||||
|
else
|
||||||
|
if [ ! -f /sys/fs/cgroup/blkio/system.slice/blkio.bfq.weight_device ]; then
|
||||||
|
skip "Kernel does not support BFQ IO scheduler"
|
||||||
|
fi
|
||||||
|
if [ $(podman_runtime) = "crun" ]; then
|
||||||
|
# As of crun 1.2, crun doesn't support blkio.bfq.weight_device
|
||||||
|
skip "crun doesn't support blkio.bfq.weight_device"
|
||||||
|
fi
|
||||||
|
run_podman run --device ${lodevice}:${lodevice} --blkio-weight-device ${lodevice}:123 --rm $IMAGE \
|
||||||
|
/bin/sh -c "cat /sys/fs/cgroup/blkio/blkio.bfq.weight_device"
|
||||||
|
is "${lines[1]}" "${lomajmin}\s\+123"
|
||||||
|
fi
|
||||||
|
}
|
Loading…
Reference in New Issue