Skip to content

Commit

Permalink
Merge pull request #4459 from kolyshkin/prio-nits
Browse files Browse the repository at this point in the history
Fixups to scheduler/priority settings
  • Loading branch information
lifubang authored Dec 25, 2024
2 parents fd932ec + 5746249 commit d48d9cf
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 55 deletions.
6 changes: 0 additions & 6 deletions libcontainer/configs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,6 @@ func ToSchedAttr(scheduler *Scheduler) (*unix.SchedAttr, error) {
}, nil
}

var IOPrioClassMapping = map[specs.IOPriorityClass]int{
specs.IOPRIO_CLASS_RT: 1,
specs.IOPRIO_CLASS_BE: 2,
specs.IOPRIO_CLASS_IDLE: 3,
}

type IOPriority = specs.LinuxIOPriority

type (
Expand Down
8 changes: 8 additions & 0 deletions libcontainer/configs/validate/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,5 +406,13 @@ func ioPriority(config *configs.Config) error {
if priority < 0 || priority > 7 {
return fmt.Errorf("invalid ioPriority.Priority: %d", priority)
}

switch class := config.IOPriority.Class; class {
case specs.IOPRIO_CLASS_RT, specs.IOPRIO_CLASS_BE, specs.IOPRIO_CLASS_IDLE:
// Valid class, do nothing.
default:
return fmt.Errorf("invalid ioPriority.Class: %q", class)
}

return nil
}
12 changes: 9 additions & 3 deletions libcontainer/configs/validate/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,15 +847,21 @@ func TestValidateIOPriority(t *testing.T) {
testCases := []struct {
isErr bool
priority int
class specs.IOPriorityClass
}{
{isErr: false, priority: 0},
{isErr: false, priority: 7},
{isErr: true, priority: -1},
{isErr: false, priority: 0, class: specs.IOPRIO_CLASS_IDLE},
{isErr: false, priority: 7, class: specs.IOPRIO_CLASS_RT},
{isErr: false, priority: 3, class: specs.IOPRIO_CLASS_BE},
// Invalid priority.
{isErr: true, priority: -1, class: specs.IOPRIO_CLASS_BE},
// Invalid class.
{isErr: true, priority: 3, class: specs.IOPriorityClass("IOPRIO_CLASS_WOW")},
}

for _, tc := range testCases {
ioPriroty := configs.IOPriority{
Priority: tc.priority,
Class: tc.class,
}
config := &configs.Config{
Rootfs: "/var",
Expand Down
32 changes: 32 additions & 0 deletions libcontainer/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,9 @@ func setupRlimits(limits []configs.Rlimit, pid int) error {
}

func setupScheduler(config *configs.Config) error {
if config.Scheduler == nil {
return nil
}
attr, err := configs.ToSchedAttr(config.Scheduler)
if err != nil {
return err
Expand All @@ -675,6 +678,35 @@ func setupScheduler(config *configs.Config) error {
return nil
}

func setupIOPriority(config *configs.Config) error {
const ioprioWhoPgrp = 1

ioprio := config.IOPriority
if ioprio == nil {
return nil
}
class := 0
switch ioprio.Class {
case specs.IOPRIO_CLASS_RT:
class = 1
case specs.IOPRIO_CLASS_BE:
class = 2
case specs.IOPRIO_CLASS_IDLE:
class = 3
default:
return fmt.Errorf("invalid io priority class: %s", ioprio.Class)
}

// Combine class and priority into a single value
// https://github.com/torvalds/linux/blob/v5.18/include/uapi/linux/ioprio.h#L5-L17
iop := (class << 13) | ioprio.Priority
_, _, errno := unix.RawSyscall(unix.SYS_IOPRIO_SET, ioprioWhoPgrp, 0, uintptr(iop))
if errno != 0 {
return fmt.Errorf("failed to set io priority: %w", errno)
}
return nil
}

func setupPersonality(config *configs.Config) error {
return system.SetLinuxPersonality(config.Personality.Domain)
}
Expand Down
24 changes: 0 additions & 24 deletions libcontainer/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,6 @@ type setnsProcess struct {
func (p *setnsProcess) start() (retErr error) {
defer p.comm.closeParent()

if p.process.IOPriority != nil {
if err := setIOPriority(p.process.IOPriority); err != nil {
return err
}
}

// get the "before" value of oom kill count
oom, _ := p.manager.OOMKillCount()
err := p.cmd.Start()
Expand Down Expand Up @@ -905,21 +899,3 @@ func (p *Process) InitializeIO(rootuid, rootgid int) (i *IO, err error) {
}
return i, nil
}

func setIOPriority(ioprio *configs.IOPriority) error {
const ioprioWhoPgrp = 1

class, ok := configs.IOPrioClassMapping[ioprio.Class]
if !ok {
return fmt.Errorf("invalid io priority class: %s", ioprio.Class)
}

// Combine class and priority into a single value
// https://github.com/torvalds/linux/blob/v5.18/include/uapi/linux/ioprio.h#L5-L17
iop := (class << 13) | ioprio.Priority
_, _, errno := unix.RawSyscall(unix.SYS_IOPRIO_SET, ioprioWhoPgrp, 0, uintptr(iop))
if errno != 0 {
return fmt.Errorf("failed to set io priority: %w", errno)
}
return nil
}
9 changes: 5 additions & 4 deletions libcontainer/setns_init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ func (l *linuxSetnsInit) Init() error {
unix.Umask(int(*l.config.Config.Umask))
}

if l.config.Config.Scheduler != nil {
if err := setupScheduler(l.config.Config); err != nil {
return err
}
if err := setupScheduler(l.config.Config); err != nil {
return err
}

if err := setupIOPriority(l.config.Config); err != nil {
return err
}
// Tell our parent that we're ready to exec. This must be done before the
// Seccomp rules have been applied, because we need to be able to read and
// write to a socket.
Expand Down
13 changes: 5 additions & 8 deletions libcontainer/standard_init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,12 @@ func (l *linuxStandardInit) Init() error {
}
}

if l.config.Config.Scheduler != nil {
if err := setupScheduler(l.config.Config); err != nil {
return err
}
if err := setupScheduler(l.config.Config); err != nil {
return err
}
if l.config.Config.IOPriority != nil {
if err := setIOPriority(l.config.Config.IOPriority); err != nil {
return err
}

if err := setupIOPriority(l.config.Config); err != nil {
return err
}

// Tell our parent that we're ready to exec. This must be done before the
Expand Down
12 changes: 2 additions & 10 deletions utils_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,15 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) {
Label: p.SelinuxLabel,
NoNewPrivileges: &p.NoNewPrivileges,
AppArmorProfile: p.ApparmorProfile,
Scheduler: p.Scheduler,
IOPriority: p.IOPriority,
}

if p.ConsoleSize != nil {
lp.ConsoleWidth = uint16(p.ConsoleSize.Width)
lp.ConsoleHeight = uint16(p.ConsoleSize.Height)
}

if p.Scheduler != nil {
s := *p.Scheduler
lp.Scheduler = &s
}

if p.IOPriority != nil {
ioPriority := *p.IOPriority
lp.IOPriority = &ioPriority
}

if p.Capabilities != nil {
lp.Capabilities = &configs.Capabilities{}
lp.Capabilities.Bounding = p.Capabilities.Bounding
Expand Down

0 comments on commit d48d9cf

Please sign in to comment.