From d70f016df1fc2fa859f2be33ae75c0c941088423 Mon Sep 17 00:00:00 2001 From: baijia Date: Mon, 7 Jan 2019 15:12:56 +0800 Subject: [PATCH] feature: support updating block io limit support updating blkio read/write bps/iops. Signed-off-by: Wang Rui --- tests/integration/update.bats | 100 ++++++++++++++++++++++++++++++- update.go | 107 +++++++++++++++++++++++++++++++++- 2 files changed, 203 insertions(+), 4 deletions(-) diff --git a/tests/integration/update.bats b/tests/integration/update.bats index fca5a27b34b..d34e3b54b76 100644 --- a/tests/integration/update.bats +++ b/tests/integration/update.bats @@ -86,6 +86,30 @@ function check_cgroup_value() { [ "$status" -eq 0 ] check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500 + blk_deivce=$(lsblk | grep [sv]da | grep disk | awk '{print $2}') + blk_major=$(echo $blk_deivce | awk -F ':' '{print $1}') + blk_minor=$(echo $blk_deivce | awk -F ':' '{print $2}') + + # update device-read-bps + runc update test_update --device-read-bps "$blk_deivce 1048576" + [ "$status" -eq 0 ] + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_bps_device" "$blk_major:$blk_minor 1048576" + + # update device-read-iops + runc update test_update --device-read-iops "$blk_deivce 2000" + [ "$status" -eq 0 ] + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_iops_device" "$blk_major:$blk_minor 2000" + + # update device-write-bps + runc update test_update --device-write-bps "$blk_deivce 2097152" + [ "$status" -eq 0 ] + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_bps_device" "$blk_major:$blk_minor 2097152" + + # update device-write-iops + runc update test_update --device-write-iops "$blk_deivce 3000" + [ "$status" -eq 0 ] + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_iops_device" "$blk_major:$blk_minor 3000" + # update cpu-period runc update test_update --cpu-period 900000 [ "$status" -eq 0 ] @@ -183,7 +207,35 @@ function check_cgroup_value() { "cpus": "0" }, "blockIO": { - "weight": 1000 + "weight": 1000, + "throttleReadBpsDevice": [ + { + "major": $blk_major, + "minor": $blk_minor, + "rate": 0 + } + ], + "throttleReadIOPSDevice": [ + { + "major": $blk_major, + "minor": $blk_minor, + "rate": 0 + } + ], + "throttleWriteBpsDevice": [ + { + "major": $blk_major, + "minor": $blk_minor, + "rate": 0 + } + ], + "throttleWriteIOPSDevice": [ + { + "major": $blk_major, + "minor": $blk_minor, + "rate": 0 + } + ] }, "pids": { "limit": 20 @@ -192,6 +244,10 @@ function check_cgroup_value() { EOF [ "$status" -eq 0 ] check_cgroup_value $CGROUP_BLKIO "blkio.weight" 1000 + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_bps_device" "" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_iops_device" "" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_bps_device" "" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_iops_device" "" check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 1000000 check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 500000 check_cgroup_value $CGROUP_CPU "cpu.shares" 100 @@ -204,11 +260,17 @@ EOF # redo all the changes at once runc update test_update --blkio-weight 500 \ + --device-read-bps "$blk_deivce 1048576" --device-read-iops "$blk_deivce 2000" \ + --device-write-bps "$blk_deivce 2097152" --device-write-iops "$blk_deivce 3000" \ --cpu-period 900000 --cpu-quota 600000 --cpu-share 200 --memory 67108864 \ --memory-reservation 33554432 --kernel-memory 50331648 --kernel-memory-tcp 41943040 \ --pids-limit 10 [ "$status" -eq 0 ] check_cgroup_value $CGROUP_BLKIO "blkio.weight" 500 + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_bps_device" "$blk_major:$blk_minor 1048576" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.read_iops_device" "$blk_major:$blk_minor 2000" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_bps_device" "$blk_major:$blk_minor 2097152" + check_cgroup_value $CGROUP_BLKIO "blkio.throttle.write_iops_device" "$blk_major:$blk_minor 3000" check_cgroup_value $CGROUP_CPU "cpu.cfs_period_us" 900000 check_cgroup_value $CGROUP_CPU "cpu.cfs_quota_us" 600000 check_cgroup_value $CGROUP_CPU "cpu.shares" 200 @@ -219,7 +281,7 @@ EOF check_cgroup_value $CGROUP_PIDS "pids.max" 10 # reset to initial test value via json file - DATA=$(cat <<"EOF" + DATA=$(cat < 0 { + var err error + *pair.dest, err = stringSliceToThrottleDevice(val) + if err != nil { + return fmt.Errorf("invalid value for %s: %s", pair.opt, err) + } + } + } if val := context.String("cpuset-cpus"); val != "" { r.CPU.Cpus = val } @@ -264,6 +318,20 @@ other options are ignored. config.Cgroups.Resources.MemorySwap = *r.Memory.Swap config.Cgroups.Resources.PidsLimit = r.Pids.Limit + for _, pair := range []struct { + dest *[]*configs.ThrottleDevice + src []specs.LinuxThrottleDevice + }{ + {&config.Cgroups.Resources.BlkioThrottleReadBpsDevice, r.BlockIO.ThrottleReadBpsDevice}, + {&config.Cgroups.Resources.BlkioThrottleWriteBpsDevice, r.BlockIO.ThrottleWriteBpsDevice}, + {&config.Cgroups.Resources.BlkioThrottleReadIOPSDevice, r.BlockIO.ThrottleReadIOPSDevice}, + {&config.Cgroups.Resources.BlkioThrottleWriteIOPSDevice, r.BlockIO.ThrottleWriteIOPSDevice}, + } { + for _, td := range pair.src { + *pair.dest = append(*pair.dest, configs.NewThrottleDevice(td.Major, td.Minor, td.Rate)) + } + } + // Update Intel RDT l3CacheSchema := context.String("l3-cache-schema") memBwSchema := context.String("mem-bw-schema") @@ -302,3 +370,40 @@ other options are ignored. return container.Set(config) }, } + +func stringSliceToThrottleDevice(ss []string) ([]specs.LinuxThrottleDevice, error) { + tds := make([]specs.LinuxThrottleDevice, 0, len(ss)) + for _, v := range ss { + parts := strings.SplitN(strings.TrimSpace(v), " ", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("failed to parse throttle device %s: the expected format is 'major:minor rate'", v) + } + devs := strings.SplitN(parts[0], ":", 2) + if len(devs) != 2 { + return nil, fmt.Errorf("failed to parse throttle device %s: the expected format is 'major:minor rate'", v) + } + + td := specs.LinuxThrottleDevice{} + for _, item := range []struct { + value string + dest *int64 + }{ + {devs[0], &td.Major}, + {devs[1], &td.Minor}, + } { + v, err := strconv.ParseInt(item.value, 10, 64) + if err != nil { + return nil, err + } + *item.dest = v + } + rate, err := strconv.ParseUint(parts[1], 10, 64) + if err != nil { + return nil, err + } + td.Rate = rate + + tds = append(tds, td) + } + return tds, nil +}