metropolis/node/core: fix invalid write in console setup
When configuring the console writers, we are iterating over a slice of
console structs, this is fine by itself, but we are also storing a
reference to the logtree reader. Since we are iterating over a struct
value and aren't using a pointer, this write won't persist into the
underlying slice and we cannot close the reader anymore. By using a
pointer to a struct instead of the raw value the issue is fixed.
Change-Id: Iaf753345cd275a03aecf9748b344c60eefcf9d69
Reviewed-on: https://review.monogon.dev/c/monogon/+/2973
Tested-by: Jenkins CI
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/node/core/main.go b/metropolis/node/core/main.go
index eb0e0e8..ba6e9fa 100644
--- a/metropolis/node/core/main.go
+++ b/metropolis/node/core/main.go
@@ -19,7 +19,6 @@
import (
"context"
"fmt"
- "io"
"net"
"os"
"strings"
@@ -55,7 +54,7 @@
// Set up logger for Metropolis. Currently logs everything to /dev/tty0 and
// /dev/ttyS{0,1}.
- consoles := []console{
+ consoles := []*console{
{
path: "/dev/tty0",
maxWidth: 80,
@@ -74,8 +73,8 @@
crash := make(chan string)
// Open up consoles and set up logging from logtree and crash channel.
- for _, console := range consoles {
- f, err := os.OpenFile(console.path, os.O_WRONLY, 0)
+ for _, c := range consoles {
+ f, err := os.OpenFile(c.path, os.O_WRONLY, 0)
if err != nil {
continue
}
@@ -83,20 +82,20 @@
if err != nil {
panic(fmt.Errorf("could not set up root log reader: %v", err))
}
- console.reader = reader
- go func(path string, maxWidth int, f io.Writer) {
- fmt.Fprintf(f, "\nMetropolis: this is %s. Verbose node logs follow.\n\n", path)
+ c.reader = reader
+ go func() {
+ fmt.Fprintf(f, "\nMetropolis: this is %s. Verbose node logs follow.\n\n", c.path)
for {
select {
case p := <-reader.Stream:
if consoleFilter(p) {
- fmt.Fprintf(f, "%s\n", p.ConciseString(logtree.MetropolisShortenDict, maxWidth))
+ fmt.Fprintf(f, "%s\n", p.ConciseString(logtree.MetropolisShortenDict, c.maxWidth))
}
case s := <-crash:
fmt.Fprintf(f, "%s\n", s)
}
}
- }(console.path, console.maxWidth, f)
+ }()
}
// Initialize persistent panic handler early
@@ -244,12 +243,12 @@
ctxC()
time.Sleep(time.Second)
// After a bit, kill all console log readers.
- for _, console := range consoles {
- if console.reader == nil {
+ for _, c := range consoles {
+ if c.reader == nil {
continue
}
- console.reader.Close()
- console.reader.Stream = nil
+ c.reader.Close()
+ c.reader.Stream = nil
}
// Wait for final logs to flush to console...
time.Sleep(time.Second)
diff --git a/metropolis/node/core/panichandler.go b/metropolis/node/core/panichandler.go
index 7a6534b..f1b4c6f 100644
--- a/metropolis/node/core/panichandler.go
+++ b/metropolis/node/core/panichandler.go
@@ -54,7 +54,7 @@
return int32(err)
}
-func initPanicHandler(lt *logtree.LogTree, consoles []console) {
+func initPanicHandler(lt *logtree.LogTree, consoles []*console) {
l := lt.MustLeveledFor("panichandler")
// Setup pstore userspace message buffer
@@ -66,11 +66,11 @@
runtimeFds = append(runtimeFds, fd)
}
- for _, console := range consoles {
- fd, err := unix.Open(console.path, os.O_WRONLY, 0)
+ for _, c := range consoles {
+ fd, err := unix.Open(c.path, os.O_WRONLY, 0)
if err == nil {
runtimeFds = append(runtimeFds, fd)
- l.Infof("Panic console: %s", console.path)
+ l.Infof("Panic console: %s", c.path)
}
}