From 23a14e4f0ebc744ff39240561b2d7cc6a596af85 Mon Sep 17 00:00:00 2001 From: Isaac True Date: Wed, 12 Apr 2023 13:52:05 +0200 Subject: [PATCH] qemu: allow specifying the machine type This allows QEMU machine types to be used other than the default "pc", such as "q35". Valid alternative machine types can be identified with the `qemu-system-x86_64 -M help` command. Signed-off-by: Isaac True --- spread/project.go | 4 ++++ spread/qemu.go | 8 ++++++++ spread/qemu_test.go | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/spread/project.go b/spread/project.go index e70470f0..8ea19628 100644 --- a/spread/project.go +++ b/spread/project.go @@ -139,6 +139,10 @@ type System struct { Priority OptionalInt Manual bool + + // Type of machine emulated, only for qemu. Defaults to "pc", which is + // the QEMU default for x86_64 + MachineType string `yaml:"machine-type"` } func (system *System) String() string { return system.Backend + ":" + system.Name } diff --git a/spread/qemu.go b/spread/qemu.go index 20f0bdb0..7dfed16a 100644 --- a/spread/qemu.go +++ b/spread/qemu.go @@ -121,6 +121,13 @@ func biosPath(biosName string) (string, error) { return "", fmt.Errorf("cannot find bios path for %q", biosName) } +func machineType(system *System) string { + if system.MachineType == "" { + return "pc" + } + return system.MachineType +} + func qemuCmd(system *System, path string, mem, port int) (*exec.Cmd, error) { serial := fmt.Sprintf("telnet:127.0.0.1:%d,server,nowait", port+100) monitor := fmt.Sprintf("telnet:127.0.0.1:%d,server,nowait", port+200) @@ -133,6 +140,7 @@ func qemuCmd(system *System, path string, mem, port int) (*exec.Cmd, error) { "-net", fwd, "-serial", serial, "-monitor", monitor, + "-M", machineType(system), path) if os.Getenv("SPREAD_QEMU_GUI") != "1" { cmd.Args = append([]string{cmd.Args[0], "-nographic"}, cmd.Args[1:]...) diff --git a/spread/qemu_test.go b/spread/qemu_test.go index 619448ec..4e444611 100644 --- a/spread/qemu_test.go +++ b/spread/qemu_test.go @@ -1,6 +1,7 @@ package spread_test import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -91,3 +92,35 @@ func (s *qemuSuite) TestQemuCmdWithEfi(c *C) { c.Check(strings.Contains(s, ":-bios:/usr/share/OVMF/OVMF_CODE.fd:"), Equals, tc.UseBiosQemuOption) } } + +func (s *qemuSuite) TestQemuMachineTypes(c *C) { + imageName := "ubuntu-20.06-64" + + restore := makeMockQemuImg(c, imageName) + defer restore() + + tests := []struct { + MachineType string + ExpectedMachineType string + }{ + // Make sure the default is "pc" + {"", "pc"}, + // Make sure the specified machine type is used + {"q35", "q35"}, + } + + for _, tc := range tests { + ms := &spread.System{ + Name: "some-name", + Image: imageName, + Backend: "qemu", + MachineType: tc.MachineType, + } + cmd, err := spread.QemuCmd(ms, "/path/to/image", 512, 9999) + c.Assert(err, IsNil) + + s := strings.Join(cmd.Args, " ") + // Make sure the QEMU command specifies the given machine type, e.g. "-M pc" + c.Assert(s, Matches, fmt.Sprintf("^.*-M %s.*$", tc.ExpectedMachineType)) + } +}