Skip to content

Commit 45a457d

Browse files
committed
Add support for remaining blkio settings
Signed-off-by: Swagat Bora <[email protected]>
1 parent 24bb81a commit 45a457d

File tree

7 files changed

+557
-27
lines changed

7 files changed

+557
-27
lines changed

cmd/nerdctl/container/container_create.go

+26-3
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,42 @@ func processContainerCreateOptions(cmd *cobra.Command) (types.ContainerCreateOpt
199199
if err != nil {
200200
return opt, err
201201
}
202+
opt.Cgroupns, err = cmd.Flags().GetString("cgroupns")
203+
if err != nil {
204+
return opt, err
205+
}
206+
opt.CgroupParent, err = cmd.Flags().GetString("cgroup-parent")
207+
if err != nil {
208+
return opt, err
209+
}
210+
opt.Device, err = cmd.Flags().GetStringSlice("device")
211+
if err != nil {
212+
return opt, err
213+
}
214+
// #endregion
215+
216+
// #region for blkio flags
202217
opt.BlkioWeight, err = cmd.Flags().GetUint16("blkio-weight")
203218
if err != nil {
204219
return opt, err
205220
}
206-
opt.Cgroupns, err = cmd.Flags().GetString("cgroupns")
221+
opt.BlkioWeightDevice, err = cmd.Flags().GetStringArray("blkio-weight-device")
207222
if err != nil {
208223
return opt, err
209224
}
210-
opt.CgroupParent, err = cmd.Flags().GetString("cgroup-parent")
225+
opt.BlkioDeviceReadBps, err = cmd.Flags().GetStringArray("device-read-bps")
211226
if err != nil {
212227
return opt, err
213228
}
214-
opt.Device, err = cmd.Flags().GetStringSlice("device")
229+
opt.BlkioDeviceWriteBps, err = cmd.Flags().GetStringArray("device-write-bps")
230+
if err != nil {
231+
return opt, err
232+
}
233+
opt.BlkioDeviceReadIOps, err = cmd.Flags().GetStringArray("device-read-iops")
234+
if err != nil {
235+
return opt, err
236+
}
237+
opt.BlkioDeviceWriteIOps, err = cmd.Flags().GetStringArray("device-write-iops")
215238
if err != nil {
216239
return opt, err
217240
}

cmd/nerdctl/container/container_run.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ func setCreateFlags(cmd *cobra.Command) {
155155
})
156156
cmd.Flags().Int64("pids-limit", -1, "Tune container pids limit (set -1 for unlimited)")
157157
cmd.Flags().StringSlice("cgroup-conf", nil, "Configure cgroup v2 (key=value)")
158-
cmd.Flags().Uint16("blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
159158
cmd.Flags().String("cgroupns", defaults.CgroupnsMode(), `Cgroup namespace to use, the default depends on the cgroup version ("host"|"private")`)
160159
cmd.Flags().String("cgroup-parent", "", "Optional parent cgroup for the container")
161160
cmd.RegisterFlagCompletionFunc("cgroupns", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
@@ -173,6 +172,15 @@ func setCreateFlags(cmd *cobra.Command) {
173172
cmd.Flags().String("rdt-class", "", "Name of the RDT class (or CLOS) to associate the container with")
174173
// #endregion
175174

175+
// #region blkio flags
176+
cmd.Flags().Uint16("blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
177+
cmd.Flags().StringArray("blkio-weight-device", []string{}, "Block IO weight (relative device weight) (default [])")
178+
cmd.Flags().StringArray("device-read-bps", []string{}, "Limit read rate (bytes per second) from a device (default [])")
179+
cmd.Flags().StringArray("device-read-iops", []string{}, "Limit read rate (IO per second) from a device (default [])")
180+
cmd.Flags().StringArray("device-write-bps", []string{}, "Limit write rate (bytes per second) to a device (default [])")
181+
cmd.Flags().StringArray("device-write-iops", []string{}, "Limit write rate (IO per second) to a device (default [])")
182+
// #endregion
183+
176184
// user flags
177185
cmd.Flags().StringP("user", "u", "", "Username or UID (format: <name|uid>[:<group|gid>])")
178186
cmd.Flags().String("umask", "", "Set the umask inside the container. Defaults to 0022")

cmd/nerdctl/container/container_run_cgroup_linux_test.go

+123
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"testing"
2626

2727
"github.com/moby/sys/userns"
28+
"github.com/opencontainers/runtime-spec/specs-go"
2829
"gotest.tools/v3/assert"
2930

3031
"github.com/containerd/cgroups/v3"
@@ -421,3 +422,125 @@ func TestRunBlkioWeightCgroupV2(t *testing.T) {
421422
base.Cmd("update", containerName, "--blkio-weight", "400").AssertOK()
422423
base.Cmd("exec", containerName, "cat", "io.bfq.weight").AssertOutExactly("default 400\n")
423424
}
425+
426+
func TestRunBlkioSettingCgroupV2(t *testing.T) {
427+
t.Parallel()
428+
if cgroups.Mode() != cgroups.Unified {
429+
t.Skip("test requires cgroup v2")
430+
}
431+
432+
// TODO: Fix logic to check if bfq is set as the scheduler for the block device
433+
//
434+
// if _, err := os.Stat("/sys/module/bfq"); err != nil {
435+
// t.Skipf("test requires \"bfq\" module to be loaded: %v", err)
436+
// }
437+
testCase := nerdtest.Setup()
438+
testCase.Require = require.Not(nerdtest.Docker)
439+
440+
base := testutil.NewBase(t)
441+
info := base.Info()
442+
switch info.CgroupDriver {
443+
case "none", "":
444+
t.Skip("test requires cgroup driver")
445+
}
446+
447+
tests := []struct {
448+
name string
449+
args []string
450+
validate func(t *testing.T, blockIO *specs.LinuxBlockIO)
451+
}{
452+
{
453+
name: "blkio-weight",
454+
args: []string{"--blkio-weight", "150"},
455+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
456+
assert.Equal(t, uint16(150), *blockIO.Weight)
457+
},
458+
},
459+
{
460+
name: "blkio-weight-device",
461+
args: []string{"--blkio-weight-device", "/dev/sda:100"},
462+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
463+
assert.Equal(t, 1, len(blockIO.WeightDevice))
464+
assert.Equal(t, uint16(100), *blockIO.WeightDevice[0].Weight)
465+
},
466+
},
467+
{
468+
name: "device-read-bps",
469+
args: []string{"--device-read-bps", "/dev/sda:1048576"},
470+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
471+
assert.Equal(t, 1, len(blockIO.ThrottleReadBpsDevice))
472+
assert.Equal(t, uint64(1048576), blockIO.ThrottleReadBpsDevice[0].Rate)
473+
},
474+
},
475+
{
476+
name: "device-write-bps",
477+
args: []string{"--device-write-bps", "/dev/sda:2097152"},
478+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
479+
assert.Equal(t, 1, len(blockIO.ThrottleWriteBpsDevice))
480+
assert.Equal(t, uint64(2097152), blockIO.ThrottleWriteBpsDevice[0].Rate)
481+
},
482+
},
483+
{
484+
name: "device-read-iops",
485+
args: []string{"--device-read-iops", "/dev/sda:1000"},
486+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
487+
assert.Equal(t, 1, len(blockIO.ThrottleReadIOPSDevice))
488+
assert.Equal(t, uint64(1000), blockIO.ThrottleReadIOPSDevice[0].Rate)
489+
},
490+
},
491+
{
492+
name: "device-write-iops",
493+
args: []string{"--device-write-iops", "/dev/sda:2000"},
494+
validate: func(t *testing.T, blockIO *specs.LinuxBlockIO) {
495+
assert.Equal(t, 1, len(blockIO.ThrottleWriteIOPSDevice))
496+
assert.Equal(t, uint64(2000), blockIO.ThrottleWriteIOPSDevice[0].Rate)
497+
},
498+
},
499+
}
500+
501+
for _, tt := range tests {
502+
tt := tt // capture range variable
503+
t.Run(tt.name, func(t *testing.T) {
504+
t.Parallel()
505+
containerName := testutil.Identifier(t)
506+
507+
args := []string{"run", "-d", "--name", containerName}
508+
args = append(args, tt.args...)
509+
args = append(args, testutil.AlpineImage, "sleep", "infinity")
510+
base.Cmd(args...).AssertOK()
511+
t.Cleanup(func() {
512+
base.Cmd("rm", "-f", containerName).Run()
513+
})
514+
515+
// Connect to containerd
516+
addr := base.ContainerdAddress()
517+
client, err := containerd.New(addr, containerd.WithDefaultNamespace(testutil.Namespace))
518+
assert.NilError(t, err)
519+
ctx := context.Background()
520+
521+
// Get container ID
522+
var cid string
523+
walker := &containerwalker.ContainerWalker{
524+
Client: client,
525+
OnFound: func(ctx context.Context, found containerwalker.Found) error {
526+
if found.MatchCount > 1 {
527+
return fmt.Errorf("multiple IDs found with provided prefix: %s", found.Req)
528+
}
529+
cid = found.Container.ID()
530+
return nil
531+
},
532+
}
533+
err = walker.WalkAll(ctx, []string{containerName}, true)
534+
assert.NilError(t, err)
535+
536+
// Get container spec
537+
container, err := client.LoadContainer(ctx, cid)
538+
assert.NilError(t, err)
539+
spec, err := container.Spec(ctx)
540+
assert.NilError(t, err)
541+
542+
// Run the validation function
543+
tt.validate(t, spec.Linux.Resources.BlockIO)
544+
})
545+
}
546+
}

