From a2c37618d30dd37b7ab1b0c06d34c6325adb0211 Mon Sep 17 00:00:00 2001 From: John Ferlan Date: Fri, 26 Apr 2013 14:29:37 -0400 Subject: [PATCH] Adjust improperly formatted uuid If the system table 'uuid' field is improperly formatted, then qemu will fail to start the guest with the error: virsh start dom error: Failed to start domain dom error: internal error process exited while connecting to monitor: Invalid SMBIOS UUID string This was because the parsing rules were lax with respect to allowing extraneous spaces and dashes in the provided UUID. As long as there were 32 hexavalues that matched the UUID for the domain the string was accepted. However startup failed because the string format wasn't correct. This patch will adjust the string format so that when it's presented to the driver it's in the expected format. Added a test for uuid comparison within sysinfo. --- src/conf/domain_conf.c | 54 ++++++++++++------- .../qemuxml2argv-smbios-uuid-match.xml | 23 ++++++++ tests/qemuxml2argvtest.c | 1 + 3 files changed, 58 insertions(+), 20 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-smbios-uuid-match.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 81560b8f5f..f0ca9d59a3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8429,10 +8429,13 @@ error: static virSysinfoDefPtr virSysinfoParseXML(const xmlNodePtr node, - xmlXPathContextPtr ctxt) + xmlXPathContextPtr ctxt, + unsigned char *domUUID, + bool uuid_generated) { virSysinfoDefPtr def; char *type; + char *tmpUUID = NULL; if (!xmlStrEqual(node->name, BAD_CAST "sysinfo")) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -8500,8 +8503,33 @@ virSysinfoParseXML(const xmlNodePtr node, virXPathString("string(system/entry[@name='version'])", ctxt); def->system_serial = virXPathString("string(system/entry[@name='serial'])", ctxt); - def->system_uuid = - virXPathString("string(system/entry[@name='uuid'])", ctxt); + tmpUUID = virXPathString("string(system/entry[@name='uuid'])", ctxt); + if (tmpUUID) { + unsigned char uuidbuf[VIR_UUID_BUFLEN]; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + if (virUUIDParse(tmpUUID, uuidbuf) < 0) { + virReportError(VIR_ERR_XML_DETAIL, + "%s", _("malformed uuid element")); + goto error; + } + if (uuid_generated) + memcpy(domUUID, uuidbuf, VIR_UUID_BUFLEN); + else if (memcmp(domUUID, uuidbuf, VIR_UUID_BUFLEN) != 0) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("UUID mismatch between and " + "")); + goto error; + } + /* Although we've validated the UUID as good, virUUIDParse() is + * lax with respect to allowing extraneous "-" and " ", but the + * underlying hypervisor may be less forgiving. Use virUUIDFormat() + * to validate format in xml is right. If not, then format it + * properly so that it's used correctly later. + */ + virUUIDFormat(uuidbuf, uuidstr); + if (VIR_STRDUP(def->system_uuid, uuidstr) < 0) + goto error; + } def->system_sku = virXPathString("string(system/entry[@name='sku'])", ctxt); def->system_family = @@ -8509,6 +8537,7 @@ virSysinfoParseXML(const xmlNodePtr node, cleanup: VIR_FREE(type); + VIR_FREE(tmpUUID); return def; error: @@ -11767,27 +11796,12 @@ virDomainDefParseXML(xmlDocPtr xml, if ((node = virXPathNode("./sysinfo[1]", ctxt)) != NULL) { xmlNodePtr oldnode = ctxt->node; ctxt->node = node; - def->sysinfo = virSysinfoParseXML(node, ctxt); + def->sysinfo = virSysinfoParseXML(node, ctxt, + def->uuid, uuid_generated); ctxt->node = oldnode; 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) { - virReportError(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) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("UUID mismatch between and " - "")); - goto error; - } - } } if ((tmp = virXPathString("string(./os/smbios/@mode)", ctxt))) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-smbios-uuid-match.xml b/tests/qemuxml2argvdata/qemuxml2argv-smbios-uuid-match.xml new file mode 100644 index 0000000000..322fb3e21a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-smbios-uuid-match.xml @@ -0,0 +1,23 @@ + + smbios + 362d1fc1-df7d-193e-5c18-49a71bd1da66 + 1048576 + 1048576 + 1 + + hvm + + + + + a94b4335-6a14-8bc4-d6da-f7ea590b6816 + + + + destroy + restart + restart + + /usr/bin/qemu + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 58aeddde29..c75144067b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -826,6 +826,7 @@ mymain(void) DO_TEST("smbios", QEMU_CAPS_SMBIOS_TYPE); DO_TEST_PARSE_ERROR("smbios-date", QEMU_CAPS_SMBIOS_TYPE); + DO_TEST_PARSE_ERROR("smbios-uuid-match", QEMU_CAPS_SMBIOS_TYPE); DO_TEST("watchdog", NONE); DO_TEST("watchdog-device", QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);