diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-08-18 20:59:37 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-08-18 21:21:47 +0200 |
commit | 2d0a0c0d297f82891faee9e3a1a286d6f20fbdd2 (patch) | |
tree | 36ad5957b6246b144ed2d2d55b40efeb5c7fd11a /pkg/rootlessport | |
parent | a3d8b48fd56a722642f7cbcad52b2fa88f12b656 (diff) | |
download | podman-2d0a0c0d297f82891faee9e3a1a286d6f20fbdd2.tar.gz podman-2d0a0c0d297f82891faee9e3a1a286d6f20fbdd2.tar.bz2 podman-2d0a0c0d297f82891faee9e3a1a286d6f20fbdd2.zip |
fix rootlessport flake
When the rootlessport process is started the stdout/stderr are attached
to the podman process. However once everything is setup podman exits and
when the rootlessport process tries to write to stdout it will fail with
SIGPIPE. The code handles this signal and puts /dev/null to stdout and
stderr but this is not robust. I do not understand the exact cause but
sometimes the process is still killed by SIGPIPE. Either go lost the
signal or the process got already killed before the goroutine could
handle it.
Instead of handling SIGPIPE just set /dev/null to stdout and stderr
before podman exits. With this there should be no race and no way to
run into SIGPIPE errors.
[NO TESTS NEEDED]
Fixes #11248
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'pkg/rootlessport')
-rw-r--r-- | pkg/rootlessport/rootlessport_linux.go | 35 |
1 files changed, 9 insertions, 26 deletions
diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index ede216bfe..9a2f93f8e 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -20,7 +20,6 @@ import ( "net" "os" "os/exec" - "os/signal" "path/filepath" "github.com/containernetworking/plugins/pkg/ns" @@ -106,30 +105,6 @@ func parent() error { return err } - exitC := make(chan os.Signal, 1) - defer close(exitC) - - go func() { - sigC := make(chan os.Signal, 1) - signal.Notify(sigC, unix.SIGPIPE) - defer func() { - signal.Stop(sigC) - close(sigC) - }() - - select { - case s := <-sigC: - if s == unix.SIGPIPE { - if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil { - unix.Dup2(int(f.Fd()), 1) // nolint:errcheck - unix.Dup2(int(f.Fd()), 2) // nolint:errcheck - f.Close() - } - } - case <-exitC: - } - }() - socketDir := filepath.Join(cfg.TmpDir, "rp") err = os.MkdirAll(socketDir, 0700) if err != nil { @@ -251,8 +226,16 @@ outer: go serve(socket, driver) } - // write and close ReadyFD (convention is same as slirp4netns --ready-fd) logrus.Info("ready") + + // https://github.com/containers/podman/issues/11248 + // Copy /dev/null to stdout and stderr to prevent SIGPIPE errors + if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil { + unix.Dup2(int(f.Fd()), 1) // nolint:errcheck + unix.Dup2(int(f.Fd()), 2) // nolint:errcheck + f.Close() + } + // write and close ReadyFD (convention is same as slirp4netns --ready-fd) if _, err := readyW.Write([]byte("1")); err != nil { return err } |