[libvirt] [REPOSTv2 PATCH v3 1/6] conf: Add VM Generation ID parse/format support

John Ferlan posted 6 patches 6 years, 12 months ago
[libvirt] [REPOSTv2 PATCH v3 1/6] conf: Add VM Generation ID parse/format support
Posted by John Ferlan 6 years, 12 months ago
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@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 @@
 &lt;domain type='kvm' id='1'&gt;
   &lt;name&gt;MyGuest&lt;/name&gt;
   &lt;uuid&gt;4dea22b3-1d52-d8f3-2516-782e98ab3fa0&lt;/uuid&gt;
+  &lt;genid&gt;43dc0cf8-809b-4adb-9bea-a9abb5f3d90e&lt;/genid&gt;
   &lt;title&gt;A short description - title - of the domain&lt;/title&gt;
   &lt;description&gt;Some human readable description&lt;/description&gt;
   &lt;metadata&gt;
@@ -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 &lt;genid/&gt; 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"));
+            goto error;
+        }
+        def->genidRequested = true;
+        if (!(tmp = virXPathString("string(./genid[1])", ctxt))) {
+            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);
+
     /* Extract short description of domain (title) */
     def->title = virXPathString("string(./title[1])", ctxt);
     if (def->title && strchr(def->title, '\n')) {
@@ -22033,6 +22061,25 @@ virDomainDefCheckABIStabilityFlags(virDomainDefPtr src,
         goto error;
     }
 
+    if (src->genidRequested != dst->genidRequested) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Target domain requested genid does not match source"));
+        goto error;
+    }
+
+    if (src->genidRequested &&
+        memcmp(src->genid, dst->genid, VIR_UUID_BUFLEN) != 0) {
+        char guidsrc[VIR_UUID_STRING_BUFLEN];
+        char guiddst[VIR_UUID_STRING_BUFLEN];
+
+        virUUIDFormat(src->genid, guidsrc);
+        virUUIDFormat(dst->genid, guiddst);
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Target domain genid %s does not match source %s"),
+                       guiddst, guidsrc);
+        goto error;
+    }
+
     /* Not strictly ABI related, but we want to make sure domains
      * don't get silently re-named through the backdoor when passing
      * custom XML into various APIs, since this would create havoc
@@ -26751,6 +26798,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
     virUUIDFormat(uuid, uuidstr);
     virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr);
 
+    if (def->genidRequested) {
+        char genidstr[VIR_UUID_STRING_BUFLEN];
+
+        virUUIDFormat(def->genid, genidstr);
+        virBufferAsprintf(buf, "<genid>%s</genid>\n", genidstr);
+    }
+
     virBufferEscapeString(buf, "<title>%s</title>\n", def->title);
 
     virBufferEscapeString(buf, "<description>%s</description>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a78fdee40c..f5264ea850 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2327,6 +2327,11 @@ struct _virDomainDef {
     virDomainVirtType virtType;
     int id;
     unsigned char uuid[VIR_UUID_BUFLEN];
+
+    unsigned char genid[VIR_UUID_BUFLEN];
+    bool genidRequested;
+    bool genidGenerated;
+
     char *name;
     char *title;
     char *description;
diff --git a/tests/qemuxml2argvdata/genid-auto.xml b/tests/qemuxml2argvdata/genid-auto.xml
new file mode 100644
index 0000000000..96ad9ddda8
--- /dev/null
+++ b/tests/qemuxml2argvdata/genid-auto.xml
@@ -0,0 +1,32 @@
+<domain type='qemu' id='1'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid/>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/genid.xml b/tests/qemuxml2argvdata/genid.xml
new file mode 100644
index 0000000000..fc41f2dd28
--- /dev/null
+++ b/tests/qemuxml2argvdata/genid.xml
@@ -0,0 +1,32 @@
+<domain type='qemu' id='1'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid>e9392370-2917-565e-692b-d057f46512d6</genid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/genid-active.xml b/tests/qemuxml2xmloutdata/genid-active.xml
new file mode 100644
index 0000000000..fc41f2dd28
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/genid-active.xml
@@ -0,0 +1,32 @@
+<domain type='qemu' id='1'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid>e9392370-2917-565e-692b-d057f46512d6</genid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/genid-auto-active.xml b/tests/qemuxml2xmloutdata/genid-auto-active.xml
new file mode 100644
index 0000000000..aeca0d7fc0
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/genid-auto-active.xml
@@ -0,0 +1,32 @@
+<domain type='qemu' id='1'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid>00010203-0405-4607-8809-0a0b0c0d0e0f</genid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/genid-auto-inactive.xml b/tests/qemuxml2xmloutdata/genid-auto-inactive.xml
new file mode 100644
index 0000000000..a7b711d469
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/genid-auto-inactive.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid>00010203-0405-4607-8809-0a0b0c0d0e0f</genid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/genid-inactive.xml b/tests/qemuxml2xmloutdata/genid-inactive.xml
new file mode 100644
index 0000000000..8bd526a7a9
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/genid-inactive.xml
@@ -0,0 +1,32 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <genid>e9392370-2917-565e-692b-d057f46512d6</genid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+  </features>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <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'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 7cedc2b999..35a41007fc 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -276,6 +276,8 @@ mymain(void)
     setenv("PATH", "/bin", 1);
 
     DO_TEST("minimal", NONE);
+    DO_TEST("genid", NONE);
+    DO_TEST("genid-auto", NONE);
     DO_TEST("machine-core-on", NONE);
     DO_TEST("machine-core-off", NONE);
     DO_TEST("machine-loadparm-multiple-disks-nets-s390", NONE);
@@ -1219,7 +1221,8 @@ mymain(void)
 }
 
 VIR_TEST_MAIN_PRELOAD(mymain,
-                      abs_builddir "/.libs/virpcimock.so")
+                      abs_builddir "/.libs/virpcimock.so",
+                      abs_builddir "/.libs/virrandommock.so")
 
 #else
 
-- 
2.14.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REPOSTv2 PATCH v3 1/6] conf: Add VM Generation ID parse/format support
Posted by Michal Privoznik 6 years, 11 months ago
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@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 @@
>  &lt;domain type='kvm' id='1'&gt;
>    &lt;name&gt;MyGuest&lt;/name&gt;
>    &lt;uuid&gt;4dea22b3-1d52-d8f3-2516-782e98ab3fa0&lt;/uuid&gt;
> +  &lt;genid&gt;43dc0cf8-809b-4adb-9bea-a9abb5f3d90e&lt;/genid&gt;
>    &lt;title&gt;A short description - title - of the domain&lt;/title&gt;
>    &lt;description&gt;Some human readable description&lt;/description&gt;
>    &lt;metadata&gt;
> @@ -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 &lt;genid/&gt; 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.

> +            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.

> +            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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REPOSTv2 PATCH v3 1/6] conf: Add VM Generation ID parse/format support
Posted by John Ferlan 6 years, 11 months ago

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@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 @@
>>  &lt;domain type='kvm' id='1'&gt;
>>    &lt;name&gt;MyGuest&lt;/name&gt;
>>    &lt;uuid&gt;4dea22b3-1d52-d8f3-2516-782e98ab3fa0&lt;/uuid&gt;
>> +  &lt;genid&gt;43dc0cf8-809b-4adb-9bea-a9abb5f3d90e&lt;/genid&gt;
>>    &lt;title&gt;A short description - title - of the domain&lt;/title&gt;
>>    &lt;description&gt;Some human readable description&lt;/description&gt;
>>    &lt;metadata&gt;
>> @@ -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 &lt;genid/&gt; 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
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list