On Wed, Feb 03, 2010 at 04:32:47PM +0000, Daniel P. Berrange wrote:
When restoring from a saved guest image, the XML would already
contain the PCI slot ID of the IDE controller & video card.
The attempt to explicitly reserve this upfront would thus fail
everytime.
slot at time of need, rather than upfront
---
src/qemu/qemu_conf.c | 83 ++++++++++++++++++++++++++++++++++++++------------
1 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 389db7b..3d83a8f 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1797,6 +1797,13 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
{
char *addr;
+ if (dev->addr.pci.domain != 0 ||
+ dev->addr.pci.bus != 0) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Only PCI domain 0 and bus 0 are available"));
+ return NULL;
+ }
+
if (virAsprintf(&addr, "%d:%d:%d",
dev->addr.pci.domain,
dev->addr.pci.bus,
@@ -1817,6 +1824,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def
ATTRIBUTE_UNUSED,
if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
char *addr = qemuPCIAddressAsString(dev);
+ VIR_DEBUG("Remembering PCI addr %s", addr);
+
if (virHashAddEntry(addrs->used, addr, addr) < 0) {
VIR_FREE(addr);
return -1;
@@ -1858,6 +1867,8 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr
addrs,
if (!addr)
return -1;
+ VIR_DEBUG("Reserving PCI addr %s", addr);
+
if (virHashLookup(addrs->used, addr)) {
qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("unable to reserve PCI address %s"), addr);
@@ -1870,6 +1881,9 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr
addrs,
return -1;
}
+ if (dev->addr.pci.slot > addrs->nextslot)
+ addrs->nextslot = dev->addr.pci.slot + 1;
+
return 0;
}
@@ -1947,6 +1961,8 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr
addrs,
addr = qemuPCIAddressAsString(&maybe);
+ VIR_DEBUG("Allocating PCI addr %s", addr);
+
if (virHashLookup(addrs->used, addr)) {
VIR_FREE(addr);
continue;
@@ -1981,12 +1997,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
qemuDomainPCIAddressSetPtr addrs)
/* Host bridge */
if (qemuDomainPCIAddressReserveSlot(addrs, 0) < 0)
goto error;
- /* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller) */
- if (qemuDomainPCIAddressReserveSlot(addrs, 1) < 0)
- goto error;
- /* VGA */
- if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
- goto error;
+
+ /* PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
+ * at slot 1....reserve it later
+ */
+
+ /* VGA at slot 2.... reserve it later */
+
/* VirtIO Balloon */
if (qemuDomainPCIAddressReserveSlot(addrs, 3) < 0)
goto error;
@@ -2033,23 +2050,34 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
qemuDomainPCIAddressSetPtr addrs)
goto error;
}
for (i = 0; i < def->nvideos ; i++) {
- if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
- continue;
/* First VGA is hardcoded slot=2 */
if (i == 0) {
- def->videos[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
- def->videos[i]->info.addr.pci.domain = 0;
- def->videos[i]->info.addr.pci.bus = 0;
- def->videos[i]->info.addr.pci.slot = 2;
- def->videos[i]->info.addr.pci.function = 0;
+ if (def->videos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
{
+ if (def->videos[i]->info.addr.pci.domain != 0 ||
+ def->videos[i]->info.addr.pci.bus != 0 ||
+ def->videos[i]->info.addr.pci.slot != 2 ||
+ def->videos[i]->info.addr.pci.function != 0) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s",
+ _("Primary video card must have PCI address
0:0:2.0"));
+ goto error;
+ }
+ } else {
+ def->videos[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ def->videos[i]->info.addr.pci.domain = 0;
+ def->videos[i]->info.addr.pci.bus = 0;
+ def->videos[i]->info.addr.pci.slot = 2;
+ def->videos[i]->info.addr.pci.function = 0;
+ if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
+ goto error;
+ }
Ah, okay, understood ...
} else {
+ if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+ continue;
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info)
< 0)
goto error;
}
}
for (i = 0; i < def->ncontrollers ; i++) {
- if (def->controllers[i]->info.type !=
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
- continue;
/* FDC lives behind the ISA bridge */
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
continue;
@@ -2057,12 +2085,27 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
qemuDomainPCIAddressSetPtr addrs)
/* First IDE controller lives on the PIIX3 at slot=1, function=1 */
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE
&&
def->controllers[i]->idx == 0) {
- def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
- def->controllers[i]->info.addr.pci.domain = 0;
- def->controllers[i]->info.addr.pci.bus = 0;
- def->controllers[i]->info.addr.pci.slot = 1;
- def->controllers[i]->info.addr.pci.function = 1;
+ if (def->controllers[i]->info.type ==
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ if (def->videos[i]->info.addr.pci.domain != 0 ||
+ def->videos[i]->info.addr.pci.bus != 0 ||
+ def->videos[i]->info.addr.pci.slot != 2 ||
+ def->videos[i]->info.addr.pci.function != 0) {
+ qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s",
+ _("Primary IDE controller must have PCI
address 0:0:1.1"));
+ goto error;
+ }
+ } else {
+ def->controllers[i]->info.type =
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+ def->controllers[i]->info.addr.pci.domain = 0;
+ def->controllers[i]->info.addr.pci.bus = 0;
+ def->controllers[i]->info.addr.pci.slot = 1;
+ def->controllers[i]->info.addr.pci.function = 1;
+ if (qemuDomainPCIAddressReserveSlot(addrs, 1) < 0)
+ goto error;
+ }
} else {
+ if (def->controllers[i]->info.type !=
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+ continue;
if (qemuDomainPCIAddressSetNextAddr(addrs,
&def->controllers[i]->info) < 0)
goto error;
}
Okay, ACK !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit
http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine
http://rpmfind.net/
http://veillard.com/ | virtualization library
http://libvirt.org/