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@xxxxxxxxxxxxxxxxxx> > --- > 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 [...] -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list