On 11/21/2016 10:58 PM, Eric Farman wrote:
Adjust the device string that is built for vhost-scsi devices so that
it
can be invoked from hotplug.
From the QEMU command line, the file descriptors are expect to be numeric only.
However, for hotplug, the file descriptors are expected to begin with at least
one alphabetic character else this error occurs:
# virsh attach-device guest_0001 ~/vhost.xml
error: Failed to attach device from /root/vhost.xml
error: internal error: unable to execute QEMU command 'getfd':
Parameter 'fdname' expects a name not starting with a digit
We also close the file descriptor in this case, so that shutting down the
guest cleans up the host cgroup entries and allows future guests to use
vhost-scsi devices. (Otherwise the guest will silently end.)
Signed-off-by: Eric Farman <farman(a)linux.vnet.ibm.com>
---
src/qemu/qemu_hotplug.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 164 insertions(+)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 0508c67..02e248f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2443,6 +2443,126 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
goto cleanup;
}
+static int
+qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr hostdev)
+{
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virErrorPtr orig_err;
+ virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
+ { .hostdev = hostdev } };
+ virDomainCCWAddressSetPtr ccwaddrs = NULL;
+ char *vhostfdName = NULL;
+ int vhostfd = -1;
+ char *devstr = NULL;
+ bool teardowncgroup = false;
+ bool teardownlabel = false;
+ bool releaseaddr = false;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("SCSI passthrough is not supported by this version of
qemu"));
+ goto cleanup;
+ }
+
+ if (qemuHostdevPrepareSCSIVHostDevices(driver, vm->def->name, &hostdev, 1)
< 0) {
+ virDomainHostdevSubsysSCSIVHostPtr hostsrc =
&hostdev->source.subsys.u.scsi_host;
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unable to prepare scsi_host hostdev: %s"),
+ hostsrc->wwpn);
+ goto cleanup;
+ }
+
+ if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
+ goto cleanup;
+ teardowncgroup = true;
+
+ if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+ vm->def, hostdev, NULL) < 0)
+ goto cleanup;
+ teardownlabel = true;
+
+ if (virSCSIVHostOpenVhostSCSI(&vhostfd) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&vhostfdName, "vhostfd-%d", vhostfd) < 0)
+ goto cleanup;
+
+ if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ if (qemuDomainMachineIsS390CCW(vm->def) &&
+ virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW))
+ hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW;
+ }
+
+ if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE ||
+ hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ if (qemuDomainEnsurePCIAddress(vm, &dev) < 0)
+ goto cleanup;
+ } else if (hostdev->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+ if (!(ccwaddrs = qemuDomainCCWAddrSetCreateFromDomain(vm->def)))
+ goto cleanup;
+ if (virDomainCCWAddressAssign(hostdev->info, ccwaddrs,
+ !hostdev->info->addr.ccw.assigned) < 0)
+ goto cleanup;
+ }
+ releaseaddr = true;
+
+ if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1)
< 0)
+ goto cleanup;
+
+ if (!(devstr = qemuBuildSCSIVHostHostdevDevStr(vm->def,
+ hostdev,
+ priv->qemuCaps,
+ vhostfdName)))
+ goto cleanup;
+
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
+ goto cleanup;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+
+ if (qemuMonitorAddDeviceWithFd(priv->mon, devstr, vhostfd, vhostfdName) < 0)
+ goto exit_monitor;
+
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto audit;
+
+ vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
+ ret = 0;
+
+ audit:
+ virDomainAuditHostdev(vm, hostdev, "attach", (ret == 0));
+
+ cleanup:
+ virDomainCCWAddressSetFree(ccwaddrs);
Similar to AttachHost{PCI|USB|SCSI}Devices since
qemuHostdevPrepareSCSIVHostDevices was called, we need to call
virHostdevReAttachSCSIVHostDevices when ret < 0
I will adjust before pushing - most likely will follow PCI or USB (it's
been a long term goal to make them all consistent).
ACK -
John
[...]