mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
conf: permit auto-assignment of controller indexes
Hand-entering indexes for 20 PCI controllers is not as tedious as manually determining and entering their PCI addresses, but it's still annoying, and the algorithm for determining the proper index is incredibly simple (in all cases except one) - just pick the lowest unused index. The one exception is USB2 controllers because multiple controllers in the same group have the same index. For these we look to see if 1) the most recently added USB controller is also a USB2 controller, and 2) the group *that* controller belongs to doesn't yet have a controller of the exact model we're just now adding - if both are true, the new controller gets the same index, but in all other cases we just assign the lowest unused index. With this patch in place and combined with the automatic PCI address assignment, we can define a PCIe switch with several ports like this: <controller type='pci' model='pcie-root-port'/> <controller type='pci' model='pcie-switch-upstream-port'/> <controller type='pci' model='pcie-switch-downstream-port'/> <controller type='pci' model='pcie-switch-downstream-port'/> <controller type='pci' model='pcie-switch-downstream-port'/> <controller type='pci' model='pcie-switch-downstream-port'/> <controller type='pci' model='pcie-switch-downstream-port'/> ... These will each get a unique index, and PCI addresses that connect them together appropriately with no pesky numbers required.
This commit is contained in:
parent
808e16ff13
commit
4d100c7a41
@ -3041,8 +3041,11 @@
|
|||||||
attribute <code>index</code> which is the decimal integer
|
attribute <code>index</code> which is the decimal integer
|
||||||
describing in which order the bus controller is encountered (for
|
describing in which order the bus controller is encountered (for
|
||||||
use in <code>controller</code> attributes of
|
use in <code>controller</code> attributes of
|
||||||
<code><address></code> elements). Some controller types
|
<code><address></code> elements).
|
||||||
have additional attributes that control specific features, such as:
|
<span class="since">Since 1.3.5</span> the index is optional; if
|
||||||
|
not specified, it will be auto-assigned to be the lowest unused
|
||||||
|
index for the given controller type. Some controller types have
|
||||||
|
additional attributes that control specific features, such as:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -1704,9 +1704,11 @@
|
|||||||
</define>
|
</define>
|
||||||
<define name="controller">
|
<define name="controller">
|
||||||
<element name="controller">
|
<element name="controller">
|
||||||
|
<optional>
|
||||||
<attribute name="index">
|
<attribute name="index">
|
||||||
<ref name="unsignedInt"/>
|
<ref name="unsignedInt"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
</optional>
|
||||||
<interleave>
|
<interleave>
|
||||||
<optional>
|
<optional>
|
||||||
<ref name="alias"/>
|
<ref name="alias"/>
|
||||||
|
@ -1647,9 +1647,11 @@ virDomainControllerDefNew(virDomainControllerType type)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
def->type = type;
|
def->type = type;
|
||||||
def->model = -1;
|
|
||||||
|
|
||||||
/* initialize anything that has a non-0 default */
|
/* initialize anything that has a non-0 default */
|
||||||
|
def->model = -1;
|
||||||
|
def->idx = -1;
|
||||||
|
|
||||||
switch ((virDomainControllerType) def->type) {
|
switch ((virDomainControllerType) def->type) {
|
||||||
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
||||||
def->opts.vioserial.ports = -1;
|
def->opts.vioserial.ports = -1;
|
||||||
@ -3585,7 +3587,7 @@ virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
|
|||||||
|
|
||||||
for (i = 0; i < def->ncontrollers; i++) {
|
for (i = 0; i < def->ncontrollers; i++) {
|
||||||
cont = def->controllers[i];
|
cont = def->controllers[i];
|
||||||
if ((int) cont->idx > max_idx[cont->type])
|
if (cont->idx > max_idx[cont->type])
|
||||||
max_idx[cont->type] = cont->idx;
|
max_idx[cont->type] = cont->idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4254,6 +4256,84 @@ virDomainDefRemoveOfflineVcpuPin(virDomainDefPtr def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virDomainAssignControllerIndexes(virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
/* the index attribute of a controller is optional in the XML, but
|
||||||
|
* is required to be valid at any time after parse. When no index
|
||||||
|
* is provided for a controller, assign one automatically by
|
||||||
|
* looking at what indexes are already used for that controller
|
||||||
|
* type in the domain - the unindexed controller gets the lowest
|
||||||
|
* unused index.
|
||||||
|
*/
|
||||||
|
size_t outer;
|
||||||
|
|
||||||
|
for (outer = 0; outer < def->ncontrollers; outer++) {
|
||||||
|
virDomainControllerDefPtr cont = def->controllers[outer];
|
||||||
|
virDomainControllerDefPtr prev = NULL;
|
||||||
|
size_t inner;
|
||||||
|
|
||||||
|
if (cont->idx != -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (outer > 0 && IS_USB2_CONTROLLER(cont)) {
|
||||||
|
/* USB2 controllers are the only exception to the simple
|
||||||
|
* "assign the lowest unused index". A group of USB2
|
||||||
|
* "companions" should all be at the same index as other
|
||||||
|
* USB2 controllers in the group, but only do this
|
||||||
|
* automatically if it appears to be the intent. To prove
|
||||||
|
* intent: the USB controller on the list just prior to
|
||||||
|
* this one must also be a USB2 controller, and there must
|
||||||
|
* not yet be a controller with the exact same model of
|
||||||
|
* this one and the same index as the previously added
|
||||||
|
* controller (e.g., if this controller is a UHCI1, then
|
||||||
|
* the previous controller must be an EHCI1 or a UHCI[23],
|
||||||
|
* and there must not already be a UHCI1 controller with
|
||||||
|
* the same index as the previous controller). If all of
|
||||||
|
* these are satisfied, set this controller to the same
|
||||||
|
* index as the previous controller.
|
||||||
|
*/
|
||||||
|
int prevIdx;
|
||||||
|
|
||||||
|
prevIdx = outer - 1;
|
||||||
|
while (prevIdx >= 0 &&
|
||||||
|
def->controllers[prevIdx]->type != VIR_DOMAIN_CONTROLLER_TYPE_USB)
|
||||||
|
prevIdx--;
|
||||||
|
if (prevIdx >= 0)
|
||||||
|
prev = def->controllers[prevIdx];
|
||||||
|
/* if the last USB controller isn't USB2, that breaks
|
||||||
|
* the chain, so we need a new index for this new
|
||||||
|
* controller
|
||||||
|
*/
|
||||||
|
if (prev && !IS_USB2_CONTROLLER(prev))
|
||||||
|
prev = NULL;
|
||||||
|
|
||||||
|
/* if prev != NULL, we've found a potential index to
|
||||||
|
* use. Make sure this index isn't already used by an
|
||||||
|
* existing USB2 controller of the same model as the new
|
||||||
|
* one.
|
||||||
|
*/
|
||||||
|
for (inner = 0; prev && inner < def->ncontrollers; inner++) {
|
||||||
|
if (def->controllers[inner]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
|
||||||
|
def->controllers[inner]->idx == prev->idx &&
|
||||||
|
def->controllers[inner]->model == cont->model) {
|
||||||
|
/* we already have a controller of this model with
|
||||||
|
* the proposed index, so we need to move to a new
|
||||||
|
* index for this controller
|
||||||
|
*/
|
||||||
|
prev = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (prev)
|
||||||
|
cont->idx = prev->idx;
|
||||||
|
}
|
||||||
|
/* if none of the above applied, prev will be NULL */
|
||||||
|
if (!prev)
|
||||||
|
cont->idx = virDomainControllerFindUnusedIndex(def, cont->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define UNSUPPORTED(FEATURE) (!((FEATURE) & xmlopt->config.features))
|
#define UNSUPPORTED(FEATURE) (!((FEATURE) & xmlopt->config.features))
|
||||||
/**
|
/**
|
||||||
* virDomainDefPostParseCheckFeatures:
|
* virDomainDefPostParseCheckFeatures:
|
||||||
@ -4422,6 +4502,11 @@ virDomainDefPostParse(virDomainDefPtr def,
|
|||||||
.parseFlags = parseFlags,
|
.parseFlags = parseFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* this must be done before the hypervisor-specific callback,
|
||||||
|
* in case presence of a controller at a specific index is checked
|
||||||
|
*/
|
||||||
|
virDomainAssignControllerIndexes(def);
|
||||||
|
|
||||||
/* call the domain config callback */
|
/* call the domain config callback */
|
||||||
if (xmlopt->config.domainPostParseCallback) {
|
if (xmlopt->config.domainPostParseCallback) {
|
||||||
ret = xmlopt->config.domainPostParseCallback(def, caps, parseFlags,
|
ret = xmlopt->config.domainPostParseCallback(def, caps, parseFlags,
|
||||||
@ -7908,16 +7993,6 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
if (!(def = virDomainControllerDefNew(type)))
|
if (!(def = virDomainControllerDefNew(type)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
idx = virXMLPropString(node, "index");
|
|
||||||
if (idx) {
|
|
||||||
if (virStrToLong_ui(idx, NULL, 10, &def->idx) < 0 ||
|
|
||||||
def->idx > INT_MAX) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Cannot parse controller index %s"), idx);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
model = virXMLPropString(node, "model");
|
model = virXMLPropString(node, "model");
|
||||||
if (model) {
|
if (model) {
|
||||||
if ((def->model = virDomainControllerModelTypeFromString(def, model)) < 0) {
|
if ((def->model = virDomainControllerModelTypeFromString(def, model)) < 0) {
|
||||||
@ -7927,6 +8002,18 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idx = virXMLPropString(node, "index");
|
||||||
|
if (idx) {
|
||||||
|
unsigned int idxVal;
|
||||||
|
if (virStrToLong_ui(idx, NULL, 10, &idxVal) < 0 ||
|
||||||
|
idxVal > INT_MAX) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Cannot parse controller index %s"), idx);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
def->idx = idxVal;
|
||||||
|
}
|
||||||
|
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (cur->type == XML_ELEMENT_NODE) {
|
if (cur->type == XML_ELEMENT_NODE) {
|
||||||
@ -8075,7 +8162,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
"have an address"));
|
"have an address"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (def->idx != 0) {
|
if (def->idx > 0) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("pci-root and pcie-root controllers "
|
_("pci-root and pcie-root controllers "
|
||||||
"should have index 0"));
|
"should have index 0"));
|
||||||
@ -13672,6 +13759,14 @@ void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
|||||||
for (idx = (def->ncontrollers - 1); idx >= 0; idx--) {
|
for (idx = (def->ncontrollers - 1); idx >= 0; idx--) {
|
||||||
current = def->controllers[idx];
|
current = def->controllers[idx];
|
||||||
if (current->type == controller->type) {
|
if (current->type == controller->type) {
|
||||||
|
if (controller->idx == -1) {
|
||||||
|
/* If the new controller doesn't have an index set
|
||||||
|
* yet, put it just past this controller, which until
|
||||||
|
* now was the last controller of this type.
|
||||||
|
*/
|
||||||
|
insertAt = idx + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (current->idx > controller->idx) {
|
if (current->idx > controller->idx) {
|
||||||
/* If bus matches and current controller is after
|
/* If bus matches and current controller is after
|
||||||
* new controller, then new controller should go here
|
* new controller, then new controller should go here
|
||||||
@ -16238,6 +16333,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
|||||||
virDomainControllerDefPtr controller = virDomainControllerDefParseXML(nodes[i],
|
virDomainControllerDefPtr controller = virDomainControllerDefParseXML(nodes[i],
|
||||||
ctxt,
|
ctxt,
|
||||||
flags);
|
flags);
|
||||||
|
|
||||||
if (!controller)
|
if (!controller)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -19552,7 +19648,7 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
virBufferAsprintf(buf,
|
virBufferAsprintf(buf,
|
||||||
"<controller type='%s' index='%u'",
|
"<controller type='%s' index='%d'",
|
||||||
type, def->idx);
|
type, def->idx);
|
||||||
|
|
||||||
if (model)
|
if (model)
|
||||||
|
@ -733,7 +733,7 @@ struct _virDomainUSBControllerOpts {
|
|||||||
/* Stores the virtual disk controller configuration */
|
/* Stores the virtual disk controller configuration */
|
||||||
struct _virDomainControllerDef {
|
struct _virDomainControllerDef {
|
||||||
int type;
|
int type;
|
||||||
unsigned int idx;
|
int idx;
|
||||||
int model; /* -1 == undef */
|
int model; /* -1 == undef */
|
||||||
unsigned int queues;
|
unsigned int queues;
|
||||||
unsigned int cmd_per_lun;
|
unsigned int cmd_per_lun;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* qemu_driver.c: core driver methods for managing qemu guests
|
* qemu_driver.c: core driver methods for managing qemu guests
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015 Red Hat, Inc.
|
* Copyright (C) 2006-2016 Red Hat, Inc.
|
||||||
* Copyright (C) 2006 Daniel P. Berrange
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
@ -7827,7 +7827,8 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
controller = dev->data.controller;
|
controller = dev->data.controller;
|
||||||
if (virDomainControllerFind(vmdef, controller->type,
|
if (controller->idx != -1 &&
|
||||||
|
virDomainControllerFind(vmdef, controller->type,
|
||||||
controller->idx) >= 0) {
|
controller->idx) >= 0) {
|
||||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||||
_("Target already exists"));
|
_("Target already exists"));
|
||||||
|
@ -425,6 +425,14 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* default idx would normally be set by virDomainDefPostParse(),
|
||||||
|
* which isn't called in the case of live attach of a single
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
|
if (controller->idx == -1)
|
||||||
|
controller->idx = virDomainControllerFindUnusedIndex(vm->def,
|
||||||
|
controller->type);
|
||||||
|
|
||||||
if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
|
if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) {
|
||||||
virReportError(VIR_ERR_OPERATION_FAILED,
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
_("target %s:%d already exists"),
|
_("target %s:%d already exists"),
|
||||||
|
53
tests/qemuxml2argvdata/qemuxml2argv-autoindex.args
Normal file
53
tests/qemuxml2argvdata/qemuxml2argv-autoindex.args
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
LC_ALL=C \
|
||||||
|
PATH=/bin \
|
||||||
|
HOME=/home/test \
|
||||||
|
USER=test \
|
||||||
|
LOGNAME=test \
|
||||||
|
QEMU_AUDIO_DRV=none \
|
||||||
|
/usr/libexec/qemu-kvm \
|
||||||
|
-name q35-test \
|
||||||
|
-S \
|
||||||
|
-M q35 \
|
||||||
|
-m 2048 \
|
||||||
|
-smp 2 \
|
||||||
|
-uuid 11dbdcdd-4c3b-482b-8903-9bdb8c0a2774 \
|
||||||
|
-nographic \
|
||||||
|
-nodefaults \
|
||||||
|
-monitor unix:/tmp/lib/domain--1-q35-test/monitor.sock,server,nowait \
|
||||||
|
-no-acpi \
|
||||||
|
-boot c \
|
||||||
|
-device i82801b11-bridge,id=pci.1,bus=pcie.0,addr=0x1e \
|
||||||
|
-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x0 \
|
||||||
|
-device ioh3420,port=0x10,chassis=3,id=pci.3,bus=pcie.0,addr=0x2 \
|
||||||
|
-device x3130-upstream,id=pci.4,bus=pci.3,addr=0x0 \
|
||||||
|
-device xio3130-downstream,port=0x0,chassis=5,id=pci.5,bus=pci.4,addr=0x0 \
|
||||||
|
-device xio3130-downstream,port=0x1,chassis=6,id=pci.6,bus=pci.4,addr=0x1 \
|
||||||
|
-device xio3130-downstream,port=0x2,chassis=7,id=pci.7,bus=pci.4,addr=0x2 \
|
||||||
|
-device xio3130-downstream,port=0x3,chassis=8,id=pci.8,bus=pci.4,addr=0x3 \
|
||||||
|
-device xio3130-downstream,port=0x4,chassis=9,id=pci.9,bus=pci.4,addr=0x4 \
|
||||||
|
-device xio3130-downstream,port=0x5,chassis=10,id=pci.10,bus=pci.4,addr=0x5 \
|
||||||
|
-device xio3130-downstream,port=0x6,chassis=11,id=pci.11,bus=pci.4,addr=0x6 \
|
||||||
|
-device xio3130-downstream,port=0x7,chassis=12,id=pci.12,bus=pci.4,addr=0x7 \
|
||||||
|
-device xio3130-downstream,port=0x8,chassis=13,id=pci.13,bus=pci.4,addr=0x8 \
|
||||||
|
-device xio3130-downstream,port=0x9,chassis=14,id=pci.14,bus=pci.4,addr=0x9 \
|
||||||
|
-device ich9-usb-ehci1,id=usb,bus=pcie.0,addr=0x1d.0x7 \
|
||||||
|
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pcie.0,multifunction=on,\
|
||||||
|
addr=0x1d \
|
||||||
|
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pcie.0,addr=0x1d.0x1 \
|
||||||
|
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pcie.0,addr=0x1d.0x2 \
|
||||||
|
-device ich9-usb-ehci1,id=usb1,bus=pcie.0,addr=0x1a.0x7 \
|
||||||
|
-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pcie.0,multifunction=on,\
|
||||||
|
addr=0x1a \
|
||||||
|
-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.2,multifunction=on,\
|
||||||
|
addr=0x1 \
|
||||||
|
-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.2,addr=0x1.0x1 \
|
||||||
|
-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.2,addr=0x1.0x2 \
|
||||||
|
-device ich9-usb-ehci1,id=usb2,bus=pci.2,addr=0x1.0x7 \
|
||||||
|
-device nec-usb-xhci,id=usb3,bus=pci.2,addr=0x2 \
|
||||||
|
-device ich9-usb-uhci1,masterbus=usb4.0,firstport=0,bus=pci.2,multifunction=on,\
|
||||||
|
addr=0x3 \
|
||||||
|
-device ich9-usb-uhci2,masterbus=usb4.0,firstport=2,bus=pci.2,addr=0x3.0x1 \
|
||||||
|
-device ich9-usb-uhci3,masterbus=usb4.0,firstport=4,bus=pci.2,addr=0x3.0x2 \
|
||||||
|
-device ich9-usb-ehci1,id=usb4,bus=pci.2,addr=0x3.0x7 \
|
||||||
|
-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-sata0-0-0 \
|
||||||
|
-device ide-drive,bus=ide.0,drive=drive-sata0-0-0,id=sata0-0-0
|
54
tests/qemuxml2argvdata/qemuxml2argv-autoindex.xml
Normal file
54
tests/qemuxml2argvdata/qemuxml2argv-autoindex.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>q35-test</name>
|
||||||
|
<uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</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='q35'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='sda' bus='sata'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='pci' model='pcie-root'/>
|
||||||
|
<controller type='pci' model='dmi-to-pci-bridge'/>
|
||||||
|
<controller type='pci' model='pci-bridge'/>
|
||||||
|
<controller type='pci' model='pcie-root-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-upstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='pci' model='pcie-switch-downstream-port'/>
|
||||||
|
<controller type='usb' model='ich9-ehci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci2'/>
|
||||||
|
<controller type='usb' model='ich9-uhci3'/>
|
||||||
|
<controller type='usb' model='ich9-ehci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci2'/>
|
||||||
|
<controller type='usb' model='ich9-uhci3'/>
|
||||||
|
<controller type='usb' model='ich9-ehci1'/>
|
||||||
|
<controller type='usb' model='nec-xhci'/>
|
||||||
|
<controller type='usb' model='ich9-uhci1'/>
|
||||||
|
<controller type='usb' model='ich9-uhci2'/>
|
||||||
|
<controller type='usb' model='ich9-uhci3'/>
|
||||||
|
<controller type='usb' model='ich9-ehci1'/>
|
||||||
|
<memballoon model='none'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -1574,6 +1574,15 @@ mymain(void)
|
|||||||
QEMU_CAPS_ICH9_AHCI,
|
QEMU_CAPS_ICH9_AHCI,
|
||||||
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
|
QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
|
||||||
QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
|
QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
|
||||||
|
DO_TEST("autoindex",
|
||||||
|
QEMU_CAPS_DEVICE_PCI_BRIDGE,
|
||||||
|
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
|
||||||
|
QEMU_CAPS_DEVICE_IOH3420,
|
||||||
|
QEMU_CAPS_DEVICE_X3130_UPSTREAM,
|
||||||
|
QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM,
|
||||||
|
QEMU_CAPS_ICH9_AHCI,
|
||||||
|
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
|
||||||
|
QEMU_CAPS_NEC_USB_XHCI);
|
||||||
|
|
||||||
DO_TEST_PARSE_ERROR("q35-wrong-root",
|
DO_TEST_PARSE_ERROR("q35-wrong-root",
|
||||||
QEMU_CAPS_DEVICE_PCI_BRIDGE,
|
QEMU_CAPS_DEVICE_PCI_BRIDGE,
|
||||||
|
153
tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml
Normal file
153
tests/qemuxml2xmloutdata/qemuxml2xmlout-autoindex.xml
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>q35-test</name>
|
||||||
|
<uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</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='q35'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/libexec/qemu-kvm</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='sda' bus='sata'/>
|
||||||
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='pci' index='0' model='pcie-root'/>
|
||||||
|
<controller type='pci' index='1' model='dmi-to-pci-bridge'>
|
||||||
|
<model name='i82801b11-bridge'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1e' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pci-bridge'>
|
||||||
|
<model name='pci-bridge'/>
|
||||||
|
<target chassisNr='2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='3' model='pcie-root-port'>
|
||||||
|
<model name='ioh3420'/>
|
||||||
|
<target chassis='3' port='0x10'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='4' model='pcie-switch-upstream-port'>
|
||||||
|
<model name='x3130-upstream'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='5' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='5' port='0x0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='6' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='6' port='0x1'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x01' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='7' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='7' port='0x2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x02' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='8' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='8' port='0x3'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x03' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='9' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='9' port='0x4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x04' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='10' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='10' port='0x5'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x05' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='11' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='11' port='0x6'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x06' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='12' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='12' port='0x7'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x07' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='13' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='13' port='0x8'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x08' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='14' model='pcie-switch-downstream-port'>
|
||||||
|
<model name='xio3130-downstream'/>
|
||||||
|
<target chassis='14' port='0x9'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x04' slot='0x09' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='0' model='ich9-ehci1'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='0' model='ich9-uhci1'>
|
||||||
|
<master startport='0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='0' model='ich9-uhci2'>
|
||||||
|
<master startport='2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='0' model='ich9-uhci3'>
|
||||||
|
<master startport='4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='1' model='ich9-ehci1'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1a' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='1' model='ich9-uhci1'>
|
||||||
|
<master startport='0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1a' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='2' model='ich9-uhci1'>
|
||||||
|
<master startport='0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='2' model='ich9-uhci2'>
|
||||||
|
<master startport='2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='2' model='ich9-uhci3'>
|
||||||
|
<master startport='4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='2' model='ich9-ehci1'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x01' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='3' model='nec-xhci'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x02' function='0x0'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='4' model='ich9-uhci1'>
|
||||||
|
<master startport='0'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x0' multifunction='on'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='4' model='ich9-uhci2'>
|
||||||
|
<master startport='2'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x1'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='4' model='ich9-uhci3'>
|
||||||
|
<master startport='4'/>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='usb' index='4' model='ich9-ehci1'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x02' slot='0x03' function='0x7'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='sata' index='0'>
|
||||||
|
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
||||||
|
</controller>
|
||||||
|
<input type='mouse' bus='ps2'/>
|
||||||
|
<input type='keyboard' bus='ps2'/>
|
||||||
|
<memballoon model='none'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -664,7 +664,15 @@ mymain(void)
|
|||||||
QEMU_CAPS_DEVICE_X3130_UPSTREAM,
|
QEMU_CAPS_DEVICE_X3130_UPSTREAM,
|
||||||
QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM,
|
QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM,
|
||||||
QEMU_CAPS_DEVICE_PXB_PCIE);
|
QEMU_CAPS_DEVICE_PXB_PCIE);
|
||||||
|
DO_TEST_FULL("autoindex", WHEN_ACTIVE, GIC_NONE,
|
||||||
|
QEMU_CAPS_DEVICE_PCI_BRIDGE,
|
||||||
|
QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
|
||||||
|
QEMU_CAPS_DEVICE_IOH3420,
|
||||||
|
QEMU_CAPS_DEVICE_X3130_UPSTREAM,
|
||||||
|
QEMU_CAPS_DEVICE_XIO3130_DOWNSTREAM,
|
||||||
|
QEMU_CAPS_ICH9_AHCI,
|
||||||
|
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1,
|
||||||
|
QEMU_CAPS_NEC_USB_XHCI);
|
||||||
|
|
||||||
DO_TEST_FULL("hostdev-scsi-lsi", WHEN_ACTIVE, GIC_NONE,
|
DO_TEST_FULL("hostdev-scsi-lsi", WHEN_ACTIVE, GIC_NONE,
|
||||||
QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI,
|
QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI,
|
||||||
|
Loading…
Reference in New Issue
Block a user