[libvirt] [PATCH 2/3] virSysinfoDef: Exempt SYSTEM variables

Michal Privoznik mprivozn at redhat.com
Tue May 12 14:56:23 UTC 2015


Move all the system_* fields into a separate struct. Not only this
simplifies the code a bit it also helps us to identify whether BIOS
info is present. We don't have to check all the four variables for
being not-NULL, but we can just check the pointer to the struct.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/conf/domain_conf.c   | 152 ++++++++++++++++++----------
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_command.c  |  41 ++++----
 src/util/virsysinfo.c    | 258 ++++++++++++++++++++++++++++++++---------------
 src/util/virsysinfo.h    |  22 ++--
 5 files changed, 312 insertions(+), 162 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e37e453..209416d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10922,66 +10922,42 @@ virSysinfoBIOSParseXML(xmlNodePtr node,
     return ret;
 }
 
-static virSysinfoDefPtr
-virSysinfoParseXML(xmlNodePtr node,
-                  xmlXPathContextPtr ctxt,
-                  unsigned char *domUUID,
-                  bool uuid_generated)
+static int
+virSysinfoSystemParseXML(xmlNodePtr node,
+                         xmlXPathContextPtr ctxt,
+                         virSysinfoSystemDefPtr *system,
+                         unsigned char *domUUID,
+                         bool uuid_generated)
 {
-    virSysinfoDefPtr def;
-    xmlNodePtr oldnode, tmpnode;
-    char *type;
+    int ret = -1;
+    virSysinfoSystemDefPtr def;
     char *tmpUUID = NULL;
 
-    if (!xmlStrEqual(node->name, BAD_CAST "sysinfo")) {
+    if (!xmlStrEqual(node->name, BAD_CAST "system")) {
         virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("XML does not contain expected 'sysinfo' element"));
-        return NULL;
+                       _("XML does not contain expected 'system' element"));
+        return ret;
     }
 
     if (VIR_ALLOC(def) < 0)
-        return NULL;
+        goto cleanup;
 
-    type = virXMLPropString(node, "type");
-    if (type == NULL) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("sysinfo must contain a type attribute"));
-        goto error;
-    }
-    if ((def->type = virSysinfoTypeFromString(type)) < 0) {
-        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("unknown sysinfo type '%s'"), type);
-        goto error;
-    }
-
-    /* Extract BIOS related metadata */
-    if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) {
-        oldnode = ctxt->node;
-        ctxt->node = tmpnode;
-        if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0) {
-            ctxt->node = oldnode;
-            goto error;
-        }
-        ctxt->node = oldnode;
-    }
-
-    /* Extract system related metadata */
-    def->system_manufacturer =
-        virXPathString("string(system/entry[@name='manufacturer'])", ctxt);
-    def->system_product =
-        virXPathString("string(system/entry[@name='product'])", ctxt);
-    def->system_version =
-        virXPathString("string(system/entry[@name='version'])", ctxt);
-    def->system_serial =
-        virXPathString("string(system/entry[@name='serial'])", ctxt);
-    tmpUUID = virXPathString("string(system/entry[@name='uuid'])", ctxt);
+    def->manufacturer =
+        virXPathString("string(entry[@name='manufacturer'])", ctxt);
+    def->product =
+        virXPathString("string(entry[@name='product'])", ctxt);
+    def->version =
+        virXPathString("string(entry[@name='version'])", ctxt);
+    def->serial =
+        virXPathString("string(entry[@name='serial'])", ctxt);
+    tmpUUID = virXPathString("string(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;
+            goto cleanup;
         }
         if (uuid_generated) {
             memcpy(domUUID, uuidbuf, VIR_UUID_BUFLEN);
@@ -10989,7 +10965,7 @@ virSysinfoParseXML(xmlNodePtr node,
             virReportError(VIR_ERR_XML_DETAIL, "%s",
                            _("UUID mismatch between <uuid> and "
                              "<sysinfo>"));
-            goto error;
+            goto cleanup;
         }
         /* Although we've validated the UUID as good, virUUIDParse() is
          * lax with respect to allowing extraneous "-" and " ", but the
@@ -10998,17 +10974,85 @@ virSysinfoParseXML(xmlNodePtr node,
          * properly so that it's used correctly later.
          */
         virUUIDFormat(uuidbuf, uuidstr);
-        if (VIR_STRDUP(def->system_uuid, uuidstr) < 0)
-            goto error;
+        if (VIR_STRDUP(def->uuid, uuidstr) < 0)
+            goto cleanup;
     }
