summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-08-18 20:59:37 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-08-18 21:21:47 +0200
commit2d0a0c0d297f82891faee9e3a1a286d6f20fbdd2 (patch)
tree36ad5957b6246b144ed2d2d55b40efeb5c7fd11a
parenta3d8b48fd56a722642f7cbcad52b2fa88f12b656 (diff)
downloadpodman-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>
-rw-r--r--pkg/rootlessport/rootlessport_linux.go35
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
}