fix: correctly wait for journalctl processes to not leave zombies when streaming machine logs (#325)

* fix: call cmd.Wait()

Even though the context is cancelled we still need to call cmd.Wait()
after a cmd.Start() to clean up the child (reap) process. Not doing so
results in a zombie journalctl.

I have manually tested this, as I'm still not sure how to e2e test for
this in a simple manner.

Before:

```
root@uncloud2:~# ps aux|grep jou
root         313  0.0  1.2  42272 23352 ?        S<s  Apr20   0:10 /usr/lib/systemd/systemd-journald
root       15751  0.0  0.0      0     0 pts/0    Z+   07:02   0:00 [journalctl] <defunct>
root       15754  0.0  0.0      0     0 pts/0    Z+   07:02   0:00 [journalctl] <defunct>
```

After:

```
root         313  0.0  1.2  42272 23592 ?        S<s  Apr20   0:10 /usr/lib/systemd/systemd-journald
```

* follow() doesnt need wait

We can keep the wait function more contraint, as follow does not need it

Signed-off-by: Miek Gieben <miek@miek.nl>

---------

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2026-04-22 19:00:15 +10:00
committed by GitHub
parent b1897ce719
commit 6fb68c22c5
2 changed files with 7 additions and 6 deletions
+2 -1
View File
@@ -16,7 +16,7 @@ func Logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (<-chan
return nil, fmt.Errorf("journal logs: invalid unit: %s", unit)
}
reader, err := logs(ctx, unit, opts)
reader, wait, err := logs(ctx, unit, opts)
if err != nil {
return nil, err
}
@@ -26,6 +26,7 @@ func Logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (<-chan
go func() {
defer close(outCh)
follow(ctx, reader, outCh)
wait()
}()
return outCh, nil