|
|
43fe83 |
From 3155b1327ffc178fea9ef96987dfbeb296862d58 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <3155b1327ffc178fea9ef96987dfbeb296862d58.1377873636.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Laine Stump <laine@laine.org>
|
|
|
43fe83 |
Date: Tue, 6 Aug 2013 13:23:20 -0600
|
|
|
43fe83 |
Subject: [PATCH] qemu: eliminate almost-duplicate code in qemu_command.c
|
|
|
43fe83 |
|
|
|
43fe83 |
This patch is part of the resolution to:
|
|
|
43fe83 |
|
|
|
43fe83 |
https://bugzilla.redhat.com/show_bug.cgi?id=819968
|
|
|
43fe83 |
|
|
|
43fe83 |
* The functions qemuDomainPCIAddressReserveAddr and
|
|
|
43fe83 |
qemuDomainPCIAddressReserveSlot were very similar (and should have
|
|
|
43fe83 |
been more similar) and were about to get more code added to them which
|
|
|
43fe83 |
would create even more duplicated code, so this patch gives
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr a "reserveEntireSlot" arg, then
|
|
|
43fe83 |
replaces the body of qemuDomainPCIAddressReserveSlot with a call to
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr.
|
|
|
43fe83 |
|
|
|
43fe83 |
You will notice that addrs->lastaddr was previously set in
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr (but *not* set in
|
|
|
43fe83 |
qemuDomainPCIAddressReserveSlot). For consistency and cleanliness of
|
|
|
43fe83 |
code, that bit was removed and put into the one caller of
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr (there is a similar place where the
|
|
|
43fe83 |
caller of qemuDomainPCIAddressReserveSlot sets lastaddr). This does
|
|
|
43fe83 |
guarantee identical functionality to pre-patch code, but in practice
|
|
|
43fe83 |
isn't really critical, because lastaddr is just keeping track of where
|
|
|
43fe83 |
to start when looking for a free slot - if it isn't updated, we will
|
|
|
43fe83 |
just start looking on a slot that's already occupied, then skip up to
|
|
|
43fe83 |
one that isn't.
|
|
|
43fe83 |
|
|
|
43fe83 |
* qemuCollectPCIAddress was essentially doing the same thing as
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr, but with some extra special case
|
|
|
43fe83 |
checking at the beginning. The duplicate code has been replaced with
|
|
|
43fe83 |
a call to qemuDomainPCIAddressReserveAddr. This required adding a
|
|
|
43fe83 |
"fromConfig" boolean, which is only used to change the log error
|
|
|
43fe83 |
code from VIR_ERR_INTERNAL_ERROR (when the address was
|
|
|
43fe83 |
auto-generated by libvirt) to VIR_ERR_XML_ERROR (when the address is
|
|
|
43fe83 |
coming from the config); without this differentiation, it would be
|
|
|
43fe83 |
difficult to tell if an error was caused by something wrong in
|
|
|
43fe83 |
libvirt's auto-allocate code or just bad config.
|
|
|
43fe83 |
|
|
|
43fe83 |
* the bit of code in qemuDomainPCIAddressValidate that checks the
|
|
|
43fe83 |
connect type flags is going to be used in a couple more places where
|
|
|
43fe83 |
we don't need to also check the slot limits (because we're generating
|
|
|
43fe83 |
the slot number ourselves), so that has been pulled out into a
|
|
|
43fe83 |
separate qemuDomainPCIAddressFlagsCompatible function.
|
|
|
43fe83 |
(cherry picked from commit 3bb0125766a301a9d99884e7cdb002ba5fa5df01)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
src/qemu/qemu_command.c | 232 ++++++++++++++++++++++++------------------------
|
|
|
43fe83 |
src/qemu/qemu_command.h | 4 +-
|
|
|
43fe83 |
2 files changed, 119 insertions(+), 117 deletions(-)
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
|
43fe83 |
index 4345456..abc973a 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_command.c
|
|
|
43fe83 |
+++ b/src/qemu/qemu_command.c
|
|
|
43fe83 |
@@ -1434,9 +1434,53 @@ struct _qemuDomainPCIAddressSet {
|
|
|
43fe83 |
};
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
-/*
|
|
|
43fe83 |
- * Check that the PCI address is valid for use
|
|
|
43fe83 |
- * with the specified PCI address set.
|
|
|
43fe83 |
+static bool
|
|
|
43fe83 |
+qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
|
|
|
43fe83 |
+ qemuDomainPCIConnectFlags busFlags,
|
|
|
43fe83 |
+ qemuDomainPCIConnectFlags devFlags,
|
|
|
43fe83 |
+ bool reportError)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ /* If this bus doesn't allow the type of connection (PCI
|
|
|
43fe83 |
+ * vs. PCIe) required by the device, or if the device requires
|
|
|
43fe83 |
+ * hot-plug and this bus doesn't have it, return false.
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ if (!(devFlags & busFlags & QEMU_PCI_CONNECT_TYPES_MASK)) {
|
|
|
43fe83 |
+ if (reportError) {
|
|
|
43fe83 |
+ if (devFlags & QEMU_PCI_CONNECT_TYPE_PCI) {
|
|
|
43fe83 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
+ _("PCI bus %.4x:%.2x is not compatible with the "
|
|
|
43fe83 |
+ "device. Device requires a standard PCI slot, "
|
|
|
43fe83 |
+ "which is not provided by this bus"),
|
|
|
43fe83 |
+ addr->domain, addr->bus);
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ /* this should never happen. If it does, there is a
|
|
|
43fe83 |
+ * bug in the code that sets the flag bits for devices.
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
43fe83 |
+ _("The device information has no PCI "
|
|
|
43fe83 |
+ "connection types listed"));
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ return false;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if ((devFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE) &&
|
|
|
43fe83 |
+ !(busFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE)) {
|
|
|
43fe83 |
+ if (reportError) {
|
|
|
43fe83 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
+ _("PCI bus %.4x:%.2x is not compatible with the "
|
|
|
43fe83 |
+ "device. Device requires hot-plug capability, "
|
|
|
43fe83 |
+ "which is not provided by the bus"),
|
|
|
43fe83 |
+ addr->domain, addr->bus);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ return false;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ return true;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+/* Verify that the address is in bounds for the chosen bus, and
|
|
|
43fe83 |
+ * that the bus is of the correct type for the device (via
|
|
|
43fe83 |
+ * comparing the flags).
|
|
|
43fe83 |
*/
|
|
|
43fe83 |
static bool
|
|
|
43fe83 |
qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
@@ -1466,24 +1510,9 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
/* assure that at least one of the requested connection types is
|
|
|
43fe83 |
* provided by this bus
|
|
|
43fe83 |
*/
|
|
|
43fe83 |
- if (!(flags & bus->flags & QEMU_PCI_CONNECT_TYPES_MASK)) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
- _("Invalid PCI address: The PCI controller "
|
|
|
43fe83 |
- "providing bus %04x doesn't support "
|
|
|
43fe83 |
- "connections appropriate for the device "
|
|
|
43fe83 |
- "(%x required vs. %x provided by bus)"),
|
|
|
43fe83 |
- addr->bus, flags & QEMU_PCI_CONNECT_TYPES_MASK,
|
|
|
43fe83 |
- bus->flags & QEMU_PCI_CONNECT_TYPES_MASK);
|
|
|
43fe83 |
- return false;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
- /* make sure this bus allows hot-plug if the caller demands it */
|
|
|
43fe83 |
- if ((flags & QEMU_PCI_CONNECT_HOTPLUGGABLE) &&
|
|
|
43fe83 |
- !(bus->flags & QEMU_PCI_CONNECT_HOTPLUGGABLE)) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
- _("Invalid PCI address: hot-pluggable slot requested, "
|
|
|
43fe83 |
- "but bus %04x doesn't support hot-plug"), addr->bus);
|
|
|
43fe83 |
+ if (!qemuDomainPCIAddressFlagsCompatible(addr, bus->flags, flags, true))
|
|
|
43fe83 |
return false;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
/* some "buses" are really just a single port */
|
|
|
43fe83 |
if (bus->minSlot && addr->slot < bus->minSlot) {
|
|
|
43fe83 |
virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
@@ -1597,10 +1626,10 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
virDomainDeviceInfoPtr info,
|
|
|
43fe83 |
void *opaque)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
+ qemuDomainPCIAddressSetPtr addrs = opaque;
|
|
|
43fe83 |
int ret = -1;
|
|
|
43fe83 |
- char *str = NULL;
|
|
|
43fe83 |
virDevicePCIAddressPtr addr = &info->addr.pci;
|
|
|
43fe83 |
- qemuDomainPCIAddressSetPtr addrs = opaque;
|
|
|
43fe83 |
+ bool entireSlot;
|
|
|
43fe83 |
/* FIXME: flags should be set according to the requirements of @device */
|
|
|
43fe83 |
qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
|
|
|
43fe83 |
QEMU_PCI_CONNECT_TYPE_PCI);
|
|
|
43fe83 |
@@ -1639,56 +1668,15 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|
|
43fe83 |
return 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
- /* add an additional bus of the correct type if needed */
|
|
|
43fe83 |
- if (addrs->dryRun &&
|
|
|
43fe83 |
- qemuDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- /* verify that the address is in bounds for the chosen bus, and
|
|
|
43fe83 |
- * that the bus is of the correct type for the device (via
|
|
|
43fe83 |
- * comparing the flags).
|
|
|
43fe83 |
- */
|
|
|
43fe83 |
- if (!qemuDomainPCIAddressValidate(addrs, addr, flags))
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- if (!(str = qemuDomainPCIAddressAsString(addr)))
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
+ entireSlot = (addr->function == 0 &&
|
|
|
43fe83 |
+ addr->multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON);
|
|
|
43fe83 |
|
|
|
43fe83 |
- /* check if already in use */
|
|
|
43fe83 |
- if (addrs->buses[addr->bus].slots[addr->slot] & (1 << addr->function)) {
|
|
|
43fe83 |
- if (info->addr.pci.function != 0) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
- _("Attempted double use of PCI Address '%s' "
|
|
|
43fe83 |
- "(may need \"multifunction='on'\" for device on function 0)"),
|
|
|
43fe83 |
- str);
|
|
|
43fe83 |
- } else {
|
|
|
43fe83 |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
- _("Attempted double use of PCI Address '%s'"), str);
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
+ if (qemuDomainPCIAddressReserveAddr(addrs, addr, flags,
|
|
|
43fe83 |
+ entireSlot, true) < 0)
|
|
|
43fe83 |
goto cleanup;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
|
|
|
43fe83 |
- /* mark as in use */
|
|
|
43fe83 |
- if ((info->addr.pci.function == 0) &&
|
|
|
43fe83 |
- (info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) {
|
|
|
43fe83 |
- /* a function 0 w/o multifunction=on must reserve the entire slot */
|
|
|
43fe83 |
- if (addrs->buses[addr->bus].slots[addr->slot]) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_XML_ERROR,
|
|
|
43fe83 |
- _("Attempted double use of PCI Address on slot '%s' "
|
|
|
43fe83 |
- "(need \"multifunction='off'\" for device "
|
|
|
43fe83 |
- "on function 0)"),
|
|
|
43fe83 |
- str);
|
|
|
43fe83 |
- goto cleanup;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
- addrs->buses[addr->bus].slots[addr->slot] = 0xFF;
|
|
|
43fe83 |
- VIR_DEBUG("Remembering PCI slot: %s (multifunction=off)", str);
|
|
|
43fe83 |
- } else {
|
|
|
43fe83 |
- VIR_DEBUG("Remembering PCI addr: %s", str);
|
|
|
43fe83 |
- addrs->buses[addr->bus].slots[addr->slot] |= 1 << addr->function;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
ret = 0;
|
|
|
43fe83 |
cleanup:
|
|
|
43fe83 |
- VIR_FREE(str);
|
|
|
43fe83 |
return ret;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1871,46 +1859,73 @@ static bool qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
+/*
|
|
|
43fe83 |
+ * Reserve a slot (or just one function) for a device. If
|
|
|
43fe83 |
+ * reserveEntireSlot is true, all functions for the slot are reserved,
|
|
|
43fe83 |
+ * otherwise only one. If fromConfig is true, the address being
|
|
|
43fe83 |
+ * requested came directly from the config and errors should be worded
|
|
|
43fe83 |
+ * appropriately. If fromConfig is false, the address was
|
|
|
43fe83 |
+ * automatically created by libvirt, so it is an internal error (not
|
|
|
43fe83 |
+ * XML).
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
int
|
|
|
43fe83 |
qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
virDevicePCIAddressPtr addr,
|
|
|
43fe83 |
- qemuDomainPCIConnectFlags flags)
|
|
|
43fe83 |
+ qemuDomainPCIConnectFlags flags,
|
|
|
43fe83 |
+ bool reserveEntireSlot,
|
|
|
43fe83 |
+ bool fromConfig)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
- char *str;
|
|
|
43fe83 |
+ int ret = -1;
|
|
|
43fe83 |
+ char *str = NULL;
|
|
|
43fe83 |
qemuDomainPCIAddressBusPtr bus;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
+ virErrorNumber errType = (fromConfig
|
|
|
43fe83 |
+ ? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
|
|
|
43fe83 |
|
|
|
43fe83 |
if (!(str = qemuDomainPCIAddressAsString(addr)))
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
|
|
|
43fe83 |
- VIR_DEBUG("Reserving PCI addr %s", str);
|
|
|
43fe83 |
+ /* Add an extra bus if necessary */
|
|
|
43fe83 |
+ if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ /* Check that the requested bus exists, is the correct type, and we
|
|
|
43fe83 |
+ * are asking for a valid slot
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ if (!qemuDomainPCIAddressValidate(addrs, addr, flags))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
|
|
|
43fe83 |
bus = &addrs->buses[addr->bus];
|
|
|
43fe83 |
- if ((bus->minSlot && addr->slot < bus->minSlot) ||
|
|
|
43fe83 |
- addr->slot > bus->maxSlot) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
- _("Unable to reserve PCI address %s. "
|
|
|
43fe83 |
- "Slot %02x can't be used on bus %04x, "
|
|
|
43fe83 |
- "only slots %02zx - %02zx are permitted on this bus."),
|
|
|
43fe83 |
- str, addr->slot, addr->bus, bus->minSlot, bus->maxSlot);
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
|
|
|
43fe83 |
- if (bus->slots[addr->slot] & (1 << addr->function)) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
- _("unable to reserve PCI address %s already in use"), str);
|
|
|
43fe83 |
- VIR_FREE(str);
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
+ if (reserveEntireSlot) {
|
|
|
43fe83 |
+ if (bus->slots[addr->slot]) {
|
|
|
43fe83 |
+ virReportError(errType,
|
|
|
43fe83 |
+ _("Attempted double use of PCI slot %s "
|
|
|
43fe83 |
+ "(may need \"multifunction='on'\" for "
|
|
|
43fe83 |
+ "device on function 0)"), str);
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ bus->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
|
|
|
43fe83 |
+ VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", str);
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ if (bus->slots[addr->slot] & (1 << addr->function)) {
|
|
|
43fe83 |
+ if (addr->function == 0) {
|
|
|
43fe83 |
+ virReportError(errType,
|
|
|
43fe83 |
+ _("Attempted double use of PCI Address %s"), str);
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ virReportError(errType,
|
|
|
43fe83 |
+ _("Attempted double use of PCI Address %s "
|
|
|
43fe83 |
+ "(may need \"multifunction='on'\" "
|
|
|
43fe83 |
+ "for device on function 0)"), str);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ bus->slots[addr->slot] |= (1 << addr->function);
|
|
|
43fe83 |
+ VIR_DEBUG("Reserving PCI address %s", str);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
VIR_FREE(str);
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- addrs->lastaddr = *addr;
|
|
|
43fe83 |
- addrs->lastaddr.function = 0;
|
|
|
43fe83 |
- addrs->lastaddr.multi = 0;
|
|
|
43fe83 |
- bus->slots[addr->slot] |= 1 << addr->function;
|
|
|
43fe83 |
- return 0;
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
|
|
|
43fe83 |
@@ -1919,26 +1934,7 @@ qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
virDevicePCIAddressPtr addr,
|
|
|
43fe83 |
qemuDomainPCIConnectFlags flags)
|
|
|
43fe83 |
{
|
|
|
43fe83 |
- char *str;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr, flags) < 0)
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- if (!(str = qemuDomainPCIAddressAsString(addr)))
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- VIR_DEBUG("Reserving PCI slot %s", str);
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- if (addrs->buses[addr->bus].slots[addr->slot]) {
|
|
|
43fe83 |
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
- _("unable to reserve PCI slot %s"), str);
|
|
|
43fe83 |
- VIR_FREE(str);
|
|
|
43fe83 |
- return -1;
|
|
|
43fe83 |
- }
|
|
|
43fe83 |
-
|
|
|
43fe83 |
- VIR_FREE(str);
|
|
|
43fe83 |
- addrs->buses[addr->bus].slots[addr->slot] = 0xFF;
|
|
|
43fe83 |
- return 0;
|
|
|
43fe83 |
+ return qemuDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
@@ -2044,12 +2040,11 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
|
|
|
43fe83 |
a.domain, a.bus, a.slot);
|
|
|
43fe83 |
}
|
|
|
43fe83 |
-
|
|
|
43fe83 |
}
|
|
|
43fe83 |
}
|
|
|
43fe83 |
|
|
|
43fe83 |
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
43fe83 |
- "%s", _("No more available PCI addresses"));
|
|
|
43fe83 |
+ "%s", _("No more available PCI slots"));
|
|
|
43fe83 |
return -1;
|
|
|
43fe83 |
|
|
|
43fe83 |
success:
|
|
|
43fe83 |
@@ -2409,9 +2404,14 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
|
|
43fe83 |
|
|
|
43fe83 |
addr.bus = tmp_addr.bus;
|
|
|
43fe83 |
addr.slot = tmp_addr.slot;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ addrs->lastaddr = addr;
|
|
|
43fe83 |
+ addrs->lastaddr.function = 0;
|
|
|
43fe83 |
+ addrs->lastaddr.multi = 0;
|
|
|
43fe83 |
}
|
|
|
43fe83 |
/* Finally we can reserve the slot+function */
|
|
|
43fe83 |
- if (qemuDomainPCIAddressReserveAddr(addrs, &addr, flags) < 0)
|
|
|
43fe83 |
+ if (qemuDomainPCIAddressReserveAddr(addrs, &addr, flags,
|
|
|
43fe83 |
+ false, false) < 0)
|
|
|
43fe83 |
goto error;
|
|
|
43fe83 |
|
|
|
43fe83 |
def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
|
43fe83 |
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
|
|
|
43fe83 |
index c9f1600..bf4953a 100644
|
|
|
43fe83 |
--- a/src/qemu/qemu_command.h
|
|
|
43fe83 |
+++ b/src/qemu/qemu_command.h
|
|
|
43fe83 |
@@ -253,7 +253,9 @@ int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
qemuDomainPCIConnectFlags flags);
|
|
|
43fe83 |
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
virDevicePCIAddressPtr addr,
|
|
|
43fe83 |
- qemuDomainPCIConnectFlags flags);
|
|
|
43fe83 |
+ qemuDomainPCIConnectFlags flags,
|
|
|
43fe83 |
+ bool reserveEntireSlot,
|
|
|
43fe83 |
+ bool fromConfig);
|
|
|
43fe83 |
int qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs,
|
|
|
43fe83 |
virDomainDeviceInfoPtr dev,
|
|
|
43fe83 |
qemuDomainPCIConnectFlags flags);
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|