]> xenbits.xensource.com Git - libvirt.git/commitdiff
Adjust improperly formatted <sysinfo> uuid
authorJohn Ferlan <jferlan@redhat.com>
Fri, 26 Apr 2013 18:29:37 +0000 (14:29 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Wed, 15 May 2013 16:05:22 +0000 (12:05 -0400)
If the <sysinfo> 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
tests/qemuxml2argvdata/qemuxml2argv-smbios-uuid-match.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c

index 81560b8f5f2dad33a4b6cf71390a1596f1147421..f0ca9d59a3a953ae3ef2b3668bfeade40008c9d6 100644 (file)
@@ -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 <sysinfo> 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 <uuid> and "
+                             "<sysinfo>"));
+            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 <uuid> and "
-                                 "<sysinfo>"));
-                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 (file)
index 0000000..322fb3e
--- /dev/null
@@ -0,0 +1,23 @@
+<domain type='qemu'>
+  <name>smbios</name>
+  <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <smbios mode="sysinfo"/>
+  </os>
+  <sysinfo type="smbios">
+    <system>
+      <entry name="uuid">a94b4335-6a14-8bc4-d6da-f7ea590b6816</entry>
+    </system>
+  </sysinfo>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+  </devices>
+</domain>
index 58aeddde29cb8442c3eaba189ea34502db0bb5f8..c75144067b26d582e91df2607899155eb9d8e648 100644 (file)
@@ -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);