container: start from locked thread
Some checks failed
Test / Sandbox (push) Successful in 2m28s
Test / Hakurei (race detector) (push) Failing after 2m52s
Test / Hakurei (push) Successful in 3m21s
Test / Hpkg (push) Successful in 4m27s
Test / Create distribution (push) Successful in 34s
Test / Flake checks (push) Has been skipped
Test / Sandbox (race detector) (push) Failing after 1m44s
Some checks failed
Test / Sandbox (push) Successful in 2m28s
Test / Hakurei (race detector) (push) Failing after 2m52s
Test / Hakurei (push) Successful in 3m21s
Test / Hpkg (push) Successful in 4m27s
Test / Create distribution (push) Successful in 34s
Test / Flake checks (push) Has been skipped
Test / Sandbox (race detector) (push) Failing after 1m44s
This allows setup that relies on per-thread state like securebits and landlock, from the parent side. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
f35733810e
commit
c72a35ef72
@ -9,6 +9,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
"time"
|
"time"
|
||||||
@ -36,6 +37,8 @@ type (
|
|||||||
setup *gob.Encoder
|
setup *gob.Encoder
|
||||||
// cancels cmd
|
// cancels cmd
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
// closed after Wait returns
|
||||||
|
wait chan struct{}
|
||||||
|
|
||||||
Stdin io.Reader
|
Stdin io.Reader
|
||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
@ -170,11 +173,23 @@ func (p *Container) Start() error {
|
|||||||
}
|
}
|
||||||
p.cmd.ExtraFiles = append(p.cmd.ExtraFiles, p.ExtraFiles...)
|
p.cmd.ExtraFiles = append(p.cmd.ExtraFiles, p.ExtraFiles...)
|
||||||
|
|
||||||
|
done := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
runtime.LockOSThread()
|
||||||
|
p.wait = make(chan struct{})
|
||||||
|
|
||||||
|
done <- func() error { // setup depending on per-thread state must happen here
|
||||||
msg.Verbose("starting container init")
|
msg.Verbose("starting container init")
|
||||||
if err := p.cmd.Start(); err != nil {
|
if err := p.cmd.Start(); err != nil {
|
||||||
return msg.WrapErr(err, err.Error())
|
return msg.WrapErr(err, err.Error())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
}()
|
||||||
|
|
||||||
|
// keep this thread alive until Wait returns for cancel
|
||||||
|
<-p.wait
|
||||||
|
}()
|
||||||
|
return <-done
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serve serves [Container.Params] to the container init.
|
// Serve serves [Container.Params] to the container init.
|
||||||
@ -215,8 +230,18 @@ func (p *Container) Serve() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait waits for the container init process to exit.
|
// Wait waits for the container init process to exit and releases any resources associated with the [Container].
|
||||||
func (p *Container) Wait() error { defer p.cancel(); return p.cmd.Wait() }
|
func (p *Container) Wait() error {
|
||||||
|
if p.wait == nil {
|
||||||
|
if p.cmd != nil {
|
||||||
|
// pass through error from Cmd
|
||||||
|
return p.cmd.Wait()
|
||||||
|
}
|
||||||
|
return EINVAL
|
||||||
|
}
|
||||||
|
defer func() { close(p.wait); p.cancel(); p.wait = nil }()
|
||||||
|
return p.cmd.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Container) String() string {
|
func (p *Container) String() string {
|
||||||
return fmt.Sprintf("argv: %q, filter: %v, rules: %d, flags: %#x, presets: %#x",
|
return fmt.Sprintf("argv: %q, filter: %v, rules: %d, flags: %#x, presets: %#x",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user