summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2020-02-12 14:57:58 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2020-02-12 18:13:30 +0100
commit2550ded989efc889da1785b07865815b7e1b9415 (patch)
treebf2964ddaed587f3653d0d75f9c37933502599cf
parente22367562515669dc05ed4d5a8980ad6c303fc02 (diff)
downloadpodman-2550ded989efc889da1785b07865815b7e1b9415.tar.gz
podman-2550ded989efc889da1785b07865815b7e1b9415.tar.bz2
podman-2550ded989efc889da1785b07865815b7e1b9415.zip
rootlessport: fix potential hang
write to the error pipe only in case of an error. Otherwise we may end up in a race condition in the select statement below as the read from errChan happens before initComplete and the function returns immediately nil. Closes: https://github.com/containers/libpod/issues/5182 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r--pkg/rootlessport/rootlessport_linux.go20
1 files changed, 14 insertions, 6 deletions
diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go
index 3e678d33a..acdf3198b 100644
--- a/pkg/rootlessport/rootlessport_linux.go
+++ b/pkg/rootlessport/rootlessport_linux.go
@@ -122,6 +122,7 @@ func parent() error {
logrus.WithError(driverErr).Warn("parent driver exited")
}
errCh <- driverErr
+ close(errCh)
}()
opaque := driver.OpaqueForChild()
logrus.Infof("opaque=%+v", opaque)
@@ -142,7 +143,7 @@ func parent() error {
}()
// reexec the child process in the child netns
- cmd := exec.Command(fmt.Sprintf("/proc/%d/exe", os.Getpid()))
+ cmd := exec.Command("/proc/self/exe")
cmd.Args = []string{reexecChildKey}
cmd.Stdin = childQuitR
cmd.Stdout = &logrusWriter{prefix: "child"}
@@ -164,12 +165,19 @@ func parent() error {
logrus.Info("waiting for initComplete")
// wait for the child to connect to the parent
- select {
- case <-initComplete:
- logrus.Infof("initComplete is closed; parent and child established the communication channel")
- case err := <-errCh:
- return err
+outer:
+ for {
+ select {
+ case <-initComplete:
+ logrus.Infof("initComplete is closed; parent and child established the communication channel")
+ break outer
+ case err := <-errCh:
+ if err != nil {
+ return err
+ }
+ }
}
+
defer func() {
logrus.Info("stopping parent driver")
quit <- struct{}{}