From b9e0ca340d32c3767335f5d13bc2f1524380e769 Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Fri, 17 Aug 2018 14:31:41 -0700 Subject: [PATCH 1/2] vendor: vendor latest govmm Includes --share-rw option for hotplugging disks. govmm Shortlog: 2706a07 qemu: Use the supplied context.Context for launching e46092e qemu: Do not try and generate invalid RTC parameters fcaf61d qemu/qmp: add vfio mediated device support 4461c45 disk: Add --share-rw option for hotplugging disks 6851999 qemu/qmp: add addr and bus to hotplug vsock devices Signed-off-by: Archana Shinde --- Gopkg.lock | 8 ++-- Gopkg.toml | 2 +- vendor/github.com/intel/govmm/qemu/qemu.go | 27 ++++++------ vendor/github.com/intel/govmm/qemu/qmp.go | 48 +++++++++++++++++++--- 4 files changed, 59 insertions(+), 26 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 8750957dc..11d95f559 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -35,7 +35,7 @@ revision = "3d382e2f5dabe3bae62ceb9ded56bdee847008ee" [[projects]] - digest = "1:3e0383c8e6689f78621ca3592fe1adfc98c23a8bf354704c514d1e7c36d550d7" + digest = "1:827ed8a74e55981880c4d77f8472d638bceb899188104ba7bf24a9548fd97292" name = "github.com/containernetworking/cni" packages = ["pkg/types"] pruneopts = "NUT" @@ -115,11 +115,11 @@ revision = "3520598351bb3500a49ae9563f5539666ae0a27c" [[projects]] - digest = "1:a801632523299b53fbd954449f36020cf751e4bd6fe2d923e3416e8f0603b4af" + digest = "1:e35245b8aac4b53c6dd7b161c8c19f038e2ad29a54a03d276a88f3fc2a656c29" name = "github.com/intel/govmm" packages = ["qemu"] pruneopts = "NUT" - revision = "eda239928bfa12b214e9c93192d548cccf4e7f1e" + revision = "d8f80cafe3ee3bba440a9ff8d234817b64a30b07" [[projects]] digest = "1:f2f0d25f32da7843fa4cdc2becb88eea9d1aa9f9c4167431b4c1cd1c3b7fb17c" @@ -389,7 +389,6 @@ "github.com/clearcontainers/proxy/api", "github.com/clearcontainers/proxy/client", "github.com/containerd/cri-containerd/pkg/annotations", - "github.com/containernetworking/cni/pkg/types", "github.com/containernetworking/plugins/pkg/ns", "github.com/dlespiau/covertool/pkg/cover", "github.com/docker/go-units", @@ -410,6 +409,7 @@ "github.com/sirupsen/logrus", "github.com/sirupsen/logrus/hooks/syslog", "github.com/stretchr/testify/assert", + "github.com/uber/jaeger-client-go", "github.com/uber/jaeger-client-go/config", "github.com/urfave/cli", "github.com/vishvananda/netlink", diff --git a/Gopkg.toml b/Gopkg.toml index 23b20327d..0aa78ed58 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -52,7 +52,7 @@ [[constraint]] name = "github.com/intel/govmm" - revision = "eda239928bfa12b214e9c93192d548cccf4e7f1e" + revision = "d8f80cafe3ee3bba440a9ff8d234817b64a30b07" [[constraint]] name = "github.com/kata-containers/agent" diff --git a/vendor/github.com/intel/govmm/qemu/qemu.go b/vendor/github.com/intel/govmm/qemu/qemu.go index 31254231d..d2f27f51d 100644 --- a/vendor/github.com/intel/govmm/qemu/qemu.go +++ b/vendor/github.com/intel/govmm/qemu/qemu.go @@ -1064,16 +1064,12 @@ type RTC struct { // Valid returns true if the RTC structure is valid and complete. func (rtc RTC) Valid() bool { - if rtc.Clock != "" { - if rtc.Clock != Host && rtc.Clock != VM { - return false - } + if rtc.Clock != Host && rtc.Clock != VM { + return false } - if rtc.DriftFix != "" { - if rtc.DriftFix != Slew && rtc.DriftFix != NoDriftFix { - return false - } + if rtc.DriftFix != Slew && rtc.DriftFix != NoDriftFix { + return false } return true @@ -1239,7 +1235,7 @@ type Config struct { // Path is the qemu binary path. Path string - // Ctx is not used at the moment. + // Ctx is the context used when launching qemu. Ctx context.Context // Name is the qemu guest name @@ -1636,7 +1632,12 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) { return "", err } - return LaunchCustomQemu(config.Ctx, config.Path, config.qemuParams, + ctx := config.Ctx + if ctx == nil { + ctx = context.Background() + } + + return LaunchCustomQemu(ctx, config.Path, config.qemuParams, config.fds, nil, logger) } @@ -1644,10 +1645,6 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) { // // The path parameter is used to pass the qemu executable path. // -// The ctx parameter is not currently used but has been added so that the -// signature of this function will not need to change when launch cancellation -// is implemented. -// // params is a slice of options to pass to qemu-system-x86_64 and fds is a // list of open file descriptors that are to be passed to the spawned qemu // process. The attrs parameter can be used to control aspects of the @@ -1672,7 +1669,7 @@ func LaunchCustomQemu(ctx context.Context, path string, params []string, fds []* } /* #nosec */ - cmd := exec.Command(path, params...) + cmd := exec.CommandContext(ctx, path, params...) if len(fds) > 0 { logger.Infof("Adding extra file %v", fds) cmd.ExtraFiles = fds diff --git a/vendor/github.com/intel/govmm/qemu/qmp.go b/vendor/github.com/intel/govmm/qemu/qmp.go index ea6cb6454..92000fe03 100644 --- a/vendor/github.com/intel/govmm/qemu/qmp.go +++ b/vendor/github.com/intel/govmm/qemu/qmp.go @@ -671,7 +671,8 @@ func (q *QMP) ExecuteBlockdevAdd(ctx context.Context, device, blockdevID string) // to a previous call to ExecuteBlockdevAdd. devID is the id of the device to // 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. -func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string) error { +// 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 { args := map[string]interface{}{ "id": devID, "driver": driver, @@ -680,6 +681,9 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b if bus != "" { args["bus"] = bus } + if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) { + args["share-rw"] = "on" + } return q.executeCommand(ctx, "device_add", args, nil) } @@ -689,8 +693,9 @@ func (q *QMP) ExecuteDeviceAdd(ctx context.Context, blockdevID, devID, driver, b // the device to add. Both strings must be valid QMP identifiers. driver is the name of the // scsi driver,e.g., scsi-hd, and bus is the name of a SCSI controller bus. // scsiID is the SCSI id, lun is logical unit number. scsiID and lun are optional, a negative value -// for scsiID and lun is ignored. -func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, driver, bus string, scsiID, lun int) error { +// 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 { // TBD: Add drivers for scsi passthrough like scsi-generic and scsi-block drivers := []string{"scsi-hd", "scsi-cd", "scsi-disk"} @@ -718,6 +723,9 @@ func (q *QMP) ExecuteSCSIDeviceAdd(ctx context.Context, blockdevID, devID, drive if lun >= 0 { args["lun"] = lun } + if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) { + args["share-rw"] = "on" + } return q.executeCommand(ctx, "device_add", args, nil) } @@ -820,8 +828,9 @@ func (q *QMP) ExecuteDeviceDel(ctx context.Context, devID string) error { // ExecutePCIDeviceAdd is the PCI version of ExecuteDeviceAdd. This function can be used // to hot plug PCI devices on PCI(E) bridges, unlike ExecuteDeviceAdd this function receive the -// device address on its parent bus. bus is optional. -func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver, addr, bus string) error { +// 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 { args := map[string]interface{}{ "id": devID, "driver": driver, @@ -831,6 +840,10 @@ func (q *QMP) ExecutePCIDeviceAdd(ctx context.Context, blockdevID, devID, driver if bus != "" { args["bus"] = bus } + if shared && (q.version.Major > 2 || (q.version.Major == 2 && q.version.Minor >= 10)) { + args["share-rw"] = "on" + } + return q.executeCommand(ctx, "device_add", args, nil) } @@ -865,6 +878,24 @@ func (q *QMP) ExecutePCIVFIODeviceAdd(ctx context.Context, devID, bdf, addr, bus return q.executeCommand(ctx, "device_add", args, nil) } +// ExecutePCIVFIOMediatedDeviceAdd adds a VFIO mediated device to a QEMU instance using the device_add command. +// This function can be used to hot plug VFIO mediated devices on PCI(E) bridges, unlike +// 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. sysfsdev is the VFIO +// mediated device. +func (q *QMP) ExecutePCIVFIOMediatedDeviceAdd(ctx context.Context, devID, sysfsdev, addr, bus string) error { + args := map[string]interface{}{ + "id": devID, + "driver": "vfio-pci", + "sysfsdev": sysfsdev, + "addr": addr, + } + if bus != "" { + args["bus"] = bus + } + return q.executeCommand(ctx, "device_add", args, nil) +} + // ExecuteCPUDeviceAdd adds a CPU to a QEMU instance using the device_add command. // 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 @@ -956,12 +987,17 @@ func (q *QMP) ExecHotplugMemory(ctx context.Context, qomtype, id, mempath string } // ExecutePCIVSockAdd adds a vhost-vsock-pci bus -func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd string, disableModern bool) error { +func (q *QMP) ExecutePCIVSockAdd(ctx context.Context, id, guestCID, vhostfd, addr, bus string, disableModern bool) error { args := map[string]interface{}{ "driver": VHostVSockPCI, "id": id, "guest-cid": guestCID, "vhostfd": vhostfd, + "addr": addr, + } + + if bus != "" { + args["bus"] = bus } if disableModern { From 70edc56fc15198d912f1efdf177a70a3f07b1108 Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Fri, 17 Aug 2018 14:37:20 -0700 Subject: [PATCH 2/2] disk: Pass the --share-rw option for hotplugging disks With qemu 2.10, a write lock was added for qcow images that prevents the same image to be passed more than once. This can be over-ridden using the --share-rw option which is desired for raw images. This solves an issue with running Kata with devicemapper using the privileged mode as in this case all devices on the host are passed to the container including the block device associated with the rootfs, causing it to be passed twice to qemu. Fixes #606 Signed-off-by: Archana Shinde --- virtcontainers/qemu.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index ade8a5ed6..3b70aae5c 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -689,7 +689,7 @@ func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error // PCI address is in the format bridge-addr/device-addr eg. "03/02" drive.PCIAddr = fmt.Sprintf("%02x", bridge.Addr) + "/" + addr - if err = q.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, devID, driver, addr, bridge.ID); err != nil { + if err = q.qmpMonitorCh.qmp.ExecutePCIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, devID, driver, addr, bridge.ID, true); err != nil { return err } } else { @@ -704,7 +704,7 @@ func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error return err } - if err = q.qmpMonitorCh.qmp.ExecuteSCSIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, devID, driver, bus, scsiID, lun); err != nil { + if err = q.qmpMonitorCh.qmp.ExecuteSCSIDeviceAdd(q.qmpMonitorCh.ctx, drive.ID, devID, driver, bus, scsiID, lun, true); err != nil { return err } }