return NULL;
}
-int qemuDomainPCIAddressReserve(qemuDomainPCIAddressSetPtr addrs,
- int slot)
+int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev)
{
- virDomainDeviceInfo dev;
char *addr;
- dev.addr.pci.domain = 0;
- dev.addr.pci.bus = 0;
- dev.addr.pci.slot = slot;
-
- addr = qemuPCIAddressAsString(&dev);
+ addr = qemuPCIAddressAsString(dev);
if (!addr)
return -1;
return 0;
}
+int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
+ int slot)
+{
+ virDomainDeviceInfo dev;
+
+ dev.addr.pci.domain = 0;
+ dev.addr.pci.bus = 0;
+ dev.addr.pci.slot = slot;
+
+ return qemuDomainPCIAddressReserveAddr(addrs, &dev);
+}
+
+
+int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev)
+{
+ int ret = 0;
+ if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+ ret = qemuDomainPCIAddressReserveAddr(addrs, dev);
+ else
+ ret = qemuDomainPCIAddressSetNextAddr(addrs, dev);
+ return ret;
+}
static void qemuDomainPCIAddressSetFreeEntry(void *payload, const char *name ATTRIBUTE_UNUSED)
{
}
+int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev)
+{
+ char *addr;
+ int ret;
+
+ addr = qemuPCIAddressAsString(dev);
+ if (!addr)
+ return -1;
+
+ ret = virHashRemoveEntry(addrs->used, addr, qemuDomainPCIAddressSetFreeEntry);
+
+ VIR_FREE(addr);
+
+ return ret;
+}
+
+
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
{
if (!addrs)
int i;
/* Host bridge */
- if (qemuDomainPCIAddressReserve(addrs, 0) < 0)
+ if (qemuDomainPCIAddressReserveSlot(addrs, 0) < 0)
goto error;
/* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller) */
- if (qemuDomainPCIAddressReserve(addrs, 1) < 0)
+ if (qemuDomainPCIAddressReserveSlot(addrs, 1) < 0)
goto error;
/* VGA */
- if (qemuDomainPCIAddressReserve(addrs, 2) < 0)
+ if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
goto error;
/* VirtIO Balloon */
- if (qemuDomainPCIAddressReserve(addrs, 3) < 0)
+ if (qemuDomainPCIAddressReserveSlot(addrs, 3) < 0)
goto error;
for (i = 0; i < def->ndisks ; i++) {
const char *args);
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def);
-int qemuDomainPCIAddressReserve(qemuDomainPCIAddressSetPtr addrs,
- int slot);
+int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
+ int slot);
+int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev);
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev);
+int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev);
+int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainDeviceInfoPtr dev);
+
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs);
return -1;
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+ if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0)
+ goto error;
+
if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCmdFlags)))
goto error;
VIR_FREE(devstr);
VIR_FREE(drivestr);
+ if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
+ qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
+ VIR_WARN("Unable to release PCI address on %s", disk->src);
+
if (driver->securityDriver &&
driver->securityDriver->domainRestoreSecurityImageLabel &&
driver->securityDriver->domainRestoreSecurityImageLabel(conn, vm, disk) < 0)
}
}
+ if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0)
+ goto cleanup;
+
if (!(devstr = qemuBuildControllerDevStr(controller))) {
virReportOOMError(NULL);
goto cleanup;
}
cleanup:
+ if ((ret != 0) &&
+ (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
+ qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &controller->info) < 0)
+ VIR_WARN0("Unable to release PCI address on controller");
+
VIR_FREE(devstr);
return ret;
}
qemuAssignNetNames(vm->def, net) < 0)
goto no_memory;
+ if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
+ goto cleanup;
+
/* Choose a vlan value greater than all other values since
* older versions did not store the value in the state file.
*/
vm->def->nets[vm->def->nnets++] = net;
cleanup:
+ if ((ret != 0) &&
+ (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
+ qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &net->info) < 0)
+ VIR_WARN0("Unable to release PCI address on NIC");
+
VIR_FREE(nicstr);
VIR_FREE(netstr);
VIR_FREE(tapfd_name);
return -1;
}
- if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
- !(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
- goto error;
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+ if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info) < 0)
+ goto error;
+
+ if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev)))
+ goto error;
+ }
qemuDomainObjEnterMonitorWithDriver(driver, vm);
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
return 0;
error:
+ if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
+ (hostdev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
+ qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &hostdev->info) < 0)
+ VIR_WARN0("Unable to release PCI address on host device");
+
VIR_FREE(devstr);
pciDeviceListDel(conn, driver->activePciHostdevs, pci);