[libvirt] [PATCHv2 07/17] conf: add new <target> subelement with chassisNr attribute to <controller>
John Ferlan
jferlan at redhat.com
Wed Jul 22 20:20:46 UTC 2015
On 07/17/2015 02:43 PM, Laine Stump wrote:
> There are some configuration options to some types of pci
> controllers that are currently automatically derived from other parts
> of the controller's configuration. For example, a pci-bridge
> controller has an option that is called "chassis_nr" in qemu; libvirt
> always sets chassis_nr to the index of the pci-bridge. So this:
>
> <controller type='pci' model='pci-bridge' index='2'/>
>
> will always result in:
>
> -device pci-bridge,chassis_nr=2,...
>
> on the qemu commandline. In the future we may decide there is a better
> way to derive that option, but even in that case we will need for
> existing domains to retain the same chassis_nr they were using in the
> past - that is something that is visible to the guest so it is part of
> the guest ABI and changing it would lead to problems for migrating
> guests (or just guests with very picky OSes).
>
> The <target> subelement has been added as a place to put the new
> "chassisNr" attribute that will be filled in by libvirt when it
> auto-generates the chassisNr; it will be saved in the config, then
> reused any time the domain is started:
>
> <controller type='pci' model='pci-bridge' index='2'>
> <model type='pci-bridge'/>
> <target chassisNr='2'/>
> </controller>
>
> The one oddity of all this is that if the controller configuration
> is changed (for example to change the index or the pci address
> where the controller is plugged in), the items in <target> will
> *not* be re-generated, which might lead to conflict. I can't
> really see any way around this, but fortunately if there is a
> material conflict qemu will let us know and we will pass that on
> to the user.
> ---
>
> new in V2 (previously was a part of the patch to add pcie-root-port,
> but adding the attributes under <model> instead of <target>)
>
> docs/formatdomain.html.in | 23 ++++++++++++++++++++
> docs/schemas/domaincommon.rng | 10 +++++++++
> src/conf/domain_conf.c | 28 +++++++++++++++++++++++--
> src/conf/domain_conf.h | 10 ++++++++-
> tests/qemuxml2argvdata/qemuxml2argv-q35.xml | 1 +
> tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml | 1 +
> 6 files changed, 70 insertions(+), 3 deletions(-)
>
Again assuming this is the generally acceptable mechanism. It seems fine
to me though
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index fa46276..ae0d66a 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -3049,6 +3049,29 @@
> libvirt. <span class="since">Since 1.3.0 (QEMU only).</span>
> </p>
> <p>
> + PCI controllers also have an optional
s/also//
> + subelement <code><target></code> with the attributes
> + listed below. These are configurable items that 1) are visible
> + to the guest OS so must be preserved for guest ABI
> + compatibility, and 2) are usually left to default values or
> + derived automatically by libvirt. In almost all cases, you
> + should not manually add a <code><target></code> subelement
> + to a controller, nor should you modify the values in the those
> + that are automatically generated by
> + libvirt. <span class="since">Since 1.3.0 (QEMU only).</span>
1.2.18
> + </p>
> + <dl>
> + <dt><code>chassisNr</code></dt>
> + <dd>
> + PCI controllers that have attribute model="pci-bridge", can
> + also have a <code>chassisNr</code> attribute in
> + the <code><target></code> subelement, which is used to
> + control QEMU's "chassis_nr" option for the pci-bridge device
> + (normally libvirt automatically sets this to the same value as
> + the index attribute of the pci controller).
Is there a valid range that needs to be documented? See comments for
rng and parse.
> + </dd>
> + </dl>
> + <p>
> 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.
> pci-root has no address.
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 66518f9..1b1f592 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -1744,6 +1744,16 @@
> <empty/>
> </element>
> </optional>
> + <optional>
> + <element name="target">
> + <optional>
> + <attribute name='chassisNr'>
> + <ref name='uint8range'/>
This is an int in domain_conf.h and is set to -1 in
virDomainControllerDefNew.
So one or the other seems to need adjustment since by this rule we can
only be between 0 and 255 inclusive.
> + </attribute>
> + </optional>
> + <empty/>
> + </element>
> + </optional>
> <!-- *-root controllers have an optional element "pcihole64"-->
> <choice>
> <group>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 380b758..17526d4 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1544,6 +1544,8 @@ virDomainControllerDefNew(virDomainControllerType type)
> def->opts.vioserial.vectors = -1;
> break;
> case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
> + def->opts.pciopts.chassisNr = -1;
> + break;
> case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
> case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
> case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
> @@ -7638,6 +7640,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
> char *cmd_per_lun = NULL;
> char *max_sectors = NULL;
> char *guestModel = NULL;
> + char *chassisNr = NULL;
> xmlNodePtr saved = ctxt->node;
> int rc;
>
> @@ -7686,6 +7689,9 @@ virDomainControllerDefParseXML(xmlNodePtr node,
> } else if (xmlStrEqual(cur->name, BAD_CAST "model")) {
> if (!guestModel)
> guestModel = virXMLPropString(cur, "type");
> + } else if (xmlStrEqual(cur->name, BAD_CAST "target")) {
> + if (!chassisNr)
> + chassisNr = virXMLPropString(cur, "chassisNr");
Similar to note about guestModel - multiple chassisNr aren't allowed by
RNG rules...
> }
> }
> cur = cur->next;
> @@ -7798,6 +7804,13 @@ virDomainControllerDefParseXML(xmlNodePtr node,
> def->opts.pciopts.type = guestModel;
> guestModel = 0;
> }
> + if (chassisNr && virStrToLong_i(chassisNr, NULL, 0,
> + &def->opts.pciopts.chassisNr) < 0) {
^
one extra space too many (just had a shot of coffee so I saw it!)
Also if the range is truly 0 to 255 inclusive, then don't we need to
test for that here as well?
> + virReportError(VIR_ERR_XML_ERROR,
> + _("Invalid chassisNr '%s' in PCI controller"),
> + chassisNr);
> + goto error;
> + }
> break;
>
> default:
> @@ -7824,6 +7837,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
> VIR_FREE(cmd_per_lun);
> VIR_FREE(max_sectors);
> VIR_FREE(guestModel);
> + VIR_FREE(chassisNr);
>
> return def;
>
> @@ -18833,7 +18847,7 @@ virDomainControllerDefFormat(virBufferPtr buf,
> {
> const char *type = virDomainControllerTypeToString(def->type);
> const char *model = NULL;
> - bool pcihole64 = false, pciModel = false;
> + bool pcihole64 = false, pciModel = false, pciTarget = false;
>
> if (!type) {
> virReportError(VIR_ERR_INTERNAL_ERROR,
> @@ -18875,13 +18889,15 @@ virDomainControllerDefFormat(virBufferPtr buf,
> pcihole64 = true;
> if (def->opts.pciopts.type)
> pciModel = true;
> + if (def->opts.pciopts.chassisNr != -1)
> + pciTarget = true;
[this]
> break;
>
> default:
> break;
> }
>
> - if (pciModel ||
> + if (pciModel || pciTarget ||
> def->queues || def->cmd_per_lun || def->max_sectors ||
> virDomainDeviceInfoNeedsFormat(&def->info, flags) || pcihole64) {
> virBufferAddLit(buf, ">\n");
> @@ -18893,6 +18909,14 @@ virDomainControllerDefFormat(virBufferPtr buf,
> virBufferAddLit(buf, "/>\n");
> }
>
> + if (pciTarget) {
This can only be true if chassisNr != -1
> + virBufferAddLit(buf, "<target");
> + if (def->opts.pciopts.chassisNr != -1)
[which means this if isn't necessary]
> + virBufferAsprintf(buf, " chassisNr='%d'",
> + def->opts.pciopts.chassisNr);
> + virBufferAddLit(buf, "/>\n");
and of course means the whole thing can be formatted in one line
> + }
> +
> if (def->queues || def->cmd_per_lun || def->max_sectors) {
> virBufferAddLit(buf, "<driver");
> if (def->queues)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 09fe3c0..32d1073 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -805,7 +805,15 @@ struct _virDomainPCIControllerOpts {
> * similar to the model of <interface> devices.
> */
> char *type; /* the exact name of the device in hypervisor */
> -};
> +
> + /* the following items are attributes of the "target" subelement
> + * of controller type='pci'. They are bits of configuration that
> + * are specified on the qemu commandline and are visible to the
> + * guest OS, so they must be preserved to ensure ABI
> + * compatibility.
> + */
> + int chassisNr; /* used by pci-bridge, -1 == unspecified */
> + };
>
> /* Stores the virtual disk controller configuration */
> struct _virDomainControllerDef {
Similar to previous comment about "reusing" a test - IDC, but perhaps
this should have been a "new" test which we're building upon rather than
stealing an existing one.
ACK with the appropriate adjustments
John
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-q35.xml b/tests/qemuxml2argvdata/qemuxml2argv-q35.xml
> index 4623a5c..815eb08 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-q35.xml
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-q35.xml
> @@ -25,6 +25,7 @@
> </controller>
> <controller type='pci' index='2' model='pci-bridge'>
> <model type='pci-bridge'/>
> + <target chassisNr='56'/>
> </controller>
> <video>
> <model type='qxl' ram='65536' vram='32768' vgamem='8192' heads='1'/>
> diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml
> index 760830a..13e4734 100644
> --- a/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml
> +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-q35.xml
> @@ -25,6 +25,7 @@
> </controller>
> <controller type='pci' index='2' model='pci-bridge'>
> <model type='pci-bridge'/>
> + <target chassisNr='56'/>
> </controller>
> <controller type='sata' index='0'/>
> <video>
>
More information about the libvir-list
mailing list