aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/container.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-02-26 16:29:47 +0900
committerOphestra <cat@gensokyo.uk>2026-02-26 16:29:47 +0900
commita6160cd410b1def222018cd88951fcbbf1a65f5c (patch)
tree8305422bbcf4f71c5bd271a8036c3d11510b0c84 /container/container.go
parent826347fe1f6131fbbd42b253441790a7c740bc86 (diff)
container: set scheduling policy
This is thread-directed so cannot be done externally. The glibc wrapper exposes this behaviour so most multithreaded programs using this is straight up incorrect. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'container/container.go')
-rw-r--r--container/container.go20
1 files changed, 20 insertions, 0 deletions
diff --git a/container/container.go b/container/container.go
index d76a0907..2a6363a5 100644
--- a/container/container.go
+++ b/container/container.go
@@ -37,6 +37,9 @@ type (
Container struct {
// Whether the container init should stay alive after its parent terminates.
AllowOrphan bool
+ // Scheduling policy to set via sched_setscheduler(2). The zero value
+ // skips this call. Supported policies are [SCHED_BATCH], [SCHED_IDLE].
+ SchedPolicy int
// Cgroup fd, nil to disable.
Cgroup *int
// ExtraFiles passed through to initial process in the container,
@@ -342,6 +345,23 @@ func (p *Container) Start() error {
landlockOut:
}
+ // sched_setscheduler: thread-directed but acts on all processes
+ // created from that thread
+ if p.SchedPolicy > 0 {
+ p.msg.Verbosef("setting scheduling policy %d", p.SchedPolicy)
+ if err := schedSetscheduler(
+ 0, // calling thread
+ p.SchedPolicy,
+ &schedParam{0},
+ ); err != nil {
+ return &StartError{
+ Fatal: true,
+ Step: "enforce landlock ruleset",
+ Err: err,
+ }
+ }
+ }
+
p.msg.Verbose("starting container init")
if err := p.cmd.Start(); err != nil {
return &StartError{false, "start container init", err, false, true}