diff --git a/qemu/qemu.go b/qemu/qemu.go index f26f093922..be23be84f2 100644 --- a/qemu/qemu.go +++ b/qemu/qemu.go @@ -62,18 +62,9 @@ const ( // NVDIMM is the Non Volatile DIMM device driver. NVDIMM DeviceDriver = "nvdimm" - // Virtio9P is the 9pfs device driver. - Virtio9P DeviceDriver = "virtio-9p-pci" - - // VirtioNet is the virt-io networking device driver. - VirtioNet DeviceDriver = "virtio-net" - // VirtioNetPCI is the virt-io pci networking device driver. VirtioNetPCI DeviceDriver = "virtio-net-pci" - // VirtioSerial is the serial device driver. - VirtioSerial DeviceDriver = "virtio-serial-pci" - // VirtioBlock is the block device driver. VirtioBlock DeviceDriver = "virtio-blk" @@ -83,9 +74,6 @@ const ( // VirtioSerialPort is the serial port device driver. VirtioSerialPort DeviceDriver = "virtserialport" - // VHostVSockPCI is the vhost vsock pci driver. - VHostVSockPCI DeviceDriver = "vhost-vsock-pci" - // VirtioRng is the paravirtualized RNG device driver. VirtioRng DeviceDriver = "virtio-rng" @@ -101,12 +89,6 @@ const ( //VhostUserBlk represents a block vhostuser device type. VhostUserBlk DeviceDriver = "vhost-user-blk-pci" - // VfioPCI represent a VFIO device type. - VfioPCI DeviceDriver = "vfio-pci" - - // VirtioScsiPCI represents a SCSI device type. - VirtioScsiPCI DeviceDriver = "virtio-scsi-pci" - // PCIBridgeDriver represents a PCI bridge device type. PCIBridgeDriver DeviceDriver = "pci-bridge" @@ -114,27 +96,19 @@ const ( PCIePCIBridgeDriver DeviceDriver = "pcie-pci-bridge" ) -// isVirtioPCI is a map indicating if a DeviceDriver is considered as a -// virtio PCI device, which is helpful to determine if the option "romfile" -// applies or not to this specific device. -var isVirtioPCI = map[DeviceDriver]bool{ - NVDIMM: false, - Virtio9P: true, - VirtioNet: true, - VirtioNetPCI: true, - VirtioSerial: true, - VirtioBlock: true, - Console: false, - VirtioSerialPort: false, - VHostVSockPCI: true, - VirtioRng: true, - VirtioBalloon: true, - VhostUserSCSI: true, - VhostUserBlk: true, - VfioPCI: true, - VirtioScsiPCI: true, - PCIBridgeDriver: true, - PCIePCIBridgeDriver: true, +// disableModern returns the parameters with the disable-modern option. +// In case the device driver is not a PCI device and it doesn't have the option +// an empty string is returned. +func (driver DeviceDriver) disableModern(disable bool) string { + if !isVirtioPCI[driver] { + return "" + } + + if disable { + return "disable-modern=true" + } + + return "disable-modern=false" } // ObjectType is a string representing a qemu object type. @@ -284,8 +258,8 @@ func (fsdev FSDevice) QemuParams(config *Config) []string { var qemuParams []string deviceParams = append(deviceParams, fmt.Sprintf("%s", fsdev.Driver)) - if fsdev.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := fsdev.Driver.disableModern(fsdev.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } deviceParams = append(deviceParams, fmt.Sprintf(",fsdev=%s", fsdev.ID)) deviceParams = append(deviceParams, fmt.Sprintf(",mount_tag=%s", fsdev.MountTag)) @@ -370,8 +344,8 @@ func (cdev CharDevice) QemuParams(config *Config) []string { var qemuParams []string deviceParams = append(deviceParams, fmt.Sprintf("%s", cdev.Driver)) - if cdev.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := cdev.Driver.disableModern(cdev.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } if cdev.Bus != "" { deviceParams = append(deviceParams, fmt.Sprintf(",bus=%s", cdev.Bus)) @@ -425,48 +399,6 @@ const ( VHOSTUSER NetDeviceType = "vhostuser" ) -// QemuNetdevParam converts to the QEMU -netdev parameter notation -func (n NetDeviceType) QemuNetdevParam() string { - switch n { - case TAP: - return "tap" - case MACVTAP: - return "tap" - case IPVTAP: - return "tap" - case VETHTAP: - return "tap" // -netdev type=tap -device virtio-net-pci - case VFIO: - return "" // -device vfio-pci (no netdev) - case VHOSTUSER: - return "vhost-user" // -netdev type=vhost-user (no device) - default: - return "" - - } -} - -// QemuDeviceParam converts to the QEMU -device parameter notation -func (n NetDeviceType) QemuDeviceParam() DeviceDriver { - switch n { - case TAP: - return "virtio-net-pci" - case MACVTAP: - return "virtio-net-pci" - case IPVTAP: - return "virtio-net-pci" - case VETHTAP: - return "virtio-net-pci" // -netdev type=tap -device virtio-net-pci - case VFIO: - return "vfio-pci" // -device vfio-pci (no netdev) - case VHOSTUSER: - return "" // -netdev type=vhost-user (no device) - default: - return "" - - } -} - // NetDevice represents a guest networking device type NetDevice struct { // Type is the netdev type (e.g. tap). @@ -527,6 +459,29 @@ func (netdev NetDevice) Valid() bool { } } +// mqParameter returns the parameters for multi-queue driver. If the driver is a PCI device then the +// vector flag is required. If the driver is a CCW type than the vector flag is not implemented and only +// multi-queue option mq needs to be activated. See comment in libvirt code at +// https://github.com/libvirt/libvirt/blob/6e7e965dcd3d885739129b1454ce19e819b54c25/src/qemu/qemu_command.c#L3633 +func (netdev NetDevice) mqParameter() string { + p := []string{",mq=on"} + + if isVirtioPCI[netdev.Driver] { + // https://www.linux-kvm.org/page/Multiqueue + // -netdev tap,vhost=on,queues=N + // enable mq and specify msix vectors in qemu cmdline + // (2N+2 vectors, N for tx queues, N for rx queues, 1 for config, and one for possible control vq) + // -device virtio-net-pci,mq=on,vectors=2N+2... + // enable mq in guest by 'ethtool -L eth0 combined $queue_num' + // Clearlinux automatically sets up the queues properly + // The agent implementation should do this to ensure that it is + // always set + vectors := len(netdev.FDs)*2 + 2 + p = append(p, fmt.Sprintf(",vectors=%d", vectors)) + } + return strings.Join(p, "") +} + // QemuDeviceParams returns the -device parameters for this network device func (netdev NetDevice) QemuDeviceParams(config *Config) []string { var deviceParams []string @@ -549,26 +504,13 @@ func (netdev NetDevice) QemuDeviceParams(config *Config) []string { deviceParams = append(deviceParams, fmt.Sprintf(",addr=%x", addr)) } } - - if netdev.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := netdev.Driver.disableModern(netdev.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } if len(netdev.FDs) > 0 { - // https://www.linux-kvm.org/page/Multiqueue - // -netdev tap,vhost=on,queues=N - // enable mq and specify msix vectors in qemu cmdline - // (2N+2 vectors, N for tx queues, N for rx queues, 1 for config, and one for possible control vq) - // -device virtio-net-pci,mq=on,vectors=2N+2... - // enable mq in guest by 'ethtool -L eth0 combined $queue_num' - // Clearlinux automatically sets up the queues properly - // The agent implementation should do this to ensure that it is - // always set - vectors := len(netdev.FDs)*2 + 2 - // Note: We are appending to the device params here - deviceParams = append(deviceParams, ",mq=on") - deviceParams = append(deviceParams, fmt.Sprintf(",vectors=%d", vectors)) + deviceParams = append(deviceParams, netdev.mqParameter()) } if isVirtioPCI[netdev.Driver] { @@ -683,8 +625,8 @@ func (dev SerialDevice) QemuParams(config *Config) []string { var qemuParams []string deviceParams = append(deviceParams, fmt.Sprintf("%s", dev.Driver)) - if dev.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := dev.Driver.disableModern(dev.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", dev.ID)) if isVirtioPCI[dev.Driver] { @@ -761,8 +703,8 @@ func (blkdev BlockDevice) QemuParams(config *Config) []string { var qemuParams []string deviceParams = append(deviceParams, fmt.Sprintf("%s", blkdev.Driver)) - if blkdev.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := blkdev.Driver.disableModern(blkdev.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } deviceParams = append(deviceParams, fmt.Sprintf(",drive=%s", blkdev.ID)) if blkdev.SCSI == false { @@ -909,7 +851,7 @@ func (vfioDev VFIODevice) QemuParams(config *Config) []string { var qemuParams []string var deviceParams []string - driver := VfioPCI + driver := Vfio deviceParams = append(deviceParams, fmt.Sprintf("%s,host=%s", driver, vfioDev.BDF)) if isVirtioPCI[driver] { @@ -956,7 +898,7 @@ func (scsiCon SCSIController) QemuParams(config *Config) []string { var qemuParams []string var devParams []string - driver := VirtioScsiPCI + driver := VirtioScsi devParams = append(devParams, fmt.Sprintf("%s,id=%s", driver, scsiCon.ID)) if scsiCon.Bus != "" { devParams = append(devParams, fmt.Sprintf("bus=%s", scsiCon.Bus)) @@ -964,8 +906,8 @@ func (scsiCon SCSIController) QemuParams(config *Config) []string { if scsiCon.Addr != "" { devParams = append(devParams, fmt.Sprintf("addr=%s", scsiCon.Addr)) } - if scsiCon.DisableModern { - devParams = append(devParams, fmt.Sprintf("disable-modern=true")) + if s := driver.disableModern(scsiCon.DisableModern); s != "" { + devParams = append(devParams, fmt.Sprintf("%s", s)) } if scsiCon.IOThread != "" { devParams = append(devParams, fmt.Sprintf("iothread=%s", scsiCon.IOThread)) @@ -1087,7 +1029,9 @@ type VSOCKDevice struct { const ( // MinimalGuestCID is the smallest valid context ID for a guest. MinimalGuestCID uint32 = 3 +) +const ( // VSOCKGuestCID is the VSOCK guest CID parameter. VSOCKGuestCID = "guest-cid" ) @@ -1106,10 +1050,10 @@ func (vsock VSOCKDevice) QemuParams(config *Config) []string { var deviceParams []string var qemuParams []string - driver := VHostVSockPCI + driver := VHostVSock deviceParams = append(deviceParams, fmt.Sprintf("%s", driver)) - if vsock.DisableModern { - deviceParams = append(deviceParams, ",disable-modern=true") + if s := driver.disableModern(vsock.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf(",%s", s)) } if vsock.VHostFD != nil { qemuFDs := config.appendFDs([]*os.File{vsock.VHostFD}) @@ -1223,13 +1167,9 @@ func (b BalloonDevice) QemuParams(_ *Config) []string { } else { deviceParams = append(deviceParams, "deflate-on-oom=off") } - - if b.DisableModern { - deviceParams = append(deviceParams, "disable-modern=on") - } else { - deviceParams = append(deviceParams, "disable-modern=off") + if s := driver.disableModern(b.DisableModern); s != "" { + deviceParams = append(deviceParams, fmt.Sprintf("%s", s)) } - qemuParams = append(qemuParams, "-device") qemuParams = append(qemuParams, strings.Join(deviceParams, ",")) diff --git a/qemu/qemu_arch_base.go b/qemu/qemu_arch_base.go new file mode 100644 index 0000000000..0db1ecaedd --- /dev/null +++ b/qemu/qemu_arch_base.go @@ -0,0 +1,103 @@ +// +build !s390x + +/* +// Copyright (c) 2016 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +package qemu + +const ( + // Virtio9P is the 9pfs device driver. + Virtio9P DeviceDriver = "virtio-9p-pci" + + // VirtioSerial is the serial device driver. + VirtioSerial DeviceDriver = "virtio-serial-pci" + + // VirtioNet is the virt-io pci networking device driver. + VirtioNet DeviceDriver = VirtioNetPCI + + // Vfio is the vfio driver + Vfio DeviceDriver = "vfio-pci" + + // VirtioScsi is the virtio-scsi device + VirtioScsi DeviceDriver = "virtio-scsi-pci" + + // VHostVSock is a generic Vsock vhost device + VHostVSock DeviceDriver = "vhost-vsock-pci" +) + +// isVirtioPCI is a map indicating if a DeviceDriver is considered as a +// virtio PCI device, which is helpful to determine if the option "romfile" +// applies or not to this specific device. +var isVirtioPCI = map[DeviceDriver]bool{ + NVDIMM: false, + Virtio9P: true, + VirtioNetPCI: true, + VirtioSerial: true, + VirtioBlock: true, + Console: false, + VirtioSerialPort: false, + VHostVSock: true, + VirtioRng: true, + VirtioBalloon: true, + VhostUserSCSI: true, + VhostUserBlk: true, + Vfio: true, + VirtioScsi: true, + PCIBridgeDriver: true, + PCIePCIBridgeDriver: true, +} + +// QemuNetdevParam converts to the QEMU -netdev parameter notation +func (n NetDeviceType) QemuNetdevParam() string { + switch n { + case TAP: + return "tap" + case MACVTAP: + return "tap" + case IPVTAP: + return "tap" + case VETHTAP: + return "tap" // -netdev type=tap -device virtio-net-pci + case VFIO: + return "" // -device vfio-pci (no netdev) + case VHOSTUSER: + return "vhost-user" // -netdev type=vhost-user (no device) + default: + return "" + + } +} + +// QemuDeviceParam converts to the QEMU -device parameter notation +func (n NetDeviceType) QemuDeviceParam() DeviceDriver { + switch n { + case TAP: + return "virtio-net-pci" + case MACVTAP: + return "virtio-net-pci" + case IPVTAP: + return "virtio-net-pci" + case VETHTAP: + return "virtio-net-pci" // -netdev type=tap -device virtio-net-pci + case VFIO: + return "vfio-pci" // -device vfio-pci (no netdev) + case VHOSTUSER: + return "" // -netdev type=vhost-user (no device) + default: + return "" + + } +} diff --git a/qemu/qemu_arch_base_test.go b/qemu/qemu_arch_base_test.go new file mode 100644 index 0000000000..a30b3bdbd8 --- /dev/null +++ b/qemu/qemu_arch_base_test.go @@ -0,0 +1,99 @@ +// +build !s390x + +/* +// Copyright (c) 2016 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +package qemu + +import "testing" + +var ( + deviceFSString = "-device virtio-9p-pci,disable-modern=true,fsdev=workload9p,mount_tag=rootfs,romfile=efi-virtio.rom -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none" + deviceNetworkString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,romfile=efi-virtio.rom" + deviceNetworkStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom" + deviceNetworkPCIString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,romfile=efi-virtio.rom" + deviceNetworkPCIStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom" + deviceSerialString = "-device virtio-serial-pci,disable-modern=true,id=serial0,romfile=efi-virtio.rom" + deviceVhostUserNetString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -netdev type=vhost-user,id=net1,chardev=char1,vhostforce -device virtio-net-pci,netdev=net1,mac=00:11:22:33:44:55,romfile=efi-virtio.rom" + deviceVSOCKString = "-device vhost-vsock-pci,disable-modern=true,id=vhost-vsock-pci0,guest-cid=4,romfile=efi-virtio.rom" + deviceVFIOString = "-device vfio-pci,host=02:10.0,romfile=efi-virtio.rom" + deviceSCSIControllerStr = "-device virtio-scsi-pci,id=foo,disable-modern=false,romfile=efi-virtio.rom" + deviceSCSIControllerBusAddrStr = "-device virtio-scsi-pci,id=foo,bus=pci.0,addr=00:04.0,disable-modern=true,iothread=iothread1,romfile=efi-virtio.rom" + deviceVhostUserSCSIString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -device vhost-user-scsi-pci,id=scsi1,chardev=char1,romfile=efi-virtio.rom" + deviceVhostUserBlkString = "-chardev socket,id=char2,path=/tmp/nonexistentsocket.socket -device vhost-user-blk-pci,logical_block_size=4096,size=512M,chardev=char2,romfile=efi-virtio.rom" + deviceBlockString = "-device virtio-blk,disable-modern=true,drive=hd0,scsi=off,config-wce=off,romfile=efi-virtio.rom -drive id=hd0,file=/var/lib/vm.img,aio=threads,format=qcow2,if=none" + devicePCIBridgeString = "-device pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,chassis_nr=5,shpc=on,addr=ff,romfile=efi-virtio.rom" + devicePCIEBridgeString = "-device pcie-pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,addr=ff,romfile=efi-virtio.rom" + romfile = "efi-virtio.rom" +) + +func TestAppendDeviceVhostUser(t *testing.T) { + + vhostuserBlkDevice := VhostUserDevice{ + SocketPath: "/tmp/nonexistentsocket.socket", + CharDevID: "char2", + TypeDevID: "", + Address: "", + VhostUserType: VhostUserBlk, + ROMFile: romfile, + } + testAppend(vhostuserBlkDevice, deviceVhostUserBlkString, t) + + vhostuserSCSIDevice := VhostUserDevice{ + SocketPath: "/tmp/nonexistentsocket.socket", + CharDevID: "char1", + TypeDevID: "scsi1", + Address: "", + VhostUserType: VhostUserSCSI, + ROMFile: romfile, + } + testAppend(vhostuserSCSIDevice, deviceVhostUserSCSIString, t) + + vhostuserNetDevice := VhostUserDevice{ + SocketPath: "/tmp/nonexistentsocket.socket", + CharDevID: "char1", + TypeDevID: "net1", + Address: "00:11:22:33:44:55", + VhostUserType: VhostUserNet, + ROMFile: romfile, + } + testAppend(vhostuserNetDevice, deviceVhostUserNetString, t) +} + +func TestAppendVirtioBalloon(t *testing.T) { + balloonDevice := BalloonDevice{ + ID: "balloon", + ROMFile: romfile, + } + + var deviceString = "-device " + string(VirtioBalloon) + deviceString += ",id=" + balloonDevice.ID + ",romfile=" + balloonDevice.ROMFile + + var OnDeflateOnOMM = ",deflate-on-oom=on" + var OffDeflateOnOMM = ",deflate-on-oom=off" + + var OnDisableModern = ",disable-modern=true" + var OffDisableModern = ",disable-modern=false" + + testAppend(balloonDevice, deviceString+OffDeflateOnOMM+OffDisableModern, t) + + balloonDevice.DeflateOnOOM = true + testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OffDisableModern, t) + + balloonDevice.DisableModern = true + testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern, t) + +} diff --git a/qemu/qemu_test.go b/qemu/qemu_test.go index e1c70e56d1..5dcdb8aebd 100644 --- a/qemu/qemu_test.go +++ b/qemu/qemu_test.go @@ -126,8 +126,6 @@ func TestAppendDeviceNVDIMM(t *testing.T) { testAppend(object, deviceNVDIMMString, t) } -var deviceFSString = "-device virtio-9p-pci,disable-modern=true,fsdev=workload9p,mount_tag=rootfs,romfile=efi-virtio.rom -fsdev local,id=workload9p,path=/var/lib/docker/devicemapper/mnt/e31ebda2,security_model=none" - func TestAppendDeviceFS(t *testing.T) { fsdev := FSDevice{ Driver: Virtio9P, @@ -143,8 +141,6 @@ func TestAppendDeviceFS(t *testing.T) { testAppend(fsdev, deviceFSString, t) } -var deviceNetworkString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,romfile=efi-virtio.rom" - func TestAppendDeviceNetwork(t *testing.T) { netdev := NetDevice{ Driver: VirtioNet, @@ -162,8 +158,6 @@ func TestAppendDeviceNetwork(t *testing.T) { testAppend(netdev, deviceNetworkString, t) } -var deviceNetworkStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom" - func TestAppendDeviceNetworkMq(t *testing.T) { foo, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test") bar, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test") @@ -192,12 +186,10 @@ func TestAppendDeviceNetworkMq(t *testing.T) { testAppend(netdev, deviceNetworkStringMq, t) } -var deviceNetworkPCIString = "-netdev tap,id=tap0,vhost=on,ifname=ceth0,downscript=no,script=no -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,romfile=efi-virtio.rom" - func TestAppendDeviceNetworkPCI(t *testing.T) { netdev := NetDevice{ - Driver: VirtioNetPCI, + Driver: VirtioNet, Type: TAP, ID: "tap0", IFName: "ceth0", @@ -208,14 +200,12 @@ func TestAppendDeviceNetworkPCI(t *testing.T) { VHost: true, MACAddress: "01:02:de:ad:be:ef", DisableModern: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(netdev, deviceNetworkPCIString, t) } -var deviceNetworkPCIStringMq = "-netdev tap,id=tap0,vhost=on,fds=3:4 -device driver=virtio-net-pci,netdev=tap0,mac=01:02:de:ad:be:ef,bus=/pci-bus/pcie.0,addr=ff,disable-modern=true,mq=on,vectors=6,romfile=efi-virtio.rom" - func TestAppendDeviceNetworkPCIMq(t *testing.T) { foo, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test") bar, _ := ioutil.TempFile(os.TempDir(), "govmm-qemu-test") @@ -228,7 +218,7 @@ func TestAppendDeviceNetworkPCIMq(t *testing.T) { }() netdev := NetDevice{ - Driver: VirtioNetPCI, + Driver: VirtioNet, Type: TAP, ID: "tap0", IFName: "ceth0", @@ -240,20 +230,18 @@ func TestAppendDeviceNetworkPCIMq(t *testing.T) { VHost: true, MACAddress: "01:02:de:ad:be:ef", DisableModern: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(netdev, deviceNetworkPCIStringMq, t) } -var deviceSerialString = "-device virtio-serial-pci,disable-modern=true,id=serial0,romfile=efi-virtio.rom" - func TestAppendDeviceSerial(t *testing.T) { sdev := SerialDevice{ Driver: VirtioSerial, ID: "serial0", DisableModern: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(sdev, deviceSerialString, t) @@ -274,8 +262,6 @@ func TestAppendDeviceSerialPort(t *testing.T) { testAppend(chardev, deviceSerialPortString, t) } -var deviceBlockString = "-device virtio-blk,disable-modern=true,drive=hd0,scsi=off,config-wce=off,romfile=efi-virtio.rom -drive id=hd0,file=/var/lib/vm.img,aio=threads,format=qcow2,if=none" - func TestAppendDeviceBlock(t *testing.T) { blkdev := BlockDevice{ Driver: VirtioBlock, @@ -287,69 +273,28 @@ func TestAppendDeviceBlock(t *testing.T) { SCSI: false, WCE: false, DisableModern: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(blkdev, deviceBlockString, t) } -var deviceVhostUserNetString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -netdev type=vhost-user,id=net1,chardev=char1,vhostforce -device virtio-net-pci,netdev=net1,mac=00:11:22:33:44:55,romfile=efi-virtio.rom" -var deviceVhostUserSCSIString = "-chardev socket,id=char1,path=/tmp/nonexistentsocket.socket -device vhost-user-scsi-pci,id=scsi1,chardev=char1,romfile=efi-virtio.rom" -var deviceVhostUserBlkString = "-chardev socket,id=char2,path=/tmp/nonexistentsocket.socket -device vhost-user-blk-pci,logical_block_size=4096,size=512M,chardev=char2,romfile=efi-virtio.rom" - -func TestAppendDeviceVhostUser(t *testing.T) { - - vhostuserBlkDevice := VhostUserDevice{ - SocketPath: "/tmp/nonexistentsocket.socket", - CharDevID: "char2", - TypeDevID: "", - Address: "", - VhostUserType: VhostUserBlk, - ROMFile: "efi-virtio.rom", - } - testAppend(vhostuserBlkDevice, deviceVhostUserBlkString, t) - - vhostuserSCSIDevice := VhostUserDevice{ - SocketPath: "/tmp/nonexistentsocket.socket", - CharDevID: "char1", - TypeDevID: "scsi1", - Address: "", - VhostUserType: VhostUserSCSI, - ROMFile: "efi-virtio.rom", - } - testAppend(vhostuserSCSIDevice, deviceVhostUserSCSIString, t) - - vhostuserNetDevice := VhostUserDevice{ - SocketPath: "/tmp/nonexistentsocket.socket", - CharDevID: "char1", - TypeDevID: "net1", - Address: "00:11:22:33:44:55", - VhostUserType: VhostUserNet, - ROMFile: "efi-virtio.rom", - } - testAppend(vhostuserNetDevice, deviceVhostUserNetString, t) -} - -var deviceVFIOString = "-device vfio-pci,host=02:10.0,romfile=efi-virtio.rom" - func TestAppendDeviceVFIO(t *testing.T) { vfioDevice := VFIODevice{ BDF: "02:10.0", - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(vfioDevice, deviceVFIOString, t) } -var deviceVSOCKString = "-device vhost-vsock-pci,disable-modern=true,id=vhost-vsock-pci0,guest-cid=4,romfile=efi-virtio.rom" - func TestAppendVSOCK(t *testing.T) { vsockDevice := VSOCKDevice{ ID: "vhost-vsock-pci0", ContextID: 4, VHostFD: nil, DisableModern: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(vsockDevice, deviceVSOCKString, t) @@ -376,10 +321,13 @@ func TestVSOCKValid(t *testing.T) { func TestAppendVirtioRng(t *testing.T) { var objectString = "-object rng-random,id=rng0" - var deviceString = "-device " + string(VirtioRng) + ",rng=rng0,romfile=efi-virtio.rom" + var deviceString = "-device " + string(VirtioRng) + ",rng=rng0" + if romfile != "" { + deviceString = deviceString + ",romfile=efi-virtio.rom" + } rngDevice := RngDevice{ ID: "rng0", - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(rngDevice, objectString+" "+deviceString, t) @@ -417,31 +365,6 @@ func TestVirtioRngValid(t *testing.T) { } -func TestAppendVirtioBalloon(t *testing.T) { - balloonDevice := BalloonDevice{ - ID: "balloon", - ROMFile: "efi-virtio.rom", - } - - var deviceString = "-device " + string(VirtioBalloon) - deviceString += ",id=" + balloonDevice.ID + ",romfile=" + balloonDevice.ROMFile - - var OnDeflateOnOMM = ",deflate-on-oom=on" - var OffDeflateOnOMM = ",deflate-on-oom=off" - - var OnDisableModern = ",disable-modern=on" - var OffDisableModern = ",disable-modern=off" - - testAppend(balloonDevice, deviceString+OffDeflateOnOMM+OffDisableModern, t) - - balloonDevice.DeflateOnOOM = true - testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OffDisableModern, t) - - balloonDevice.DisableModern = true - testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern, t) - -} - func TestVirtioBalloonValid(t *testing.T) { balloon := BalloonDevice{ ID: "", @@ -457,13 +380,10 @@ func TestVirtioBalloonValid(t *testing.T) { } } -var deviceSCSIControllerStr = "-device virtio-scsi-pci,id=foo,romfile=efi-virtio.rom" -var deviceSCSIControllerBusAddrStr = "-device virtio-scsi-pci,id=foo,bus=pci.0,addr=00:04.0,disable-modern=true,iothread=iothread1,romfile=efi-virtio.rom" - func TestAppendDeviceSCSIController(t *testing.T) { scsiCon := SCSIController{ ID: "foo", - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(scsiCon, deviceSCSIControllerStr, t) @@ -474,8 +394,6 @@ func TestAppendDeviceSCSIController(t *testing.T) { testAppend(scsiCon, deviceSCSIControllerBusAddrStr, t) } -var devicePCIBridgeString = "-device pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,chassis_nr=5,shpc=on,addr=ff,romfile=efi-virtio.rom" - func TestAppendPCIBridgeDevice(t *testing.T) { bridge := BridgeDevice{ @@ -485,14 +403,12 @@ func TestAppendPCIBridgeDevice(t *testing.T) { Addr: "255", Chassis: 5, SHPC: true, - ROMFile: "efi-virtio.rom", + ROMFile: romfile, } testAppend(bridge, devicePCIBridgeString, t) } -var devicePCIEBridgeString = "-device pcie-pci-bridge,bus=/pci-bus/pcie.0,id=mybridge,addr=ff,romfile=efi-virtio.rom" - func TestAppendPCIEBridgeDevice(t *testing.T) { bridge := BridgeDevice{ diff --git a/qemu/qmp.go b/qemu/qmp.go index 43daed369d..7f89bdbda3 100644 --- a/qemu/qmp.go +++ b/qemu/qmp.go @@ -991,7 +991,7 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, romfile string) error { args := map[string]interface{}{ "id": devID, - "driver": "vfio-pci", + "driver": Vfio, "host": bdf, "romfile": romfile, } @@ -1006,11 +1006,12 @@ func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, romfile stri func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus, romfile string) error { args := map[string]interface{}{ "id": devID, - "driver": "vfio-pci", + "driver": Vfio, "host": bdf, "addr": addr, "romfile": romfile, } + if bus != "" { args["bus"] = bus } @@ -1025,10 +1026,11 @@ func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus, romfile string) error { args := map[string]interface{}{ "id": devID, - "driver": "vfio-pci", + "driver": Vfio, "sysfsdev": sysfsdev, "romfile": romfile, } + if bus != "" { args["bus"] = bus } @@ -1215,7 +1217,7 @@ func (q *QMP) ExecuteBalloon(ctx context.Context, bytes uint64) error { // ExecutePCIVSockAdd adds a vhost-vsock-pci bus func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd, addr, bus, romfile string, disableModern bool) error { args := map[string]interface{}{ - "driver": VHostVSockPCI, + "driver": VHostVSock, "id": id, "guest-cid": guestCID, "vhostfd": vhostfd,