mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-29 00:37:24 +00:00
qemu: Detect and fail a bad machine type earlier
Currently, newQemuArch() doesn't return an error. So, if passed an invalid machine type, it will return a technically valid, but unusable qemuArch object, which will probably fail with other errors shortly down the track. Change this, to more cleanly fail the newQemuArch itself, letting us detect a bad machine type earlier. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
d6e7a58ac9
commit
97a02131c6
@ -238,7 +238,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 {
|
||||||
@ -2172,7 +2175,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
|
||||||
|
|
||||||
|
@ -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,12 +78,23 @@ 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
|
||||||
@ -124,7 +136,7 @@ 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 {
|
||||||
|
@ -22,35 +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) {
|
func TestQemuAmd64BadMachineType(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
amd64 := newTestQemu("no-such-machine-type")
|
config := qemuConfig("no-such-machine-type")
|
||||||
amd64.bridges(5)
|
_, err := newQemuArch(config)
|
||||||
bridges := amd64.getBridges()
|
assert.Error(err)
|
||||||
assert.Nil(bridges)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
@ -64,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)
|
||||||
@ -79,7 +80,7 @@ func TestQemuAmd64Bridges(t *testing.T) {
|
|||||||
|
|
||||||
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()
|
||||||
@ -101,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)
|
||||||
@ -135,7 +136,8 @@ 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)
|
||||||
|
assert.NoError(err)
|
||||||
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines {
|
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines {
|
||||||
assert.Contains(m.Options, qemuNvdimmOption)
|
assert.Contains(m.Options, qemuNvdimmOption)
|
||||||
}
|
}
|
||||||
@ -159,7 +161,8 @@ 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)
|
||||||
|
assert.NoError(err)
|
||||||
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines {
|
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines {
|
||||||
assert.NotContains(m.Options, qemuNvdimmOption)
|
assert.NotContains(m.Options, qemuNvdimmOption)
|
||||||
}
|
}
|
||||||
@ -185,7 +188,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()
|
||||||
@ -208,7 +211,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()
|
||||||
@ -237,7 +240,8 @@ 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 {
|
for _, m := range amd64.(*qemuAmd64).supportedQemuMachines {
|
||||||
assert.NotContains(m.Options, qemuNvdimmOption)
|
assert.NotContains(m.Options, qemuNvdimmOption)
|
||||||
@ -249,7 +253,8 @@ 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"})
|
||||||
|
@ -125,12 +125,16 @@ 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,
|
machineType: machineType,
|
||||||
@ -146,7 +150,7 @@ 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) {
|
||||||
|
@ -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()
|
||||||
|
@ -57,12 +57,16 @@ 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,
|
machineType: machineType,
|
||||||
@ -79,7 +83,7 @@ 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 {
|
||||||
|
@ -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)
|
||||||
|
@ -55,12 +55,16 @@ 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,
|
machineType: machineType,
|
||||||
@ -81,7 +85,7 @@ 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) {
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user