From ea50ce6a5915f71e0cf355d2006ad035adf37034 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 31 Oct 2018 11:43:33 +0100 Subject: 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 --- libpod/networking_linux.go | 28 +++++++++++++++++++++++++--- 1 file 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 } -- cgit v1.2.3-54-g00ecf