1
0

Add stdout trace for qemu

This commit is contained in:
dump_stack() 2023-04-06 19:50:57 +00:00
parent 483e56163e
commit f57b3408be
Signed by: dump_stack
GPG Key ID: BE44DA8C062D87DC
2 changed files with 35 additions and 32 deletions

View File

@ -257,12 +257,12 @@ func handleLine(q *qemu.System) (err error) {
fmt.Printf("ssh\t: print arguments to ssh command\n") fmt.Printf("ssh\t: print arguments to ssh command\n")
fmt.Printf("quit\t: quit\n") fmt.Printf("quit\t: quit\n")
case "l", "log": case "l", "log":
fmt.Println(string(q.Stdout)) fmt.Println(q.Stdout)
case "cl", "clog": case "cl", "clog":
fmt.Println(string(q.Stdout)) fmt.Println(q.Stdout)
q.Stdout = []byte{} q.Stdout = ""
case "c", "cleanup": case "c", "cleanup":
q.Stdout = []byte{} q.Stdout = ""
case "s", "ssh": case "s", "ssh":
fmt.Println(q.GetSSHCommand()) fmt.Println(q.GetSSHCommand())
case "q", "quit": case "q", "quit":

View File

@ -6,7 +6,6 @@ package qemu
import ( import (
"bufio" "bufio"
"bytes"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -19,30 +18,11 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
) )
func readUntilEOF(pipe io.ReadCloser, buf *[]byte) (err error) {
bufSize := 1024
for err != io.EOF {
stdout := make([]byte, bufSize)
var n int
n, err = pipe.Read(stdout)
if err != nil && err != io.EOF {
return
}
*buf = append(*buf, stdout[:n]...)
}
if err == io.EOF {
err = nil
}
return
}
type arch string type arch string
const ( const (
@ -98,18 +78,25 @@ type System struct {
stdout io.ReadCloser stdout io.ReadCloser
} }
Stdout, Stderr []byte Stdout, Stderr string
// accessible after qemu is closed // accessible after qemu is closed
exitErr error exitErr error
log zerolog.Logger
} }
// NewSystem constructor // NewSystem constructor
func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error) { func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error) {
q = &System{}
q.log = log.With().
Str("kernel", kernel.KernelPath).
Logger()
if _, err = exec.LookPath("qemu-system-" + string(arch)); err != nil { if _, err = exec.LookPath("qemu-system-" + string(arch)); err != nil {
return return
} }
q = &System{}
q.arch = arch q.arch = arch
if _, err = os.Stat(kernel.KernelPath); err != nil { if _, err = os.Stat(kernel.KernelPath); err != nil {
@ -188,11 +175,12 @@ func kvmExists() bool {
func (q *System) panicWatcher() { func (q *System) panicWatcher() {
for { for {
time.Sleep(time.Second) time.Sleep(time.Second)
if bytes.Contains(q.Stdout, []byte("Kernel panic")) { if strings.Contains(q.Stdout, "Kernel panic") {
q.KernelPanic = true
q.log.Debug().Msg("kernel panic")
time.Sleep(time.Second) time.Sleep(time.Second)
// There is no reason to stay alive after kernel panic // There is no reason to stay alive after kernel panic
q.Stop() q.Stop()
q.KernelPanic = true
return return
} }
} }
@ -259,7 +247,7 @@ func (q *System) Start() (err error) {
qemuArgs = append(qemuArgs, "-append", q.cmdline()) qemuArgs = append(qemuArgs, "-append", q.cmdline())
q.cmd = exec.Command("qemu-system-"+string(q.arch), qemuArgs...) q.cmd = exec.Command("qemu-system-"+string(q.arch), qemuArgs...)
log.Debug().Msgf("%v", q.cmd) q.log.Debug().Msgf("%v", q.cmd)
if q.pipe.stdin, err = q.cmd.StdinPipe(); err != nil { if q.pipe.stdin, err = q.cmd.StdinPipe(); err != nil {
return return
@ -278,8 +266,23 @@ func (q *System) Start() (err error) {
return return
} }
go readUntilEOF(q.pipe.stdout, &q.Stdout) go func() {
go readUntilEOF(q.pipe.stderr, &q.Stderr) scanner := bufio.NewScanner(q.pipe.stdout)
for scanner.Scan() {
m := scanner.Text()
q.Stdout += m + "\n"
q.log.Trace().Str("stdout", m).Msg("")
}
}()
go func() {
scanner := bufio.NewScanner(q.pipe.stderr)
for scanner.Scan() {
m := scanner.Text()
q.Stderr += m + "\n"
q.log.Trace().Str("stderr", m).Msg("")
}
}()
go func() { go func() {
q.exitErr = q.cmd.Wait() q.exitErr = q.cmd.Wait()