vendor: Update govmm vendoring

Shortlog:

f9b31c0 qemu: Allow disable-modern option from QMP
d617307 Run tests for the s390x build
b36b5a8 Contributors: Add Clare Chen to CONTRIBUTORS.md
b41939c Contributors: Add my name
dab4cf1 qmp: Add tests
5ea6da1 Verify govmm builds on s390x
ee75813 contributors: add my name
c80fc3b qemu: Add s390x support
ca477a1 Update source file headers
e68e005 Update the CONTRIBUTING.md
2b7db54 Add the CONTRIBUTORS.md file
b3b765c qemu: test Valid for Vsock for Context ID
3becff5 qemu: change of ContextID from uint32 to uint64
f30fd13 qmp: Output error detail when execute QMP command failed
7da6a4c qmp: fix mem-path properties for hotplug memory.
e4892e3 qemu/qmp: preparation for s390x support
110d2fa qemu/qmp: add new function ExecuteBlockdevAddWithCache
a0b0c86 qmp_test: Change QMP version from 2.6 to 2.9
10c36a1 qemu: add support for pidfile option

Fixes #983

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2018-12-05 23:46:07 -08:00
parent 0a7a4379dc
commit 018c8c1468
11 changed files with 458 additions and 148 deletions

View File

@@ -1,5 +1,5 @@
/*
// Copyright (c) 2016 Intel Corporation
// Copyright contributors to the Virtual Machine Manager for Go project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -313,7 +313,7 @@ func (q *QMP) finaliseCommandWithResponse(cmdEl *list.Element, cmdQueue *list.Li
if succeeded {
cmd.res <- qmpResult{response: response}
} else {
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed")}
cmd.res <- qmpResult{err: fmt.Errorf("QMP command failed: %v", response)}
}
}
if cmdQueue.Len() > 0 {
@@ -325,6 +325,23 @@ func (q *QMP) finaliseCommand(cmdEl *list.Element, cmdQueue *list.List, succeede
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, nil)
}
func (q *QMP) errorDesc(errorData interface{}) (string, error) {
// convert error to json
data, err := json.Marshal(errorData)
if err != nil {
return "", fmt.Errorf("Unable to extract error information: %v", err)
}
// see: https://github.com/qemu/qemu/blob/stable-2.12/qapi/qmp-dispatch.c#L125
var qmpErr map[string]string
// convert json to qmpError
if err = json.Unmarshal(data, &qmpErr); err != nil {
return "", fmt.Errorf("Unable to convert json to qmpError: %v", err)
}
return qmpErr["desc"], nil
}
func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
var vmData map[string]interface{}
err := json.Unmarshal(line, &vmData)
@@ -339,7 +356,7 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
}
response, succeeded := vmData["return"]
_, failed := vmData["error"]
errData, failed := vmData["error"]
if !succeeded && !failed {
return
@@ -353,6 +370,14 @@ func (q *QMP) processQMPInput(line []byte, cmdQueue *list.List) {
}
cmd := cmdEl.Value.(*qmpCommand)
if failed || cmd.filter == nil {
if errData != nil {
desc, err := q.errorDesc(errData)
if err != nil {
q.cfg.Logger.Infof("Get error description failed: %v", err)
} else {
response = desc
}
}
q.finaliseCommandWithResponse(cmdEl, cmdQueue, succeeded, response)
} else {
cmd.resultReceived = true
@@ -722,11 +747,7 @@ func (q *QMP) ExecuteQuit(ctx context.Context) error {
return q.executeCommand(ctx, "quit", nil, nil)
}
// ExecuteBlockdevAdd sends a blockdev-add to the QEMU instance. device is the
// path of the device to add, e.g., /dev/rdb0, and blockdevID is an identifier
// used to name the device. As this identifier will be passed directly to QMP,
// it must obey QMP's naming rules, e,g., it must start with a letter.
func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) error {
func (q *QMP) blockdevAddBaseArgs(device, blockdevID string) (map[string]interface{}, map[string]interface{}) {
var args map[string]interface{}
blockdevArgs := map[string]interface{}{
@@ -747,6 +768,39 @@ func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string)
}
}
return args, blockdevArgs
}
// ExecuteBlockdevAdd sends a blockdev-add to the QEMU instance. device is the
// path of the device to add, e.g., /dev/rdb0, and blockdevID is an identifier
// used to name the device. As this identifier will be passed directly to QMP,
// it must obey QMP's naming rules, e,g., it must start with a letter.
func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) error {
args, _ := q.blockdevAddBaseArgs(device, blockdevID)
return q.executeCommand(ctx, "blockdev-add", args, nil)
}
// ExecuteBlockdevAddWithCache has two more parameters direct and noFlush
// than ExecuteBlockdevAdd.
// They are cache-related options for block devices that are described in
// https://github.com/qemu/qemu/blob/master/qapi/block-core.json.
// direct denotes whether use of O_DIRECT (bypass the host page cache)
// is enabled. noFlush denotes whether flush requests for the device are
// ignored.
func (q *QMP) ExecuteBlockdevAddWithCache(ctx context.Context, device, blockdevID string, direct, noFlush bool) error {
args, blockdevArgs := q.blockdevAddBaseArgs(device, blockdevID)
if q.version.Major < 2 || (q.version.Major == 2 && q.version.Minor < 9) {
return fmt.Errorf("versions of qemu (%d.%d) older than 2.9 do not support set cache-related options for block devices",
q.version.Major, q.version.Minor)
}
blockdevArgs["cache"] = map[string]interface{}{
"direct": direct,
"no-flush": noFlush,
}
return q.executeCommand(ctx, "blockdev-add", args, nil)
}
@@ -756,7 +810,10 @@ 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, romfile string, shared bool) error {
// disableModern indicates if virtio version 1.0 should be replaced by the
// former version 0.9, as there is a KVM bug that occurs when using virtio
// 1.0 in nested environments.
func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus, romfile string, shared, disableModern bool) error {
args := map[string]interface{}{
"id": devID,
"driver": driver,
@@ -770,6 +827,10 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
if disableModern {
args["disable-modern"] = disableModern
}
}
return q.executeCommand(ctx, "device_add", args, nil)
@@ -783,7 +844,10 @@ 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, romfile string, scsiID, lun int, shared bool) error {
// disableModern indicates if virtio version 1.0 should be replaced by the
// former version 0.9, as there is a KVM bug that occurs when using virtio
// 1.0 in nested environments.
func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus, romfile string, scsiID, lun int, shared, disableModern bool) error {
// TBD: Add drivers for scsi passthrough like scsi-generic and scsi-block
drivers := []string{"scsi-hd", "scsi-cd", "scsi-disk"}
@@ -816,6 +880,10 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
if disableModern {
args["disable-modern"] = disableModern
}
}
return q.executeCommand(ctx, "device_add", args, nil)
@@ -908,7 +976,10 @@ 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, romfile string, queues int) error {
// disableModern indicates if virtio version 1.0 should be replaced by the
// former version 0.9, as there is a KVM bug that occurs when using virtio
// 1.0 in nested environments.
func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus, romfile string, queues int, disableModern bool) error {
args := map[string]interface{}{
"id": devID,
"driver": VirtioNetPCI,
@@ -927,6 +998,9 @@ func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAd
if netdevID != "" {
args["netdev"] = netdevID
}
if disableModern {
args["disable-modern"] = disableModern
}
if queues > 0 {
// (2N+2 vectors, N for tx queues, N for rx queues, 1 for config, and one for possible control vq)
@@ -942,6 +1016,26 @@ func (q *QMP) ExecuteNetPCIDeviceAdd(ctx context.Context, netdevID, devID, macAd
return q.executeCommand(ctx, "device_add", args, nil)
}
// ExecuteNetCCWDeviceAdd adds a Net CCW device to a QEMU instance
// 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) ExecuteNetCCWDeviceAdd(ctx context.Context, netdevID, devID, macAddr, addr, bus string, queues int) error {
args := map[string]interface{}{
"id": devID,
"driver": VirtioNetCCW,
"netdev": netdevID,
"mac": macAddr,
"addr": addr,
}
if queues > 0 {
args["mq"] = "on"
}
return q.executeCommand(ctx, "device_add", args, nil)
}
// ExecuteDeviceDel deletes guest portion of a QEMU device by sending a
// device_del command. devId is the identifier of the device to delete.
// Typically it would match the devID parameter passed to an earlier call
@@ -964,7 +1058,10 @@ 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, romfile string, shared bool) error {
// disableModern indicates if virtio version 1.0 should be replaced by the
// former version 0.9, as there is a KVM bug that occurs when using virtio
// 1.0 in nested environments.
func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver, addr, bus, romfile string, shared, disableModern bool) error {
args := map[string]interface{}{
"id": devID,
"driver": driver,
@@ -979,6 +1076,10 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver
}
if isVirtioPCI[DeviceDriver(driver)] {
args["romfile"] = romfile
if disableModern {
args["disable-modern"] = disableModern
}
}
return q.executeCommand(ctx, "device_add", args, nil)
@@ -991,7 +1092,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 +1107,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 +1127,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
}
@@ -1170,13 +1273,14 @@ func (q *QMP) ExecQueryCpusFast(ctx context.Context) ([]CPUInfoFast, error) {
// ExecHotplugMemory adds size of MiB memory to the guest
func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string, size int) error {
props := map[string]interface{}{"size": uint64(size) << 20}
args := map[string]interface{}{
"qom-type": qomtype,
"id": id,
"props": map[string]interface{}{"size": uint64(size) << 20},
"props": props,
}
if mempath != "" {
args["mem-path"] = mempath
props["mem-path"] = mempath
}
err := q.executeCommand(ctx, "object-add", args, nil)
if err != nil {
@@ -1213,9 +1317,12 @@ func (q *QMP) ExecuteBalloon(ctx context.Context, bytes uint64) error {
}
// ExecutePCIVSockAdd adds a vhost-vsock-pci bus
// disableModern indicates if virtio version 1.0 should be replaced by the
// former version 0.9, as there is a KVM bug that occurs when using virtio
// 1.0 in nested environments.
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,