diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index c9e74188e2b..ab030974f33 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -700,6 +700,7 @@ func (c *Container) newInitConfig(process *Process) *initConfig { AppArmorProfile: c.config.AppArmorProfile, ProcessLabel: c.config.ProcessLabel, Rlimits: c.config.Rlimits, + IOPriority: c.config.IOPriority, CreateConsole: process.ConsoleSocket != nil, ConsoleWidth: process.ConsoleWidth, ConsoleHeight: process.ConsoleHeight, @@ -722,6 +723,9 @@ func (c *Container) newInitConfig(process *Process) *initConfig { if len(process.Rlimits) > 0 { cfg.Rlimits = process.Rlimits } + if process.IOPriority != nil { + cfg.IOPriority = process.IOPriority + } // Set misc properties. diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index dbe2d50658d..762ccdaac3e 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -81,6 +81,7 @@ type initConfig struct { NoNewPrivileges bool `json:"no_new_privileges"` ProcessLabel string `json:"process_label"` Rlimits []configs.Rlimit `json:"rlimits"` + IOPriority *configs.IOPriority `json:"io_priority,omitempty"` // Properties that only exist in container config. // FIXME: they are also passed in Config above. @@ -678,7 +679,7 @@ func setupScheduler(config *configs.Config) error { return nil } -func setupIOPriority(config *configs.Config) error { +func setupIOPriority(config *initConfig) error { const ioprioWhoPgrp = 1 ioprio := config.IOPriority diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index b42b3be1a89..708ffda8b94 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -76,7 +76,7 @@ func (l *linuxSetnsInit) Init() error { return err } - if err := setupIOPriority(l.config.Config); err != nil { + if err := setupIOPriority(l.config); err != nil { return err } // Tell our parent that we're ready to exec. This must be done before the diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 510f9483baa..88ce7c0dd02 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -160,7 +160,7 @@ func (l *linuxStandardInit) Init() error { return err } - if err := setupIOPriority(l.config.Config); err != nil { + if err := setupIOPriority(l.config); err != nil { return err } diff --git a/tests/integration/ioprio.bats b/tests/integration/ioprio.bats index a907d782f01..adb0ff863a5 100644 --- a/tests/integration/ioprio.bats +++ b/tests/integration/ioprio.bats @@ -22,9 +22,23 @@ function teardown() { [ "$status" -eq 0 ] [[ "$output" = *'best-effort: prio 4'* ]] - # Check the process made from the exec command. + # Check the process made from the exec command, + # which should derive ioprio from config.json. runc exec test_ioprio ionice [ "$status" -eq 0 ] - [[ "$output" = *'best-effort: prio 4'* ]] + + # Run exec with a different priority. + proc=' +{ + "terminal": false, + "ioPriority": { + "class": "IOPRIO_CLASS_IDLE" + }, + "args": [ "/usr/bin/ionice" ], + "cwd": "/" +}' + runc exec --process <(echo "$proc") test_ioprio + [ "$status" -eq 0 ] + [[ "$output" = *'idle'* ]] }