Skip to content

Commit

Permalink
rootlessport: fix potential hang
Browse files Browse the repository at this point in the history
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: containers#5182

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Feb 12, 2020
1 parent e223675 commit 2550ded
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions pkg/rootlessport/rootlessport_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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"}
Expand All @@ -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{}{}
Expand Down

0 comments on commit 2550ded

Please sign in to comment.