vendor: Update govmm vendoring

Shortlog:

9c819db qemu: Fix virtio-net-pci QMP command
7fdfc6a qemu: Add support for romfile option
e74de3c Update guidelines on security issue reporting
ec83abe qemu: Add virtio-balloon device suppport.
4697078 qemu: Show full path to qemu binary at launch time

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2018-10-16 18:26:56 -07:00
parent d00742f43f
commit 6f0873a2c3
4 changed files with 262 additions and 60 deletions

4
Gopkg.lock generated
View File

@ -123,11 +123,11 @@
revision = "3520598351bb3500a49ae9563f5539666ae0a27c"
[[projects]]
digest = "1:c63a5bf4f3fd94ae838ce53e3492c0a467c40d09cada9301d228df7164ba4e55"
digest = "1:6cfbc8646c1b7746e366eacb17a6f6f97f28beabd87eebffe961447419eb60bf"
name = "github.com/intel/govmm"
packages = ["qemu"]
pruneopts = "NUT"
revision = "f03df80fc3dc52f65ed6c7d12806279b44185d32"
revision = "e82e8498c5a214b24ac75e0a05ace556bf91a9ab"
[[projects]]
digest = "1:672470f31bc4e50f9ba09a1af7ab6035bf8b1452db64dfd79b1a22614bb30710"

View File

@ -52,7 +52,7 @@
[[constraint]]
name = "github.com/intel/govmm"
revision = "f03df80fc3dc52f65ed6c7d12806279b44185d32"
revision = "e82e8498c5a214b24ac75e0a05ace556bf91a9ab"
[[constraint]]
name = "github.com/kata-containers/agent"

View File

