Skip to content

Commit d48d9cf

Browse files
authored
Merge pull request #4459 from kolyshkin/prio-nits
Fixups to scheduler/priority settings
2 parents fd932ec + 5746249 commit d48d9cf

File tree

8 files changed

+61
-55
lines changed

8 files changed

+61
-55
lines changed

libcontainer/configs/config.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,6 @@ func ToSchedAttr(scheduler *Scheduler) (*unix.SchedAttr, error) {
286286
}, nil
287287
}
288288

289-
var IOPrioClassMapping = map[specs.IOPriorityClass]int{
290-
specs.IOPRIO_CLASS_RT: 1,
291-
specs.IOPRIO_CLASS_BE: 2,
292-
specs.IOPRIO_CLASS_IDLE: 3,
293-
}
294-
295289
type IOPriority = specs.LinuxIOPriority
296290

297291
type (

libcontainer/configs/validate/validator.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,5 +406,13 @@ func ioPriority(config *configs.Config) error {
406406
if priority < 0 || priority > 7 {
407407
return fmt.Errorf("invalid ioPriority.Priority: %d", priority)
408408
}
409+
410+
switch class := config.IOPriority.Class; class {
411+
case specs.IOPRIO_CLASS_RT, specs.IOPRIO_CLASS_BE, specs.IOPRIO_CLASS_IDLE:
412+
// Valid class, do nothing.
413+
default:
414+
return fmt.Errorf("invalid ioPriority.Class: %q", class)
415+
}
416+
409417
return nil
410418
}

libcontainer/configs/validate/validator_test.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -847,15 +847,21 @@ func TestValidateIOPriority(t *testing.T) {
847847
testCases := []struct {
848848
isErr bool
849849
priority int
850+
class specs.IOPriorityClass
850851
}{
851-
{isErr: false, priority: 0},
852-
{isErr: false, priority: 7},
853-
{isErr: true, priority: -1},
852+
{isErr: false, priority: 0, class: specs.IOPRIO_CLASS_IDLE},
853+
{isErr: false, priority: 7, class: specs.IOPRIO_CLASS_RT},
854+
{isErr: false, priority: 3, class: specs.IOPRIO_CLASS_BE},
855+
// Invalid priority.
856+
{isErr: true, priority: -1, class: specs.IOPRIO_CLASS_BE},
857+
// Invalid class.
858+
{isErr: true, priority: 3, class: specs.IOPriorityClass("IOPRIO_CLASS_WOW")},
854859
}
855860

856861
for _, tc := range testCases {
857862
ioPriroty := configs.IOPriority{
858863
Priority: tc.priority,
864+
Class: tc.class,
859865
}
860866
config := &configs.Config{
861867
Rootfs: "/var",

libcontainer/init_linux.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,9 @@ func setupRlimits(limits []configs.Rlimit, pid int) error {
662662
}
663663

664664
func setupScheduler(config *configs.Config) error {
665+
if config.Scheduler == nil {
666+
return nil
667+
}
665668
attr, err := configs.ToSchedAttr(config.Scheduler)
666669
if err != nil {
667670
return err
@@ -675,6 +678,35 @@ func setupScheduler(config *configs.Config) error {
675678
return nil
676679
}
677680

681+
func setupIOPriority(config *configs.Config) error {
682+
const ioprioWhoPgrp = 1
683+
684+
ioprio := config.IOPriority
685+
if ioprio == nil {
686+
return nil
687+
}
688+
class := 0
689+
switch ioprio.Class {
690+
case specs.IOPRIO_CLASS_RT:
691+
class = 1
692+
case specs.IOPRIO_CLASS_BE:
693+
class = 2
694+
case specs.IOPRIO_CLASS_IDLE:
695+
class = 3
696+
default:
697+
return fmt.Errorf("invalid io priority class: %s", ioprio.Class)
698+
}
699+
700+
// Combine class and priority into a single value
701+
// https://github.com/torvalds/linux/blob/v5.18/include/uapi/linux/ioprio.h#L5-L17
702+
iop := (class << 13) | ioprio.Priority
703+
_, _, errno := unix.RawSyscall(unix.SYS_IOPRIO_SET, ioprioWhoPgrp, 0, uintptr(iop))
704+
if errno != 0 {
705+
return fmt.Errorf("failed to set io priority: %w", errno)
706+
}
707+
return nil
708+
}
709+
678710
func setupPersonality(config *configs.Config) error {
679711
return system.SetLinuxPersonality(config.Personality.Domain)
680712
}

libcontainer/process_linux.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,6 @@ type setnsProcess struct {
166166
func (p *setnsProcess) start() (retErr error) {
167167
defer p.comm.closeParent()
168168

169-
if p.process.IOPriority != nil {
170-
if err := setIOPriority(p.process.IOPriority); err != nil {
171-
return err
172-
}
173-
}
174-
175169
// get the "before" value of oom kill count
176170
oom, _ := p.manager.OOMKillCount()
177171
err := p.cmd.Start()
@@ -905,21 +899,3 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
905899
}
906900
return i, nil
907901
}
908-
909-
func setIOPriority(ioprio *configs.IOPriority) error {
910-
const ioprioWhoPgrp = 1
911-
912-
class, ok := configs.IOPrioClassMapping[ioprio.Class]
913-
if !ok {
914-
return fmt.Errorf("invalid io priority class: %s", ioprio.Class)
915-
}
916-
917-
// Combine class and priority into a single value
918-
// https://github.com/torvalds/linux/blob/v5.18/include/uapi/linux/ioprio.h#L5-L17
919-
iop := (class << 13) | ioprio.Priority
920-
_, _, errno := unix.RawSyscall(unix.SYS_IOPRIO_SET, ioprioWhoPgrp, 0, uintptr(iop))
921-
if errno != 0 {
922-
return fmt.Errorf("failed to set io priority: %w", errno)
923-
}
924-
return nil
925-
}

libcontainer/setns_init_linux.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ func (l *linuxSetnsInit) Init() error {
7171
unix.Umask(int(*l.config.Config.Umask))
7272
}
7373

74-
if l.config.Config.Scheduler != nil {
75-
if err := setupScheduler(l.config.Config); err != nil {
76-
return err
77-
}
74+
if err := setupScheduler(l.config.Config); err != nil {
75+
return err
7876
}
7977

78+
if err := setupIOPriority(l.config.Config); err != nil {
79+
return err
80+
}
8081
// Tell our parent that we're ready to exec. This must be done before the
8182
// Seccomp rules have been applied, because we need to be able to read and
8283
// write to a socket.

libcontainer/standard_init_linux.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,12 @@ func (l *linuxStandardInit) Init() error {
155155
}
156156
}
157157

158-
if l.config.Config.Scheduler != nil {
159-
if err := setupScheduler(l.config.Config); err != nil {
160-
return err
161-
}
158+
if err := setupScheduler(l.config.Config); err != nil {
159+
return err
162160
}
163-
if l.config.Config.IOPriority != nil {
164-
if err := setIOPriority(l.config.Config.IOPriority); err != nil {
165-
return err
166-
}
161+
162+
if err := setupIOPriority(l.config.Config); err != nil {
163+
return err
167164
}
168165

169166
// Tell our parent that we're ready to exec. This must be done before the

utils_linux.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,15 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
5555
Label: p.SelinuxLabel,
5656
NoNewPrivileges: &p.NoNewPrivileges,
5757
AppArmorProfile: p.ApparmorProfile,
58+
Scheduler: p.Scheduler,
59+
IOPriority: p.IOPriority,
5860
}
5961

6062
if p.ConsoleSize != nil {
6163
lp.ConsoleWidth = uint16(p.ConsoleSize.Width)
6264
lp.ConsoleHeight = uint16(p.ConsoleSize.Height)
6365
}
6466

65-
if p.Scheduler != nil {
66-
s := *p.Scheduler
67-
lp.Scheduler = &s
68-
}
69-
70-
if p.IOPriority != nil {
71-
ioPriority := *p.IOPriority
72-
lp.IOPriority = &ioPriority
73-
}
74-
7567
if p.Capabilities != nil {
7668
lp.Capabilities = &configs.Capabilities{}
7769
lp.Capabilities.Bounding = p.Capabilities.Bounding

0 commit comments

Comments
 (0)