long id = -1;
virDomainDefPtr def;
unsigned long count;
+ bool uuid_generated = false;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
goto error;
}
- /* Extract domain uuid */
+ /* Extract domain uuid. If both uuid and sysinfo/system/entry/uuid
+ * exist, they must match; and if only the latter exists, it can
+ * also serve as the uuid. */
tmp = virXPathString("string(./uuid[1])", ctxt);
if (!tmp) {
if (virUUIDGenerate(def->uuid)) {
"%s", _("Failed to generate UUID"));
goto error;
}
+ uuid_generated = true;
} else {
if (virUUIDParse(tmp, def->uuid) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
if (def->sysinfo == NULL)
goto error;
+ if (def->sysinfo->system_uuid != NULL) {
+ unsigned char uuidbuf[VIR_UUID_BUFLEN];
+ if (virUUIDParse(def->sysinfo->system_uuid, uuidbuf) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed uuid element"));
+ goto error;
+ }
+ if (uuid_generated)
+ memcpy(def->uuid, uuidbuf, VIR_UUID_BUFLEN);
+ else if (memcmp(def->uuid, uuidbuf, VIR_UUID_BUFLEN) != 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("UUID mismatch between <uuid> and "
+ "<sysinfo>"));
+ goto error;
+ }
+ }
}
tmp = virXPathString("string(./os/smbios/@mode)", ctxt);
if (tmp) {
return(NULL);
}
-static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def)
+static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def, bool skip_uuid)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) &&
- (def->system_product == NULL) && (def->system_uuid == NULL) &&
- (def->system_version == NULL) && (def->system_serial == NULL) &&
- (def->system_family == NULL))
- return(NULL);
+ (def->system_product == NULL) && (def->system_version == NULL) &&
+ (def->system_serial == NULL) && (def->system_family == NULL) &&
+ (def->system_uuid == NULL || skip_uuid))
+ return NULL;
virBufferAddLit(&buf, "type=1");
if (def->system_serial)
virBufferVSprintf(&buf, ",serial=%s", def->system_serial);
/* 1:UUID */
- if (def->system_uuid)
+ if (def->system_uuid && !skip_uuid)
virBufferVSprintf(&buf, ",uuid=%s", def->system_uuid);
/* 1:SKU Number */
if (def->system_sku)
if ((def->os.smbios_mode != VIR_DOMAIN_SMBIOS_NONE) &&
(def->os.smbios_mode != VIR_DOMAIN_SMBIOS_EMULATE)) {
virSysinfoDefPtr source = NULL;
+ bool skip_uuid = false;
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_SMBIOS_TYPE)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
goto error;
}
source = driver->hostsysinfo;
+ /* Host and guest uuid must differ, by definition of UUID. */
+ skip_uuid = true;
} else if (def->os.smbios_mode == VIR_DOMAIN_SMBIOS_SYSINFO) {
if (def->sysinfo == NULL) {
qemuReportError(VIR_ERR_XML_ERROR,
goto error;
}
source = def->sysinfo;
+ /* domain_conf guaranteed that system_uuid matches guest uuid. */
}
if (source != NULL) {
char *smbioscmd;
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);
}
- smbioscmd = qemuBuildSmbiosSystemStr(source);
+ smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid);
if (smbioscmd != NULL) {
virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
VIR_FREE(smbioscmd);