summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/oci_attach_linux.go6
-rw-r--r--libpod/oci_conmon_linux.go37
2 files changed, 33 insertions, 10 deletions
diff --git a/libpod/oci_attach_linux.go b/libpod/oci_attach_linux.go
index 433993edb..fb0a54bff 100644
--- a/libpod/oci_attach_linux.go
+++ b/libpod/oci_attach_linux.go
@@ -200,8 +200,10 @@ func setupStdioChannels(streams *AttachStreams, conn *net.UnixConn, detachKeys [
var err error
if streams.AttachInput {
_, err = utils.CopyDetachable(conn, streams.InputStream, detachKeys)
- if connErr := conn.CloseWrite(); connErr != nil {
- logrus.Errorf("unable to close conn: %q", connErr)
+ if err == nil {
+ if connErr := conn.CloseWrite(); connErr != nil {
+ logrus.Errorf("unable to close conn: %q", connErr)
+ }
}
}
stdinDone <- err
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index ce888c690..6a0097b8e 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -575,13 +575,36 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, httpConn net.Conn, httpBuf
}
}
+// isRetryable returns whether the error was caused by a blocked syscall or the
+// specified operation on a non blocking file descriptor wasn't ready for completion.
+func isRetryable(err error) bool {
+ if errno, isErrno := errors.Cause(err).(syscall.Errno); isErrno {
+ return errno == syscall.EINTR || errno == syscall.EAGAIN
+ }
+ return false
+}
+
+// openControlFile opens the terminal control file.
+func openControlFile(ctr *Container, parentDir string) (*os.File, error) {
+ controlPath := filepath.Join(parentDir, "ctl")
+ for i := 0; i < 600; i++ {
+ controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY|unix.O_NONBLOCK, 0)
+ if err == nil {
+ return controlFile, err
+ }
+ if !isRetryable(err) {
+ return nil, errors.Wrapf(err, "could not open ctl file for terminal resize for container %s", ctr.ID())
+ }
+ time.Sleep(time.Second / 10)
+ }
+ return nil, errors.Errorf("timeout waiting for %q", controlPath)
+}
+
// AttachResize resizes the terminal used by the given container.
func (r *ConmonOCIRuntime) AttachResize(ctr *Container, newSize remotecommand.TerminalSize) error {
- // TODO: probably want a dedicated function to get ctl file path?
- controlPath := filepath.Join(ctr.bundlePath(), "ctl")
- controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY, 0)
+ controlFile, err := openControlFile(ctr, ctr.bundlePath())
if err != nil {
- return errors.Wrapf(err, "could not open ctl file for terminal resize")
+ return err
}
defer controlFile.Close()
@@ -785,11 +808,9 @@ func (r *ConmonOCIRuntime) ExecContainer(c *Container, sessionID string, options
// ExecAttachResize resizes the TTY of the given exec session.
func (r *ConmonOCIRuntime) ExecAttachResize(ctr *Container, sessionID string, newSize remotecommand.TerminalSize) error {
- // TODO: probably want a dedicated function to get ctl file path?
- controlPath := filepath.Join(ctr.execBundlePath(sessionID), "ctl")
- controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY, 0)
+ controlFile, err := openControlFile(ctr, ctr.execBundlePath(sessionID))
if err != nil {
- return errors.Wrapf(err, "could not open ctl file for terminal resize for container %s exec session %s", ctr.ID(), sessionID)
+ return err
}
defer controlFile.Close()