On 05/25/2018 04:24 AM, Michal Privoznik wrote:
On 05/17/2018 02:42 PM, John Ferlan wrote:
> The VM Generation ID is a mechanism to provide a unique 128-bit,
> cryptographically random, and integer value identifier known as
> the GUID (Globally Unique Identifier) to the guest OS. The value
> is used to help notify the guest operating system when the virtual
> machine is executed with a different configuration.
>
> This patch adds support for a new "genid" XML element similar to
> the "uuid" element. The "genid" element can have two forms
"<genid/>"
> or "<genid>$GUID</genid>". If the $GUID is not provided,
libvirt
> will generate one and save it in the XML.
>
> Since adding support for a generated GUID (or UUID like) value to
> be displayed modifying the xml2xml test to include virrandommock.so
> is necessary since it will generate a "known" value.
>
> Signed-off-by: John Ferlan <jferlan(a)redhat.com>
> ---
> docs/formatdomain.html.in | 27 ++++++++++++
> docs/schemas/domaincommon.rng | 8 ++++
> src/conf/domain_conf.c | 54 ++++++++++++++++++++++++
> src/conf/domain_conf.h | 5 +++
> tests/qemuxml2argvdata/genid-auto.xml | 32 ++++++++++++++
> tests/qemuxml2argvdata/genid.xml | 32 ++++++++++++++
> tests/qemuxml2xmloutdata/genid-active.xml | 32 ++++++++++++++
> tests/qemuxml2xmloutdata/genid-auto-active.xml | 32 ++++++++++++++
> tests/qemuxml2xmloutdata/genid-auto-inactive.xml | 32 ++++++++++++++
> tests/qemuxml2xmloutdata/genid-inactive.xml | 32 ++++++++++++++
> tests/qemuxml2xmltest.c | 5 ++-
> 11 files changed, 290 insertions(+), 1 deletion(-)
> create mode 100644 tests/qemuxml2argvdata/genid-auto.xml
> create mode 100644 tests/qemuxml2argvdata/genid.xml
> create mode 100644 tests/qemuxml2xmloutdata/genid-active.xml
> create mode 100644 tests/qemuxml2xmloutdata/genid-auto-active.xml
> create mode 100644 tests/qemuxml2xmloutdata/genid-auto-inactive.xml
> create mode 100644 tests/qemuxml2xmloutdata/genid-inactive.xml
>
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index 0d0fd3b9f3..72a55ff075 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -34,6 +34,7 @@
> <domain type='kvm' id='1'>
> <name>MyGuest</name>
> <uuid>4dea22b3-1d52-d8f3-2516-782e98ab3fa0</uuid>
> + <genid>43dc0cf8-809b-4adb-9bea-a9abb5f3d90e</genid>
> <title>A short description - title - of the
domain</title>
> <description>Some human readable
description</description>
> <metadata>
> @@ -61,6 +62,32 @@
> specification. <span class="since">Since 0.0.1, sysinfo
> since 0.8.7</span></dd>
>
> + <dt><code>genid</code></dt>
> + <dd><span class="since">Since 4.4.0</span>, the
<code>genid</code>
> + element can be used to add a Virtual Machine Generation ID which
> + exposes a 128-bit, cryptographically random, integer value identifier,
> + referred to as a Globally Unique Identifier (GUID) using the same
> + format as the <code>uuid</code>. The value is used to help
notify
> + the guest operating system when the virtual machine is re-executing
> + something that has already executed before, such as:
> +
> + <ul>
> + <li>VM starts executing a snapshot</li>
> + <li>VM is recovered from backup</li>
> + <li>VM is failover in a disaster recovery environment</li>
> + <li>VM is imported, copied, or cloned</li>
> + </ul>
> +
> + The guest operating system notices the change and is then able to
> + react as appropriate by marking its copies of distributed databases
> + as dirty, re-initializing its random number generator, etc.
> +
> + <p>
> + The libvirt XML parser will accept both a provided GUID value
> + or just <genid/> in which case a GUID will be generated
> + and saved in the XML. For the transitions such as above, libvirt
> + will change the GUID before re-executing.</p></dd>
> +
> <dt><code>title</code></dt>
> <dd>The optional element <code>title</code> provides space
for a
> short description of the domain. The title should not contain
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 71ac3d079c..1fba108927 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -502,6 +502,14 @@
> <ref name="UUID"/>
> </element>
> </optional>
> + <optional>
> + <element name="genid">
> + <choice>
> + <ref name="UUID"/>
> + <empty/>
> + </choice>
> + </element>
> + </optional>
> </interleave>
> </define>
> <define name="idmap">
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 3689ac0a82..4d5f3c6740 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -18919,6 +18919,34 @@ virDomainDefParseXML(xmlDocPtr xml,
> VIR_FREE(tmp);
> }
>
> + /* Extract domain genid - a genid can either be provided or generated */
> + if ((n = virXPathNodeSet("./genid", ctxt, &nodes)) < 0)
> + goto error;
> +
> + if (n > 0) {
> + if (n != 1) {
> + virReportError(VIR_ERR_XML_ERROR, "%s",
> + _("element 'genid' can only appear
once"));
This _() seems misaligned.
Right - good eyes. Fixed.
> + goto error;
> + }
> + def->genidRequested = true;
> + if (!(tmp = virXPathString("string(./genid[1])", ctxt))) {
Since you check that there's only onde <genid/> above, this [1] seems
redundant.
As with many other XML parses, the code is essentially copied from
elsewhere. Where exactly, I don't recall - I've removed the [1] though.
John
> + if (virUUIDGenerate(def->genid) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("Failed to generate
genid"));
> + goto error;
> + }
> + def->genidGenerated = true;
> + } else {
> + if (virUUIDParse(tmp, def->genid) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("malformed genid
element"));
> + goto error;
> + }
> + }
> + }
> + VIR_FREE(nodes);
> +
Michal