-    def->system_sku =
-        virXPathString("string(system/entry[@name='sku'])", ctxt);
-    def->system_family =
-        virXPathString("string(system/entry[@name='family'])", ctxt);
+    def->sku =
+        virXPathString("string(entry[@name='sku'])", ctxt);
+    def->family =
+        virXPathString("string(entry[@name='family'])", ctxt);
 
+    if (!def->manufacturer && !def->product && !def->version &&
+        !def->serial && !def->uuid && !def->sku && !def->family) {
+        virSysinfoSystemDefFree(def);
+        def = NULL;
+    }
+
+    *system = def;
+    def = NULL;
+    ret = 0;
  cleanup:
-    VIR_FREE(type);
+    virSysinfoSystemDefFree(def);
     VIR_FREE(tmpUUID);
+    return ret;
+}
+
+static virSysinfoDefPtr
+virSysinfoParseXML(xmlNodePtr node,
+                  xmlXPathContextPtr ctxt,
+                  unsigned char *domUUID,
+                  bool uuid_generated)
+{
+    virSysinfoDefPtr def;
+    xmlNodePtr oldnode, tmpnode;
+    char *type;
+
+    if (!xmlStrEqual(node->name, BAD_CAST "sysinfo")) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("XML does not contain expected 'sysinfo' element"));
+        return NULL;
+    }
+
+    if (VIR_ALLOC(def) < 0)
+        return NULL;
+
+    type = virXMLPropString(node, "type");
+    if (type == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("sysinfo must contain a type attribute"));
+        goto error;
+    }
+    if ((def->type = virSysinfoTypeFromString(type)) < 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("unknown sysinfo type '%s'"), type);
+        goto error;
+    }
+
+    /* Extract BIOS related metadata */
+    if ((tmpnode = virXPathNode("./bios[1]", ctxt)) != NULL) {
+        oldnode = ctxt->node;
+        ctxt->node = tmpnode;
+        if (virSysinfoBIOSParseXML(tmpnode, ctxt, &def->bios) < 0) {
+            ctxt->node = oldnode;
+            goto error;
+        }
+        ctxt->node = oldnode;
+    }
+
+    /* Extract system related metadata */
+    if ((tmpnode = virXPathNode("./system[1]", ctxt)) != NULL) {
+        oldnode = ctxt->node;
+        ctxt->node = tmpnode;
+        if (virSysinfoSystemParseXML(tmpnode, ctxt, &def->system,
+                                     domUUID, uuid_generated) < 0) {
+            ctxt->node = oldnode;
+            goto error;
+        }
+        ctxt->node = oldnode;
+    }
+
+ cleanup:
+    VIR_FREE(type);
     return def;
 
  error:
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 06ef7ae..bd619d3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2181,6 +2181,7 @@ virSysinfoDefFree;
 virSysinfoFormat;
 virSysinfoRead;
 virSysinfoSetup;
+virSysinfoSystemDefFree;
 
 
 # util/virsystemd.h
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7d58cb5..489cab3 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6692,40 +6692,41 @@ static char *qemuBuildSmbiosBiosStr(virSysinfoBIOSDefPtr def)
     return NULL;
 }
 
-static char *qemuBuildSmbiosSystemStr(virSysinfoDefPtr def, bool skip_uuid)
+static char *qemuBuildSmbiosSystemStr(virSysinfoSystemDefPtr def,
+                                      bool skip_uuid)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    if ((def->system_manufacturer == NULL) && (def->system_sku == NULL) &&
-        (def->system_product == NULL) && (def->system_version == NULL) &&
-        (def->system_serial == NULL) && (def->system_family == NULL) &&
-        (def->system_uuid == NULL || skip_uuid))
+    if (!def ||
+        (!def->manufacturer && !def->product && !def->version &&
+         !def->serial && (!def->uuid || skip_uuid) &&
+         def->sku && !def->family))
         return NULL;
 
     virBufferAddLit(&buf, "type=1");
 
     /* 1:Manufacturer */
-    if (def->system_manufacturer)
+    if (def->manufacturer)
         virBufferAsprintf(&buf, ",manufacturer=%s",
-                          def->system_manufacturer);
+                          def->manufacturer);
      /* 1:Product Name */
