[libvirt] [PATCH 2/7] prevent hot unplugging multi function PCI device

Daniel P. Berrange berrange at redhat.com
Fri Jun 3 13:24:06 UTC 2011


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 :|




More information about the libvir-list mailing list