pkg/api/types/container_types.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,6 @@ type ContainerCreateOptions struct {
140140
PidsLimit int64
141141
// CgroupConf specifies to configure cgroup v2 (key=value)
142142
CgroupConf []string
143-
// BlkioWeight specifies the block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
144-
BlkioWeight uint16
145143
// Cgroupns specifies the cgroup namespace to use
146144
Cgroupns string
147145
// CgroupParent specifies the optional parent cgroup for the container
@@ -150,6 +148,21 @@ type ContainerCreateOptions struct {
150148
Device []string
151149
// #endregion
152150

151+
// #region for blkio related flags
152+
// BlkioWeight specifies the block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
153+
BlkioWeight uint16
154+
// BlkioWeightDevice specifies the Block IO weight (relative device weight)
155+
BlkioWeightDevice []string
156+
// BlkioDeviceReadBps specifies the Block IO read rate limit(bytes per second) of a device
157+
BlkioDeviceReadBps []string
158+
// BlkioDeviceWriteBps specifies the Block IO write rate limit(bytes per second) of a device
159+
BlkioDeviceWriteBps []string
160+
// BlkioDeviceReadIOps specifies the Block IO read rate limit(IO per second) of a device
161+
BlkioDeviceReadIOps []string
162+
// BlkioDeviceWriteIOps specifies the Block IO read rate limit(IO per second) of a device
163+
BlkioDeviceWriteIOps []string
164+
// #endregion
165+
153166
// #region for intel RDT flags
154167
// RDTClass specifies the Intel Resource Director Technology (RDT) class
155168
RDTClass string

0 commit comments

Comments
 (0)