@ -88,8 +88,55 @@ const (
// VirtioRng is the paravirtualized RNG device driver.
VirtioRng DeviceDriver = "virtio-rng"
// VirtioBalloon is the memory balloon device driver.
VirtioBalloon DeviceDriver = "virtio-balloon"
//VhostUserSCSI represents a SCSI vhostuser device type.
VhostUserSCSI DeviceDriver = "vhost-user-scsi-pci"
//VhostUserNet represents a net vhostuser device type.
VhostUserNet DeviceDriver = "virtio-net-pci"
//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"
// PCIePCIBridgeDriver represents a PCIe to PCI bridge device type.
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,
}
// ObjectType is a string representing a qemu object type.
type ObjectType string
@ -216,6 +263,9 @@ type FSDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the FSDevice structure is valid and complete.
@ -239,6 +289,9 @@ func (fsdev FSDevice) QemuParams(config *Config) []string {
}
deviceParams = append(deviceParams, fmt.Sprintf(",fsdev=%s", fsdev.ID))
deviceParams = append(deviceParams, fmt.Sprintf(",mount_tag=%s", fsdev.MountTag))
if isVirtioPCI[fsdev.Driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", fsdev.ROMFile))
}
fsParams = append(fsParams, string(fsdev.FSDriver))
fsParams = append(fsParams, fmt.Sprintf(",id=%s", fsdev.ID))
@ -296,6 +349,9 @@ type CharDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the CharDevice structure is valid and complete.
@ -325,6 +381,9 @@ func (cdev CharDevice) QemuParams(config *Config) []string {
if cdev.Name != "" {
deviceParams = append(deviceParams, fmt.Sprintf(",name=%s", cdev.Name))
}
if isVirtioPCI[cdev.Driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", cdev.ROMFile))
}
cdevParams = append(cdevParams, string(cdev.Backend))
cdevParams = append(cdevParams, fmt.Sprintf(",id=%s", cdev.ID))
@ -388,7 +447,7 @@ func (n NetDeviceType) QemuNetdevParam() string {
}
// QemuDeviceParam converts to the QEMU -device parameter notation
func (n NetDeviceType) QemuDeviceParam() string {
func (n NetDeviceType) QemuDeviceParam() DeviceDriver {
switch n {
case TAP:
return "virtio-net-pci"
@ -447,6 +506,9 @@ type NetDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the NetDevice structure is valid and complete.
@ -473,8 +535,7 @@ func (netdev NetDevice) QemuDeviceParams(config *Config) []string {
return nil
}
deviceParams = append(deviceParams, "driver=")
deviceParams = append(deviceParams, netdev.Type.QemuDeviceParam())
deviceParams = append(deviceParams, fmt.Sprintf("driver=%s", netdev.Type.QemuDeviceParam()))
deviceParams = append(deviceParams, fmt.Sprintf(",netdev=%s", netdev.ID))
deviceParams = append(deviceParams, fmt.Sprintf(",mac=%s", netdev.MACAddress))
@ -510,6 +571,10 @@ func (netdev NetDevice) QemuDeviceParams(config *Config) []string {
deviceParams = append(deviceParams, fmt.Sprintf(",vectors=%d", vectors))
}
if isVirtioPCI[netdev.Driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", netdev.ROMFile))
}
return deviceParams
}
@ -598,6 +663,9 @@ type SerialDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the SerialDevice structure is valid and complete.
@ -619,6 +687,9 @@ func (dev SerialDevice) QemuParams(config *Config) []string {
deviceParams = append(deviceParams, ",disable-modern=true")
}
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", dev.ID))
if isVirtioPCI[dev.Driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", dev.ROMFile))
}
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
@ -669,6 +740,9 @@ type BlockDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the BlockDevice structure is valid and complete.
@ -699,6 +773,10 @@ func (blkdev BlockDevice) QemuParams(config *Config) []string {
deviceParams = append(deviceParams, ",config-wce=off")
}
if isVirtioPCI[blkdev.Driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", blkdev.ROMFile))
}
blkParams = append(blkParams, fmt.Sprintf("id=%s", blkdev.ID))
blkParams = append(blkParams, fmt.Sprintf(",file=%s", blkdev.File))
blkParams = append(blkParams, fmt.Sprintf(",aio=%s", blkdev.AIO))
@ -714,18 +792,6 @@ func (blkdev BlockDevice) QemuParams(config *Config) []string {
return qemuParams
}
// VhostUserDeviceType is a qemu vhost-user device type.
type VhostUserDeviceType string
const (
//VhostUserSCSI represents a SCSI vhostuser device type
VhostUserSCSI = "vhost-user-scsi-pci"
//VhostUserNet represents a net vhostuser device type
VhostUserNet = "virtio-net-pci"
//VhostUserBlk represents a block vhostuser device type
VhostUserBlk = "vhost-user-blk-pci"
)
// VhostUserDevice represents a qemu vhost-user device meant to be passed
// in to the guest
type VhostUserDevice struct {
@ -733,7 +799,10 @@ type VhostUserDevice struct {
CharDevID string
TypeDevID string //variable QEMU parameter based on value of VhostUserType
Address string //used for MAC address in net case
VhostUserType VhostUserDeviceType
VhostUserType DeviceDriver
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if there is a valid structure defined for VhostUserDevice
@ -766,6 +835,7 @@ func (vhostuserDev VhostUserDevice) QemuParams(config *Config) []string {
var charParams []string
var netParams []string
var devParams []string
var driver DeviceDriver
charParams = append(charParams, "socket")
charParams = append(charParams, fmt.Sprintf("id=%s", vhostuserDev.CharDevID))
@ -774,20 +844,23 @@ func (vhostuserDev VhostUserDevice) QemuParams(config *Config) []string {
switch vhostuserDev.VhostUserType {
// if network based vhost device:
case VhostUserNet:
driver = VhostUserNet
netParams = append(netParams, "type=vhost-user")
netParams = append(netParams, fmt.Sprintf("id=%s", vhostuserDev.TypeDevID))
netParams = append(netParams, fmt.Sprintf("chardev=%s", vhostuserDev.CharDevID))
netParams = append(netParams, "vhostforce")
devParams = append(devParams, VhostUserNet)
devParams = append(devParams, string(driver))
devParams = append(devParams, fmt.Sprintf("netdev=%s", vhostuserDev.TypeDevID))
devParams = append(devParams, fmt.Sprintf("mac=%s", vhostuserDev.Address))
case VhostUserSCSI:
devParams = append(devParams, VhostUserSCSI)
driver = VhostUserSCSI
devParams = append(devParams, string(driver))
devParams = append(devParams, fmt.Sprintf("id=%s", vhostuserDev.TypeDevID))
devParams = append(devParams, fmt.Sprintf("chardev=%s", vhostuserDev.CharDevID))
case VhostUserBlk:
devParams = append(devParams, VhostUserBlk)
driver = VhostUserBlk
devParams = append(devParams, string(driver))
devParams = append(devParams, "logical_block_size=4096")
devParams = append(devParams, "size=512M")
devParams = append(devParams, fmt.Sprintf("chardev=%s", vhostuserDev.CharDevID))
@ -795,6 +868,10 @@ func (vhostuserDev VhostUserDevice) QemuParams(config *Config) []string {
return nil
}
if isVirtioPCI[driver] {
devParams = append(devParams, fmt.Sprintf("romfile=%s", vhostuserDev.ROMFile))
}
qemuParams = append(qemuParams, "-chardev")
qemuParams = append(qemuParams, strings.Join(charParams, ","))
@ -813,6 +890,9 @@ func (vhostuserDev VhostUserDevice) QemuParams(config *Config) []string {
type VFIODevice struct {
// Bus-Device-Function of device
BDF string
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the VFIODevice structure is valid and complete.
@ -827,10 +907,17 @@ func (vfioDev VFIODevice) Valid() bool {
// QemuParams returns the qemu parameters built out of this vfio device.
func (vfioDev VFIODevice) QemuParams(config *Config) []string {
var qemuParams []string
var deviceParams []string
driver := VfioPCI
deviceParams = append(deviceParams, fmt.Sprintf("%s,host=%s", driver, vfioDev.BDF))
if isVirtioPCI[driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", vfioDev.ROMFile))
}
deviceParam := fmt.Sprintf("vfio-pci,host=%s", vfioDev.BDF)
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, deviceParam)
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
return qemuParams
}
@ -850,6 +937,9 @@ type SCSIController struct {
// IOThread is the IO thread on which IO will be handled
IOThread string
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the SCSIController structure is valid and complete.
@ -866,7 +956,8 @@ func (scsiCon SCSIController) QemuParams(config *Config) []string {
var qemuParams []string
var devParams []string
devParams = append(devParams, fmt.Sprintf("virtio-scsi-pci,id=%s", scsiCon.ID))
driver := VirtioScsiPCI
devParams = append(devParams, fmt.Sprintf("%s,id=%s", driver, scsiCon.ID))
if scsiCon.Bus != "" {
devParams = append(devParams, fmt.Sprintf("bus=%s", scsiCon.Bus))
}
@ -879,6 +970,9 @@ func (scsiCon SCSIController) QemuParams(config *Config) []string {
if scsiCon.IOThread != "" {
devParams = append(devParams, fmt.Sprintf("iothread=%s", scsiCon.IOThread))
}
if isVirtioPCI[driver] {
devParams = append(devParams, fmt.Sprintf("romfile=%s", scsiCon.ROMFile))
}
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, strings.Join(devParams, ","))
@ -916,6 +1010,9 @@ type BridgeDevice struct {
// PCI Slot
Addr string
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the BridgeDevice structure is valid and complete.
@ -938,28 +1035,35 @@ func (bridgeDev BridgeDevice) Valid() bool {
// QemuParams returns the qemu parameters built out of this bridge device.
func (bridgeDev BridgeDevice) QemuParams(config *Config) []string {
var qemuParams []string
var deviceParam string
var deviceParam []string
var driver DeviceDriver
switch bridgeDev.Type {
case PCIEBridge:
deviceParam = fmt.Sprintf("pcie-pci-bridge,bus=%s,id=%s", bridgeDev.Bus, bridgeDev.ID)
driver = PCIePCIBridgeDriver
deviceParam = append(deviceParam, fmt.Sprintf("%s,bus=%s,id=%s", driver, bridgeDev.Bus, bridgeDev.ID))
default:
driver = PCIBridgeDriver
shpc := "off"
if bridgeDev.SHPC {
shpc = "on"
}
deviceParam = fmt.Sprintf("pci-bridge,bus=%s,id=%s,chassis_nr=%d,shpc=%s", bridgeDev.Bus, bridgeDev.ID, bridgeDev.Chassis, shpc)
deviceParam = append(deviceParam, fmt.Sprintf("%s,bus=%s,id=%s,chassis_nr=%d,shpc=%s", driver, bridgeDev.Bus, bridgeDev.ID, bridgeDev.Chassis, shpc))
}
if bridgeDev.Addr != "" {
addr, err := strconv.Atoi(bridgeDev.Addr)
if err == nil && addr >= 0 {
deviceParam += fmt.Sprintf(",addr=%x", addr)
deviceParam = append(deviceParam, fmt.Sprintf(",addr=%x", addr))
}
}
if isVirtioPCI[driver] {
deviceParam = append(deviceParam, fmt.Sprintf(",romfile=%s", bridgeDev.ROMFile))
}
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, deviceParam)
qemuParams = append(qemuParams, strings.Join(deviceParam, ""))
return qemuParams
}
@ -975,16 +1079,14 @@ type VSOCKDevice struct {
// DisableModern prevents qemu from relying on fast MMIO.
DisableModern bool
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
const (
// MinimalGuestCID is the smallest valid context ID for a guest.
MinimalGuestCID uint32 = 3
)
const (
// VhostVSOCKPCI is the VSOCK vhost device type.
VhostVSOCKPCI = "vhost-vsock-pci"
// VSOCKGuestCID is the VSOCK guest CID parameter.
VSOCKGuestCID = "guest-cid"
@ -1004,7 +1106,8 @@ func (vsock VSOCKDevice) QemuParams(config *Config) []string {
var deviceParams []string
var qemuParams []string
deviceParams = append(deviceParams, fmt.Sprintf("%s", VhostVSOCKPCI))
driver := VHostVSockPCI
deviceParams = append(deviceParams, fmt.Sprintf("%s", driver))
if vsock.DisableModern {
deviceParams = append(deviceParams, ",disable-modern=true")
}
@ -1015,6 +1118,10 @@ func (vsock VSOCKDevice) QemuParams(config *Config) []string {
deviceParams = append(deviceParams, fmt.Sprintf(",id=%s", vsock.ID))
deviceParams = append(deviceParams, fmt.Sprintf(",%s=%d", VSOCKGuestCID, vsock.ContextID))
if isVirtioPCI[driver] {
deviceParams = append(deviceParams, fmt.Sprintf(",romfile=%s", vsock.ROMFile))
}
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, strings.Join(deviceParams, ""))
@ -1031,6 +1138,8 @@ type RngDevice struct {
MaxBytes uint
// Period is duration of a read period in seconds
Period uint
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// Valid returns true if the RngDevice structure is valid and complete.
@ -1051,12 +1160,17 @@ func (v RngDevice) QemuParams(_ *Config) []string {
//-device virtio-rng-pci,rng=rng0,max-bytes=1024,period=1000
var deviceParams []string
driver := VirtioRng
objectParams = append(objectParams, "rng-random")
objectParams = append(objectParams, "id="+v.ID)
deviceParams = append(deviceParams, string(VirtioRng))
deviceParams = append(deviceParams, string(driver))
deviceParams = append(deviceParams, "rng="+v.ID)
if isVirtioPCI[driver] {
deviceParams = append(deviceParams, fmt.Sprintf("romfile=%s", v.ROMFile))
}
if v.Filename != "" {
objectParams = append(objectParams, "filename="+v.Filename)
}
@ -1078,6 +1192,59 @@ func (v RngDevice) QemuParams(_ *Config) []string {
return qemuParams
}
// BalloonDevice represents a memory balloon device.
type BalloonDevice struct {
DeflateOnOOM bool
DisableModern bool
ID string
// ROMFile specifies the ROM file being used for this device.
ROMFile string
}
// QemuParams returns the qemu parameters built out of the BalloonDevice.
func (b BalloonDevice) QemuParams(_ *Config) []string {
var qemuParams []string
var deviceParams []string
driver := VirtioBalloon
deviceParams = append(deviceParams, string(driver))
if b.ID != "" {
deviceParams = append(deviceParams, "id="+b.ID)
}
if isVirtioPCI[driver] {
deviceParams = append(deviceParams, fmt.Sprintf("romfile=%s", b.ROMFile))
}
if b.DeflateOnOOM {
deviceParams = append(deviceParams, "deflate-on-oom=on")
} else {
deviceParams = append(deviceParams, "deflate-on-oom=off")
}
if b.DisableModern {
deviceParams = append(deviceParams, "disable-modern=on")
} else {
deviceParams = append(deviceParams, "disable-modern=off")
}
qemuParams = append(qemuParams, "-device")
qemuParams = append(qemuParams, strings.Join(deviceParams, ","))
return qemuParams
}
// Valid returns true if the balloonDevice structure is valid and complete.
func (b BalloonDevice) Valid() bool {
if b.ID == "" {
return false
}
return true
}
// RTCBaseType is the qemu RTC base time type.
type RTCBaseType string
@ -1740,11 +1907,11 @@ func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []*
var stderr bytes.Buffer
cmd.Stderr = &stderr
logger.Infof("launching qemu with: %v", params)
logger.Infof("launching %s with: %v", path, params)
err := cmd.Run()
if err != nil {
logger.Errorf("Unable to launch qemu: %v", err)
logger.Errorf("Unable to launch %s: %v", path, err)
errStr = stderr.String()
logger.Errorf("%s", errStr)
}

View File

@ -756,7 +756,7 @@ func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string)
// add. Both strings must be valid QMP identifiers. driver is the name of the
// driver,e.g., virtio-blk-pci, and bus is the name of the bus. bus is optional.
// shared denotes if the drive can be shared allowing it to be passed more than once.
func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string, shared bool) error {
func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus, romfile string, shared bool) error {
args := map[string]interface{}{
"id": devID,
"driver": driver,
@ -768,6 +768,10 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b
if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) {
args["share-rw"] = "on"
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -779,7 +783,7 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b
// scsiID is the SCSI id, lun is logical unit number. scsiID and lun are optional, a negative value
// for scsiID and lun is ignored. shared denotes if the drive can be shared allowing it
// to be passed more than once.
func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string, scsiID, lun int, shared bool) error {
func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus, romfile string, scsiID, lun int, shared bool) error {
// TBD: Add drivers for scsi passthrough like scsi-generic and scsi-block
drivers := []string{"scsi-hd", "scsi-cd", "scsi-disk"}
@ -810,6 +814,9 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive
if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) {
args["share-rw"] = "on"
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -901,18 +908,25 @@ func (q *QMP) ExecuteNetdevDel(ctx context.Context, netdevID string) error {
// using the device_add command. devID is the id of the device to add.
// Must be valid QMP identifier. netdevID is the id of nic added by previous netdev_add.
// queues is the number of queues of a nic.
func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus string, queues int) error {
func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus, romfile string, queues int) error {
args := map[string]interface{}{
"id": devID,
"driver": VirtioNetPCI,
"netdev": netdevID,
"mac": macAddr,
"addr": addr,
"id": devID,
"driver": VirtioNetPCI,
"romfile": romfile,
}
if bus != "" {
args["bus"] = bus
}
if addr != "" {
args["addr"] = addr
}
if macAddr != "" {
args["mac"] = macAddr
}
if netdevID != "" {
args["netdev"] = netdevID
}
if queues > 0 {
// (2N+2 vectors, N for tx queues, N for rx queues, 1 for config, and one for possible control vq)
@ -950,7 +964,7 @@ func (q *QMP) ExecuteDeviceDel(ctx context.Context, devID string) error {
// to hot plug PCI devices on PCI(E) bridges, unlike ExecuteDeviceAdd this function receive the
// device address on its parent bus. bus is optional. shared denotes if the drive can be shared
// allowing it to be passed more than once.
func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver, addr, bus string, shared bool) error {
func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver, addr, bus, romfile string, shared bool) error {
args := map[string]interface{}{
"id": devID,
"driver": driver,
@ -963,6 +977,9 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver
if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) {
args["share-rw"] = "on"
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -971,11 +988,12 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver
// using the device_add command. devID is the id of the device to add.
// Must be valid QMP identifier. bdf is the PCI bus-device-function
// of the pci device.
func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf string) error {
func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf, romfile string) error {
args := map[string]interface{}{
"id": devID,
"driver": "vfio-pci",
"host": bdf,
"id": devID,
"driver": "vfio-pci",
"host": bdf,
"romfile": romfile,
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -985,12 +1003,13 @@ func (q *QMP) ExecuteVFIODeviceAdd(ctx context.Context, devID, bdf string) error
// ExecuteVFIODeviceAdd this function receives the bus and the device address on its parent bus.
// bus is optional. devID is the id of the device to add.Must be valid QMP identifier. bdf is the
// PCI bus-device-function of the pci device.
func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus string) error {
func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus, romfile string) error {
args := map[string]interface{}{
"id": devID,
"driver": "vfio-pci",
"host": bdf,
"addr": addr,
"id": devID,
"driver": "vfio-pci",
"host": bdf,
"addr": addr,
"romfile": romfile,
}
if bus != "" {
args["bus"] = bus
@ -1003,11 +1022,12 @@ func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus
// ExecuteVFIODeviceAdd this function receives the bus and the device address on its parent bus.
// devID is the id of the device to add. Must be valid QMP identifier. sysfsdev is the VFIO mediated device.
// Both bus and addr are optional. If they are both set to be empty, the system will pick up an empty slot on root bus.
func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus string) error {
func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus, romfile string) error {
args := map[string]interface{}{
"id": devID,
"driver": "vfio-pci",
"sysfsdev": sysfsdev,
"romfile": romfile,
}
if bus != "" {
args["bus"] = bus
@ -1022,7 +1042,7 @@ func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsd
// driver is the CPU model, cpuID must be a unique ID to identify the CPU, socketID is the socket number within
// node/board the CPU belongs to, coreID is the core number within socket the CPU belongs to, threadID is the
// thread number within core the CPU belongs to.
func (q *QMP) ExecuteCPUDeviceAdd(ctx context.Context, driver, cpuID, socketID, coreID, threadID string) error {
func (q *QMP) ExecuteCPUDeviceAdd(ctx context.Context, driver, cpuID, socketID, coreID, threadID, romfile string) error {
args := map[string]interface{}{
"driver": driver,
"id": cpuID,
@ -1030,6 +1050,11 @@ func (q *QMP) ExecuteCPUDeviceAdd(ctx context.Context, driver, cpuID, socketID,
"core-id": coreID,
"thread-id": threadID,
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
}
return q.executeCommand(ctx, "device_add", args, nil)
}
@ -1178,14 +1203,24 @@ func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string
return err
}
// ExecuteBalloon sets the size of the balloon, hence updates the memory
// allocated for the VM.
func (q *QMP) ExecuteBalloon(ctx context.Context, bytes uint64) error {
args := map[string]interface{}{
"value": bytes,
}
return q.executeCommand(ctx, "balloon", args, nil)
}
// ExecutePCIVSockAdd adds a vhost-vsock-pci bus
func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd, addr, bus string, disableModern bool) error {
func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd, addr, bus, romfile string, disableModern bool) error {
args := map[string]interface{}{
"driver": VHostVSockPCI,
"id": id,
"guest-cid": guestCID,
"vhostfd": vhostfd,
"addr": addr,
"romfile": romfile,
}
if bus != "" {