Skip to content

Commit

Permalink
fix rootlessport flake
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Luap99 committed Aug 18, 2021
1 parent a3d8b48 commit 2d0a0c0
Showing 1 changed file with 9 additions and 26 deletions.
35 changes: 9 additions & 26 deletions pkg/rootlessport/rootlessport_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"net"
"os"
"os/exec"
"os/signal"
"path/filepath"

"github.com/containernetworking/plugins/pkg/ns"
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit 2d0a0c0

Please sign in to comment.