From 9197f566702a39a8844216548ccf703e38c4e33c Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 23 Sep 2020 12:32:34 -0400 Subject: [PATCH 1/3] kola/qemu: transform ConsoleToFile() to ConsoleFile field That way, the builder will be able to just inspect that field to know if the serial console is being redirected. Prep for next patch. --- mantle/cmd/kola/testiso.go | 2 +- mantle/platform/machine/qemuiso/cluster.go | 2 +- mantle/platform/machine/unprivqemu/cluster.go | 2 +- mantle/platform/qemu.go | 12 +++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mantle/cmd/kola/testiso.go b/mantle/cmd/kola/testiso.go index dd62d57c30..d5eda68aa3 100644 --- a/mantle/cmd/kola/testiso.go +++ b/mantle/cmd/kola/testiso.go @@ -185,7 +185,7 @@ func newQemuBuilder(outdir string) (*platform.QemuBuilder, *conf.Conf, error) { } if !builder.InheritConsole { - builder.ConsoleToFile(filepath.Join(outdir, "console.txt")) + builder.ConsoleFile = filepath.Join(outdir, "console.txt") } config, err := conf.EmptyIgnition().Render(kola.IsIgnitionV2()) if err != nil { diff --git a/mantle/platform/machine/qemuiso/cluster.go b/mantle/platform/machine/qemuiso/cluster.go index 94ec8860b5..9389473873 100644 --- a/mantle/platform/machine/qemuiso/cluster.go +++ b/mantle/platform/machine/qemuiso/cluster.go @@ -102,7 +102,7 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl builder.Firmware = qc.flight.opts.Firmware } builder.Hostname = fmt.Sprintf("qemu%d", qc.BaseCluster.AllocateMachineSerial()) - builder.ConsoleToFile(qm.consolePath) + builder.ConsoleFile = qm.consolePath if qc.flight.opts.Memory != "" { memory, err := strconv.ParseInt(qc.flight.opts.Memory, 10, 32) diff --git a/mantle/platform/machine/unprivqemu/cluster.go b/mantle/platform/machine/unprivqemu/cluster.go index 723a36ae0a..40beeaa3b7 100644 --- a/mantle/platform/machine/unprivqemu/cluster.go +++ b/mantle/platform/machine/unprivqemu/cluster.go @@ -104,7 +104,7 @@ func (qc *Cluster) NewMachineWithQemuOptions(userdata *conf.UserData, options pl builder.Firmware = qc.flight.opts.Firmware builder.Swtpm = qc.flight.opts.Swtpm builder.Hostname = fmt.Sprintf("qemu%d", qc.BaseCluster.AllocateMachineSerial()) - builder.ConsoleToFile(qm.consolePath) + builder.ConsoleFile = qm.consolePath if qc.flight.opts.Memory != "" { memory, err := strconv.ParseInt(qc.flight.opts.Memory, 10, 32) diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 31ed7354f6..465b5099a1 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -303,6 +303,9 @@ type QemuBuilder struct { ForceConfigInjection bool configInjected bool + // File to which to redirect the serial console + ConsoleFile string + // Memory defaults to 1024 on most architectures, others it may be 2048 Memory int // Processors < 0 means to use host count, unset means 1, values > 1 are directly used @@ -436,11 +439,6 @@ func virtio(device, args string) string { return fmt.Sprintf("virtio-%s-%s,%s", device, suffix, args) } -// ConsoleToFile configures the instance to have a serial console, logging to `path`. -func (builder *QemuBuilder) ConsoleToFile(path string) { - builder.Append("-display", "none", "-chardev", "file,id=log,path="+path, "-serial", "chardev:log") -} - // EnableUsermodeNetworking configure forwarding for all requested ports, // via usermode network helpers. func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort) { @@ -1307,6 +1305,10 @@ func (builder *QemuBuilder) Exec() (*QemuInstance, error) { fdnum++ } + if builder.ConsoleFile != "" { + builder.Append("-display", "none", "-chardev", "file,id=log,path="+builder.ConsoleFile, "-serial", "chardev:log") + } + // And the custom arguments argv = append(argv, builder.Argv...) From 87ad35f447f2f2540540f8718a8335b131d963ab Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 23 Sep 2020 12:34:14 -0400 Subject: [PATCH 2/3] mantle/qemu: default to `-serial mon:stdio` if not redirecting This restores access to the monitor via `Ctrl-A C` and allows passing through `Ctrl-C` to the guest as before. This used to be what QEMU did by default, but when we added an explicit QMP socket in #1705 it disabled that sugar. Closes: #1725 --- mantle/platform/qemu.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mantle/platform/qemu.go b/mantle/platform/qemu.go index 465b5099a1..354a7b8110 100644 --- a/mantle/platform/qemu.go +++ b/mantle/platform/qemu.go @@ -1307,6 +1307,8 @@ func (builder *QemuBuilder) Exec() (*QemuInstance, error) { if builder.ConsoleFile != "" { builder.Append("-display", "none", "-chardev", "file,id=log,path="+builder.ConsoleFile, "-serial", "chardev:log") + } else { + builder.Append("-serial", "mon:stdio") } // And the custom arguments From 1d128b83241d66e760196adc5506c3083a48ef48 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 23 Sep 2020 12:35:34 -0400 Subject: [PATCH 3/3] kola/qemuexec: add --console-to-file We want kola to be in control of what happens to the serial console. But `runvm` wants to redirect the console to a file. Add a flag to `qemuexec` to make that possible. --- mantle/cmd/kola/qemuexec.go | 8 ++++++++ src/cmdlib.sh | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mantle/cmd/kola/qemuexec.go b/mantle/cmd/kola/qemuexec.go index bf48552a46..3f151107b9 100644 --- a/mantle/cmd/kola/qemuexec.go +++ b/mantle/cmd/kola/qemuexec.go @@ -61,6 +61,8 @@ var ( devshell bool devshellConsole bool + + consoleFile string ) func init() { @@ -81,6 +83,7 @@ func init() { cmdQemuExec.Flags().StringArrayVar(&bindrw, "bind-rw", nil, "Same as above, but writable") cmdQemuExec.Flags().BoolVarP(&forceConfigInjection, "inject-ignition", "", false, "Force injecting Ignition config using guestfs") cmdQemuExec.Flags().BoolVar(&propagateInitramfsFailure, "propagate-initramfs-failure", false, "Error out if the system fails in the initramfs") + cmdQemuExec.Flags().StringVarP(&consoleFile, "console-to-file", "", "", "Filepath in which to save serial console logs") } @@ -114,6 +117,10 @@ func runQemuExec(cmd *cobra.Command, args []string) error { if devshellConsole { devshell = true + + if consoleFile != "" { + return fmt.Errorf("Cannot use console devshell and --console-to-file") + } } if devshell { if directIgnition { @@ -244,6 +251,7 @@ func runQemuExec(cmd *cobra.Command, args []string) error { builder.EnableUsermodeNetworking(h) } builder.InheritConsole = true + builder.ConsoleFile = consoleFile builder.Append(args...) if devshell && !devshellConsole { diff --git a/src/cmdlib.sh b/src/cmdlib.sh index c264f9c3d6..c73eefcb38 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -500,7 +500,8 @@ EOF echo "$@" > "${tmp_builddir}"/cmd.sh touch "${runvm_console}" - kola_args=(kola qemuexec -m 2048 --auto-cpus -U --workdir none) + kola_args=(kola qemuexec -m 2048 --auto-cpus -U --workdir none \ + --console-to-file "${runvm_console}") base_qemu_args=(-drive 'if=none,id=root,format=raw,snapshot=on,file='"${vmbuilddir}"'/root,index=1' \ -device 'virtio-blk,drive=root' -kernel "${vmbuilddir}/kernel" -initrd "${vmbuilddir}/initrd" \ @@ -518,7 +519,6 @@ EOF if [ -z "${RUNVM_SHELL:-}" ]; then if ! "${kola_args[@]}" -- "${base_qemu_args[@]}" \ - -serial file:"${runvm_console}" \ -device virtserialport,chardev=virtioserial0,name=cosa-cmdout \ -chardev stdio,id=virtioserial0 \ "${qemu_args[@]}" <&-; then # the <&- here closes stdin otherwise qemu waits forever