return -1;
}
+static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainDeviceInfoPtr dev1,
+ void *opaque)
+{
+ virDomainDeviceInfoPtr dev2 = opaque;
+
+ if (dev1->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI ||
+ dev2->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+ return 0;
+
+ if (dev1->addr.pci.slot == dev2->addr.pci.slot &&
+ dev1->addr.pci.function != dev2->addr.pci.function)
+ return -1;
+ return 0;
+}
+
+static bool qemuIsMultiFunctionDevice(virDomainDefPtr def,
+ virDomainDeviceInfoPtr dev)
+{
+ if (virDomainDeviceInfoIterate(def, qemuComparePCIDevice, dev) < 0)
+ return true;
+ return false;
+}
+
int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainObjPtr vm,
detach = vm->def->disks[i];
+ if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot hot unplug multifunction PCI device: %s"),
+ dev->data.disk->dst);
+ goto cleanup;
+ }
+
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
goto cleanup;
}
+ if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot hot unplug multifunction PCI device: %s"),
+ dev->data.disk->dst);
+ goto cleanup;
+ }
+
if (qemuDomainControllerIsBusy(vm, detach)) {
qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("device cannot be detached: device is busy"));
goto cleanup;
}
+ if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot hot unplug multifunction PCI device :%s"),
+ dev->data.disk->dst);
+ goto cleanup;
+ }
+
if ((vlan = qemuDomainNetVLAN(detach)) < 0) {
qemuReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("unable to determine original VLAN"));
return -1;
}
+ if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("cannot hot unplug multifunction PCI device: %s"),
+ dev->data.disk->dst);
+ return -1;
+ }
+
if (!virDomainDeviceAddressIsValid(&detach->info,
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
qemuReportError(VIR_ERR_OPERATION_FAILED,