1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-28 11:21:44 +03:00

the hotplugged PCI device should use the whole slot

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.
This commit is contained in:
Wen Congyang 2011-05-23 15:43:35 +08:00
parent f12f34fe2f
commit 6fe678cdaf
3 changed files with 61 additions and 11 deletions

View File

@ -876,10 +876,21 @@ 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);
}
return ret;
}
@ -914,6 +925,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)

View File

@ -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);

View File

@ -242,7 +242,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,
@ -314,7 +315,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);
@ -739,7 +741,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)
@ -870,7 +873,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);
@ -1257,7 +1261,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
qemuAuditDisk(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 %s", dev->data.disk->src);
virDomainDiskRemove(vm->def, i);
@ -1496,7 +1501,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);
@ -1595,7 +1601,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);
@ -1719,7 +1726,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) {