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 <[email protected]>
  • Loading branch information
giuseppe authored and snj33v committed May 31, 2020
1 parent b1b2b15 commit c6ada03
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 c6ada03

Please sign in to comment.