mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-09-08 16:54:49 +00:00
qemu: auto-add bridges and allow using them
Add a "dry run" address allocation to figure out how many bridges will be needed for all the devices without explicit addresses. Auto-add just enough bridges to put all the devices on, or up to the bridge with the largest specified index.
This commit is contained in:
parent
b33eb0dca1
commit
9d6e56dbce
@ -1210,6 +1210,8 @@ struct _qemuDomainPCIAddressSet {
|
||||
qemuDomainPCIAddressBus *used;
|
||||
virDevicePCIAddress lastaddr;
|
||||
size_t nbuses; /* allocation of 'used' */
|
||||
bool dryRun; /* on a dry run, new buses are auto-added
|
||||
and addresses aren't saved in device infos */
|
||||
};
|
||||
|
||||
|
||||
@ -1229,9 +1231,10 @@ static bool qemuPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs ATTRIBUTE_UN
|
||||
_("Only PCI domain 0 is available"));
|
||||
return false;
|
||||
}
|
||||
if (addr->bus != 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Only PCI bus 0 is available"));
|
||||
if (addr->bus >= addrs->nbuses) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Only PCI buses up to %zu are available"),
|
||||
addrs->nbuses - 1);
|
||||
return false;
|
||||
}
|
||||
if (addr->function >= QEMU_PCI_ADDRESS_FUNCTION_LAST) {
|
||||
@ -1246,9 +1249,45 @@ static bool qemuPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs ATTRIBUTE_UN
|
||||
QEMU_PCI_ADDRESS_SLOT_LAST);
|
||||
return false;
|
||||
}
|
||||
if (addr->slot == 0) {
|
||||
if (addr->bus) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Slot 0 is unusable on PCI bridges"));
|
||||
} else {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Slot 0 on bus 0 is reserved for the host bridge"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Ensure addr fits in the address set, by expanding it if needed.
|
||||
* Return value:
|
||||
* -1 = OOM
|
||||
* 0 = no action performed
|
||||
* >0 = number of buses added
|
||||
*/
|
||||
static int
|
||||
qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs,
|
||||
virDevicePCIAddressPtr addr)
|
||||
{
|
||||
int add, i;
|
||||
|
||||
add = addr->bus - addrs->nbuses + 1;
|
||||
i = addrs->nbuses;
|
||||
if (add <= 0)
|
||||
return 0;
|
||||
if (VIR_EXPAND_N(addrs->used, addrs->nbuses, add) < 0) {
|
||||
virReportOOMError();
|
||||
return -1;
|
||||
}
|
||||
/* reserve slot 0 on the new buses */
|
||||
for (; i < addrs->nbuses; i++)
|
||||
addrs->used[i][0] = 0xFF;
|
||||
return add;
|
||||
}
|
||||
|
||||
|
||||
static char *qemuPCIAddressAsString(virDevicePCIAddressPtr addr)
|
||||
{
|
||||
@ -1286,6 +1325,9 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr) < 0)
|
||||
return -1;
|
||||
|
||||
if (!qemuPCIAddressValidate(addrs, addr))
|
||||
return -1;
|
||||
|
||||
@ -1339,15 +1381,53 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
||||
qemuDomainObjPrivatePtr priv = NULL;
|
||||
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||
int max_idx = -1;
|
||||
int nbuses = 0;
|
||||
int i;
|
||||
int rv;
|
||||
|
||||
for (i = 0; i < def->ncontrollers; i++) {
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI)
|
||||
nbuses++;
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
|
||||
if (def->controllers[i]->idx > max_idx)
|
||||
max_idx = def->controllers[i]->idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses)))
|
||||
nbuses = max_idx + 1;
|
||||
|
||||
if (nbuses > 0 &&
|
||||
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
|
||||
virDomainDeviceInfo info;
|
||||
/* 1st pass to figure out how many PCI bridges we need */
|
||||
if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, true)))
|
||||
goto cleanup;
|
||||
if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
|
||||
goto cleanup;
|
||||
/* Reserve 1 extra slot for a (potential) bridge */
|
||||
if (qemuDomainPCIAddressSetNextAddr(addrs, &info) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 1; i < addrs->nbuses; i++) {
|
||||
if ((rv = virDomainDefMaybeAddController(
|
||||
def, VIR_DOMAIN_CONTROLLER_TYPE_PCI,
|
||||
i, VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE)) < 0)
|
||||
goto cleanup;
|
||||
/* If we added a new bridge, we will need one more address */
|
||||
if (rv > 0 && qemuDomainPCIAddressSetNextAddr(addrs, &info) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
nbuses = addrs->nbuses;
|
||||
qemuDomainPCIAddressSetFree(addrs);
|
||||
addrs = NULL;
|
||||
|
||||
} else if (max_idx > 0) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("PCI bridges are not supported "
|
||||
"by this QEMU binary"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(addrs = qemuDomainPCIAddressSetCreate(def, nbuses, false)))
|
||||
goto cleanup;
|
||||
|
||||
if (qemuAssignDevicePCISlots(def, qemuCaps, addrs) < 0)
|
||||
@ -1393,7 +1473,8 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
|
||||
}
|
||||
|
||||
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
|
||||
unsigned int nbuses)
|
||||
unsigned int nbuses,
|
||||
bool dryRun)
|
||||
{
|
||||
qemuDomainPCIAddressSetPtr addrs;
|
||||
int i;
|
||||
@ -1405,6 +1486,7 @@ qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
|
||||
goto no_memory;
|
||||
|
||||
addrs->nbuses = nbuses;
|
||||
addrs->dryRun = dryRun;
|
||||
|
||||
/* reserve slot 0 in every bus - it's used by the host bridge on bus 0
|
||||
* and unusable on PCI bridges */
|
||||
@ -1437,6 +1519,9 @@ int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(str = qemuPCIAddressAsString(addr)))
|
||||
return -1;
|
||||
|
||||
@ -1463,6 +1548,9 @@ int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (addrs->dryRun && qemuDomainPCIAddressSetGrow(addrs, addr) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(str = qemuPCIAddressAsString(addr)))
|
||||
return -1;
|
||||
|
||||
@ -1537,36 +1625,54 @@ static int
|
||||
qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||
virDevicePCIAddressPtr next_addr)
|
||||
{
|
||||
virDevicePCIAddress tmp_addr = addrs->lastaddr;
|
||||
int i;
|
||||
char *addr;
|
||||
virDevicePCIAddress a = addrs->lastaddr;
|
||||
|
||||
tmp_addr.slot++;
|
||||
for (i = 0; i < QEMU_PCI_ADDRESS_SLOT_LAST; i++, tmp_addr.slot++) {
|
||||
if (QEMU_PCI_ADDRESS_SLOT_LAST <= tmp_addr.slot) {
|
||||
tmp_addr.slot = 0;
|
||||
if (addrs->nbuses == 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s", _("No PCI buses available"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Start the search at the last used bus and slot */
|
||||
for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
|
||||
for ( ; a.slot < QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) {
|
||||
if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
|
||||
goto success;
|
||||
|
||||
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
|
||||
a.domain, a.bus, a.slot);
|
||||
}
|
||||
a.slot = 1;
|
||||
}
|
||||
|
||||
if (!(addr = qemuPCIAddressAsString(&tmp_addr)))
|
||||
/* There were no free slots after the last used one */
|
||||
if (addrs->dryRun) {
|
||||
/* a is already set to the first new bus and slot 1 */
|
||||
if (qemuDomainPCIAddressSetGrow(addrs, &a) < 0)
|
||||
return -1;
|
||||
goto success;
|
||||
} else {
|
||||
/* Check the buses from 0 up to the last used one */
|
||||
for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
|
||||
for (a.slot = 1; a.slot < QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) {
|
||||
if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
|
||||
goto success;
|
||||
|
||||
VIR_DEBUG("PCI slot %.4x:%.2x:%.2x already in use",
|
||||
a.domain, a.bus, a.slot);
|
||||
}
|
||||
|
||||
if (qemuDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
|
||||
VIR_DEBUG("PCI addr %s already in use", addr);
|
||||
VIR_FREE(addr);
|
||||
continue;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Found free PCI addr %s", addr);
|
||||
VIR_FREE(addr);
|
||||
|
||||
addrs->lastaddr = tmp_addr;
|
||||
*next_addr = tmp_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("No more available PCI addresses"));
|
||||
return -1;
|
||||
|
||||
success:
|
||||
VIR_DEBUG("Found free PCI slot %.4x:%.2x:%.2x",
|
||||
a.domain, a.bus, a.slot);
|
||||
*next_addr = a;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||
@ -1579,8 +1685,10 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||
if (qemuDomainPCIAddressReserveSlot(addrs, &addr) < 0)
|
||||
return -1;
|
||||
|
||||
dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||
dev->addr.pci = addr;
|
||||
if (!addrs->dryRun) {
|
||||
dev->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||
dev->addr.pci = addr;
|
||||
}
|
||||
|
||||
addrs->lastaddr = addr;
|
||||
return 0;
|
||||
@ -1754,6 +1862,18 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
||||
}
|
||||
}
|
||||
|
||||
/* PCI controllers */
|
||||
for (i = 0; i < def->ncontrollers; i++) {
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
|
||||
if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT)
|
||||
continue;
|
||||
if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
||||
continue;
|
||||
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->controllers[i]->info) < 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < def->nfss ; i++) {
|
||||
if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
||||
continue;
|
||||
@ -1793,9 +1913,10 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
|
||||
|
||||
/* Device controllers (SCSI, USB, but not IDE, FDC or CCID) */
|
||||
for (i = 0; i < def->ncontrollers ; i++) {
|
||||
/* PCI root has no address */
|
||||
/* PCI controllers have been dealt with earlier */
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI)
|
||||
continue;
|
||||
|
||||
/* FDC lives behind the ISA bridge; CCID is a usb device */
|
||||
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC ||
|
||||
def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_CCID)
|
||||
@ -1985,16 +2106,29 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX
|
||||
* When QEMU grows support for > 1 PCI bus, then pci.0 changes
|
||||
* to pci.1, pci.2, etc
|
||||
* When QEMU grows support for > 1 PCI domain, then pci.0 change
|
||||
* to pciNN.0 where NN is the domain number
|
||||
/*
|
||||
* PCI bridge support is required for multiple buses
|
||||
* 'pci.%u' is the ID of the bridge as specified in
|
||||
* qemuBuildControllerDevStr
|
||||
*
|
||||
* PCI_MULTIBUS capability indicates that the implicit
|
||||
* PCI bus is named 'pci.0' instead of 'pci'.
|
||||
*/
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS))
|
||||
virBufferAsprintf(buf, ",bus=pci.0");
|
||||
else
|
||||
virBufferAsprintf(buf, ",bus=pci");
|
||||
if (info->addr.pci.bus != 0) {
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_PCI_BRIDGE)) {
|
||||
virBufferAsprintf(buf, ",bus=pci.%u", info->addr.pci.bus);
|
||||
} else {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("Multiple PCI buses are not supported "
|
||||
"with this QEMU binary"));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS))
|
||||
virBufferAsprintf(buf, ",bus=pci.0");
|
||||
else
|
||||
virBufferAsprintf(buf, ",bus=pci");
|
||||
}
|
||||
if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON)
|
||||
virBufferAddLit(buf, ",multifunction=on");
|
||||
else if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_OFF)
|
||||
|
@ -197,7 +197,8 @@ int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
||||
virQEMUCapsPtr qemuCaps,
|
||||
virDomainObjPtr obj);
|
||||
qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
|
||||
unsigned int nbuses);
|
||||
unsigned int nbuses,
|
||||
bool dryRun);
|
||||
int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
|
||||
virDevicePCIAddressPtr addr);
|
||||
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
|
||||
|
12
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-addr.args
Normal file
12
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-addr.args
Normal file
@ -0,0 +1,12 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
|
||||
/usr/libexec/qemu-kvm -S -M pc-1.2 -m 2048 -smp 2 -nographic -nodefaults \
|
||||
-monitor unix:/tmp/test-monitor,server,nowait -boot c \
|
||||
-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x3 \
|
||||
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.0,addr=0x4 \
|
||||
-device pci-bridge,chassis_nr=3,id=pci.3,bus=pci.0,addr=0x5 \
|
||||
-device pci-bridge,chassis_nr=4,id=pci.4,bus=pci.0,addr=0x6 \
|
||||
-device pci-bridge,chassis_nr=5,id=pci.5,bus=pci.0,addr=0x7 \
|
||||
-device pci-bridge,chassis_nr=6,id=pci.6,bus=pci.0,addr=0x8 \
|
||||
-device pci-bridge,chassis_nr=7,id=pci.7,bus=pci.0,addr=0x9 \
|
||||
-usb -cdrom /var/iso/f18kde.iso \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.7,addr=0x6
|
44
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-addr.xml
Normal file
44
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-addr.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<domain type='qemu'>
|
||||
<name>fdr-br</name>
|
||||
<uuid>3ec6cbe1-b5a2-4515-b800-31a61855df41</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-1.2'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/iso/f18kde.iso'/>
|
||||
<target dev='hdc' bus='ide'/>
|
||||
<readonly/>
|
||||
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||
</controller>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||
</video>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x07' slot='0x06' function='0x0'/>
|
||||
</memballoon>
|
||||
</devices>
|
||||
</domain>
|
13
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-idx.args
Normal file
13
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-idx.args
Normal file
@ -0,0 +1,13 @@
|
||||
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
|
||||
/usr/libexec/qemu-kvm -S -M pc-1.2 -m 2048 -smp 2 -nographic -nodefaults \
|
||||
-monitor unix:/tmp/test-monitor,server,nowait -boot c \
|
||||
-device pci-bridge,chassis_nr=8,id=pci.8,bus=pci.0,addr=0x3 \
|
||||
-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.0,addr=0x4 \
|
||||
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.0,addr=0x5 \
|
||||
-device pci-bridge,chassis_nr=3,id=pci.3,bus=pci.0,addr=0x6 \
|
||||
-device pci-bridge,chassis_nr=4,id=pci.4,bus=pci.0,addr=0x7 \
|
||||
-device pci-bridge,chassis_nr=5,id=pci.5,bus=pci.0,addr=0x8 \
|
||||
-device pci-bridge,chassis_nr=6,id=pci.6,bus=pci.0,addr=0x9 \
|
||||
-device pci-bridge,chassis_nr=7,id=pci.7,bus=pci.0,addr=0xa \
|
||||
-usb -cdrom /var/iso/f18kde.iso \
|
||||
-device virtio-balloon-pci,id=balloon0,bus=pci.4,addr=0x6
|
45
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-idx.xml
Normal file
45
tests/qemuxml2argvdata/qemuxml2argv-pci-autoadd-idx.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<domain type='qemu'>
|
||||
<name>fdr-br</name>
|
||||
<uuid>3ec6cbe1-b5a2-4515-b800-31a61855df41</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-1.2'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/iso/f18kde.iso'/>
|
||||
<target dev='hdc' bus='ide'/>
|
||||
<readonly/>
|
||||
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='8' model='pci-bridge'/>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||
</video>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x04' slot='0x06' function='0x0'/>
|
||||
</memballoon>
|
||||
</devices>
|
||||
</domain>
|
210
tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.xml
Normal file
210
tests/qemuxml2argvdata/qemuxml2argv-pci-bridge.xml
Normal file
@ -0,0 +1,210 @@
|
||||
<domain type='qemu'>
|
||||
<name>fdr-br</name>
|
||||
<uuid>3ec6cbe1-b5a2-4515-b800-31a61855df41</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-1.2'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/iso/f18kde.iso'/>
|
||||
<target dev='hdc' bus='ide'/>
|
||||
<readonly/>
|
||||
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<controller type='pci' index='1' model='pci-bridge'/>
|
||||
<controller type='pci' index='2' model='pci-bridge'/>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:f1:95:51'/>
|
||||
<source network='default'/>
|
||||
<model type='rtl8139'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:5c:c6:1a'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:39:97:ac'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:45:28:cb'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:ee:b9:a8'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:a9:f7:17'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:df:2b:f3'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:78:94:b4'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:6b:9b:06'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:17:df:bc'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:3b:d0:51'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:8d:2d:17'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:a7:66:af'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:54:ab:d7'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:1f:99:90'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:c8:43:87'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:df:22:b2'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:d2:9a:47'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:86:05:e2'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:8c:1c:c2'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:48:58:92'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:99:e5:bf'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:b1:8c:25'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:60:e0:d0'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:37:00:6a'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:c7:c8:ad'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:4e:a7:cf'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:00:79:69'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:47:00:6f'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:2a:8c:8b'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:ec:d5:e3'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<interface type='network'>
|
||||
<mac address='52:54:00:7e:6e:c8'/>
|
||||
<source network='default'/>
|
||||
<model type='e1000'/>
|
||||
</interface>
|
||||
<input type='mouse' bus='ps2'/>
|
||||
<graphics type='vnc' port='-1' autoport='yes' listen='127.0.0.1' keymap='en-us'>
|
||||
<listen type='address' address='127.0.0.1'/>
|
||||
</graphics>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||
</video>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
|
||||
</memballoon>
|
||||
</devices>
|
||||
</domain>
|
@ -951,6 +951,9 @@ mymain(void)
|
||||
DO_TEST("tpm-passthrough", QEMU_CAPS_DEVICE,
|
||||
QEMU_CAPS_DEVICE_TPM_PASSTHROUGH, QEMU_CAPS_DEVICE_TPM_TIS);
|
||||
|
||||
DO_TEST("pci-autoadd-addr", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
|
||||
DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
|
||||
|
||||
virObjectUnref(driver.config);
|
||||
virObjectUnref(driver.caps);
|
||||
virObjectUnref(driver.xmlopt);
|
||||
|
44
tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-autoadd-addr.xml
Normal file
44
tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-autoadd-addr.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<domain type='qemu'>
|
||||
<name>fdr-br</name>
|
||||
<uuid>3ec6cbe1-b5a2-4515-b800-31a61855df41</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-1.2'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/iso/f18kde.iso'/>
|
||||
<target dev='hdc' bus='ide'/>
|
||||
<readonly/>
|
||||
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||
</video>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x07' slot='0x06' function='0x0'/>
|
||||
</memballoon>
|
||||
</devices>
|
||||
</domain>
|
45
tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-autoadd-idx.xml
Normal file
45
tests/qemuxml2xmloutdata/qemuxml2xmlout-pci-autoadd-idx.xml
Normal file
@ -0,0 +1,45 @@
|
||||
<domain type='qemu'>
|
||||
<name>fdr-br</name>
|
||||
<uuid>3ec6cbe1-b5a2-4515-b800-31a61855df41</uuid>
|
||||
<memory unit='KiB'>2097152</memory>
|
||||
<currentMemory unit='KiB'>2097152</currentMemory>
|
||||
<vcpu placement='static' cpuset='0-1'>2</vcpu>
|
||||
<os>
|
||||
<type arch='x86_64' machine='pc-1.2'>hvm</type>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<features>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
<pae/>
|
||||
</features>
|
||||
<clock offset='utc'/>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<devices>
|
||||
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||
<disk type='file' device='cdrom'>
|
||||
<driver name='qemu' type='raw'/>
|
||||
<source file='/var/iso/f18kde.iso'/>
|
||||
<target dev='hdc' bus='ide'/>
|
||||
<readonly/>
|
||||
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
|
||||
</disk>
|
||||
<controller type='usb' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
||||
</controller>
|
||||
<controller type='ide' index='0'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
|
||||
</controller>
|
||||
<controller type='pci' index='8' model='pci-bridge'/>
|
||||
<controller type='pci' index='0' model='pci-root'/>
|
||||
<video>
|
||||
<model type='cirrus' vram='9216' heads='1'/>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||
</video>
|
||||
<memballoon model='virtio'>
|
||||
<address type='pci' domain='0x0000' bus='0x04' slot='0x06' function='0x0'/>
|
||||
</memballoon>
|
||||
</devices>
|
||||
</domain>
|
@ -278,6 +278,9 @@ mymain(void)
|
||||
DO_TEST_DIFFERENT("metadata");
|
||||
|
||||
DO_TEST("tpm-passthrough");
|
||||
DO_TEST("pci-bridge");
|
||||
DO_TEST_DIFFERENT("pci-autoadd-addr");
|
||||
DO_TEST_DIFFERENT("pci-autoadd-idx");
|
||||
|
||||
virObjectUnref(driver.caps);
|
||||
virObjectUnref(driver.xmlopt);
|
||||
|
Loading…
Reference in New Issue
Block a user