diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2018-10-31 11:43:33 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2018-10-31 13:08:23 +0100 |
commit | ea50ce6a5915f71e0cf355d2006ad035adf37034 (patch) | |
tree | 8157563017e5120afec08d554d74812d538c640d /libpod | |
parent | ee513cca8612bebfda36e31203ab215aa682e8c0 (diff) | |
download | podman-ea50ce6a5915f71e0cf355d2006ad035adf37034.tar.gz podman-ea50ce6a5915f71e0cf355d2006ad035adf37034.tar.bz2 podman-ea50ce6a5915f71e0cf355d2006ad035adf37034.zip |
rootless: avoid hang on failed slirp4netns
If for any reason slirp4netns fails at startup, podman waits
indefinitely. Check every second if the process is still running so
that we avoid to hang.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/networking_linux.go | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 0d9ec2809..863a764e2 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" "syscall" + "time" cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" @@ -134,12 +135,33 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { cmd.ExtraFiles = append(cmd.ExtraFiles, ctr.rootlessSlirpSyncR, syncW) if err := cmd.Start(); err != nil { - return errors.Wrapf(err, "failed to start process") + return errors.Wrapf(err, "failed to start slirp4netns process") } + defer cmd.Process.Release() b := make([]byte, 16) - if _, err := syncR.Read(b); err != nil { - return errors.Wrapf(err, "failed to read from sync pipe") + for { + if err := syncR.SetDeadline(time.Now().Add(1 * time.Second)); err != nil { + return errors.Wrapf(err, "error setting slirp4netns pipe timeout") + } + if _, err := syncR.Read(b); err == nil { + break + } else { + if os.IsTimeout(err) { + // Check if the process is still running. + var status syscall.WaitStatus + _, err := syscall.Wait4(cmd.Process.Pid, &status, syscall.WNOHANG, nil) + if err != nil { + return errors.Wrapf(err, "failed to read slirp4netns process status") + } + if status.Exited() || status.Signaled() { + return errors.New("slirp4netns failed") + } + + continue + } + return errors.Wrapf(err, "failed to read from slirp4netns sync pipe") + } } return nil } |