diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-07-29 03:06:49 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-07-29 03:06:49 +0900 |
| commit | f7bd28118c4ac34a9a444073b31ca8f2579188f3 (patch) | |
| tree | d094700b4d367250e9de16226cc7cc49a0dc3b55 /internal | |
| parent | 940ee00ffee9208a244a99ff085a981c1af1d7c4 (diff) | |
hst: configurable wait delay
This is useful for programs that take a long time to clean up.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/app/container_linux.go | 2 | ||||
| -rw-r--r-- | internal/app/errors.go (renamed from internal/app/errors_linux.go) | 0 | ||||
| -rw-r--r-- | internal/app/process_linux.go | 10 | ||||
| -rw-r--r-- | internal/app/seal_linux.go | 3 | ||||
| -rw-r--r-- | internal/app/shim_linux.go | 18 | ||||
| -rw-r--r-- | internal/app/strings.go (renamed from internal/app/strings_linux.go) | 0 |
6 files changed, 27 insertions, 6 deletions
diff --git a/internal/app/container_linux.go b/internal/app/container_linux.go index baea57d9..5efd3de7 100644 --- a/internal/app/container_linux.go +++ b/internal/app/container_linux.go @@ -35,7 +35,7 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain // the container is canceled when shim is requested to exit or receives an interrupt or termination signal; // this behaviour is implemented in the shim - ForwardCancel: !s.ImmediateTermination, + ForwardCancel: s.WaitDelay >= 0, } { diff --git a/internal/app/errors_linux.go b/internal/app/errors.go index b9bd6f57..b9bd6f57 100644 --- a/internal/app/errors_linux.go +++ b/internal/app/errors.go diff --git a/internal/app/process_linux.go b/internal/app/process_linux.go index 818c7d7b..516beb4b 100644 --- a/internal/app/process_linux.go +++ b/internal/app/process_linux.go @@ -123,7 +123,15 @@ func (seal *outcome) Run(rs *RunState) error { // this prevents blocking forever on an early failure waitErr, setupErr := make(chan error, 1), make(chan error, 1) go func() { waitErr <- cmd.Wait(); cancel() }() - go func() { setupErr <- e.Encode(&shimParams{os.Getpid(), seal.container, seal.user.data, hlog.Load()}) }() + go func() { + setupErr <- e.Encode(&shimParams{ + os.Getpid(), + seal.waitDelay, + seal.container, + seal.user.data, + hlog.Load(), + }) + }() select { case err := <-setupErr: diff --git a/internal/app/seal_linux.go b/internal/app/seal_linux.go index 40c68c1b..13257211 100644 --- a/internal/app/seal_linux.go +++ b/internal/app/seal_linux.go @@ -15,6 +15,7 @@ import ( "strings" "sync/atomic" "syscall" + "time" "hakurei.app/container" "hakurei.app/hst" @@ -79,6 +80,7 @@ type outcome struct { sys *system.I ctx context.Context + waitDelay time.Duration container *container.Params env map[string]string sync *os.File @@ -281,6 +283,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co var uid, gid int var err error seal.container, seal.env, err = newContainer(config.Container, sys, &uid, &gid) + seal.waitDelay = config.Container.WaitDelay if err != nil { return hlog.WrapErrSuffix(err, "cannot initialise container configuration:") diff --git a/internal/app/shim_linux.go b/internal/app/shim_linux.go index c88c8672..e423b321 100644 --- a/internal/app/shim_linux.go +++ b/internal/app/shim_linux.go @@ -28,6 +28,10 @@ type shimParams struct { // monitor pid, checked against ppid in signal handler Monitor int + // duration to wait for after interrupting a container's initial process before the container is killed; + // zero value defaults to [DefaultShimWaitDelay], values exceeding [MaxShimWaitDelay] becomes [MaxShimWaitDelay] + WaitDelay time.Duration + // finalised container params Container *container.Params // path to outer home directory @@ -43,9 +47,8 @@ const ( // ShimExitOrphan is returned when the shim is orphaned before monitor delivers a signal. ShimExitOrphan = 3 - // ShimWaitDelay is the duration to wait after interrupting a container's initial process - // before the container is fully killed off. - ShimWaitDelay = 5 * time.Second + DefaultShimWaitDelay = 5 * time.Second + MaxShimWaitDelay = 30 * time.Second ) // ShimMain is the main function of the shim process and runs as the unconstrained target user. @@ -163,7 +166,14 @@ func ShimMain() { z := container.New(ctx, name) z.Params = *params.Container z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr - z.WaitDelay = ShimWaitDelay + + z.WaitDelay = params.WaitDelay + if z.WaitDelay == 0 { + z.WaitDelay = DefaultShimWaitDelay + } + if z.WaitDelay > MaxShimWaitDelay { + z.WaitDelay = MaxShimWaitDelay + } if err := z.Start(); err != nil { hlog.PrintBaseError(err, "cannot start container:") diff --git a/internal/app/strings_linux.go b/internal/app/strings.go index e4465cee..e4465cee 100644 --- a/internal/app/strings_linux.go +++ b/internal/app/strings.go |
