qemu: allow using legacy serial device for the console

This allows to get guest early boot logs which are usually
missed when virtconsole is used.
- It utilizes previous work on the govmm side:
https://github.com/kata-containers/govmm/pull/203
- unit test added

Fixes: #4237
Signed-off-by: Snir Sheriber <ssheribe@redhat.com>
This commit is contained in:
Snir Sheriber 2022-05-12 14:26:51 +03:00
parent 44814dce19
commit c67b9d2975
10 changed files with 82 additions and 19 deletions

View File

@ -389,6 +389,9 @@ valid_entropy_sources = @DEFVALIDENTROPYSOURCES@
# be default_memory.
#enable_guest_swap = true
# use legacy serial for guest console if available and implemented for architecture. Default false
#use_legacy_serial = true
[factory]
# VM templating support. Once enabled, new VMs are created from template
# using vm cloning. They will share the same initial kernel, initramfs and

View File

@ -89,6 +89,7 @@ const defaultGuestSwap = false
const defaultRootlessHypervisor = false
const defaultDisableSeccomp = false
const defaultVfioMode = "guest-kernel"
const defaultLegacySerial = false
var defaultSGXEPCSize = int64(0)

View File

@ -146,6 +146,7 @@ type hypervisor struct {
Rootless bool `toml:"rootless"`
DisableSeccomp bool `toml:"disable_seccomp"`
DisableSeLinux bool `toml:"disable_selinux"`
LegacySerial bool `toml:"use_legacy_serial"`
}
type runtime struct {
@ -775,6 +776,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
ConfidentialGuest: h.ConfidentialGuest,
GuestSwap: h.GuestSwap,
Rootless: h.Rootless,
LegacySerial: h.LegacySerial,
}, nil
}
@ -1132,6 +1134,7 @@ func GetDefaultHypervisorConfig() vc.HypervisorConfig {
GuestSwap: defaultGuestSwap,
Rootless: defaultRootlessHypervisor,
DisableSeccomp: defaultDisableSeccomp,
LegacySerial: defaultLegacySerial,
}
}

View File

@ -537,6 +537,9 @@ type HypervisorConfig struct {
// Disable selinux from the hypervisor process
DisableSeLinux bool
// Use legacy serial for the guest console
LegacySerial bool
}
// vcpu mapping from vcpu number to thread number

View File

@ -122,6 +122,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
disableNvdimm: config.DisableImageNvdimm,
dax: true,
protection: noneProtection,
legacySerial: config.LegacySerial,
},
vmFactory: factory,
}

View File

@ -169,6 +169,7 @@ type qemuArchBase struct {
vhost bool
disableNvdimm bool
dax bool
legacySerial bool
}
const (
@ -318,16 +319,34 @@ func (q *qemuArchBase) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8
}
func (q *qemuArchBase) appendConsole(_ context.Context, devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {
serial := govmmQemu.SerialDevice{
var serial, console govmmQemu.Device
var consoleKernelParams []Param
if q.legacySerial {
serial = govmmQemu.LegacySerialDevice{
Chardev: "charconsole0",
}
console = govmmQemu.CharDevice{
Driver: govmmQemu.LegacySerial,
Backend: govmmQemu.Socket,
DeviceID: "console0",
ID: "charconsole0",
Path: path,
}
consoleKernelParams = []Param{
{"console", "ttyS0"},
}
} else {
serial = govmmQemu.SerialDevice{
Driver: govmmQemu.VirtioSerial,
ID: "serial0",
DisableModern: q.nestedRun,
MaxPorts: uint(2),
}
devices = append(devices, serial)
console := govmmQemu.CharDevice{
console = govmmQemu.CharDevice{
Driver: govmmQemu.Console,
Backend: govmmQemu.Socket,
DeviceID: "console0",
@ -335,12 +354,14 @@ func (q *qemuArchBase) appendConsole(_ context.Context, devices []govmmQemu.Devi
Path: path,
}
devices = append(devices, console)
consoleKernelParams := []Param{
consoleKernelParams = []Param{
{"console", "hvc0"},
{"console", "hvc1"},
}
}
devices = append(devices, serial)
devices = append(devices, console)
q.kernelParams = append(q.kernelParams, consoleKernelParams...)
return devices, nil

View File

@ -263,6 +263,34 @@ func TestQemuArchBaseAppendConsoles(t *testing.T) {
assert.Contains(qemuArchBase.kernelParams, Param{"console", "hvc1"})
}
func TestQemuArchBaseAppendConsolesLegacy(t *testing.T) {
var devices []govmmQemu.Device
var err error
assert := assert.New(t)
qemuArchBase := newQemuArchBase()
qemuArchBase.legacySerial = true
path := filepath.Join(filepath.Join(fs.MockRunStoragePath(), "test"), consoleSocket)
expectedOut := []govmmQemu.Device{
govmmQemu.LegacySerialDevice{
Chardev: "charconsole0",
},
govmmQemu.CharDevice{
Driver: govmmQemu.LegacySerial,
Backend: govmmQemu.Socket,
DeviceID: "console0",
ID: "charconsole0",
Path: path,
},
}
devices, err = qemuArchBase.appendConsole(context.Background(), devices, path)
assert.NoError(err)
assert.Equal(expectedOut, devices)
assert.Contains(qemuArchBase.kernelParams, Param{"console", "ttyS0"})
}
func TestQemuArchBaseAppendImage(t *testing.T) {
var devices []govmmQemu.Device
assert := assert.New(t)

View File

@ -62,6 +62,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
disableNvdimm: config.DisableImageNvdimm,
dax: true,
protection: noneProtection,
legacySerial: config.LegacySerial,
},
}

View File

@ -74,6 +74,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams,
protection: noneProtection,
legacySerial: config.LegacySerial,
},
}

View File

@ -66,6 +66,7 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams,
legacySerial: false,
},
}
// Set first bridge type to CCW