Skip to content

Commit f580ae0

Browse files
Merge pull request #23985 from Luap99/wait-hang
wait: fix handling of multiple conditions with exited
2 parents 62c1016 + aa10892 commit f580ae0

File tree

3 files changed

+32
-17
lines changed

3 files changed

+32
-17
lines changed

libpod/container_api.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"io"
1010
"net/http"
1111
"os"
12-
"sync"
1312
"time"
1413

1514
"github.com/containers/common/pkg/resize"
@@ -596,7 +595,7 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
596595

597596
// we cannot wait locked as we would hold the lock forever, so we unlock and then lock again
598597
c.lock.Unlock()
599-
err := waitForConmonExit(conmonPID, conmonPidFd, pollInterval)
598+
err := waitForConmonExit(ctx, conmonPID, conmonPidFd, pollInterval)
600599
c.lock.Lock()
601600
if err != nil {
602601
return -1, fmt.Errorf("failed to wait for conmon to exit: %w", err)
@@ -619,15 +618,24 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
619618
return c.runtime.state.GetContainerExitCode(id)
620619
}
621620

622-
func waitForConmonExit(conmonPID, conmonPidFd int, pollInterval time.Duration) error {
621+
func waitForConmonExit(ctx context.Context, conmonPID, conmonPidFd int, pollInterval time.Duration) error {
623622
if conmonPidFd > -1 {
624623
for {
625624
fds := []unix.PollFd{{Fd: int32(conmonPidFd), Events: unix.POLLIN}}
626-
if _, err := unix.Poll(fds, -1); err != nil {
625+
if n, err := unix.Poll(fds, int(pollInterval.Milliseconds())); err != nil {
627626
if err == unix.EINTR {
628627
continue
629628
}
630629
return err
630+
} else if n == 0 {
631+
// n == 0 means timeout
632+
select {
633+
case <-ctx.Done():
634+
return define.ErrCanceled
635+
default:
636+
// context not done, wait again
637+
continue
638+
}
631639
}
632640
return nil
633641
}
@@ -640,7 +648,11 @@ func waitForConmonExit(conmonPID, conmonPidFd int, pollInterval time.Duration) e
640648
}
641649
return err
642650
}
643-
time.Sleep(pollInterval)
651+
select {
652+
case <-ctx.Done():
653+
return define.ErrCanceled
654+
case <-time.After(pollInterval):
655+
}
644656
}
645657
return nil
646658
}
@@ -695,22 +707,15 @@ func (c *Container) WaitForConditionWithInterval(ctx context.Context, waitTimeou
695707
}
696708
}
697709

698-
var wg sync.WaitGroup
699-
700710
if waitForExit {
701-
wg.Add(1)
702711
go func() {
703-
defer wg.Done()
704-
705712
code, err := c.WaitForExit(ctx, waitTimeout)
706713
trySend(code, err)
707714
}()
708715
}
709716

710717
if len(wantedStates) > 0 || len(wantedHealthStates) > 0 {
711-
wg.Add(1)
712718
go func() {
713-
defer wg.Done()
714719
stoppedCount := 0
715720
for {
716721
if len(wantedStates) > 0 {
@@ -780,7 +785,6 @@ func (c *Container) WaitForConditionWithInterval(ctx context.Context, waitTimeou
780785
case <-ctx.Done():
781786
result = waitResult{-1, define.ErrCanceled}
782787
}
783-
wg.Wait()
784788
return result.code, result.err
785789
}
786790

test/e2e/wait_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,19 @@ var _ = Describe("Podman wait", func() {
108108
Expect(session).Should(ExitCleanly())
109109
Expect(session.OutputToStringArray()).To(Equal([]string{"0", "0", "0"}))
110110
})
111+
112+
It("podman wait on multiple conditions", func() {
113+
session := podmanTest.Podman([]string{"run", "-d", ALPINE, "sleep", "100"})
114+
session.Wait(20)
115+
Expect(session).Should(ExitCleanly())
116+
cid := session.OutputToString()
117+
118+
// condition should return once nay of the condition is met not all of them,
119+
// as the container is running this should return immediately
120+
// https://github.com/containers/podman-py/issues/425
121+
session = podmanTest.Podman([]string{"wait", "--condition", "running,exited", cid})
122+
session.Wait(20)
123+
Expect(session).Should(ExitCleanly())
124+
Expect(session.OutputToString()).To(Equal("-1"))
125+
})
111126
})

test/system/035-logs.bats

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,6 @@ function _log_test_restarted() {
136136
fi
137137
cname="c-ltr-$(safename)"
138138
run_podman run --log-driver=$driver ${events_backend} --name $cname $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log'
139-
# FIXME: #9597
140-
# run/start is flaking for remote so let's wait for the container condition
141-
# to stop wasting energy until the root cause gets fixed.
142-
run_podman container wait --condition=exited --condition=stopped $cname
143139
run_podman ${events_backend} start -a $cname
144140
logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX)
145141
$PODMAN $_PODMAN_TEST_OPTS ${events_backend} logs -f $cname > $logfile

0 commit comments

Comments
 (0)