diff --git a/container/container_init.go b/container/container_init.go index 39e9560..47fcba1 100644 --- a/container/container_init.go +++ b/container/container_init.go @@ -73,6 +73,27 @@ func (c *Container) Init(reexecCmd string, reexecArgs []string) error { }) } + // if ns.Type == specs.TimeNamespace { + // if c.Spec.Linux.TimeOffsets != nil && len(c.Spec.Linux.TimeOffsets) > 0 { + // var tos bytes.Buffer + // for clock, offset := range c.Spec.Linux.TimeOffsets { + // if n, err := tos.WriteString( + // fmt.Sprintf("%s %d %d\n", clock, offset.Secs, offset.Nanosecs), + // ); err != nil || n == 0 { + // return fmt.Errorf("write time offsets") + // } + // } + // + // if err := os.WriteFile( + // "/proc/self/timens_offsets", + // tos.Bytes(), + // 0644, + // ); err != nil { + // return fmt.Errorf("write timens offsets: %w", err) + // } + // } + // } + if ns.Path == "" { cloneFlags |= ns.ToFlag() } else { diff --git a/container/container_reexec.go b/container/container_reexec.go index 14ad739..00d2e8c 100644 --- a/container/container_reexec.go +++ b/container/container_reexec.go @@ -15,6 +15,7 @@ import ( "github.com/nixpig/brownie/capabilities" "github.com/nixpig/brownie/cgroups" "github.com/nixpig/brownie/filesystem" + "github.com/nixpig/brownie/scheduler" "github.com/nixpig/brownie/terminal" "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" @@ -115,6 +116,23 @@ func (c *Container) Reexec() error { return err } + if c.Spec.Linux.Sysctl != nil { + if len(c.Spec.Linux.Sysctl) > 0 { + // fmt.Println(c.Spec.Linux.Sysctl) + // for k, v := range c.Spec.Linux.Sysctl { + // fmt.Print(k, v) + // kp := strings.ReplaceAll(k, ".", "/") + // if err := os.WriteFile( + // path.Join("/proc/sys", kp), + // []byte(v), + // 0644, + // ); err != nil { + // // return fmt.Errorf("write sysctl (%s: %s): %w", kp, v, err) + // } + // } + } + } + if err := filesystem.MountMaskedPaths( c.Spec.Linux.MaskedPaths, ); err != nil { @@ -170,6 +188,35 @@ func (c *Container) Reexec() error { } } + if c.Spec.Process.Scheduler != nil { + policy, err := scheduler.PolicyToInt(c.Spec.Process.Scheduler.Policy) + if err != nil { + return fmt.Errorf("scheduler policy to int: %w", err) + } + + flags, err := scheduler.FlagsToInt(c.Spec.Process.Scheduler.Flags) + if err != nil { + return fmt.Errorf("scheduler flags to int: %w", err) + } + + schedAttr := unix.SchedAttr{ + Deadline: c.Spec.Process.Scheduler.Deadline, + Flags: uint64(flags), + Size: unix.SizeofSchedAttr, + Nice: c.Spec.Process.Scheduler.Nice, + Period: c.Spec.Process.Scheduler.Period, + Policy: uint32(policy), + Priority: uint32(c.Spec.Process.Scheduler.Priority), + Runtime: c.Spec.Process.Scheduler.Runtime, + } + + if err := unix.SchedSetAttr(0, &schedAttr, 0); err != nil { + return fmt.Errorf("set schedattrs: %w", err) + } + } + + // TODO: IOPriority + if err := syscall.Setuid(int(c.Spec.Process.User.UID)); err != nil { return fmt.Errorf("set UID: %w", err) } diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go new file mode 100644 index 0000000..8110d7a --- /dev/null +++ b/scheduler/scheduler.go @@ -0,0 +1,55 @@ +package scheduler + +import ( + "fmt" + + "github.com/opencontainers/runtime-spec/specs-go" +) + +func PolicyToInt(policy specs.LinuxSchedulerPolicy) (int, error) { + switch policy { + case specs.SchedOther: + return 0, nil + case specs.SchedFIFO: + return 1, nil + case specs.SchedRR: + return 2, nil + case specs.SchedBatch: + return 3, nil + case specs.SchedISO: + return 4, nil + case specs.SchedIdle: + return 5, nil + case specs.SchedDeadline: + return 6, nil + default: + return -1, fmt.Errorf("unknown policy: %s", policy) + } +} + +func FlagsToInt(flags []specs.LinuxSchedulerFlag) (int, error) { + var f int + + for _, flag := range flags { + switch flag { + case specs.SchedFlagResetOnFork: + f |= 0x01 + case specs.SchedFlagReclaim: + f |= 0x02 + case specs.SchedFlagDLOverrun: + f |= 0x04 + case specs.SchedFlagKeepPolicy: + f |= 0x08 + case specs.SchedFlagKeepParams: + f |= 0x10 + case specs.SchedFlagUtilClampMin: + f |= 0x20 + case specs.SchedFlagUtilClampMax: + f |= 0x40 + default: + return -1, fmt.Errorf("unknown flag: %s", flag) + } + } + + return f, nil +}