-    if (def->system_product)
-        virBufferAsprintf(&buf, ",product=%s", def->system_product);
+    if (def->product)
+        virBufferAsprintf(&buf, ",product=%s", def->product);
     /* 1:Version */
-    if (def->system_version)
-        virBufferAsprintf(&buf, ",version=%s", def->system_version);
+    if (def->version)
+        virBufferAsprintf(&buf, ",version=%s", def->version);
     /* 1:Serial Number */
-    if (def->system_serial)
-        virBufferAsprintf(&buf, ",serial=%s", def->system_serial);
+    if (def->serial)
+        virBufferAsprintf(&buf, ",serial=%s", def->serial);
     /* 1:UUID */
-    if (def->system_uuid && !skip_uuid)
-        virBufferAsprintf(&buf, ",uuid=%s", def->system_uuid);
+    if (def->uuid && !skip_uuid)
+        virBufferAsprintf(&buf, ",uuid=%s", def->uuid);
     /* 1:SKU Number */
-    if (def->system_sku)
-        virBufferAsprintf(&buf, ",sku=%s", def->system_sku);
+    if (def->sku)
+        virBufferAsprintf(&buf, ",sku=%s", def->sku);
     /* 1:Family */
-    if (def->system_family)
-        virBufferAsprintf(&buf, ",family=%s", def->system_family);
+    if (def->family)
+        virBufferAsprintf(&buf, ",family=%s", def->family);
 
     if (virBufferCheckError(&buf) < 0)
         goto error;
@@ -8919,7 +8920,7 @@ qemuBuildCommandLine(virConnectPtr conn,
                 virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                 VIR_FREE(smbioscmd);
             }
-            smbioscmd = qemuBuildSmbiosSystemStr(source, skip_uuid);
+            smbioscmd = qemuBuildSmbiosSystemStr(source->system, skip_uuid);
             if (smbioscmd != NULL) {
                 virCommandAddArgList(cmd, "-smbios", smbioscmd, NULL);
                 VIR_FREE(smbioscmd);
diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c
index 72b7bb7..4c939ec 100644
--- a/src/util/virsysinfo.c
+++ b/src/util/virsysinfo.c
@@ -76,6 +76,22 @@ void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def)
     VIR_FREE(def);
 }
 
+void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def)
+{
+    if (def == NULL)
+        return;
+
+    VIR_FREE(def->manufacturer);
+    VIR_FREE(def->product);
+    VIR_FREE(def->version);
+    VIR_FREE(def->serial);
+    VIR_FREE(def->uuid);
+    VIR_FREE(def->sku);
+    VIR_FREE(def->family);
+    VIR_FREE(def);
+}
+
+
 /**
  * virSysinfoDefFree:
  * @def: a sysinfo structure
@@ -91,14 +107,7 @@ void virSysinfoDefFree(virSysinfoDefPtr def)
         return;
 
     virSysinfoBIOSDefFree(def->bios);
-
-    VIR_FREE(def->system_manufacturer);
-    VIR_FREE(def->system_product);
-    VIR_FREE(def->system_version);
-    VIR_FREE(def->system_serial);
-    VIR_FREE(def->system_uuid);
-    VIR_FREE(def->system_sku);
-    VIR_FREE(def->system_family);
+    virSysinfoSystemDefFree(def->system);
 
     for (i = 0; i < def->nprocessor; i++) {
         VIR_FREE(def->processor[i].processor_socket_destination);
@@ -141,39 +150,55 @@ void virSysinfoDefFree(virSysinfoDefPtr def)
 
 #if defined(__powerpc__)
 static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
 {
+    int ret = -1;
     char *eol = NULL;
     const char *cur;
+    virSysinfoSystemDefPtr def;
 
     if ((cur = strstr(base, "platform")) == NULL)
         return 0;
 
+    if (VIR_ALLOC(def) < 0)
+        return ret;
+
     base = cur;
     /* Account for format 'platform    : XXXX'*/
     cur = strchr(cur, ':') + 1;
     eol = strchr(cur, '\n');
     virSkipSpaces(&cur);
