At 06/03/2011 09:28 PM, Daniel P. Berrange Write: > On Fri, May 27, 2011 at 06:22:34PM +0800, Wen Congyang wrote: >> Hot pluging/unpluging multi PCI device is not supported now. So the function >> of hotplugged PCI device must be 0. When we hot unplug it, we should set release >> all functions in the slot. >> --- >> src/qemu/qemu_command.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- >> src/qemu/qemu_command.h | 1 + >> src/qemu/qemu_hotplug.c | 24 ++++++++++++++++-------- >> 3 files changed, 60 insertions(+), 11 deletions(-) >> >> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c >> index 6f9540c..da18719 100644 >> --- a/src/qemu/qemu_command.c >> +++ b/src/qemu/qemu_command.c >> @@ -876,9 +876,19 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs, >> virDomainDeviceInfoPtr dev) >> { >> int ret = 0; >> - if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) >> - ret = qemuDomainPCIAddressReserveAddr(addrs, dev); >> - else >> + if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { >> + /* We do not support hotplug multi-function PCI device now, so we should >> + * reserve the whole slot. The function of the PCI device must be 0. >> + */ >> + if (dev->addr.pci.function != 0) { >> + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", >> + _("Only PCI device addresses with function=0" >> + " are supported")); >> + return -1; >> + } >> + >> + ret = qemuDomainPCIAddressReserveSlot(addrs, dev->addr.pci.slot); >> + } else >> ret = qemuDomainPCIAddressSetNextAddr(addrs, dev); > > Since the if() uses {}, you should add {} around the else clause > too. > >> return ret; >> } >> @@ -914,6 +924,36 @@ int qemuDomainPCIAddressReleaseFunction(qemuDomainPCIAddressSetPtr addrs, >> return qemuDomainPCIAddressReleaseAddr(addrs, &dev); >> } >> >> +int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot) >> +{ >> + virDomainDeviceInfo dev; >> + char *addr; >> + int function; >> + int ret = 0; >> + >> + dev.addr.pci.domain = 0; >> + dev.addr.pci.bus = 0; >> + dev.addr.pci.slot = slot; >> + >> + for (function = 0; function <= QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) { >> + addr = qemuPCIAddressAsString(&dev); >> + if (!addr) >> + return -1; >> + >> + if (!virHashLookup(addrs->used, addr)) { >> + VIR_FREE(addr); >> + continue; >> + } >> + >> + VIR_FREE(addr); >> + >> + if (qemuDomainPCIAddressReleaseFunction(addrs, slot, function) < 0) >> + ret = -1; >> + } >> + >> + return ret; >> +} >> + >> void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs) >> { >> if (!addrs) >> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h >> index 4c83182..d7673ad 100644 >> --- a/src/qemu/qemu_command.h >> +++ b/src/qemu/qemu_command.h >> @@ -160,6 +160,7 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs, >> virDomainDeviceInfoPtr dev); >> int qemuDomainPCIAddressReleaseFunction(qemuDomainPCIAddressSetPtr addrs, >> int slot, int function); >> +int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot); >> >> void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs); >> int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs); >> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c >> index e98c677..9f0ec06 100644 >> --- a/src/qemu/qemu_hotplug.c >> +++ b/src/qemu/qemu_hotplug.c >> @@ -221,7 +221,8 @@ error: >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && >> releaseaddr && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + disk->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on %s", disk->src); >> >> if (virSecurityManagerRestoreImageLabel(driver->securityManager, >> @@ -290,7 +291,8 @@ cleanup: >> qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && >> releaseaddr && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &controller->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + controller->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on controller"); >> >> VIR_FREE(devstr); >> @@ -697,7 +699,8 @@ cleanup: >> qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && >> releaseaddr && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &net->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + net->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on NIC"); >> >> if (ret != 0) >> @@ -828,7 +831,8 @@ error: >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> (hostdev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && >> releaseaddr && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &hostdev->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + hostdev->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on host device"); >> >> qemuDomainReAttachHostdevDevices(driver, &hostdev, 1); >> @@ -1198,7 +1202,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, >> qemuAuditDisk(vm, detach, NULL, "detach", ret >= 0); >> >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + detach->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src); >> >> virDomainDiskRemove(vm->def, i); >> @@ -1430,7 +1435,8 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, >> } >> >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + detach->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on controller"); >> >> virDomainControllerDefFree(detach); >> @@ -1529,7 +1535,8 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, >> qemuAuditNet(vm, detach, NULL, "detach", true); >> >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + detach->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on NIC"); >> >> virDomainConfNWFilterTeardown(detach); >> @@ -1653,7 +1660,8 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, >> } >> >> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && >> - qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) >> + qemuDomainPCIAddressReleaseSlot(priv->pciaddrs, >> + detach->info.addr.pci.slot) < 0) >> VIR_WARN("Unable to release PCI address on host device"); >> >> if (vm->def->nhostdevs > 1) { > > ACK > > > Daniel I addressed this comment, rebased this patch and pushed this series patch. Thanks for reviewing it. -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list