podman events: fix error race

The events code makes use of two channels, one for the events and one
for the resulting error. Then in the main file we have a loop reading
from both channels that should exit on first error it gets.

However in case the event channel is closed before the error channel
cotains the error it could caused an early exit as it looked like all
events were done. Commit c46884aa93 fixed that somewhat by checking for
an error in the error channel before exiting. This however was still
racy as it added a default case in the select which means the channel
check is non blocking. Thus the error was not yet send into the channel.

To fix this we should make it a blocking read to wait for the error in
the channel. Also the err != nil check can be removed as we either
return err or nil anyway.

And as last step make sure the error channel is closed, that prevents us
from blocking forever in case the main select already processed the nil
error.

Fixes #23165

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2024-07-03 11:11:51 +02:00
parent b5bfd7233b
commit d00e68e550
No known key found for this signature in database
GPG Key ID: EB145DD938A3CAF2
1 changed files with 3 additions and 8 deletions

View File

@ -163,6 +163,7 @@ func eventsCmd(cmd *cobra.Command, _ []string) error {
go func() {
errChannel <- registry.ContainerEngine().Events(context.Background(), eventOptions)
close(errChannel)
}()
for {
@ -170,14 +171,8 @@ func eventsCmd(cmd *cobra.Command, _ []string) error {
case event, ok := <-eventChannel:
if !ok {
// channel was closed we can exit
select {
case err := <-errChannel:
if err != nil {
return err
}
default:
}
return nil
// read the error channel blocking to make sure we are not missing any errors (#23165)
return <-errChannel
}
switch {
case doJSON: