]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsmem: fix missing zone info when memory blocks start at an index other than 0
authorChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Fri, 20 Feb 2026 00:02:09 +0000 (19:02 -0500)
committerChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Fri, 20 Feb 2026 00:02:09 +0000 (19:02 -0500)
On systems that have an uncommon physical memory layout, e.g. where hotpluggable
memory blocks start at an offset greater than 0, we failed to set the 'have_zones'
control flag, which caused an omission of the ZONES information of the listed
individual memory block or a block range. This is because we explicitly tested for
/sys/devices/system/memory/memory0/valid_zones, however it is better to simply
look for any memory<n> directory entry and validate the existence of the valid_zones
attribute.

Closes: #4055
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
sys-utils/lsmem.c

index 79d90ff55721cd732b7040d6cb744514d0bb8996..c68f2317c4bd56e0c3d6146be9c0b38b3c5babd2 100644 (file)
@@ -422,6 +422,25 @@ static int memory_block_get_node(struct lsmem *lsmem, char *name)
        return node;
 }
 
+static int memory_block_has_zones(struct lsmem *lsmem, char *name)
+{
+       char *path = NULL;
+       int rc;
+
+       if (!name)
+               return -EINVAL;
+
+       xasprintf(&path, "%s/valid_zones", name);
+       rc = ul_path_access(lsmem->sysmem, F_OK, path);
+       if (rc != 0) {
+               free(path);
+               return rc;
+       }
+
+       free(path);
+       return 0;
+}
+
 static int memory_block_read_attrs(struct lsmem *lsmem, char *name,
                                    struct memory_block *blk)
 {
@@ -611,9 +630,23 @@ static void read_basic_info(struct lsmem *lsmem)
                }
        }
 
-       /* The valid_zones sysmem attribute was introduced with kernel 3.18 */
-       if (ul_path_access(lsmem->sysmem, F_OK, "memory0/valid_zones") == 0)
-               lsmem->have_zones = 1;
+       /* The valid_zones sysmem attribute was introduced with kernel 3.18.
+        *
+        * Note that some systems can have different physical memory layouts which
+        * make it so that the first hotpluggable memory block starts with an ID
+        * other than 0. Therefore, we have to walk through the sysmem dir and
+        * find the memory<n>/ entries and test whether the valid_zones attribute
+        * is available.
+        */
+       for (i = 0; i < lsmem->ndirs; i++) {
+               if (strncmp("memory", lsmem->dirs[i]->d_name, 6) != 0)
+                       continue;
+
+               if (memory_block_has_zones(lsmem, lsmem->dirs[i]->d_name) == 0) {
+                       lsmem->have_zones = 1;
+                       break;
+               }
+       }
 }
 
 static void __attribute__((__noreturn__)) usage(void)