mirror of
https://github.com/containers/podman
synced 2024-10-22 10:13:33 +00:00
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>
This commit is contained in:
parent
a3d8b48fd5
commit
2d0a0c0d29
|
@ -20,7 +20,6 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
|
@ -106,30 +105,6 @@ func parent() error {
|
||||||
return err
|
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")
|
socketDir := filepath.Join(cfg.TmpDir, "rp")
|
||||||
err = os.MkdirAll(socketDir, 0700)
|
err = os.MkdirAll(socketDir, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -251,8 +226,16 @@ outer:
|
||||||
go serve(socket, driver)
|
go serve(socket, driver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// write and close ReadyFD (convention is same as slirp4netns --ready-fd)
|
|
||||||
logrus.Info("ready")
|
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 {
|
if _, err := readyW.Write([]byte("1")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue