]> xenbits.xensource.com Git - libvirt.git/commitdiff
Auto-assign PCI addresses
authorDaniel P. Berrange <berrange@redhat.com>
Thu, 7 Jan 2010 19:25:41 +0000 (19:25 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 18 Jan 2010 13:55:57 +0000 (13:55 +0000)
Instead of relying on QEMU to assign PCI addresses and then querying
them with 'info pci', manually assign all PCI addresses before starting
the guest.  These addresses are not stable across reboots. That will
come in a later patch

NB, the PIIX3 (IDE, FDC, ISA-Bridge) will always have slot 1 and
VGA will always have slot 2. We declare the Virtio Balloon gets
slot 3, and then all remaining slots are for configured devices.

* src/qemu/qemu_conf.c: If -device is supported, then assign all PCI
  addresses when building the command line
* src/qemu/qemu_driver.c: Don't query monitor for PCI addresses if
  they have already been assigned
* tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args,
  tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args,
  tests/qemuxml2argvdata/qemuxml2argv-sound-device.args,
  tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args: Update
  to include PCI slot/bus information

src/qemu/qemu_conf.c
src/qemu/qemu_driver.c
tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args
tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args

index 3321fbf5e2f0776a6cd1d7cd12af6f2fc4b26e70..7f5ec5a566e1a6208ac1d68d693054b7ed5eba58 100644 (file)
@@ -1547,6 +1547,108 @@ qemuAssignDeviceAliases(virDomainDefPtr def)
 }
 
 
+static void
+qemuAssignDevicePCISlot(virDomainDeviceInfoPtr info,
+                        int slot)
+{
+    info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
+    info->addr.pci.domain = 0;
+    info->addr.pci.bus = 0;
+    info->addr.pci.slot = slot;
+    info->addr.pci.function = 0;
+}
+
+static void
+qemuAssignDevicePCISlots(virDomainDefPtr def)
+{
+    int i;
+    /*
+     * slot = 0 -> Host bridge
+     * slot = 1 -> PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller)
+     * slot = 2 -> VGA
+     * slot = 3 -> VirtIO Balloon
+     */
+    int nextslot = 4;
+
+    for (i = 0; i < def->ndisks ; i++) {
+        if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+
+        /* Only VirtIO disks use PCI addrs */
+        if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO)
+            continue;
+
+        qemuAssignDevicePCISlot(&def->disks[i]->info, nextslot++);
+    }
+
+    for (i = 0; i < def->nnets ; i++) {
+        if (def->nets[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+        qemuAssignDevicePCISlot(&def->nets[i]->info, nextslot++);
+    }
+
+    for (i = 0; i < def->nsounds ; i++) {
+        if (def->sounds[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+        /* Skip ISA sound card, and PCSPK */
+        if (def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_SB16 ||
+            def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK)
+            continue;
+
+        qemuAssignDevicePCISlot(&def->sounds[i]->info, nextslot++);
+    }
+
+    for (i = 0; i < def->nhostdevs ; i++) {
+        if (def->hostdevs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+            continue;
+        if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+            def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            continue;
+
+        qemuAssignDevicePCISlot(&def->hostdevs[i]->info, nextslot++);
+    }
+    for (i = 0; i < def->nvideos ; i++) {
+        /* First VGA is hardcoded slot=2 */
+        if (i == 0)
+            qemuAssignDevicePCISlot(&def->videos[i]->info, 2);
+        else
+            qemuAssignDevicePCISlot(&def->videos[i]->info, nextslot++);
+    }
+    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;
+
+        /* 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) {
+            qemuAssignDevicePCISlot(&def->controllers[i]->info, 1);
+            def->controllers[i]->info.addr.pci.function = 1;
+        } else {
+            qemuAssignDevicePCISlot(&def->controllers[i]->info, nextslot++);
+        }
+    }
+    for (i = 0; i < def->ninputs ; i++) {
+        /* Nada - none are PCI based (yet) */
+    }
+    for (i = 0; i < def->nparallels ; i++) {
+        /* Nada - none are PCI based (yet) */
+    }
+    for (i = 0; i < def->nserials ; i++) {
+        /* Nada - none are PCI based (yet) */
+    }
+    for (i = 0; i < def->nchannels ; i++) {
+        /* Nada - none are PCI based (yet) */
+        /* XXX virtio-serial will need one */
+    }
+    if (def->watchdog) {
+        qemuAssignDevicePCISlot(&def->watchdog->info, nextslot++);
+    }
+}
+
+
 static char *qemuDiskLegacyName(const virDomainDiskDefPtr disk)
 {
     char *devname;
@@ -2609,10 +2711,12 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
     uname_normalize(&ut);
 
-    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
         qemuAssignDeviceAliases(def);
-    else
+        qemuAssignDevicePCISlots(def);
+    } else {
         qemuAssignDiskAliases(def, qemuCmdFlags);
+    }
 
     virUUIDFormat(def->uuid, uuid);
 
index b13398fe761edfc173bb49f4470738eeea65b431..2d80774bc1248ae1a830457c1b080f9e10757c75 100644 (file)
@@ -2708,6 +2708,11 @@ qemuPrepareMonitorChr(virConnectPtr conn,
     monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX;
     monConfig->data.nix.listen = 1;
 
+    if (!(monConfig->info.alias = strdup("monitor"))) {
+        virReportOOMError(conn);
+        return -1;
+    }
+
     if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor",
                     driver->libDir, vm) < 0) {
         virReportOOMError(conn);
@@ -2931,8 +2936,12 @@ static int qemudStartVMDaemon(virConnectPtr conn,
     if (qemuInitPasswords(driver, vm) < 0)
         goto abort;
 
-    if (qemuInitPCIAddresses(driver, vm) < 0)
-        goto abort;
+    /* If we have -device, then addresses are assigned explicitly.
+     * If not, then we have to detect dynamic ones here */
+    if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+        if (qemuInitPCIAddresses(driver, vm) < 0)
+            goto abort;
+    }
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
     if (qemuMonitorSetBalloon(priv->mon, vm->def->memory) < 0) {
index f1865ee7dbad99518424c236dfb7068fc7e5a159..611950a05bba0ce8e5aa6823ee6022d2fb1362f3 100644 (file)
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0,addr=4
index 2b5e856be3abf674686483b8f6c8ff4a6ff21f16..93240478d7bd11ff6e1a5252bbf99593507398ae 100644 (file)
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55 -usb
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55,addr=4 -usb
index 31ac0ee0e42bb79e0a7faca09268b13d1b583e3d..b9adec609cd653a873358a4b3fb014df950e60b4 100644 (file)
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1 -device sb16,id=sound2 -device AC97,id=sound3
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,addr=4 -device sb16,id=sound2 -device AC97,id=sound3,addr=5
index 5f3a42849749fd69f311c5ea6baf292e82f8f0b6..f05111ca5d555105c091d5ebbadcdd89bb188217 100644 (file)
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0 -watchdog-action poweroff
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0,addr=4 -watchdog-action poweroff