-    if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
-        return -1;
+    if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
+        goto cleanup;
 
     if ((cur = strstr(base, "model")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
+            goto cleanup;
     }
 
     if ((cur = strstr(base, "machine")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
+            goto cleanup;
     }
 
-    return 0;
+    if (!def->manufacturer && !def->product && !def->version &&
+        !def->serial && !def->uuid && !def->sku && !def->family) {
+        virSysinfoSystemDefFree(def);
+        def = NULL;
+    }
+
+    *system = def;
+    def = NULL;
+    ret = 0;
+ cleanup:
+    virSysinfoSystemDefFree(def);
+    return ret;
 }
 
 static int
@@ -243,7 +268,7 @@ virSysinfoRead(void)
     if (virSysinfoParseProcessor(outbuf, ret) < 0)
         goto no_memory;
 
-    if (virSysinfoParseSystem(outbuf, ret) < 0)
+    if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
         goto no_memory;
 
     return ret;
@@ -255,27 +280,32 @@ virSysinfoRead(void)
 
 #elif defined(__arm__) || defined(__aarch64__)
 static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
 {
+    int ret = -1;
     char *eol = NULL;
     const char *cur;
+    virSysinfoSystemDefPtr def;
 
     if ((cur = strstr(base, "platform")) == NULL)
         return 0;
 
+    if (VIR_ALLOC(def) < 0)
+        return ret;
+
     base = cur;
     /* Account for format 'platform    : XXXX'*/
     cur = strchr(cur, ':') + 1;
     eol = strchr(cur, '\n');
     virSkipSpaces(&cur);
-    if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
+    if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
         return -1;
 
     if ((cur = strstr(base, "model")) != NULL) {
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
+        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
             return -1;
     }
 
@@ -283,11 +313,22 @@ virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
         cur = strchr(cur, ':') + 1;
         eol = strchr(cur, '\n');
         virSkipSpaces(&cur);
-        if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
+        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
             return -1;
     }
 
-    return 0;
+    if (!def->manufacturer && !def->product && !def->version &&
+        !def->serial && !def->uuid && !def->sku && !def->family) {
+        virSysinfoSystemDefFree(def);
+        def = NULL;
+    }
+
+    *system = def;
+    def = NULL;
+    ret = 0;
+ cleanup:
+    virSysinfoSystemDefFree(def);
+    return ret;
 }
 
 static int
@@ -361,7 +402,7 @@ virSysinfoRead(void)
     if (virSysinfoParseProcessor(outbuf, ret) < 0)
         goto no_memory;
 
-    if (virSysinfoParseSystem(outbuf, ret) < 0)
+    if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
         goto no_memory;
 
     return ret;
@@ -413,17 +454,38 @@ virSysinfoParseLine(const char *base, const char *name, char **value)
 }
 
 static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
 {
-    if (virSysinfoParseLine(base, "Manufacturer",
-                            &ret->system_manufacturer) &&
-        virSysinfoParseLine(base, "Type",
-                            &ret->system_family) &&
-        virSysinfoParseLine(base, "Sequence Code",
-                            &ret->system_serial))
-        return 0;
-    else
-        return -1;
+    int ret = -1;
+    virSysinfoSystemDefPtr def;
+
+    if (VIR_ALLOC(def) < 0)
+        return ret;
+
+    if (!virSysinfoParseLine(base, "Manufacturer",
+                             &def->manufacturer))
+        goto cleanup;
+
+    if (!virSysinfoParseLine(base, "Type",
+                             &def->family))
+        goto cleanup;
+
+    if (!virSysinfoParseLine(base, "Sequence Code",
+                             &def->serial))
+        goto cleanup;
+
+    if (!def->manufacturer && !def->product && !def->version &&
+        !def->serial && !def->uuid && !def->sku && !def->family) {
+        virSysinfoSystemDefFree(def);
+        def = NULL;
+    }
+
+    *system = def;
+    def = NULL;
+    ret = 0;
+ cleanup:
+    virSysinfoSystemDefFree(def);
+    return ret;
 }
 
 static int
@@ -500,7 +562,7 @@ virSysinfoRead(void)
         return NULL;
     }
 
-    if (virSysinfoParseSystem(outbuf, ret) < 0)
+    if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
         goto no_memory;
 
     return ret;
@@ -586,58 +648,74 @@ virSysinfoParseBIOS(const char *base, virSysinfoBIOSDefPtr *bios)
 }
 
 static int
