mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Support process.scheduler
Spec: https://github.com/opencontainers/runtime-spec/pull/1188 Fix: https://github.com/opencontainers/runc/issues/3895 Co-authored-by: lifubang <lifubang@acmcoder.com> Signed-off-by: utam0k <k0ma@utam0k.jp> Signed-off-by: lifubang <lifubang@acmcoder.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
selinux "github.com/opencontainers/selinux/go-selinux"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -30,6 +31,7 @@ func Validate(config *configs.Config) error {
|
||||
intelrdtCheck,
|
||||
rootlessEUIDCheck,
|
||||
mountsStrict,
|
||||
scheduler,
|
||||
}
|
||||
for _, c := range checks {
|
||||
if err := c(config); err != nil {
|
||||
@@ -353,3 +355,24 @@ func isHostNetNS(path string) (bool, error) {
|
||||
|
||||
return (st1.Dev == st2.Dev) && (st1.Ino == st2.Ino), nil
|
||||
}
|
||||
|
||||
// scheduler is to validate scheduler configs according to https://man7.org/linux/man-pages/man2/sched_setattr.2.html
|
||||
func scheduler(config *configs.Config) error {
|
||||
s := config.Scheduler
|
||||
if s == nil {
|
||||
return nil
|
||||
}
|
||||
if s.Policy == "" {
|
||||
return errors.New("scheduler policy is required")
|
||||
}
|
||||
if s.Nice < -20 || s.Nice > 19 {
|
||||
return fmt.Errorf("invalid scheduler.nice: %d", s.Nice)
|
||||
}
|
||||
if s.Priority != 0 && (s.Policy != specs.SchedFIFO && s.Policy != specs.SchedRR) {
|
||||
return errors.New("scheduler.priority can only be specified for SchedFIFO or SchedRR policy")
|
||||
}
|
||||
if s.Policy != specs.SchedDeadline && (s.Runtime != 0 || s.Deadline != 0 || s.Period != 0) {
|
||||
return errors.New("scheduler runtime/deadline/period can only be specified for SchedDeadline policy")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -616,3 +616,53 @@ func TestValidateIDMapMounts(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateScheduler(t *testing.T) {
|
||||
testCases := []struct {
|
||||
isErr bool
|
||||
policy string
|
||||
niceValue int32
|
||||
priority int32
|
||||
runtime uint64
|
||||
deadline uint64
|
||||
period uint64
|
||||
}{
|
||||
{isErr: true, niceValue: 0},
|
||||
{isErr: false, policy: "SCHED_OTHER", niceValue: 19},
|
||||
{isErr: false, policy: "SCHED_OTHER", niceValue: -20},
|
||||
{isErr: true, policy: "SCHED_OTHER", niceValue: 20},
|
||||
{isErr: true, policy: "SCHED_OTHER", niceValue: -21},
|
||||
{isErr: true, policy: "SCHED_OTHER", priority: 100},
|
||||
{isErr: false, policy: "SCHED_FIFO", priority: 100},
|
||||
{isErr: true, policy: "SCHED_FIFO", runtime: 20},
|
||||
{isErr: true, policy: "SCHED_BATCH", deadline: 30},
|
||||
{isErr: true, policy: "SCHED_IDLE", period: 40},
|
||||
{isErr: true, policy: "SCHED_DEADLINE", priority: 100},
|
||||
{isErr: false, policy: "SCHED_DEADLINE", runtime: 200},
|
||||
{isErr: false, policy: "SCHED_DEADLINE", deadline: 300},
|
||||
{isErr: false, policy: "SCHED_DEADLINE", period: 400},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
scheduler := configs.Scheduler{
|
||||
Policy: specs.LinuxSchedulerPolicy(tc.policy),
|
||||
Nice: tc.niceValue,
|
||||
Priority: tc.priority,
|
||||
Runtime: tc.runtime,
|
||||
Deadline: tc.deadline,
|
||||
Period: tc.period,
|
||||
}
|
||||
config := &configs.Config{
|
||||
Rootfs: "/var",
|
||||
Scheduler: &scheduler,
|
||||
}
|
||||
|
||||
err := Validate(config)
|
||||
if tc.isErr && err == nil {
|
||||
t.Errorf("scheduler: %d, expected error, got nil", tc.niceValue)
|
||||
}
|
||||
if !tc.isErr && err != nil {
|
||||
t.Errorf("scheduler: %d, expected nil, got error %v", tc.niceValue, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user