summaryrefslogtreecommitdiff
path: root/libpod/container_attach_linux.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2019-05-14 14:54:21 -0400
committerMatthew Heon <matthew.heon@pm.me>2019-05-14 14:54:21 -0400
commitd83d0abfbf6f914303c1b33d954aa115accbd999 (patch)
tree1842018b4c49e4c2a379de239833cb8f6bbda229 /libpod/container_attach_linux.go
parenta261b60cc8851c04efd191be6f6e2e4598439822 (diff)
downloadpodman-d83d0abfbf6f914303c1b33d954aa115accbd999.tar.gz
podman-d83d0abfbf6f914303c1b33d954aa115accbd999.tar.bz2
podman-d83d0abfbf6f914303c1b33d954aa115accbd999.zip
Ensure that start() in StartAndAttach() is locked
StartAndAttach() runs start() in a goroutine, which can allow it to fire after the caller returns - and thus, after the defer to unlock the container lock has fired. The start() call _must_ occur while the container is locked, or else state inconsistencies may occur. Fixes #3114 Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/container_attach_linux.go')
-rw-r--r--libpod/container_attach_linux.go17
1 files changed, 13 insertions, 4 deletions
diff --git a/libpod/container_attach_linux.go b/libpod/container_attach_linux.go
index 3ff6ddc76..7e9b7697b 100644
--- a/libpod/container_attach_linux.go
+++ b/libpod/container_attach_linux.go
@@ -8,6 +8,7 @@ import (
"net"
"os"
"path/filepath"
+ "sync"
"github.com/containers/libpod/pkg/kubeutils"
"github.com/containers/libpod/utils"
@@ -31,7 +32,7 @@ const (
// Attach to the given container
// Does not check if state is appropriate
-func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool) error {
+func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan remotecommand.TerminalSize, startContainer bool, wg *sync.WaitGroup) error {
if !streams.AttachOutput && !streams.AttachError && !streams.AttachInput {
return errors.Wrapf(ErrInvalidArg, "must provide at least one stream to attach to")
}
@@ -48,12 +49,17 @@ func (c *Container) attach(streams *AttachStreams, keys string, resize <-chan re
logrus.Debugf("Attaching to container %s", c.ID())
- return c.attachContainerSocket(resize, detachKeys, streams, startContainer)
+ return c.attachContainerSocket(resize, detachKeys, streams, startContainer, wg)
}
-// attachContainerSocket connects to the container's attach socket and deals with the IO
+// attachContainerSocket connects to the container's attach socket and deals with the IO.
+// wg is only required if startContainer is true
// TODO add a channel to allow interrupting
-func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, detachKeys []byte, streams *AttachStreams, startContainer bool) error {
+func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSize, detachKeys []byte, streams *AttachStreams, startContainer bool, wg *sync.WaitGroup) error {
+ if startContainer && wg == nil {
+ return errors.Wrapf(ErrInternal, "wait group not passed when startContainer set")
+ }
+
kubeutils.HandleResizing(resize, func(size remotecommand.TerminalSize) {
controlPath := filepath.Join(c.bundlePath(), "ctl")
controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY, 0)
@@ -84,10 +90,13 @@ func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSi
}
defer conn.Close()
+ // If starting was requested, start the container and notify when that's
+ // done.
if startContainer {
if err := c.start(); err != nil {
return err
}
+ wg.Done()
}
receiveStdoutError := make(chan error)