-virSysinfoParseSystem(const char *base, virSysinfoDefPtr ret)
+virSysinfoParseSystem(const char *base, virSysinfoSystemDefPtr *system)
 {
+    int ret = -1;
     const char *cur, *eol = NULL;
+    virSysinfoSystemDefPtr def;
 
     if ((cur = strstr(base, "System Information")) == NULL)
         return 0;
 
+    if (VIR_ALLOC(def) < 0)
+        return ret;
+
     base = cur;
     if ((cur = strstr(base, "Manufacturer: ")) != NULL) {
         cur += 14;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_manufacturer, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->manufacturer, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "Product Name: ")) != NULL) {
         cur += 14;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_product, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->product, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "Version: ")) != NULL) {
         cur += 9;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_version, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->version, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "Serial Number: ")) != NULL) {
         cur += 15;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_serial, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->serial, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "UUID: ")) != NULL) {
         cur += 6;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_uuid, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->uuid, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "SKU Number: ")) != NULL) {
         cur += 12;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_sku, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->sku, cur, eol - cur) < 0)
+            goto cleanup;
     }
     if ((cur = strstr(base, "Family: ")) != NULL) {
         cur += 8;
         eol = strchr(cur, '\n');
-        if (eol && VIR_STRNDUP(ret->system_family, cur, eol - cur) < 0)
-            return -1;
+        if (eol && VIR_STRNDUP(def->family, cur, eol - cur) < 0)
+            goto cleanup;
     }
 
-    return 0;
+    if (!def->manufacturer && !def->product && !def->version &&
+        !def->serial && !def->uuid && !def->sku && !def->family) {
+        virSysinfoSystemDefFree(def);
+        def = NULL;
+    }
+
+    *system = def;
+    def = NULL;
+    ret = 0;
+ cleanup:
+    virSysinfoSystemDefFree(def);
+    return ret;
 }
 
 static int
@@ -876,7 +954,7 @@ virSysinfoRead(void)
     if (virSysinfoParseBIOS(outbuf, &ret->bios) < 0)
         goto error;
 
-    if (virSysinfoParseSystem(outbuf, ret) < 0)
+    if (virSysinfoParseSystem(outbuf, &ret->system) < 0)
         goto error;
 
     ret->nprocessor = 0;
@@ -923,29 +1001,27 @@ virSysinfoBIOSFormat(virBufferPtr buf, virSysinfoBIOSDefPtr def)
 }
 
 static void
-virSysinfoSystemFormat(virBufferPtr buf, virSysinfoDefPtr def)
+virSysinfoSystemFormat(virBufferPtr buf, virSysinfoSystemDefPtr def)
 {
-    if (!def->system_manufacturer && !def->system_product &&
-        !def->system_version && !def->system_serial &&
-        !def->system_uuid && !def->system_sku && !def->system_family)
+    if (!def)
         return;
 
     virBufferAddLit(buf, "<system>\n");
     virBufferAdjustIndent(buf, 2);
     virBufferEscapeString(buf, "<entry name='manufacturer'>%s</entry>\n",
-                          def->system_manufacturer);
+                          def->manufacturer);
     virBufferEscapeString(buf, "<entry name='product'>%s</entry>\n",
-                          def->system_product);
+                          def->product);
     virBufferEscapeString(buf, "<entry name='version'>%s</entry>\n",
-                          def->system_version);
+                          def->version);
     virBufferEscapeString(buf, "<entry name='serial'>%s</entry>\n",
-                          def->system_serial);
+                          def->serial);
     virBufferEscapeString(buf, "<entry name='uuid'>%s</entry>\n",
-                          def->system_uuid);
+                          def->uuid);
     virBufferEscapeString(buf, "<entry name='sku'>%s</entry>\n",
-                          def->system_sku);
+                          def->sku);
     virBufferEscapeString(buf, "<entry name='family'>%s</entry>\n",
-                          def->system_family);
+                          def->family);
     virBufferAdjustIndent(buf, -2);
     virBufferAddLit(buf, "</system>\n");
 }
@@ -1080,7 +1156,7 @@ virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
     virBufferAdjustIndent(buf, 2);
 
     virSysinfoBIOSFormat(buf, def->bios);
-    virSysinfoSystemFormat(buf, def);
+    virSysinfoSystemFormat(buf, def->system);
     virSysinfoProcessorFormat(buf, def);
     virSysinfoMemoryFormat(buf, def);
 
