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)
 		}
 	}