aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/container.go
diff options
context:
space:
mode:
Diffstat (limited to 'container/container.go')
-rw-r--r--container/container.go42
1 files changed, 27 insertions, 15 deletions
diff --git a/container/container.go b/container/container.go
index 480452cd..d45d7a97 100644
--- a/container/container.go
+++ b/container/container.go
@@ -53,7 +53,7 @@ type (
ExtraFiles []*os.File
// Write end of a pipe connected to the init to deliver [Params].
- setup *os.File
+ setup [2]*os.File
// Cancels the context passed to the underlying cmd.
cancel context.CancelFunc
// Closed after Wait returns. Keeps the spawning thread alive.
@@ -287,14 +287,16 @@ func (p *Container) Start() error {
}
// place setup pipe before user supplied extra files, this is later restored by init
- if fd, f, err := Setup(&p.cmd.ExtraFiles); err != nil {
+ if r, w, err := os.Pipe(); err != nil {
return &StartError{
Fatal: true,
Step: "set up params stream",
Err: err,
}
} else {
- p.setup = f
+ fd := 3 + len(p.cmd.ExtraFiles)
+ p.cmd.ExtraFiles = append(p.cmd.ExtraFiles, r)
+ p.setup[0], p.setup[1] = r, w
p.cmd.Env = []string{setupEnv + "=" + strconv.Itoa(fd)}
}
p.cmd.ExtraFiles = append(p.cmd.ExtraFiles, p.ExtraFiles...)
@@ -428,14 +430,30 @@ func (p *Container) Start() error {
// Serve serves [Container.Params] to the container init.
//
// Serve must only be called once.
-func (p *Container) Serve() error {
- if p.setup == nil {
+func (p *Container) Serve() (err error) {
+ if p.setup[0] == nil || p.setup[1] == nil {
panic("invalid serve")
}
+ defer func() {
+ if closeErr := p.setup[1].Close(); err == nil {
+ err = closeErr
+ }
+
+ if err != nil {
+ p.cancel()
+ }
+ p.setup[0], p.setup[1] = nil, nil
+ }()
+ if err = p.setup[0].Close(); err != nil {
+ return &StartError{
+ Fatal: true,
+ Step: "close read end of init pipe",
+ Err: err,
+ Passthrough: true,
+ }
+ }
- setup := p.setup
- p.setup = nil
- if err := setup.SetDeadline(time.Now().Add(initSetupTimeout)); err != nil {
+ if err = p.setup[1].SetDeadline(time.Now().Add(initSetupTimeout)); err != nil {
return &StartError{
Fatal: true,
Step: "set init pipe deadline",
@@ -445,7 +463,6 @@ func (p *Container) Serve() error {
}
if p.Path == nil {
- p.cancel()
return &StartError{
Step: "invalid executable pathname",
Err: EINVAL,
@@ -461,18 +478,13 @@ func (p *Container) Serve() error {
p.SeccompRules = make([]std.NativeRule, 0)
}
- err := gob.NewEncoder(setup).Encode(&initParams{
+ return gob.NewEncoder(p.setup[1]).Encode(&initParams{
p.Params,
Getuid(),
Getgid(),
len(p.ExtraFiles),
p.msg.IsVerbose(),
})
- _ = setup.Close()
- if err != nil {
- p.cancel()
- }
- return err
}
// Wait blocks until the container init process to exit and releases any