:since:`Since 0.8.7`, it is also possible to provide the UUID via a
`SMBIOS System Information`_ specification.
+``hwuuid``
+ The optional ``hwuuid`` element can be used to supply an alternative UUID for
+ identifying the virtual machine from the domain ``uuid`` above. The difference
+ between using the ``hwuuid`` element and simply providing an alternative UUID
+ via a `SMBIOS System Information`_ specification is that the ``hwuuid`` affects
+ all devices that expose the UUID to the guest.
+ :since:`Since 11.6.0 QEMU/KVM only`
``genid``
:since:`Since 4.4.0`, the ``genid`` element can be used to add a Virtual
Machine Generation ID which exposes a 128-bit, cryptographically random,
virSysinfoSystemParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
virSysinfoSystemDef **sysdef,
+ unsigned char *hwUUID,
unsigned char *domUUID,
bool uuid_generated)
{
}
if (uuid_generated) {
memcpy(domUUID, uuidbuf, VIR_UUID_BUFLEN);
- } else if (memcmp(domUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) {
- virReportError(VIR_ERR_XML_DETAIL, "%s",
+ } else if (virUUIDIsValid(hwUUID)) {
+ if (memcmp(hwUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
+ _("UUID mismatch between <hwuuid> and <sysinfo>"));
+ return -1;
+ }
+ } else {
+ if (memcmp(domUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) {
+ virReportError(VIR_ERR_XML_DETAIL, "%s",
_("UUID mismatch between <uuid> and <sysinfo>"));
- return -1;
+ return -1;
+ }
}
/* Although we've validated the UUID as good, virUUIDParse() is
* lax with respect to allowing extraneous "-" and " ", but the
static int
virSysinfoParseSMBIOSDef(virSysinfoDef *def,
xmlXPathContextPtr ctxt,
+ unsigned char *hwUUID,
unsigned char *domUUID,
bool uuid_generated)
{
/* Extract system related metadata */
if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) {
- if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system,
+ if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system, hwUUID,
domUUID, uuid_generated) < 0)
return -1;
}
static virSysinfoDef *
virSysinfoParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
+ unsigned char *hwUUID,
unsigned char *domUUID,
bool uuid_generated)
{
switch (def->type) {
case VIR_SYSINFO_SMBIOS:
- if (virSysinfoParseSMBIOSDef(def, ctxt, domUUID, uuid_generated) < 0)
+ if (virSysinfoParseSMBIOSDef(def, ctxt, hwUUID, domUUID,
+ uuid_generated) < 0)
return NULL;
break;
VIR_FREE(tmp);
}
+ /* Extract hardware uuid (optional). For some use cases e.g. cloning a
+ * domain from a snapshot, the hardware uuid must remain constant and
+ * separate from the domain uuid. */
+ tmp = virXPathString("string(./hwuuid[1])", ctxt);
+ if (tmp) {
+ if (virUUIDParse(tmp, def->hw_uuid) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed hwuuid element"));
+ return -1;
+ }
+ VIR_FREE(tmp);
+ } else {
+ memset(def->hw_uuid, 0, VIR_UUID_BUFLEN);
+ }
+
/* Extract domain genid - a genid can either be provided or generated */
if ((n = virXPathNodeSet("./genid", ctxt, &nodes)) < 0)
return -1;
for (i = 0; i < n; i++) {
virSysinfoDef *sysinfo = virSysinfoParseXML(nodes[i], ctxt,
+ def->hw_uuid,
def->uuid, uuid_generated);
if (!sysinfo)
virUUIDFormat(uuid, uuidstr);
virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuidstr);
+ if (virUUIDIsValid(def->hw_uuid)) {
+ virUUIDFormat(def->hw_uuid, uuidstr);
+ virBufferAsprintf(buf, "<hwuuid>%s</hwuuid>\n", uuidstr);
+ }
+
if (def->genidRequested) {
char genidstr[VIR_UUID_STRING_BUFLEN];