diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 665d0f2529..9f6e8ee732 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. Since 0.0.1, sysinfo
since 0.8.7
+
genid
+ Since 4.4.0 , the genid
+ 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 uuid
. 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:
+
+
+ VM starts executing a snapshot
+ VM is recovered from backup
+ VM is failover in a disaster recovery environment
+ VM is imported, copied, or cloned
+
+
+ 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.
+
+
+ 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.
+
title
The optional element title
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 f16e157397..2cb9bfea98 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -502,6 +502,14 @@
+
+
+
+
+
+
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2253098090..d6ac47c629 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -18920,6 +18920,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)", 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')) {
@@ -22034,6 +22062,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
@@ -26752,6 +26799,13 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virUUIDFormat(uuid, uuidstr);
virBufferAsprintf(buf, "%s \n", uuidstr);
+ if (def->genidRequested) {
+ char genidstr[VIR_UUID_STRING_BUFLEN];
+
+ virUUIDFormat(def->genid, genidstr);
+ virBufferAsprintf(buf, "%s \n", genidstr);
+ }
+
virBufferEscapeString(buf, "%s \n", def->title);
virBufferEscapeString(buf, "%s \n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 37356df42d..b7e52a1e03 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2328,6 +2328,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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ e9392370-2917-565e-692b-d057f46512d6
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ e9392370-2917-565e-692b-d057f46512d6
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 00010203-0405-4607-8809-0a0b0c0d0e0f
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ 00010203-0405-4607-8809-0a0b0c0d0e0f
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
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 @@
+
+ QEMUGuest1
+ c7a5fdbd-edaf-9455-926a-d65c16db1809
+ e9392370-2917-565e-692b-d057f46512d6
+ 219136
+ 219136
+ 1
+
+ hvm
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+ /usr/bin/qemu-system-x86_64
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index e31d8212fe..bd7433dce4 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);
@@ -1220,7 +1222,8 @@ mymain(void)
}
VIR_TEST_MAIN_PRELOAD(mymain,
- abs_builddir "/.libs/virpcimock.so")
+ abs_builddir "/.libs/virpcimock.so",
+ abs_builddir "/.libs/virrandommock.so")
#else