Blob Blame History Raw
From 2afe96801354fdf6bb49d230f357131c6b49fbcc Mon Sep 17 00:00:00 2001
From: Dan Callaghan <dcallagh@redhat.com>
Date: Thu, 16 Jul 2015 16:46:44 +1000
Subject: [PATCH 23/26] dmi: avoid creating multiple memory nodes (#700)

The rest of the codebase expects to only find at most one "memory" node,
even though the SMBIOS data may indicate more than one.

If we really do find more than one memory array with type System Memory
in SMBIOS, we just discard the subsequent ones and place all memory
devices (DIMMs) into the first memory array.
---
 src/core/dmi.cc | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/src/core/dmi.cc b/src/core/dmi.cc
index 8242fed..d5a771d 100644
--- a/src/core/dmi.cc
+++ b/src/core/dmi.cc
@@ -1392,39 +1392,52 @@ int dmiversionmin)
       case 16:
 // Physical Memory Array
         {
-          hwNode newnode("memory",
-            hw::memory);
-          string id = "";
+          string id = "memory";
           string description = "";
+          bool claim = false, memory_icon = false;
           switch (data[5])
           {
             case 0x03:
               description = _("System Memory");
-              newnode.claim();
-              newnode.addHint("icon", string("memory"));
+              claim = true;
+              memory_icon = true;
               break;
             case 0x04:
+              id = "videomemory";
               description = _("Video Memory");
               break;
             case 0x05:
+              id = "flash";
               description = _("Flash Memory");
               break;
             case 0x06:
+              id = "nvram";
               description = _("NVRAM");
               break;
             case 0x07:
+              id = "cache";
               description = _("Cache Memory");
-              newnode.addHint("icon", string("memory"));
+              memory_icon = true;
               break;
             default:
               description = _("Generic Memory");
-              newnode.addHint("icon", string("memory"));
+              memory_icon = true;
           }
-
+          if (id == "memory" && hardwarenode->getChild("memory"))
+          {
+            // we don't want multiple "System memory" nodes,
+            // so just ignore this one
+            break;
+          }
+          hwNode newnode(id, hw::memory);
           newnode.setHandle(handle);
           newnode.setPhysId(dm->handle);
           newnode.setDescription(description);
           newnode.setSlot(dmi_memory_array_location(data[4]));
+          if (memory_icon)
+            newnode.addHint("icon", string("memory"));
+          if (claim)
+            newnode.claim();
           switch (data[6])
           {
             case 0x04:
@@ -1552,16 +1565,17 @@ int dmiversionmin)
             newnode.setDescription(newnode.getDescription() + " " + _("[empty]"));
           newnode.setClock(clock);
           hwNode *memoryarray = hardwarenode->findChildByHandle(arrayhandle);
-          if (memoryarray)
-            memoryarray->addChild(newnode);
-          else
+          if (!memoryarray)
+            memoryarray = hardwarenode->getChild("memory");
+          if (!memoryarray)
           {
             hwNode ramnode("memory",
               hw::memory);
-            ramnode.addChild(newnode);
             ramnode.addHint("icon", string("memory"));
             hardwarenode->addChild(ramnode);
+            memoryarray = hardwarenode->getChild("memory");
           }
+          memoryarray->addChild(newnode);
         }
         break;
       case 18:
-- 
2.10.2