From 1ee7704edd00f2e7e0f663d9f039817d07003c20 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Thu, 12 Mar 2026 01:20:08 +0900 Subject: [PATCH] hst: expose scheduling priority This is useful when limits are configured to allow it. Signed-off-by: Ophestra --- cmd/hakurei/command.go | 14 +++++++++++--- cmd/hakurei/command_test.go | 8 +++++--- hst/config.go | 10 ++++++++-- internal/outcome/outcome.go | 3 ++- internal/outcome/shim.go | 3 +++ test/test.py | 4 ++-- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go index 242e138..bf638e2 100644 --- a/cmd/hakurei/command.go +++ b/cmd/hakurei/command.go @@ -16,6 +16,7 @@ import ( "hakurei.app/command" "hakurei.app/container/check" "hakurei.app/container/fhs" + "hakurei.app/container/std" "hakurei.app/hst" "hakurei.app/internal/dbus" "hakurei.app/internal/env" @@ -88,7 +89,9 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr flagGroups command.RepeatableFlag flagHomeDir string flagUserName string - flagSched string + + flagSchedPolicy string + flagSchedPriority int flagPrivateRuntime, flagPrivateTmpdir bool @@ -178,9 +181,12 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr }, } - if err := config.SchedPolicy.UnmarshalText([]byte(flagSched)); err != nil { + if err := config.SchedPolicy.UnmarshalText( + []byte(flagSchedPolicy), + ); err != nil { log.Fatal(err) } + config.SchedPriority = std.Int(flagSchedPriority) // bind GPU stuff if et&(hst.EX11|hst.EWayland) != 0 { @@ -292,8 +298,10 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr "Container home directory"). Flag(&flagUserName, "u", command.StringFlag("chronos"), "Passwd user name within sandbox"). - Flag(&flagSched, "sched", command.StringFlag(""), + Flag(&flagSchedPolicy, "policy", command.StringFlag(""), "Scheduling policy to set for the container"). + Flag(&flagSchedPriority, "priority", command.IntFlag(0), + "Scheduling priority to set for the container"). Flag(&flagPrivateRuntime, "private-runtime", command.BoolFlag(false), "Do not share XDG_RUNTIME_DIR between containers under the same identity"). Flag(&flagPrivateTmpdir, "private-tmpdir", command.BoolFlag(false), diff --git a/cmd/hakurei/command_test.go b/cmd/hakurei/command_test.go index 8b5ae63..67c8069 100644 --- a/cmd/hakurei/command_test.go +++ b/cmd/hakurei/command_test.go @@ -36,7 +36,7 @@ Commands: }, { "run", []string{"run", "-h"}, ` -Usage: hakurei run [-h | --help] [--dbus-config ] [--dbus-system ] [--mpris] [--dbus-log] [--id ] [-a ] [-g ] [-d ] [-u ] [--sched ] [--private-runtime] [--private-tmpdir] [--wayland] [-X] [--dbus] [--pipewire] [--pulse] COMMAND [OPTIONS] +Usage: hakurei run [-h | --help] [--dbus-config ] [--dbus-system ] [--mpris] [--dbus-log] [--id ] [-a ] [-g ] [-d ] [-u ] [--policy ] [--priority ] [--private-runtime] [--private-tmpdir] [--wayland] [-X] [--dbus] [--pipewire] [--pulse] COMMAND [OPTIONS] Flags: -X Enable direct connection to X11 @@ -60,14 +60,16 @@ Flags: Allow owning MPRIS D-Bus path, has no effect if custom config is available -pipewire Enable connection to PipeWire via SecurityContext + -policy string + Scheduling policy to set for the container + -priority int + Scheduling priority to set for the container -private-runtime Do not share XDG_RUNTIME_DIR between containers under the same identity -private-tmpdir Do not share TMPDIR between containers under the same identity -pulse Enable PulseAudio compatibility daemon - -sched string - Scheduling policy to set for the container -u string Passwd user name within sandbox (default "chronos") -wayland diff --git a/hst/config.go b/hst/config.go index 5c02063..a21be79 100644 --- a/hst/config.go +++ b/hst/config.go @@ -104,9 +104,15 @@ type Config struct { // Init user namespace supplementary groups inherited by all container processes. Groups []string `json:"groups"` - // Scheduling policy to set for the container. The zero value retains the - // current scheduling policy. + // Scheduling policy to set for the container. + // + // The zero value retains the current scheduling policy. SchedPolicy std.SchedPolicy `json:"sched_policy,omitempty"` + // Scheduling priority to set for the container. + // + // The zero value implies the minimum priority of the current SchedPolicy. + // Has no effect if SchedPolicy is zero. + SchedPriority std.Int `json:"sched_priority,omitempty"` // High level configuration applied to the underlying [container]. Container *ContainerConfig `json:"container"` diff --git a/internal/outcome/outcome.go b/internal/outcome/outcome.go index cb86b39..c72f688 100644 --- a/internal/outcome/outcome.go +++ b/internal/outcome/outcome.go @@ -100,7 +100,8 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *hst.ID, config *h PrivPID: k.getpid(), Verbose: msg.IsVerbose(), - SchedPolicy: config.SchedPolicy, + SchedPolicy: config.SchedPolicy, + SchedPriority: config.SchedPriority, }, ID: id, diff --git a/internal/outcome/shim.go b/internal/outcome/shim.go index 6d3e8d8..a35ea1f 100644 --- a/internal/outcome/shim.go +++ b/internal/outcome/shim.go @@ -75,6 +75,8 @@ type shimParams struct { // Copied from [hst.Config]. SchedPolicy std.SchedPolicy + // Copied from [hst.Config]. + SchedPriority std.Int // Outcome setup ops, contains setup state. Populated by outcome.finalise. Ops []outcomeOp @@ -276,6 +278,7 @@ func shimEntrypoint(k syscallDispatcher) { z := container.New(ctx, msg) z.SetScheduler = state.Shim.SchedPolicy > 0 z.SchedPolicy = state.Shim.SchedPolicy + z.SchedPriority = state.Shim.SchedPriority z.Params = *stateParams.params z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr diff --git a/test/test.py b/test/test.py index 57cf208..571b71d 100644 --- a/test/test.py +++ b/test/test.py @@ -210,10 +210,10 @@ print(machine.succeed('grep "shim: got SIGCONT from unexpected process$" /tmp/sh sched_unset = int(machine.succeed("sudo -u alice -i hakurei -v run cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) if sched_unset != 0: raise Exception(f"unexpected unset policy: {sched_unset}") -sched_idle = int(machine.succeed("sudo -u alice -i hakurei -v run --sched=idle cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) +sched_idle = int(machine.succeed("sudo -u alice -i hakurei -v run --policy=idle cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) if sched_idle != 5: raise Exception(f"unexpected idle policy: {sched_idle}") -sched_rr = int(machine.succeed("sudo -u alice -i hakurei -v run --sched=rr cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) +sched_rr = int(machine.succeed("sudo -u alice -i hakurei -v run --policy=rr cat /proc/self/sched | grep '^policy' | tr -d ' ' | cut -d ':' -f 2")) if sched_rr != 2: raise Exception(f"unexpected round-robin policy: {sched_idle}")