From 1d1a23134a28df661204f05714574e7f1fdf074c Mon Sep 17 00:00:00 2001 From: Manohar Castelino Date: Fri, 8 Oct 2021 12:48:30 -0700 Subject: [PATCH] qemu: Add support for legacy serial device - Add support for legacy serial device - Additionally add support for the file backend for chardev Legacy serial plus char backend file will allow us to support capture early boot messages. Signed-off-by: Manohar Castelino --- qemu/qemu.go | 50 +++++++++++++++++++++++++++++++++++++++++++++-- qemu/qemu_test.go | 22 +++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/qemu/qemu.go b/qemu/qemu.go index f1c67e4fe3..b8f442b5f0 100644 --- a/qemu/qemu.go +++ b/qemu/qemu.go @@ -66,6 +66,9 @@ type Device interface { type DeviceDriver string const ( + // LegacySerial is the legacy serial device driver + LegacySerial DeviceDriver = "serial" + // NVDIMM is the Non Volatile DIMM device driver. NVDIMM DeviceDriver = "nvdimm" @@ -549,6 +552,9 @@ const ( // PTY creates a new pseudo-terminal on the host and connect to it. PTY CharDeviceBackend = "pty" + + // File sends traffic from the guest to a file on the host. + File CharDeviceBackend = "file" ) // CharDevice represents a qemu character device. @@ -637,8 +643,11 @@ func (cdev CharDevice) QemuParams(config *Config) []string { cdevParams = append(cdevParams, fmt.Sprintf("path=%s", cdev.Path)) } - qemuParams = append(qemuParams, "-device") - qemuParams = append(qemuParams, strings.Join(deviceParams, ",")) + // Legacy serial is special. It does not follow the device + driver model + if cdev.Driver != LegacySerial { + qemuParams = append(qemuParams, "-device") + qemuParams = append(qemuParams, strings.Join(deviceParams, ",")) + } qemuParams = append(qemuParams, "-chardev") qemuParams = append(qemuParams, strings.Join(cdevParams, ",")) @@ -978,6 +987,43 @@ func (netdev NetDevice) QemuParams(config *Config) []string { return qemuParams } +// LegacySerialDevice represents a qemu legacy serial device. +type LegacySerialDevice struct { + // ID is the serial device identifier. + // This maps to the char dev associated with the device + // as serial does not have a notion of id + // e.g: + // -chardev stdio,id=char0,mux=on,logfile=serial.log,signal=off -serial chardev:char0 + // -chardev file,id=char0,path=serial.log -serial chardev:char0 + Chardev string +} + +// Valid returns true if the LegacySerialDevice structure is valid and complete. +func (dev LegacySerialDevice) Valid() bool { + return dev.Chardev != "" +} + +// QemuParams returns the qemu parameters built out of this serial device. +func (dev LegacySerialDevice) QemuParams(config *Config) []string { + var deviceParam string + var qemuParams []string + + deviceParam = fmt.Sprintf("chardev:%s", dev.Chardev) + + qemuParams = append(qemuParams, "-serial") + qemuParams = append(qemuParams, deviceParam) + + return qemuParams +} + +/* Not used currently +// deviceName returns the QEMU device name for the current combination of +// driver and transport. +func (dev LegacySerialDevice) deviceName(config *Config) string { + return dev.Chardev +} +*/ + // SerialDevice represents a qemu serial device. type SerialDevice struct { // Driver is the qemu device driver diff --git a/qemu/qemu_test.go b/qemu/qemu_test.go index 844ed085f4..ab16b5aaee 100644 --- a/qemu/qemu_test.go +++ b/qemu/qemu_test.go @@ -274,6 +274,28 @@ func TestAppendDeviceNetworkPCIMq(t *testing.T) { testAppend(netdev, deviceNetworkPCIStringMq, t) } +var deviceLegacySerialString = "-serial chardev:tlserial0" + +func TestAppendLegacySerial(t *testing.T) { + sdev := LegacySerialDevice{ + Chardev: "tlserial0", + } + + testAppend(sdev, deviceLegacySerialString, t) +} + +var deviceLegacySerialPortString = "-chardev file,id=char0,path=/tmp/serial.log" + +func TestAppendDeviceLegacySerialPort(t *testing.T) { + chardev := CharDevice{ + Driver: LegacySerial, + Backend: File, + ID: "char0", + Path: "/tmp/serial.log", + } + testAppend(chardev, deviceLegacySerialPortString, t) +} + func TestAppendDeviceSerial(t *testing.T) { sdev := SerialDevice{ Driver: VirtioSerial,