Skip to content

Commit 7e26176

Browse files
committed
runc exec: fix setting process.Scheduler
Commit 770728e added Scheduler field into both Config and Process, but forgot to add a mechanism to actually use Process.Scheduler. As a result, runc exec does not set Process.Scheduler ever. Fix it, and a test case (which fails before the fix). Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
1 parent 2347937 commit 7e26176

File tree

7 files changed

+51
-10
lines changed

7 files changed

+51
-10
lines changed

CHANGELOG.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
github.com/moby/sys/user for that. (#3999)
1919

2020
### Fixed
21-
* `runc exec -p` no longer ignores specified `ioPriority` setting.
22-
Similarly, libcontainer's `Container.Start` and `Container.Run`
23-
methods no longer ignore `Process.IOPriority` setting. (#4585)
21+
* `runc exec -p` no longer ignores specified `ioPriority` and `scheduler`
22+
settings. Similarly, libcontainer's `Container.Start` and `Container.Run`
23+
methods no longer ignore `Process.IOPriority` and `Process.Scheduler`
24+
settings. (#4585)
2425

2526
## [1.2.0] - 2024-10-22
2627

libcontainer/container_linux.go

+4
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,7 @@ func (c *Container) newInitConfig(process *Process) *initConfig {
708708
ProcessLabel: c.config.ProcessLabel,
709709
Rlimits: c.config.Rlimits,
710710
IOPriority: c.config.IOPriority,
711+
Scheduler: c.config.Scheduler,
711712
CreateConsole: process.ConsoleSocket != nil,
712713
ConsoleWidth: process.ConsoleWidth,
713714
ConsoleHeight: process.ConsoleHeight,
@@ -733,6 +734,9 @@ func (c *Container) newInitConfig(process *Process) *initConfig {
733734
if process.IOPriority != nil {
734735
cfg.IOPriority = process.IOPriority
735736
}
737+
if process.Scheduler != nil {
738+
cfg.Scheduler = process.Scheduler
739+
}
736740

737741
// Set misc properties.
738742

libcontainer/init_linux.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type initConfig struct {
8282
ProcessLabel string `json:"process_label"`
8383
Rlimits []configs.Rlimit `json:"rlimits"`
8484
IOPriority *configs.IOPriority `json:"io_priority,omitempty"`
85+
Scheduler *configs.Scheduler `json:"scheduler,omitempty"`
8586

8687
// Miscellaneous properties, filled in by [Container.newInitConfig]
8788
// unless documented otherwise.
@@ -607,7 +608,7 @@ func setupRlimits(limits []configs.Rlimit, pid int) error {
607608
return nil
608609
}
609610

610-
func setupScheduler(config *configs.Config) error {
611+
func setupScheduler(config *initConfig) error {
611612
if config.Scheduler == nil {
612613
return nil
613614
}
@@ -616,7 +617,7 @@ func setupScheduler(config *configs.Config) error {
616617
return err
617618
}
618619
if err := unix.SchedSetAttr(0, attr, 0); err != nil {
619-
if errors.Is(err, unix.EPERM) && config.Cgroups.CpusetCpus != "" {
620+
if errors.Is(err, unix.EPERM) && config.Config.Cgroups.CpusetCpus != "" {
620621
return errors.New("process scheduler can't be used together with AllowedCPUs")
621622
}
622623
return fmt.Errorf("error setting scheduler: %w", err)

libcontainer/process.go

+3
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ type Process struct {
112112
// For cgroup v2, the only key allowed is "".
113113
SubCgroupPaths map[string]string
114114

115+
// Scheduler represents the scheduling attributes for a process.
116+
//
117+
// If not empty, takes precedence over container's [configs.Config.Scheduler].
115118
Scheduler *configs.Scheduler
116119

117120
// IOPriority is a process I/O priority.

libcontainer/setns_init_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (l *linuxSetnsInit) Init() error {
7171
unix.Umask(int(*l.config.Config.Umask))
7272
}
7373

74-
if err := setupScheduler(l.config.Config); err != nil {
74+
if err := setupScheduler(l.config); err != nil {
7575
return err
7676
}
7777

libcontainer/standard_init_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func (l *linuxStandardInit) Init() error {
155155
}
156156
}
157157

158-
if err := setupScheduler(l.config.Config); err != nil {
158+
if err := setupScheduler(l.config); err != nil {
159159
return err
160160
}
161161

tests/integration/scheduler.bats

+35-3
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,49 @@ function teardown() {
1212
}
1313

1414
@test "scheduler is applied" {
15-
update_config ' .process.scheduler = {"policy": "SCHED_DEADLINE", "nice": 19, "priority": 0, "runtime": 42000, "deadline": 1000000, "period": 1000000, }'
15+
update_config ' .process.scheduler = {
16+
"policy": "SCHED_BATCH",
17+
"priority": 0,
18+
"nice": 19
19+
}'
1620

1721
runc run -d --console-socket "$CONSOLE_SOCKET" test_scheduler
1822
[ "$status" -eq 0 ]
1923

24+
# Check init settings.
2025
runc exec test_scheduler chrt -p 1
2126
[ "$status" -eq 0 ]
27+
[[ "${lines[0]}" == *"scheduling policy: SCHED_BATCH" ]]
28+
[[ "${lines[1]}" == *"priority: 0" ]]
29+
30+
# Check exec settings derived from config.json.
31+
runc exec test_scheduler sh -c 'chrt -p $$'
32+
[ "$status" -eq 0 ]
33+
[[ "${lines[0]}" == *"scheduling policy: SCHED_BATCH" ]]
34+
[[ "${lines[1]}" == *"priority: 0" ]]
35+
36+
# Another exec, with different scheduler settings.
37+
proc='
38+
{
39+
"terminal": false,
40+
"args": [ "/bin/sleep", "600" ],
41+
"cwd": "/",
42+
"scheduler": {
43+
"policy": "SCHED_DEADLINE",
44+
"flags": [ "SCHED_FLAG_RESET_ON_FORK" ],
45+
"nice": 19,
46+
"priority": 0,
47+
"runtime": 42000,
48+
"deadline": 100000,
49+
"period": 1000000
50+
}
51+
}'
52+
__runc exec -d --pid-file pid.txt --process <(echo "$proc") test_scheduler
2253

23-
[[ "${lines[0]}" == *"scheduling policy: SCHED_DEADLINE" ]]
54+
run chrt -p "$(cat pid.txt)"
55+
[[ "${lines[0]}" == *"scheduling policy: SCHED_DEADLINE|SCHED_RESET_ON_FORK" ]]
2456
[[ "${lines[1]}" == *"priority: 0" ]]
25-
[[ "${lines[2]}" == *"runtime/deadline/period parameters: 42000/1000000/1000000" ]]
57+
[[ "${lines[2]}" == *"runtime/deadline/period parameters: 42000/100000/1000000" ]]
2658
}
2759

2860
# Checks that runc emits a specific error when scheduling policy is used

0 commit comments

Comments
 (0)