@@ -1128,6 +1204,43 @@ virSysinfoBIOSIsEqual(virSysinfoBIOSDefPtr src,
     return identical;
 }
 
+static bool
+virSysinfoSystemIsEqual(virSysinfoSystemDefPtr src,
+                        virSysinfoSystemDefPtr dst)
+{
+    bool identical = false;
+
+    if (!src && !dst)
+        return true;
+
+    if ((src && !dst) || (!src && dst)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Target sysinfo does not match source"));
+        goto cleanup;
+    }
+
+#define CHECK_FIELD(name, desc)                                         \
+    do {                                                                \
+        if (STRNEQ_NULLABLE(src->name, dst->name)) {                    \
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,                  \
+                           _("Target sysinfo %s %s does not match source %s"), \
+                           desc, NULLSTR(src->name), NULLSTR(dst->name)); \
+        }                                                               \
+    } while (0)
+    CHECK_FIELD(manufacturer, "system vendor");
+    CHECK_FIELD(product, "system product");
+    CHECK_FIELD(version, "system version");
+    CHECK_FIELD(serial, "system serial");
+    CHECK_FIELD(uuid, "system uuid");
+    CHECK_FIELD(sku, "system sku");
+    CHECK_FIELD(family, "system family");
+#undef CHECK_FIELD
+
+    identical = true;
+ cleanup:
+    return identical;
+}
+
 bool virSysinfoIsEqual(virSysinfoDefPtr src,
                        virSysinfoDefPtr dst)
 {
@@ -1153,23 +1266,8 @@ bool virSysinfoIsEqual(virSysinfoDefPtr src,
     if (!virSysinfoBIOSIsEqual(src->bios, dst->bios))
         goto cleanup;
 
-#define CHECK_FIELD(name, desc)                                         \
-    do {                                                                \
-        if (STRNEQ_NULLABLE(src->name, dst->name)) {                    \
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,                  \
-                           _("Target sysinfo %s %s does not match source %s"), \
-                           desc, NULLSTR(src->name), NULLSTR(dst->name)); \
-        }                                                               \
-    } while (0)
-    CHECK_FIELD(system_manufacturer, "system vendor");
-    CHECK_FIELD(system_product, "system product");
-    CHECK_FIELD(system_version, "system version");
-    CHECK_FIELD(system_serial, "system serial");
-    CHECK_FIELD(system_uuid, "system uuid");
-    CHECK_FIELD(system_sku, "system sku");
-    CHECK_FIELD(system_family, "system family");
-
-#undef CHECK_FIELD
+    if (!virSysinfoSystemIsEqual(src->system, dst->system))
+        goto cleanup;
 
     identical = true;
 
diff --git a/src/util/virsysinfo.h b/src/util/virsysinfo.h
index ec32f6c..c8cc1e8 100644
--- a/src/util/virsysinfo.h
+++ b/src/util/virsysinfo.h
@@ -74,20 +74,25 @@ struct _virSysinfoBIOSDef {
     char *release;
 };
 
+typedef struct _virSysinfoSystemDef virSysinfoSystemDef;
+typedef virSysinfoSystemDef *virSysinfoSystemDefPtr;
+struct _virSysinfoSystemDef {
+    char *manufacturer;
+    char *product;
+    char *version;
+    char *serial;
+    char *uuid;
+    char *sku;
+    char *family;
+};
+
 typedef struct _virSysinfoDef virSysinfoDef;
 typedef virSysinfoDef *virSysinfoDefPtr;
 struct _virSysinfoDef {
     int type;
 
     virSysinfoBIOSDefPtr bios;
-
-    char *system_manufacturer;
-    char *system_product;
-    char *system_version;
-    char *system_serial;
-    char *system_uuid;
-    char *system_sku;
-    char *system_family;
+    virSysinfoSystemDefPtr system;
 
     size_t nprocessor;
     virSysinfoProcessorDefPtr processor;
@@ -99,6 +104,7 @@ struct _virSysinfoDef {
 virSysinfoDefPtr virSysinfoRead(void);
 
 void virSysinfoBIOSDefFree(virSysinfoBIOSDefPtr def);
+void virSysinfoSystemDefFree(virSysinfoSystemDefPtr def);
 void virSysinfoDefFree(virSysinfoDefPtr def);
 
 int virSysinfoFormat(virBufferPtr buf, virSysinfoDefPtr def)
-- 
2.3.6




More information about the libvir-list mailing list