Merge pull request #320 from dgibson/cleanups

Clean up some unnecessary data structures
This commit is contained in:
Peng Tao 2020-06-26 16:18:16 +08:00 committed by GitHub
commit 9d90906546
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 159 additions and 209 deletions

View File

@ -199,10 +199,7 @@ func (q *qemu) qemuPath() (string, error) {
} }
if p == "" { if p == "" {
p, err = q.arch.qemuPath() p = q.arch.qemuPath()
if err != nil {
return "", err
}
} }
if _, err = os.Stat(p); os.IsNotExist(err) { if _, err = os.Stat(p); os.IsNotExist(err) {
@ -238,7 +235,10 @@ func (q *qemu) setup(id string, hypervisorConfig *HypervisorConfig) error {
q.id = id q.id = id
q.config = *hypervisorConfig q.config = *hypervisorConfig
q.arch = newQemuArch(q.config) q.arch, err = newQemuArch(q.config)
if err != nil {
return err
}
initrdPath, err := q.config.InitrdAssetPath() initrdPath, err := q.config.InitrdAssetPath()
if err != nil { if err != nil {
@ -332,10 +332,7 @@ func (q *qemu) qmpSocketPath(id string) (string, error) {
} }
func (q *qemu) getQemuMachine() (govmmQemu.Machine, error) { func (q *qemu) getQemuMachine() (govmmQemu.Machine, error) {
machine, err := q.arch.machine() machine := q.arch.machine()
if err != nil {
return govmmQemu.Machine{}, err
}
accelerators := q.config.MachineAccelerators accelerators := q.config.MachineAccelerators
if accelerators != "" { if accelerators != "" {
@ -1536,10 +1533,7 @@ func (q *qemu) hotplugAddCPUs(amount uint32) (uint32, error) {
return 0, fmt.Errorf("failed to query hotpluggable CPUs: %v", err) return 0, fmt.Errorf("failed to query hotpluggable CPUs: %v", err)
} }
machine, err := q.arch.machine() machine := q.arch.machine()
if err != nil {
return 0, fmt.Errorf("failed to query machine type: %v", err)
}
var hotpluggedVCPUs uint32 var hotpluggedVCPUs uint32
for _, hc := range hotpluggableVCPUs { for _, hc := range hotpluggableVCPUs {
@ -2169,7 +2163,10 @@ func (q *qemu) fromGrpc(ctx context.Context, hypervisorConfig *HypervisorConfig,
q.qmpMonitorCh.path = qp.QmpChannelpath q.qmpMonitorCh.path = qp.QmpChannelpath
q.qemuConfig.Ctx = ctx q.qemuConfig.Ctx = ctx
q.state = qp.State q.state = qp.State
q.arch = newQemuArch(q.config) q.arch, err = newQemuArch(q.config)
if err != nil {
return err
}
q.ctx = ctx q.ctx = ctx
q.nvdimmCount = qp.NvdimmCount q.nvdimmCount = qp.NvdimmCount

View File

@ -6,6 +6,7 @@
package virtcontainers package virtcontainers
import ( import (
"fmt"
"time" "time"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
@ -77,18 +78,28 @@ func MaxQemuVCPUs() uint32 {
return uint32(240) return uint32(240)
} }
func newQemuArch(config HypervisorConfig) qemuArch { func newQemuArch(config HypervisorConfig) (qemuArch, error) {
machineType := config.HypervisorMachineType machineType := config.HypervisorMachineType
if machineType == "" { if machineType == "" {
machineType = defaultQemuMachineType machineType = defaultQemuMachineType
} }
var mp *govmmQemu.Machine
for _, m := range supportedQemuMachines {
if m.Type == machineType {
mp = &m
break
}
}
if mp == nil {
return nil, fmt.Errorf("unrecognised machinetype: %v", machineType)
}
factory := false factory := false
if config.BootToBeTemplate || config.BootFromTemplate { if config.BootToBeTemplate || config.BootFromTemplate {
factory = true factory = true
} }
var qemuMachines = supportedQemuMachines
if config.IOMMU { if config.IOMMU {
var q35QemuIOMMUOptions = "accel=kvm,kernel_irqchip=split" var q35QemuIOMMUOptions = "accel=kvm,kernel_irqchip=split"
@ -97,22 +108,16 @@ func newQemuArch(config HypervisorConfig) qemuArch {
kernelParams = append(kernelParams, kernelParams = append(kernelParams,
Param{"iommu", "pt"}) Param{"iommu", "pt"})
for i, m := range qemuMachines { if mp.Type == QemuQ35 {
if m.Type == QemuQ35 { mp.Options = q35QemuIOMMUOptions
qemuMachines[i].Options = q35QemuIOMMUOptions
}
} }
} else {
kernelParams = append(kernelParams,
Param{"iommu", "off"})
} }
q := &qemuAmd64{ q := &qemuAmd64{
qemuArchBase: qemuArchBase{ qemuArchBase: qemuArchBase{
machineType: machineType, qemuMachine: *mp,
qemuExePath: qemuPaths[machineType],
memoryOffset: config.MemOffset, memoryOffset: config.MemOffset,
qemuPaths: qemuPaths,
supportedQemuMachines: qemuMachines,
kernelParamsNonDebug: kernelParamsNonDebug, kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug, kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams, kernelParams: kernelParams,
@ -124,15 +129,15 @@ func newQemuArch(config HypervisorConfig) qemuArch {
q.handleImagePath(config) q.handleImagePath(config)
return q return q, nil
} }
func (q *qemuAmd64) capabilities() types.Capabilities { func (q *qemuAmd64) capabilities() types.Capabilities {
var caps types.Capabilities var caps types.Capabilities
if q.machineType == QemuPC || if q.qemuMachine.Type == QemuPC ||
q.machineType == QemuQ35 || q.qemuMachine.Type == QemuQ35 ||
q.machineType == QemuVirt { q.qemuMachine.Type == QemuVirt {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
} }
@ -143,7 +148,7 @@ func (q *qemuAmd64) capabilities() types.Capabilities {
} }
func (q *qemuAmd64) bridges(number uint32) { func (q *qemuAmd64) bridges(number uint32) {
q.Bridges = genericBridges(number, q.machineType) q.Bridges = genericBridges(number, q.qemuMachine.Type)
} }
func (q *qemuAmd64) cpuModel() string { func (q *qemuAmd64) cpuModel() string {
@ -175,5 +180,5 @@ func (q *qemuAmd64) appendImage(devices []govmmQemu.Device, path string) ([]govm
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { func (q *qemuAmd64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
return genericAppendBridges(devices, q.Bridges, q.machineType) return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type)
} }

View File

@ -22,26 +22,36 @@ func qemuConfig(machineType string) HypervisorConfig {
} }
} }
func newTestQemu(machineType string) qemuArch { func newTestQemu(assert *assert.Assertions, machineType string) qemuArch {
config := qemuConfig(machineType) config := qemuConfig(machineType)
return newQemuArch(config) arch, err := newQemuArch(config)
assert.NoError(err)
return arch
}
func TestQemuAmd64BadMachineType(t *testing.T) {
assert := assert.New(t)
config := qemuConfig("no-such-machine-type")
_, err := newQemuArch(config)
assert.Error(err)
} }
func TestQemuAmd64Capabilities(t *testing.T) { func TestQemuAmd64Capabilities(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
amd64 := newTestQemu(QemuPC) amd64 := newTestQemu(assert, QemuPC)
caps := amd64.capabilities() caps := amd64.capabilities()
assert.True(caps.IsBlockDeviceHotplugSupported()) assert.True(caps.IsBlockDeviceHotplugSupported())
amd64 = newTestQemu(QemuQ35) amd64 = newTestQemu(assert, QemuQ35)
caps = amd64.capabilities() caps = amd64.capabilities()
assert.True(caps.IsBlockDeviceHotplugSupported()) assert.True(caps.IsBlockDeviceHotplugSupported())
} }
func TestQemuAmd64Bridges(t *testing.T) { func TestQemuAmd64Bridges(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
amd64 := newTestQemu(QemuPC) amd64 := newTestQemu(assert, QemuPC)
len := 5 len := 5
amd64.bridges(uint32(len)) amd64.bridges(uint32(len))
@ -55,7 +65,7 @@ func TestQemuAmd64Bridges(t *testing.T) {
assert.NotNil(b.Devices) assert.NotNil(b.Devices)
} }
amd64 = newTestQemu(QemuQ35) amd64 = newTestQemu(assert, QemuQ35)
amd64.bridges(uint32(len)) amd64.bridges(uint32(len))
bridges = amd64.getBridges() bridges = amd64.getBridges()
assert.Len(bridges, len) assert.Len(bridges, len)
@ -66,16 +76,11 @@ func TestQemuAmd64Bridges(t *testing.T) {
assert.Equal(id, b.ID) assert.Equal(id, b.ID)
assert.NotNil(b.Devices) assert.NotNil(b.Devices)
} }
amd64 = newTestQemu(QemuQ35 + QemuPC)
amd64.bridges(uint32(len))
bridges = amd64.getBridges()
assert.Nil(bridges)
} }
func TestQemuAmd64CPUModel(t *testing.T) { func TestQemuAmd64CPUModel(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
amd64 := newTestQemu(QemuPC) amd64 := newTestQemu(assert, QemuPC)
expectedOut := defaultCPUModel expectedOut := defaultCPUModel
model := amd64.cpuModel() model := amd64.cpuModel()
@ -97,7 +102,7 @@ func TestQemuAmd64CPUModel(t *testing.T) {
func TestQemuAmd64MemoryTopology(t *testing.T) { func TestQemuAmd64MemoryTopology(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
amd64 := newTestQemu(QemuPC) amd64 := newTestQemu(assert, QemuPC)
memoryOffset := 1024 memoryOffset := 1024
hostMem := uint64(100) hostMem := uint64(100)
@ -131,10 +136,9 @@ func TestQemuAmd64AppendImage(t *testing.T) {
cfg := qemuConfig(QemuPC) cfg := qemuConfig(QemuPC)
cfg.ImagePath = f.Name() cfg.ImagePath = f.Name()
cfg.DisableImageNvdimm = false cfg.DisableImageNvdimm = false
amd64 := newQemuArch(cfg) amd64, err := newQemuArch(cfg)
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines { assert.NoError(err)
assert.Contains(m.Options, qemuNvdimmOption) assert.Contains(amd64.machine().Options, qemuNvdimmOption)
}
expectedOut := []govmmQemu.Device{ expectedOut := []govmmQemu.Device{
govmmQemu.Object{ govmmQemu.Object{
@ -155,10 +159,9 @@ func TestQemuAmd64AppendImage(t *testing.T) {
assert.Equal(len(supportedQemuMachines), copy(supportedQemuMachines, machinesCopy)) assert.Equal(len(supportedQemuMachines), copy(supportedQemuMachines, machinesCopy))
cfg.DisableImageNvdimm = true cfg.DisableImageNvdimm = true
amd64 = newQemuArch(cfg) amd64, err = newQemuArch(cfg)
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines { assert.NoError(err)
assert.NotContains(m.Options, qemuNvdimmOption) assert.NotContains(amd64.machine().Options, qemuNvdimmOption)
}
found := false found := false
devices, err = amd64.appendImage(nil, f.Name()) devices, err = amd64.appendImage(nil, f.Name())
@ -181,7 +184,7 @@ func TestQemuAmd64AppendBridges(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
// check PC // check PC
amd64 := newTestQemu(QemuPC) amd64 := newTestQemu(assert, QemuPC)
amd64.bridges(1) amd64.bridges(1)
bridges := amd64.getBridges() bridges := amd64.getBridges()
@ -204,7 +207,7 @@ func TestQemuAmd64AppendBridges(t *testing.T) {
assert.Equal(expectedOut, devices) assert.Equal(expectedOut, devices)
// Check Q35 // Check Q35
amd64 = newTestQemu(QemuQ35) amd64 = newTestQemu(assert, QemuQ35)
amd64.bridges(1) amd64.bridges(1)
bridges = amd64.getBridges() bridges = amd64.getBridges()
@ -233,11 +236,10 @@ func TestQemuAmd64WithInitrd(t *testing.T) {
cfg := qemuConfig(QemuPC) cfg := qemuConfig(QemuPC)
cfg.InitrdPath = "dummy-initrd" cfg.InitrdPath = "dummy-initrd"
amd64 := newQemuArch(cfg) amd64, err := newQemuArch(cfg)
assert.NoError(err)
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines { assert.NotContains(amd64.machine().Options, qemuNvdimmOption)
assert.NotContains(m.Options, qemuNvdimmOption)
}
} }
func TestQemuAmd64Iommu(t *testing.T) { func TestQemuAmd64Iommu(t *testing.T) {
@ -245,13 +247,12 @@ func TestQemuAmd64Iommu(t *testing.T) {
config := qemuConfig(QemuQ35) config := qemuConfig(QemuQ35)
config.IOMMU = true config.IOMMU = true
qemu := newQemuArch(config) qemu, err := newQemuArch(config)
assert.NoError(err)
p := qemu.kernelParameters(false) p := qemu.kernelParameters(false)
assert.Contains(p, Param{"intel_iommu", "on"}) assert.Contains(p, Param{"intel_iommu", "on"})
m, err := qemu.machine() m := qemu.machine()
assert.NoError(err)
assert.Contains(m.Options, "kernel_irqchip=split") assert.Contains(m.Options, "kernel_irqchip=split")
} }

View File

@ -38,10 +38,10 @@ type qemuArch interface {
disableVhostNet() disableVhostNet()
// machine returns the machine type // machine returns the machine type
machine() (govmmQemu.Machine, error) machine() govmmQemu.Machine
// qemuPath returns the path to the QEMU binary // qemuPath returns the path to the QEMU binary
qemuPath() (string, error) qemuPath() string
// kernelParameters returns the kernel parameters // kernelParameters returns the kernel parameters
// if debug is true then kernel debug parameters are included // if debug is true then kernel debug parameters are included
@ -136,15 +136,14 @@ type qemuArch interface {
} }
type qemuArchBase struct { type qemuArchBase struct {
machineType string qemuMachine govmmQemu.Machine
qemuExePath string
memoryOffset uint32 memoryOffset uint32
nestedRun bool nestedRun bool
vhost bool vhost bool
disableNvdimm bool disableNvdimm bool
dax bool dax bool
networkIndex int networkIndex int
qemuPaths map[string]string
supportedQemuMachines []govmmQemu.Machine
kernelParamsNonDebug []Param kernelParamsNonDebug []Param
kernelParamsDebug []Param kernelParamsDebug []Param
kernelParams []Param kernelParams []Param
@ -239,23 +238,12 @@ func (q *qemuArchBase) disableVhostNet() {
q.vhost = false q.vhost = false
} }
func (q *qemuArchBase) machine() (govmmQemu.Machine, error) { func (q *qemuArchBase) machine() govmmQemu.Machine {
for _, m := range q.supportedQemuMachines { return q.qemuMachine
if m.Type == q.machineType {
return m, nil
}
}
return govmmQemu.Machine{}, fmt.Errorf("unrecognised machine type: %v", q.machineType)
} }
func (q *qemuArchBase) qemuPath() (string, error) { func (q *qemuArchBase) qemuPath() string {
p, ok := q.qemuPaths[q.machineType] return q.qemuExePath
if !ok {
return "", fmt.Errorf("Unknown machine type: %s", q.machineType)
}
return p, nil
} }
func (q *qemuArchBase) kernelParameters(debug bool) []Param { func (q *qemuArchBase) kernelParameters(debug bool) []Param {
@ -681,12 +669,9 @@ func (q *qemuArchBase) handleImagePath(config HypervisorConfig) {
if config.ImagePath != "" { if config.ImagePath != "" {
kernelRootParams := commonVirtioblkKernelRootParams kernelRootParams := commonVirtioblkKernelRootParams
if !q.disableNvdimm { if !q.disableNvdimm {
for i := range q.supportedQemuMachines { q.qemuMachine.Options = strings.Join([]string{
q.supportedQemuMachines[i].Options = strings.Join([]string{ q.qemuMachine.Options, qemuNvdimmOption,
q.supportedQemuMachines[i].Options, }, ",")
qemuNvdimmOption,
}, ",")
}
if q.dax { if q.dax {
kernelRootParams = commonNvdimmKernelRootParams kernelRootParams = commonNvdimmKernelRootParams
} else { } else {
@ -767,13 +752,12 @@ func (q *qemuArchBase) addBridge(b types.Bridge) {
// appendPCIeRootPortDevice appends to devices the given pcie-root-port // appendPCIeRootPortDevice appends to devices the given pcie-root-port
func (q *qemuArchBase) appendPCIeRootPortDevice(devices []govmmQemu.Device, number uint32) []govmmQemu.Device { func (q *qemuArchBase) appendPCIeRootPortDevice(devices []govmmQemu.Device, number uint32) []govmmQemu.Device {
return genericAppendPCIeRootPort(devices, number, q.machineType) return genericAppendPCIeRootPort(devices, number, q.qemuMachine.Type)
} }
// appendIOMMU appends a virtual IOMMU device // appendIOMMU appends a virtual IOMMU device
func (q *qemuArchBase) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { func (q *qemuArchBase) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) {
switch q.machineType { switch q.qemuMachine.Type {
case QemuQ35: case QemuQ35:
iommu := govmmQemu.IommuDev{ iommu := govmmQemu.IommuDev{
Intremap: true, Intremap: true,
@ -784,6 +768,6 @@ func (q *qemuArchBase) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Devi
devices = append(devices, iommu) devices = append(devices, iommu)
return devices, nil return devices, nil
default: default:
return devices, fmt.Errorf("Machine Type %s does not support vIOMMU", q.machineType) return devices, fmt.Errorf("Machine Type %s does not support vIOMMU", q.qemuMachine.Type)
} }
} }

View File

@ -23,12 +23,15 @@ import (
) )
const ( const (
qemuArchBaseMachineType = "pc"
qemuArchBaseQemuPath = "/usr/bin/qemu-system-x86_64" qemuArchBaseQemuPath = "/usr/bin/qemu-system-x86_64"
) )
var qemuArchBaseMachine = govmmQemu.Machine{
Type: "pc",
}
var qemuArchBaseQemuPaths = map[string]string{ var qemuArchBaseQemuPaths = map[string]string{
qemuArchBaseMachineType: qemuArchBaseQemuPath, qemuArchBaseMachine.Type: qemuArchBaseQemuPath,
} }
var qemuArchBaseKernelParamsNonDebug = []Param{ var qemuArchBaseKernelParamsNonDebug = []Param{
@ -47,18 +50,11 @@ var qemuArchBaseKernelParams = []Param{
{"rootfstype", "ext4"}, {"rootfstype", "ext4"},
} }
var qemuArchBaseSupportedQemuMachines = []govmmQemu.Machine{
{
Type: qemuArchBaseMachineType,
},
}
func newQemuArchBase() *qemuArchBase { func newQemuArchBase() *qemuArchBase {
return &qemuArchBase{ return &qemuArchBase{
machineType: qemuArchBaseMachineType, qemuMachine: qemuArchBaseMachine,
qemuExePath: qemuArchBaseQemuPaths[qemuArchBaseMachine.Type],
nestedRun: false, nestedRun: false,
qemuPaths: qemuArchBaseQemuPaths,
supportedQemuMachines: qemuArchBaseSupportedQemuMachines,
kernelParamsNonDebug: qemuArchBaseKernelParamsNonDebug, kernelParamsNonDebug: qemuArchBaseKernelParamsNonDebug,
kernelParamsDebug: qemuArchBaseKernelParamsDebug, kernelParamsDebug: qemuArchBaseKernelParamsDebug,
kernelParams: qemuArchBaseKernelParams, kernelParams: qemuArchBaseKernelParams,
@ -85,36 +81,16 @@ func TestQemuArchBaseMachine(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
qemuArchBase := newQemuArchBase() qemuArchBase := newQemuArchBase()
m, err := qemuArchBase.machine() m := qemuArchBase.machine()
assert.NoError(err) assert.Equal(m.Type, qemuArchBaseMachine.Type)
assert.Equal(m.Type, qemuArchBaseMachineType)
machines := []govmmQemu.Machine{
{
Type: "bad",
},
}
qemuArchBase.supportedQemuMachines = machines
m, err = qemuArchBase.machine()
assert.Error(err)
assert.Equal("", m.Type)
} }
func TestQemuArchBaseQemuPath(t *testing.T) { func TestQemuArchBaseQemuPath(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
qemuArchBase := newQemuArchBase() qemuArchBase := newQemuArchBase()
p, err := qemuArchBase.qemuPath() p := qemuArchBase.qemuPath()
assert.NoError(err)
assert.Equal(p, qemuArchBaseQemuPath) assert.Equal(p, qemuArchBaseQemuPath)
paths := map[string]string{
"bad": qemuArchBaseQemuPath,
}
qemuArchBase.qemuPaths = paths
p, err = qemuArchBase.qemuPath()
assert.Error(err)
assert.Equal("", p)
} }
func TestQemuArchBaseKernelParameters(t *testing.T) { func TestQemuArchBaseKernelParameters(t *testing.T) {
@ -166,7 +142,7 @@ func TestQemuAddDeviceToBridge(t *testing.T) {
// addDeviceToBridge successfully // addDeviceToBridge successfully
q := newQemuArchBase() q := newQemuArchBase()
q.machineType = QemuPC q.qemuMachine.Type = QemuPC
q.bridges(1) q.bridges(1)
for i := uint32(1); i <= types.PCIBridgeMaxCapacity; i++ { for i := uint32(1); i <= types.PCIBridgeMaxCapacity; i++ {
@ -181,7 +157,7 @@ func TestQemuAddDeviceToBridge(t *testing.T) {
// addDeviceToBridge fails cause q.Bridges == 0 // addDeviceToBridge fails cause q.Bridges == 0
q = newQemuArchBase() q = newQemuArchBase()
q.machineType = QemuPCLite q.qemuMachine.Type = QemuPCLite
q.bridges(0) q.bridges(0)
_, _, err = q.addDeviceToBridge("qemu-bridge", types.PCI) _, _, err = q.addDeviceToBridge("qemu-bridge", types.PCI)
if assert.Error(err) { if assert.Error(err) {
@ -581,11 +557,11 @@ func TestQemuArchBaseAppendIOMMU(t *testing.T) {
}, },
} }
// Test IOMMU is not appended to PC machine type // Test IOMMU is not appended to PC machine type
qemuArchBase.machineType = QemuPC qemuArchBase.qemuMachine.Type = QemuPC
devices, err = qemuArchBase.appendIOMMU(devices) devices, err = qemuArchBase.appendIOMMU(devices)
assert.Error(err) assert.Error(err)
qemuArchBase.machineType = QemuQ35 qemuArchBase.qemuMachine.Type = QemuQ35
devices, err = qemuArchBase.appendIOMMU(devices) devices, err = qemuArchBase.appendIOMMU(devices)
assert.NoError(err) assert.NoError(err)
assert.Equal(expectedOut, devices) assert.Equal(expectedOut, devices)

View File

@ -30,21 +30,15 @@ const qmpMigrationWaitTimeout = 10 * time.Second
var defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=" + getGuestGICVersion() var defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=" + getGuestGICVersion()
var qemuPaths = map[string]string{
QemuVirt: defaultQemuPath,
}
var kernelParams = []Param{ var kernelParams = []Param{
{"console", "hvc0"}, {"console", "hvc0"},
{"console", "hvc1"}, {"console", "hvc1"},
{"iommu.passthrough", "0"}, {"iommu.passthrough", "0"},
} }
var supportedQemuMachines = []govmmQemu.Machine{ var supportedQemuMachine = govmmQemu.Machine {
{ Type: QemuVirt,
Type: QemuVirt, Options: defaultQemuMachineOptions,
Options: defaultQemuMachineOptions,
},
} }
// Logger returns a logrus logger appropriate for logging qemu-aarch64 messages // Logger returns a logrus logger appropriate for logging qemu-aarch64 messages
@ -125,18 +119,21 @@ func MaxQemuVCPUs() uint32 {
return uint32(runtime.NumCPU()) return uint32(runtime.NumCPU())
} }
func newQemuArch(config HypervisorConfig) qemuArch { func newQemuArch(config HypervisorConfig) (qemuArch, error) {
machineType := config.HypervisorMachineType machineType := config.HypervisorMachineType
if machineType == "" { if machineType == "" {
machineType = defaultQemuMachineType machineType = defaultQemuMachineType
} }
if machineType != defaultQemuMachineType {
return nil, fmt.Errorf("unrecognised machinetype: %v", machineType)
}
q := &qemuArm64{ q := &qemuArm64{
qemuArchBase{ qemuArchBase{
machineType: machineType, qemuMachine: supportedQemuMachine,
qemuExePath: defaultQemuPath,
memoryOffset: config.MemOffset, memoryOffset: config.MemOffset,
qemuPaths: qemuPaths,
supportedQemuMachines: supportedQemuMachines,
kernelParamsNonDebug: kernelParamsNonDebug, kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug, kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams, kernelParams: kernelParams,
@ -146,16 +143,16 @@ func newQemuArch(config HypervisorConfig) qemuArch {
q.handleImagePath(config) q.handleImagePath(config)
return q return q, nil
} }
func (q *qemuArm64) bridges(number uint32) { func (q *qemuArm64) bridges(number uint32) {
q.Bridges = genericBridges(number, q.machineType) q.Bridges = genericBridges(number, q.qemuMachine.Type)
} }
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuArm64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { func (q *qemuArm64) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
return genericAppendBridges(devices, q.Bridges, q.machineType) return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type)
} }
func (q *qemuArm64) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) { func (q *qemuArm64) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {

View File

@ -23,14 +23,16 @@ func qemuConfig(machineType string) HypervisorConfig {
} }
} }
func newTestQemu(machineType string) qemuArch { func newTestQemu(assert *assert.Assertions, machineType string) qemuArch {
config := qemuConfig(machineType) config := qemuConfig(machineType)
return newQemuArch(config) arch, err := newQemuArch(config)
assert.NoError(err)
return arch
} }
func TestQemuArm64CPUModel(t *testing.T) { func TestQemuArm64CPUModel(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
arm64 := newTestQemu(QemuVirt) arm64 := newTestQemu(assert, QemuVirt)
expectedOut := defaultCPUModel expectedOut := defaultCPUModel
model := arm64.cpuModel() model := arm64.cpuModel()
@ -39,7 +41,7 @@ func TestQemuArm64CPUModel(t *testing.T) {
func TestQemuArm64MemoryTopology(t *testing.T) { func TestQemuArm64MemoryTopology(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
arm64 := newTestQemu(QemuVirt) arm64 := newTestQemu(assert, QemuVirt)
hostMem := uint64(4096) hostMem := uint64(4096)
mem := uint64(1024) mem := uint64(1024)
@ -107,7 +109,7 @@ func TestQemuArm64AppendBridges(t *testing.T) {
var devices []govmmQemu.Device var devices []govmmQemu.Device
assert := assert.New(t) assert := assert.New(t)
arm64 := newTestQemu(QemuVirt) arm64 := newTestQemu(assert, QemuVirt)
arm64.bridges(1) arm64.bridges(1)
bridges := arm64.getBridges() bridges := arm64.getBridges()
@ -150,9 +152,7 @@ func TestQemuArm64AppendImage(t *testing.T) {
cfg := qemuConfig(QemuVirt) cfg := qemuConfig(QemuVirt)
cfg.ImagePath = f.Name() cfg.ImagePath = f.Name()
arm64 := newQemuArch(cfg) arm64 := newQemuArch(cfg)
for _, m := range arm64.(*qemuArm64).supportedQemuMachines { assert.Contains(m.machine().Options, qemuNvdimmOption)
assert.Contains(m.Options, qemuNvdimmOption)
}
expectedOut := []govmmQemu.Device{ expectedOut := []govmmQemu.Device{
govmmQemu.Object{ govmmQemu.Object{
@ -180,7 +180,5 @@ func TestQemuArm64WithInitrd(t *testing.T) {
cfg.InitrdPath = "dummy-initrd" cfg.InitrdPath = "dummy-initrd"
arm64 := newQemuArch(cfg) arm64 := newQemuArch(cfg)
for _, m := range arm64.(*qemuArm64).supportedQemuMachines { assert.NotContains(m.machine().Options, qemuNvdimmOption)
assert.NotContains(m.Options, qemuNvdimmOption)
}
} }

View File

@ -27,10 +27,6 @@ const defaultQemuMachineOptions = "accel=kvm,usb=off"
const qmpMigrationWaitTimeout = 5 * time.Second const qmpMigrationWaitTimeout = 5 * time.Second
var qemuPaths = map[string]string{
QemuPseries: defaultQemuPath,
}
var kernelParams = []Param{ var kernelParams = []Param{
{"rcupdate.rcu_expedited", "1"}, {"rcupdate.rcu_expedited", "1"},
{"reboot", "k"}, {"reboot", "k"},
@ -40,11 +36,9 @@ var kernelParams = []Param{
{"net.ifnames", "0"}, {"net.ifnames", "0"},
} }
var supportedQemuMachines = []govmmQemu.Machine{ var supportedQemuMachine = govmmQemu.Machine {
{ Type: QemuPseries,
Type: QemuPseries, Options: defaultQemuMachineOptions,
Options: defaultQemuMachineOptions,
},
} }
// Logger returns a logrus logger appropriate for logging qemu messages // Logger returns a logrus logger appropriate for logging qemu messages
@ -57,18 +51,21 @@ func MaxQemuVCPUs() uint32 {
return uint32(128) return uint32(128)
} }
func newQemuArch(config HypervisorConfig) qemuArch { func newQemuArch(config HypervisorConfig) (qemuArch, error) {
machineType := config.HypervisorMachineType machineType := config.HypervisorMachineType
if machineType == "" { if machineType == "" {
machineType = defaultQemuMachineType machineType = defaultQemuMachineType
} }
if machineType != defaultQemuMachineType {
return nil, fmt.Errorf("unrecognised machinetype: %v", machineType)
}
q := &qemuPPC64le{ q := &qemuPPC64le{
qemuArchBase{ qemuArchBase{
machineType: machineType, qemuMachine: supportedQemuMachine,
qemuExePath: defaultQemuPath,
memoryOffset: config.MemOffset, memoryOffset: config.MemOffset,
qemuPaths: qemuPaths,
supportedQemuMachines: supportedQemuMachines,
kernelParamsNonDebug: kernelParamsNonDebug, kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug, kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams, kernelParams: kernelParams,
@ -79,14 +76,14 @@ func newQemuArch(config HypervisorConfig) qemuArch {
q.memoryOffset = config.MemOffset q.memoryOffset = config.MemOffset
return q return q, nil
} }
func (q *qemuPPC64le) capabilities() types.Capabilities { func (q *qemuPPC64le) capabilities() types.Capabilities {
var caps types.Capabilities var caps types.Capabilities
// pseries machine type supports hotplugging drives // pseries machine type supports hotplugging drives
if q.machineType == QemuPseries { if q.qemuMachine.Type == QemuPseries {
caps.SetBlockDeviceHotplugSupport() caps.SetBlockDeviceHotplugSupport()
} }
@ -97,7 +94,7 @@ func (q *qemuPPC64le) capabilities() types.Capabilities {
} }
func (q *qemuPPC64le) bridges(number uint32) { func (q *qemuPPC64le) bridges(number uint32) {
q.Bridges = genericBridges(number, q.machineType) q.Bridges = genericBridges(number, q.qemuMachine.Type)
} }
func (q *qemuPPC64le) cpuModel() string { func (q *qemuPPC64le) cpuModel() string {
@ -113,7 +110,7 @@ func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8)
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { func (q *qemuPPC64le) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
return genericAppendBridges(devices, q.Bridges, q.machineType) return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type)
} }
func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) { func (q *qemuPPC64le) appendIOMMU(devices []govmmQemu.Device) ([]govmmQemu.Device, error) {

View File

@ -13,16 +13,18 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func newTestQemu(machineType string) qemuArch { func newTestQemu(assert *assert.Assertions, machineType string) qemuArch {
config := HypervisorConfig{ config := HypervisorConfig{
HypervisorMachineType: machineType, HypervisorMachineType: machineType,
} }
return newQemuArch(config) arch, err := newQemuArch(config)
assert.NoError(err)
return arch
} }
func TestQemuPPC64leCPUModel(t *testing.T) { func TestQemuPPC64leCPUModel(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ppc64le := newTestQemu(QemuPseries) ppc64le := newTestQemu(assert, QemuPseries)
expectedOut := defaultCPUModel expectedOut := defaultCPUModel
model := ppc64le.cpuModel() model := ppc64le.cpuModel()
@ -31,7 +33,7 @@ func TestQemuPPC64leCPUModel(t *testing.T) {
func TestQemuPPC64leMemoryTopology(t *testing.T) { func TestQemuPPC64leMemoryTopology(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
ppc64le := newTestQemu(QemuPseries) ppc64le := newTestQemu(assert, QemuPseries)
memoryOffset := 1024 memoryOffset := 1024
hostMem := uint64(1024) hostMem := uint64(1024)

View File

@ -29,10 +29,6 @@ const virtioSerialCCW = "virtio-serial-ccw"
const qmpMigrationWaitTimeout = 5 * time.Second const qmpMigrationWaitTimeout = 5 * time.Second
var qemuPaths = map[string]string{
QemuCCWVirtio: defaultQemuPath,
}
// Verify needed parameters // Verify needed parameters
var kernelParams = []Param{ var kernelParams = []Param{
{"console", "ttysclp0"}, {"console", "ttysclp0"},
@ -40,11 +36,9 @@ var kernelParams = []Param{
var ccwbridge = types.NewBridge(types.CCW, "", make(map[uint32]string, types.CCWBridgeMaxCapacity), 0) var ccwbridge = types.NewBridge(types.CCW, "", make(map[uint32]string, types.CCWBridgeMaxCapacity), 0)
var supportedQemuMachines = []govmmQemu.Machine{ var supportedQemuMachine = govmmQemu.Machine {
{ Type: QemuCCWVirtio,
Type: QemuCCWVirtio, Options: defaultQemuMachineOptions,
Options: defaultQemuMachineOptions,
},
} }
// MaxQemuVCPUs returns the maximum number of vCPUs supported // MaxQemuVCPUs returns the maximum number of vCPUs supported
@ -55,18 +49,21 @@ func MaxQemuVCPUs() uint32 {
return uint32(248) return uint32(248)
} }
func newQemuArch(config HypervisorConfig) qemuArch { func newQemuArch(config HypervisorConfig) (qemuArch, error) {
machineType := config.HypervisorMachineType machineType := config.HypervisorMachineType
if machineType == "" { if machineType == "" {
machineType = defaultQemuMachineType machineType = defaultQemuMachineType
} }
if machineType != defaultQemuMachineType {
return nil, fmt.Errorf("unrecognised machinetype: %v", machineType)
}
q := &qemuS390x{ q := &qemuS390x{
qemuArchBase{ qemuArchBase{
machineType: machineType, qemuMachine: supportedQemuMachine,
qemuExePath: defaultQemuPath,
memoryOffset: config.MemOffset, memoryOffset: config.MemOffset,
qemuPaths: qemuPaths,
supportedQemuMachines: supportedQemuMachines,
kernelParamsNonDebug: kernelParamsNonDebug, kernelParamsNonDebug: kernelParamsNonDebug,
kernelParamsDebug: kernelParamsDebug, kernelParamsDebug: kernelParamsDebug,
kernelParams: kernelParams, kernelParams: kernelParams,
@ -81,11 +78,11 @@ func newQemuArch(config HypervisorConfig) qemuArch {
q.kernelParamsDebug = append(q.kernelParamsDebug, kernelParamsSystemdDebug...) q.kernelParamsDebug = append(q.kernelParamsDebug, kernelParamsSystemdDebug...)
} }
return q return q, nil
} }
func (q *qemuS390x) bridges(number uint32) { func (q *qemuS390x) bridges(number uint32) {
q.Bridges = genericBridges(number, q.machineType) q.Bridges = genericBridges(number, q.qemuMachine.Type)
} }
// appendConsole appends a console to devices. // appendConsole appends a console to devices.
@ -226,7 +223,7 @@ func (q *qemuS390x) append9PVolume(devices []govmmQemu.Device, volume types.Volu
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges
func (q *qemuS390x) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device { func (q *qemuS390x) appendBridges(devices []govmmQemu.Device) []govmmQemu.Device {
return genericAppendBridges(devices, q.Bridges, q.machineType) return genericAppendBridges(devices, q.Bridges, q.qemuMachine.Type)
} }
func (q *qemuS390x) appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread, error) { func (q *qemuS390x) appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread, error) {

View File

@ -14,16 +14,18 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func newTestQemu(machineType string) qemuArch { func newTestQemu(assert *assert.Assertions, machineType string) qemuArch {
config := HypervisorConfig{ config := HypervisorConfig{
HypervisorMachineType: machineType, HypervisorMachineType: machineType,
} }
return newQemuArch(config) arch, err := newQemuArch(config)
assert.NoError(err)
return arch
} }
func TestQemuS390xCPUModel(t *testing.T) { func TestQemuS390xCPUModel(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
s390x := newTestQemu(QemuCCWVirtio) s390x := newTestQemu(assert, QemuCCWVirtio)
expectedOut := defaultCPUModel expectedOut := defaultCPUModel
model := s390x.cpuModel() model := s390x.cpuModel()
@ -37,7 +39,7 @@ func TestQemuS390xCPUModel(t *testing.T) {
func TestQemuS390xMemoryTopology(t *testing.T) { func TestQemuS390xMemoryTopology(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
s390x := newTestQemu(QemuCCWVirtio) s390x := newTestQemu(assert, QemuCCWVirtio)
hostMem := uint64(1024) hostMem := uint64(1024)
mem := uint64(120) mem := uint64(120)

View File

@ -342,10 +342,11 @@ func TestQemuQemuPath(t *testing.T) {
qemuConfig := newQemuConfig() qemuConfig := newQemuConfig()
qemuConfig.HypervisorPath = expectedPath qemuConfig.HypervisorPath = expectedPath
qkvm := &qemuArchBase{ qkvm := &qemuArchBase{
machineType: "pc", qemuMachine: govmmQemu.Machine{
qemuPaths: map[string]string{ Type: "pc",
"pc": expectedPath, Options: "",
}, },
qemuExePath: expectedPath,
} }
q := &qemu{ q := &qemu{
@ -369,13 +370,6 @@ func TestQemuQemuPath(t *testing.T) {
path, err = q.qemuPath() path, err = q.qemuPath()
assert.NoError(err) assert.NoError(err)
assert.Equal(path, expectedPath) assert.Equal(path, expectedPath)
// bad machine type, arch should fail
qkvm.machineType = "rgb"
q.arch = qkvm
path, err = q.qemuPath()
assert.Error(err)
assert.Equal(path, "")
} }
func TestHotplugUnsupportedDeviceType(t *testing.T) { func TestHotplugUnsupportedDeviceType(t *testing.T) {