]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
zramctl: add COMP-RATIO column
authorKarel Zak <kzak@redhat.com>
Mon, 25 Nov 2024 11:10:37 +0000 (12:10 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 25 Nov 2024 11:18:22 +0000 (12:18 +0100)
* Improve get_mm_stat() to return both numbers and strings.
* Add get_mm_stat_number() and get_mm_stat_string() functions.
* Add a new COL_COMPRATIO column.

Based on https://github.com/util-linux/util-linux/pull/3293

Co-Author: davidemanini
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/zramctl.c

index 3c9dd58b07346d47e7f8c50f5ffb4e8a27de9ad9..6755d2577cde85487581afe8f5bfb8a531f332ef 100644 (file)
@@ -68,6 +68,7 @@ enum {
        COL_MEMLIMIT,
        COL_MEMUSED,
        COL_MIGRATED,
+       COL_COMPRATIO,
        COL_MOUNTPOINT
 };
 
@@ -83,6 +84,7 @@ static const struct colinfo infos[] = {
        [COL_MEMLIMIT]  = { "MEM-LIMIT",    5, SCOLS_FL_RIGHT, N_("memory limit used to store compressed data") },
        [COL_MEMUSED]   = { "MEM-USED",     5, SCOLS_FL_RIGHT, N_("memory zram have been consumed to store compressed data") },
        [COL_MIGRATED]  = { "MIGRATED",     5, SCOLS_FL_RIGHT, N_("number of objects migrated by compaction") },
+       [COL_COMPRATIO] = { "COMP-RATIO",   5, SCOLS_FL_RIGHT, N_("compression ratio: DATA/TOTAL") },
        [COL_MOUNTPOINT]= { "MOUNTPOINT",0.10, SCOLS_FL_TRUNC, N_("where the device is mounted") },
 };
 
@@ -341,7 +343,9 @@ static struct zram *find_free_zram(void)
        return z;
 }
 
-static char *get_mm_stat(struct zram *z, size_t idx, int bytes)
+static int get_mm_stat(struct zram *z,
+                        size_t idx, int bytes,
+                        char **re_str, uint64_t *re_num)
 {
        struct path_cxt *sysfs;
        const char *name;
@@ -353,7 +357,7 @@ static char *get_mm_stat(struct zram *z, size_t idx, int bytes)
 
        sysfs = zram_get_sysfs(z);
        if (!sysfs)
-               return NULL;
+               return -ENOENT;
 
        /* Linux >= 4.1 uses /sys/block/zram<id>/mm_stat */
        if (!z->mm_stat && !z->mm_stat_probed) {
@@ -372,25 +376,50 @@ static char *get_mm_stat(struct zram *z, size_t idx, int bytes)
        }
 
        if (z->mm_stat) {
-               if (bytes)
-                       return xstrdup(z->mm_stat[idx]);
+               if (re_str && bytes)
+                       *re_str = xstrdup(z->mm_stat[idx]);
 
                num = strtou64_or_err(z->mm_stat[idx], _("Failed to parse mm_stat"));
-               return size_to_human_string(SIZE_SUFFIX_1LETTER, num);
+               if (re_num)
+                       *re_num = num;
+               if (re_str && !bytes)
+                       *re_str = size_to_human_string(SIZE_SUFFIX_1LETTER, num);
+               return 0;
        }
 
        /* Linux < 4.1 uses /sys/block/zram<id>/<attrname> */
        name = mm_stat_names[idx];
-       if (bytes) {
+       if (re_str && bytes)
                ul_path_read_string(sysfs, &str, name);
-               return str;
 
+       if ((re_str && !bytes) || re_num) {
+               int rc = ul_path_read_u64(sysfs, &num, name);
+               if (rc != 0)
+                       return rc;
+
+               if (re_str && !bytes)
+                       *re_str = size_to_human_string(SIZE_SUFFIX_1LETTER, num);
+               if (re_num)
+                       *re_num = num;
        }
 
-       if (ul_path_read_u64(sysfs, &num, name) == 0)
-               return size_to_human_string(SIZE_SUFFIX_1LETTER, num);
+       return 0;
+}
+
+static char *get_mm_stat_string(struct zram *z, size_t idx, int bytes)
+{
+       char *str = NULL;
+
+       get_mm_stat(z, idx, bytes, &str, NULL);
+       return str;
+}
+
+static uint64_t get_mm_stat_number(struct zram *z, size_t idx)
+{
+       uint64_t num = 0;
 
-       return NULL;
+       get_mm_stat(z, idx, 0, NULL, &num);
+       return num;
 }
 
 static void fill_table_row(struct libscols_table *tb, struct zram *z)
@@ -452,29 +481,34 @@ static void fill_table_row(struct libscols_table *tb, struct zram *z)
                                str = xstrdup(path);
                        break;
                }
+               case COL_COMPRATIO:
+                       xasprintf(&str, "%.4f",
+                               (double) get_mm_stat_number(z, MM_ORIG_DATA_SIZE)
+                               / get_mm_stat_number(z, MM_MEM_USED_TOTAL));
+                       break;
                case COL_STREAMS:
                        ul_path_read_string(sysfs, &str, "max_comp_streams");
                        break;
                case COL_ZEROPAGES:
-                       str = get_mm_stat(z, MM_ZERO_PAGES, 1);
+                       str = get_mm_stat_string(z, MM_ZERO_PAGES, 1);
                        break;
                case COL_ORIG_SIZE:
-                       str = get_mm_stat(z, MM_ORIG_DATA_SIZE, inbytes);
+                       str = get_mm_stat_string(z, MM_ORIG_DATA_SIZE, inbytes);
                        break;
                case COL_COMP_SIZE:
-                       str = get_mm_stat(z, MM_COMPR_DATA_SIZE, inbytes);
+                       str = get_mm_stat_string(z, MM_COMPR_DATA_SIZE, inbytes);
                        break;
                case COL_MEMTOTAL:
-                       str = get_mm_stat(z, MM_MEM_USED_TOTAL, inbytes);
+                       str = get_mm_stat_string(z, MM_MEM_USED_TOTAL, inbytes);
                        break;
                case COL_MEMLIMIT:
-                       str = get_mm_stat(z, MM_MEM_LIMIT, inbytes);
+                       str = get_mm_stat_string(z, MM_MEM_LIMIT, inbytes);
                        break;
                case COL_MEMUSED:
-                       str = get_mm_stat(z, MM_MEM_USED_MAX, inbytes);
+                       str = get_mm_stat_string(z, MM_MEM_USED_MAX, inbytes);
                        break;
                case COL_MIGRATED:
-                       str = get_mm_stat(z, MM_NUM_MIGRATED, inbytes);
+                       str = get_mm_stat_string(z, MM_NUM_MIGRATED, inbytes);
                        break;
                }
                if (str && scols_line_refer_data(ln, i, str))