mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 09:53:10 +00:00
conf: add new <model> subelement with name attribute to <controller>
This new subelement is used in PCI controllers: the toplevel *attribute* "model" of a controller denotes what kind of PCI controller is being described, e.g. a "dmi-to-pci-bridge", "pci-bridge", or "pci-root". But in the future there will be different implementations of some of those types of PCI controllers, which behave similarly from libvirt's point of view (and so should have the same model), but use a different device in qemu (and present themselves as a different piece of hardware in the guest). In an ideal world we (i.e. "I") would have thought of that back when the pci controllers were added, and used some sort of type/class/model notation (where class was used in the way we are now using model, and model was used for the actual manufacturer's model number of a particular family of PCI controller), but that opportunity is long past, so as an alternative, this patch allows selecting a particular implementation of a pci controller with the "name" attribute of the <model> subelement, e.g.: <controller type='pci' model='dmi-to-pci-bridge' index='1'> <model name='i82801b11-bridge'/> </controller> In this case, "dmi-to-pci-bridge" is the kind of controller (one that has a single PCIe port upstream, and 32 standard PCI ports downstream, which are not hotpluggable), and the qemu device to be used to implement this kind of controller is named "i82801b11-bridge". Implementing the above now will allow us in the future to add a new kind of dmi-to-pci-bridge that doesn't use qemu's i82801b11-bridge device, but instead uses something else (which doesn't yet exist, but qemu people have been discussing it), all without breaking existing configs. (note that for the existing "pci-bridge" type of PCI controller, both the model attribute and <model> name are 'pci-bridge'. This is just a coincidence, since it turns out that in this case the device name in qemu really is a generic 'pci-bridge' rather than being the name of some real-world chip)
This commit is contained in:
parent
f8fe8f0345
commit
bf20251048
@ -3043,6 +3043,19 @@
|
|||||||
are recent enough to support 64-bit PCI holes, unless this is disabled
|
are recent enough to support 64-bit PCI holes, unless this is disabled
|
||||||
(set to 0). <span class="since">Since 1.1.2 (QEMU only)</span>
|
(set to 0). <span class="since">Since 1.1.2 (QEMU only)</span>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
PCI controllers also have an optional
|
||||||
|
subelement <code><model></code> with an attribute
|
||||||
|
<code>name</code>. The name attribute holds the name of the
|
||||||
|
specific device that qemu is emulating (e.g. "i82801b11-bridge")
|
||||||
|
rather than simply the class of device ("dmi-to-pci-bridge",
|
||||||
|
"pci-bridge"), which is set in the controller element's
|
||||||
|
model <b>attribute</b>. In almost all cases, you should not
|
||||||
|
manually add a <code><model></code> subelement to a
|
||||||
|
controller, nor should you modify one that is automatically
|
||||||
|
generated by libvirt. <span class="since">Since 1.2.19 (QEMU
|
||||||
|
only).</span>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For machine types which provide an implicit PCI bus, the pci-root
|
For machine types which provide an implicit PCI bus, the pci-root
|
||||||
controller with index=0 is auto-added and required to use PCI devices.
|
controller with index=0 is auto-added and required to use PCI devices.
|
||||||
|
@ -1731,6 +1731,19 @@
|
|||||||
<attribute name="type">
|
<attribute name="type">
|
||||||
<value>pci</value>
|
<value>pci</value>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<element name="model">
|
||||||
|
<attribute name="name">
|
||||||
|
<choice>
|
||||||
|
<!-- implementations of 'pci-bridge' -->
|
||||||
|
<value>pci-bridge</value>
|
||||||
|
<!-- implementations of 'dmi-to-pci-bridge' -->
|
||||||
|
<value>i82801b11-bridge</value>
|
||||||
|
</choice>
|
||||||
|
</attribute>
|
||||||
|
<empty/>
|
||||||
|
</element>
|
||||||
|
</optional>
|
||||||
<!-- *-root controllers have an optional element "pcihole64"-->
|
<!-- *-root controllers have an optional element "pcihole64"-->
|
||||||
<choice>
|
<choice>
|
||||||
<group>
|
<group>
|
||||||
|
@ -326,6 +326,12 @@ VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
|
|||||||
"pci-bridge",
|
"pci-bridge",
|
||||||
"dmi-to-pci-bridge")
|
"dmi-to-pci-bridge")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainControllerPCIModelName,
|
||||||
|
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST,
|
||||||
|
"none",
|
||||||
|
"pci-bridge",
|
||||||
|
"i82801b11-bridge")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
|
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
|
||||||
"auto",
|
"auto",
|
||||||
"buslogic",
|
"buslogic",
|
||||||
@ -7802,6 +7808,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
char *queues = NULL;
|
char *queues = NULL;
|
||||||
char *cmd_per_lun = NULL;
|
char *cmd_per_lun = NULL;
|
||||||
char *max_sectors = NULL;
|
char *max_sectors = NULL;
|
||||||
|
bool processedModel = false;
|
||||||
|
char *modelName = NULL;
|
||||||
xmlNodePtr saved = ctxt->node;
|
xmlNodePtr saved = ctxt->node;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -7845,6 +7853,15 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
queues = virXMLPropString(cur, "queues");
|
queues = virXMLPropString(cur, "queues");
|
||||||
cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
|
cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
|
||||||
max_sectors = virXMLPropString(cur, "max_sectors");
|
max_sectors = virXMLPropString(cur, "max_sectors");
|
||||||
|
} else if (xmlStrEqual(cur->name, BAD_CAST "model")) {
|
||||||
|
if (processedModel) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("Multiple <model> elements in "
|
||||||
|
"controller definition not allowed"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
modelName = virXMLPropString(cur, "name");
|
||||||
|
processedModel = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
@ -7953,6 +7970,15 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
def->opts.pciopts.pcihole64size = VIR_DIV_UP(bytes, 1024);
|
def->opts.pciopts.pcihole64size = VIR_DIV_UP(bytes, 1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (modelName &&
|
||||||
|
(def->opts.pciopts.modelName
|
||||||
|
= virDomainControllerPCIModelNameTypeFromString(modelName)) <= 0) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Unknown PCI controller model name '%s'"),
|
||||||
|
modelName);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -7977,6 +8003,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
|||||||
VIR_FREE(queues);
|
VIR_FREE(queues);
|
||||||
VIR_FREE(cmd_per_lun);
|
VIR_FREE(cmd_per_lun);
|
||||||
VIR_FREE(max_sectors);
|
VIR_FREE(max_sectors);
|
||||||
|
VIR_FREE(modelName);
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
|
|
||||||
@ -18988,7 +19015,8 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
|||||||
{
|
{
|
||||||
const char *type = virDomainControllerTypeToString(def->type);
|
const char *type = virDomainControllerTypeToString(def->type);
|
||||||
const char *model = NULL;
|
const char *model = NULL;
|
||||||
bool pcihole64 = false;
|
const char *modelName = NULL;
|
||||||
|
bool pcihole64 = false, pciModel = false;
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -19028,17 +19056,31 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
|||||||
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
|
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
|
||||||
if (def->opts.pciopts.pcihole64)
|
if (def->opts.pciopts.pcihole64)
|
||||||
pcihole64 = true;
|
pcihole64 = true;
|
||||||
|
if (def->opts.pciopts.modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE)
|
||||||
|
pciModel = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (def->queues || def->cmd_per_lun || def->max_sectors ||
|
if (pciModel ||
|
||||||
|
def->queues || def->cmd_per_lun || def->max_sectors ||
|
||||||
virDomainDeviceInfoNeedsFormat(&def->info, flags) || pcihole64) {
|
virDomainDeviceInfoNeedsFormat(&def->info, flags) || pcihole64) {
|
||||||
virBufferAddLit(buf, ">\n");
|
virBufferAddLit(buf, ">\n");
|
||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
|
if (pciModel) {
|
||||||
|
modelName = virDomainControllerPCIModelNameTypeToString(def->opts.pciopts.modelName);
|
||||||
|
if (!modelName) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected model name value %d"),
|
||||||
|
def->opts.pciopts.modelName);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
virBufferAsprintf(buf, "<model name='%s'/>\n", modelName);
|
||||||
|
}
|
||||||
|
|
||||||
if (def->queues || def->cmd_per_lun || def->max_sectors) {
|
if (def->queues || def->cmd_per_lun || def->max_sectors) {
|
||||||
virBufferAddLit(buf, "<driver");
|
virBufferAddLit(buf, "<driver");
|
||||||
if (def->queues)
|
if (def->queues)
|
||||||
|
@ -756,6 +756,14 @@ typedef enum {
|
|||||||
VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
|
VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
|
||||||
} virDomainControllerModelPCI;
|
} virDomainControllerModelPCI;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE,
|
||||||
|
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCI_BRIDGE,
|
||||||
|
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE,
|
||||||
|
|
||||||
|
VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST
|
||||||
|
} virDomainControllerPCIModelName;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO,
|
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO,
|
||||||
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC,
|
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC,
|
||||||
@ -797,6 +805,13 @@ typedef virDomainPCIControllerOpts *virDomainPCIControllerOptsPtr;
|
|||||||
struct _virDomainPCIControllerOpts {
|
struct _virDomainPCIControllerOpts {
|
||||||
bool pcihole64;
|
bool pcihole64;
|
||||||
unsigned long pcihole64size;
|
unsigned long pcihole64size;
|
||||||
|
|
||||||
|
/* the exact controller name is in the "model" subelement, e.g.:
|
||||||
|
* <controller type='pci' model='pcie-root-port'>
|
||||||
|
* <model name='ioh3420''/>
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
int modelName; /* the exact name of the device in hypervisor */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Stores the virtual disk controller configuration */
|
/* Stores the virtual disk controller configuration */
|
||||||
@ -2978,6 +2993,7 @@ VIR_ENUM_DECL(virDomainDiskDiscard)
|
|||||||
VIR_ENUM_DECL(virDomainDiskMirrorState)
|
VIR_ENUM_DECL(virDomainDiskMirrorState)
|
||||||
VIR_ENUM_DECL(virDomainController)
|
VIR_ENUM_DECL(virDomainController)
|
||||||
VIR_ENUM_DECL(virDomainControllerModelPCI)
|
VIR_ENUM_DECL(virDomainControllerModelPCI)
|
||||||
|
VIR_ENUM_DECL(virDomainControllerPCIModelName)
|
||||||
VIR_ENUM_DECL(virDomainControllerModelSCSI)
|
VIR_ENUM_DECL(virDomainControllerModelSCSI)
|
||||||
VIR_ENUM_DECL(virDomainControllerModelUSB)
|
VIR_ENUM_DECL(virDomainControllerModelUSB)
|
||||||
VIR_ENUM_DECL(virDomainFS)
|
VIR_ENUM_DECL(virDomainFS)
|
||||||
|
@ -192,6 +192,8 @@ virDomainControllerModelSCSITypeFromString;
|
|||||||
virDomainControllerModelSCSITypeToString;
|
virDomainControllerModelSCSITypeToString;
|
||||||
virDomainControllerModelUSBTypeFromString;
|
virDomainControllerModelUSBTypeFromString;
|
||||||
virDomainControllerModelUSBTypeToString;
|
virDomainControllerModelUSBTypeToString;
|
||||||
|
virDomainControllerPCIModelNameTypeFromString;
|
||||||
|
virDomainControllerPCIModelNameTypeToString;
|
||||||
virDomainControllerRemove;
|
virDomainControllerRemove;
|
||||||
virDomainControllerTypeToString;
|
virDomainControllerTypeToString;
|
||||||
virDomainCpuPlacementModeTypeFromString;
|
virDomainCpuPlacementModeTypeFromString;
|
||||||
|
@ -20,8 +20,12 @@
|
|||||||
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
</disk>
|
</disk>
|
||||||
<controller type='pci' index='0' model='pcie-root'/>
|
<controller type='pci' index='0' model='pcie-root'/>
|
||||||
<controller type='pci' index='1' model='dmi-to-pci-bridge'/>
|
<controller type='pci' index='1' model='dmi-to-pci-bridge'>
|
||||||
<controller type='pci' index='2' model='pci-bridge'/>
|
<model name='i82801b11-bridge'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pci-bridge'>
|
||||||
|
<model name='pci-bridge'/>
|
||||||
|
</controller>
|
||||||
<video>
|
<video>
|
||||||
<model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
<model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
||||||
</video>
|
</video>
|
||||||
|
@ -20,8 +20,12 @@
|
|||||||
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
|
||||||
</disk>
|
</disk>
|
||||||
<controller type='pci' index='0' model='pcie-root'/>
|
<controller type='pci' index='0' model='pcie-root'/>
|
||||||
<controller type='pci' index='1' model='dmi-to-pci-bridge'/>
|
<controller type='pci' index='1' model='dmi-to-pci-bridge'>
|
||||||
<controller type='pci' index='2' model='pci-bridge'/>
|
<model name='i82801b11-bridge'/>
|
||||||
|
</controller>
|
||||||
|
<controller type='pci' index='2' model='pci-bridge'>
|
||||||
|
<model name='pci-bridge'/>
|
||||||
|
</controller>
|
||||||
<controller type='sata' index='0'/>
|
<controller type='sata' index='0'/>
|
||||||
<video>
|
<video>
|
||||||
<model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
<model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
|
||||||
|
Loading…
Reference in New Issue
Block a user