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

Wen Congyang wency at cn.fujitsu.com
Thu Jun 9 08:43:16 UTC 2011


At 06/09/2011 04:37 PM, shu ming Write:
> Hi
>    I applied these pacches to libvirt tree
> 
> 8077d64f964705c1034555abeea38773532b762f
> 
> And built a qemu-kvm from the upstream qemu-kvm tree version 0.14.  I
> tested these new binaries on my Redhat Enterprise Linux 6.1 GA.
> 
> Now I can have multiple function devices after I changed the VM XML
> config file manually, please see the 'lspci' output below.  Also, I can
> hotplug one device, but it seems that unplugging it failed.
> -------------------------------------------------------------------------------------
> 
> [root at kvm-rhel-6 qemu]# virsh qemu-monitor-command
> kvm-rhel-6.1-multifunction-1 --hmp 'device_add
> lsi,id=scsi10,bus=pci.0,addr=0x7.0x00'
> 
> VM: **In the VM, 'lspci" can see one line added:
> 
> VM: **00:07.0 SCSI storage controller: LSI logic / Symbios Logic 5sc895a
> 
> [root at kvm-rhel-6 qemu]# virsh qemu-monitor-command
> kvm-rhel-6.1-multifunction-1 --hmp 'device_del
> lsi,id=scsi10,bus=pci.0,addr=0x7.0x00'

Oh, the command is wrong. The parameters of device_del is id. Please try:
'device_del scsi10'.

Thanks.
Wen Congyang

> Device 'lsi,id=scsi10,bus=pci.0,addr=0x7.0x00' not found
> 
> 
> ---------------------------------------------------------------------------------------------------------------
> 
> #lspci
>  00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev
>  02)
>  00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II]
>  00:01.1 IDE interface: Intel Coporation 82371SB PIIX3 IDE [Natoma/Triton
>  II]
>  00:01.2 USB Controller: Intel Corporation 82371SB PIIX3 USB Natoma/Triton
>  II]
>  00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03)
>  00:02.0 VGA compatible controller: Cirrus Logic GD 5446
>  00:03.0 Ethernet controller: Red Hat, Inc Virtio network device   --->
> function 0
>  00:03.1 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.2 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.3 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.4 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.5 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.6 Ethernet controller: Red Hat, Inc Virtio network device
>  00:03.7 Ethernet controller: Red Hat, Inc Virtio network device  --->
> function 7
>  00:04.0 Audio device: Intel Corporation 82801FB/FBM/FR/FW/FRW
> (ICH6 Family)
>  High
>  00:05.0 SCSI storage controller: Red Hat, Inc Virtio bloc device
>  00:06.0 RAM memory: Red Hat, Inc Virtio memory balloon
> 
> 
> 
> Daniel P. Berrange:
>> 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
> 
> 
> 




More information about the libvir-list mailing list