Skip to content

Commit

Permalink
Merge pull request #509 from pippolo84/master
Browse files Browse the repository at this point in the history
Add --blkio-weight option to run subcommand
  • Loading branch information
AkihiroSuda authored Nov 12, 2021
2 parents 5579a69 + 3ab0ffd commit 0f3e1e6
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ Cgroup flags:
- :whale: `--memory`: Memory limit
- :whale: `--pids-limit`: Tune container pids limit
- :nerd_face: `--cgroup-conf`: Configure cgroup v2 (key=value)
- :whale: `blkio-weight`: Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
- :whale: `--cgroupns=(host|private)`: Cgroup namespace to use
- Default: "private" on cgroup v2 hosts, "host" on cgroup v1 hosts
- :whale: `--device`: Add a host device to the container
Expand Down
1 change: 1 addition & 0 deletions cmd/nerdctl/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func newRunCommand() *cobra.Command {
})
runCommand.Flags().Int("pids-limit", -1, "Tune container pids limit (set -1 for unlimited)")
runCommand.Flags().StringSlice("cgroup-conf", nil, "Configure cgroup v2 (key=value)")
runCommand.Flags().Uint16("blkio-weight", 0, "Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)")
runCommand.Flags().String("cgroupns", defaults.CgroupnsMode(), `Cgroup namespace to use, the default depends on the cgroup version ("host"|"private")`)
runCommand.RegisterFlagCompletionFunc("cgroupns", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"host", "private"}, cobra.ShellCompDirectiveNoFileComp
Expand Down
33 changes: 33 additions & 0 deletions cmd/nerdctl/run_cgroup_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"context"
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"

Expand Down Expand Up @@ -133,6 +135,27 @@ func generateCgroupOpts(cmd *cobra.Command, id string) ([]oci.SpecOpts, error) {
}
opts = append(opts, withUnified(unifieds))

blkioWeight, err := cmd.Flags().GetUint16("blkio-weight")
if err != nil {
return nil, err
}
if infoutil.CgroupsVersion() == "1" {
blkioController := "/sys/fs/cgroup/blkio"
blkioWeightPath := filepath.Join(blkioController, "blkio.weight")
if _, err := os.Stat(blkioWeightPath); errors.Is(err, fs.ErrNotExist) {
// if bfq io scheduler is used, the blkio.weight knob will be exposed as blkio.bfq.weight
blkioBfqWeightPath := filepath.Join(blkioController, "blkio.bfq.weight")
if _, err := os.Stat(blkioBfqWeightPath); errors.Is(err, fs.ErrNotExist) {
logrus.Warn("kernel support for cgroup blkio weight missing, weight discarded")
blkioWeight = 0
}
}
}
if blkioWeight > 0 && blkioWeight < 10 || blkioWeight > 1000 {
return nil, errors.New("range of blkio weight is from 10 to 1000")
}
opts = append(opts, withBlkioWeight(blkioWeight))

cgroupns, err := cmd.Flags().GetString("cgroupns")
if err != nil {
return nil, err
Expand Down Expand Up @@ -224,3 +247,13 @@ func withUnified(unified map[string]string) oci.SpecOpts {
return nil
}
}

func withBlkioWeight(blkioWeight uint16) oci.SpecOpts {
return func(_ context.Context, _ oci.Client, _ *containers.Container, s *oci.Spec) error {
if blkioWeight == 0 {
return nil
}
s.Linux.Resources.BlockIO = &specs.LinuxBlockIO{Weight: &blkioWeight}
return nil
}
}
11 changes: 11 additions & 0 deletions cmd/nerdctl/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ func TestRunCgroupConf(t *testing.T) {
"sh", "-ec", "cd /sys/fs/cgroup && cat memory.high").AssertOutContains("33554432")
}

func TestRunBlkioWeightCgroupV2(t *testing.T) {
if cgroups.Mode() != cgroups.Unified {
t.Skip("test requires cgroup v2")
}
base := testutil.NewBase(t)

// when bfq io scheduler is used, the io.weight knob is exposed as io.bfq.weight
base.Cmd("run", "--rm", "--blkio-weight", "300", testutil.AlpineImage,
"sh", "-ec", "cd /sys/fs/cgroup && cat io.bfq.weight").AssertOutContains("300")
}

func TestRunAddHost(t *testing.T) {
base := testutil.NewBase(t)
base.Cmd("run", "--rm", "--add-host", "testing.example.com:10.0.0.1", testutil.AlpineImage, "sh", "-c", "cat /etc/hosts").AssertOutWithFunc(func(stdout string) error {
Expand Down
13 changes: 13 additions & 0 deletions pkg/composer/serviceparser/serviceparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func warnUnknownFields(svc compose.ServiceConfig) {
if unknown := reflectutil.UnknownNonEmptyFields(&svc,
"Name",
"Build",
"BlkioConfig",
"CapAdd",
"CapDrop",
"CPUS",
Expand Down Expand Up @@ -81,6 +82,14 @@ func warnUnknownFields(svc compose.ServiceConfig) {
logrus.Warnf("Ignoring: service %s: %+v", svc.Name, unknown)
}

if svc.BlkioConfig != nil {
if unknown := reflectutil.UnknownNonEmptyFields(svc.BlkioConfig,
"Weight",
); len(unknown) > 0 {
logrus.Warnf("Ignoring: service %s: blkio_config: %+v", svc.Name, unknown)
}
}

for depName, dep := range svc.DependsOn {
if unknown := reflectutil.UnknownNonEmptyFields(&dep,
"Condition",
Expand Down Expand Up @@ -418,6 +427,10 @@ func newContainer(project *compose.Project, parsed *Service, i int) (*Container,
"--pull=never", // because image will be ensured before running replicas with `nerdctl run`.
}

if svc.BlkioConfig != nil && svc.BlkioConfig.Weight != 0 {
c.RunArgs = append(c.RunArgs, fmt.Sprintf("--blkio-weight=%d", svc.BlkioConfig.Weight))
}

for _, v := range svc.CapAdd {
c.RunArgs = append(c.RunArgs, fmt.Sprintf("--cap-add=%s", v))
}
Expand Down

0 comments on commit 0f3e1e6

Please sign in to comment.