]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chmem: add helper function to sensibly detect the 'valid_zones' attribute
authorChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Mon, 25 May 2026 20:38:53 +0000 (16:38 -0400)
committerChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Tue, 26 May 2026 11:03:13 +0000 (07:03 -0400)
On some systems the first available memory blocks start at an index
greater than 0, and on such systems we fail to properly detect the
valid_zones attribute, because we naively checked for the presence
of the memory block directory 'memory0'. To sensibly and reliably
detect the first memory block, we can use the directory sysmem->dirs
that are sorted in numeric order, so we can assume that the first
entry is the first memory block, i.e. sysmem->dirs[0]->d_name is
the name of the first configurable memory block.

Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
sys-utils/chmem.c

index 00a5f863b87d48a77130acf5047b714bd40bae80..8a70d85eb94d3aac3bb8e5ee535cd3fe80ef14be 100644 (file)
@@ -84,6 +84,23 @@ static const char *const zone_names[] = {
        [ZONE_DEVICE]   = "Device",
 };
 
+
+static int have_mem_blk_zones(struct path_cxt *pctx, const char *dirname)
+{
+       int rc = 0;
+       char *path = NULL;
+
+       if (!pctx || !dirname)
+               return -EINVAL;
+
+       path = ul_strconcat(dirname, "/valid_zones");
+       if (ul_path_access(pctx, F_OK, path) == 0)
+               rc = 1;
+
+       free(path);
+       return rc;
+}
+
 /*
  * name must be null-terminated
  */
@@ -667,7 +684,7 @@ int main(int argc, char **argv)
                .memmap_on_memory = -1,
        }, *desc = &_desc;
        int cmd = CMD_NONE, zone_id = -1;
-       char *zone = NULL, *sysroot = NULL;
+       char *zone = NULL, *sysroot = NULL, *first_memblk_dirname = NULL;
        int c, rc;
 
        static const struct option longopts[] = {
@@ -758,14 +775,17 @@ int main(int argc, char **argv)
                err(EXIT_FAILURE, _("failed to initialize %s handler"), _PATH_SYS_MEMCONFIG);
        if (sysroot && ul_path_set_prefix(desc->sysmemconfig, sysroot) != 0)
                err(EXIT_FAILURE, _("invalid argument to --sysroot"));
-       if (ul_path_access(desc->sysmemconfig, F_OK, "memory0") == 0)
-               desc->have_memconfig = 1;
 
        read_info(desc);
        parse_parameter(desc, argv[optind]);
 
+       first_memblk_dirname = desc->dirs[0]->d_name;
+
+       if (ul_path_access(desc->sysmemconfig, F_OK, first_memblk_dirname) == 0)
+               desc->have_memconfig = 1;
+
        /* The valid_zones sysfs attribute was introduced with kernel 3.18 */
-       if (ul_path_access(desc->sysmem, F_OK, "memory0/valid_zones") == 0)
+       if (have_mem_blk_zones(desc->sysmem, first_memblk_dirname) > 0)
                desc->have_zones = 1;
        else if (zone)
                warnx(_("zone ignored, no valid_zones sysfs attribute present"));