On Fri, May 27, 2011 at 06:20:10PM +0800, Wen Congyang wrote: > We do not support to hot unplug multi function PCI device now. If the device is > one function of multi function PCI device, we shoul not allow to hot unplugg > it. > --- > src/qemu/qemu_hotplug.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 52 insertions(+), 0 deletions(-) > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index 3cf7d35..e98c677 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -1100,6 +1100,30 @@ static inline int qemuFindDisk(virDomainDefPtr def, const char *dst) > 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, > @@ -1121,6 +1145,13 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, > > 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, > @@ -1351,6 +1382,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, > 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")); > @@ -1438,6 +1476,13 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, > 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")); > @@ -1567,6 +1612,13 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, > 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, ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list