diff options
author | Matthew Heon <matthew.heon@pm.me> | 2020-07-01 16:21:57 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2020-07-02 09:57:39 -0400 |
commit | 9e4cf6ca513fa0646f33ade14955e1fc4335e176 (patch) | |
tree | 9c820378fb4e2d0873ca24da5766691ffc4b6ccd /libpod/events | |
parent | 1a1e3f4b24e6f856a5c2e16da0cc34a8191c9403 (diff) | |
download | podman-9e4cf6ca513fa0646f33ade14955e1fc4335e176.tar.gz podman-9e4cf6ca513fa0646f33ade14955e1fc4335e176.tar.bz2 podman-9e4cf6ca513fa0646f33ade14955e1fc4335e176.zip |
Fix `system service` panic from early hangup in events
We weren't actually halting the goroutine that sent events, so it
would continue sending even when the channel closed (the most
notable cause being early hangup - e.g. Control-c on a curl
session). Use a context to cancel the events goroutine and stop
sending events.
Fixes #6805
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'libpod/events')
-rw-r--r-- | libpod/events/config.go | 3 | ||||
-rw-r--r-- | libpod/events/journal_linux.go | 3 | ||||
-rw-r--r-- | libpod/events/logfile.go | 17 | ||||
-rw-r--r-- | libpod/events/nullout.go | 6 |
4 files changed, 24 insertions, 5 deletions
diff --git a/libpod/events/config.go b/libpod/events/config.go index 8fe551c5d..c34408e63 100644 --- a/libpod/events/config.go +++ b/libpod/events/config.go @@ -1,6 +1,7 @@ package events import ( + "context" "time" "github.com/pkg/errors" @@ -52,7 +53,7 @@ type Eventer interface { // Write an event to a backend Write(event Event) error // Read an event from the backend - Read(options ReadOptions) error + Read(ctx context.Context, options ReadOptions) error // String returns the type of event logger String() string } diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 482435038..d341ca7b5 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -3,6 +3,7 @@ package events import ( + "context" "fmt" "strconv" "time" @@ -53,7 +54,7 @@ func (e EventJournalD) Write(ee Event) error { } // Read reads events from the journal and sends qualified events to the event channel -func (e EventJournalD) Read(options ReadOptions) error { +func (e EventJournalD) Read(ctx context.Context, options ReadOptions) error { defer close(options.EventChannel) eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until) if err != nil { diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go index 93e6fa3c9..28d0dc07e 100644 --- a/libpod/events/logfile.go +++ b/libpod/events/logfile.go @@ -1,6 +1,7 @@ package events import ( + "context" "fmt" "os" @@ -40,7 +41,7 @@ func (e EventLogFile) Write(ee Event) error { } // Reads from the log file -func (e EventLogFile) Read(options ReadOptions) error { +func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error { defer close(options.EventChannel) eventOptions, err := generateEventOptions(options.Filters, options.Since, options.Until) if err != nil { @@ -50,6 +51,17 @@ func (e EventLogFile) Read(options ReadOptions) error { if err != nil { return err } + funcDone := make(chan bool) + copy := true + go func() { + select { + case <-funcDone: + // Do nothing + case <-ctx.Done(): + copy = false + t.Kill(errors.New("hangup by client")) + } + }() for line := range t.Lines { event, err := newEventFromJSONString(line.Text) if err != nil { @@ -65,10 +77,11 @@ func (e EventLogFile) Read(options ReadOptions) error { for _, filter := range eventOptions { include = include && filter(event) } - if include { + if include && copy { options.EventChannel <- event } } + funcDone <- true return nil } diff --git a/libpod/events/nullout.go b/libpod/events/nullout.go index f3b36e609..3eca9e8db 100644 --- a/libpod/events/nullout.go +++ b/libpod/events/nullout.go @@ -1,5 +1,9 @@ package events +import ( + "context" +) + // EventToNull is an eventer type that only performs write operations // and only writes to /dev/null. It is meant for unittests only type EventToNull struct{} @@ -10,7 +14,7 @@ func (e EventToNull) Write(ee Event) error { } // Read does nothing. Do not use it. -func (e EventToNull) Read(options ReadOptions) error { +func (e EventToNull) Read(ctx context.Context, options ReadOptions) error { return nil } |