diff options
author | Karel Zak | 2016-05-11 12:43:40 +0200 |
---|---|---|
committer | Karel Zak | 2016-05-11 12:43:40 +0200 |
commit | 627258104b936eeaaa19e8f21650f28378b661c8 (patch) | |
tree | 4f4e7b4ab62d33e8dbb31e034b276b20593bda9c /sys-utils/zramctl.c | |
parent | libfdisk: use fdisk_add_partition() for unused partno (diff) | |
download | kernel-qcow2-util-linux-627258104b936eeaaa19e8f21650f28378b661c8.tar.gz kernel-qcow2-util-linux-627258104b936eeaaa19e8f21650f28378b661c8.tar.xz kernel-qcow2-util-linux-627258104b936eeaaa19e8f21650f28378b661c8.zip |
ramctl: add support for zram-control
Based on patch from Timofey Titovets.
Addresses: https://github.com/karelzak/util-linux/issues/318
Reported-by: Timofey Titovets <nefelim4ag@gmail.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/zramctl.c')
-rw-r--r-- | sys-utils/zramctl.c | 64 |
1 files changed, 61 insertions, 3 deletions
diff --git a/sys-utils/zramctl.c b/sys-utils/zramctl.c index 29041eb72..171380556 100644 --- a/sys-utils/zramctl.c +++ b/sys-utils/zramctl.c @@ -36,6 +36,7 @@ #include "ismounted.h" #include "strv.h" #include "path.h" +#include "pathnames.h" /*#define CONFIG_ZRAM_DEBUG*/ @@ -112,7 +113,9 @@ struct zram { struct sysfs_cxt sysfs; char **mm_stat; - unsigned int mm_stat_probed : 1; + unsigned int mm_stat_probed : 1, + control_probed : 1, + has_control : 1; /* has /sys/class/zram-control/ */ }; #define ZRAM_EMPTY { .devname = { '\0' }, .sysfs = UL_SYSFSCXT_EMPTY } @@ -171,6 +174,17 @@ static void zram_set_devname(struct zram *z, const char *devname, size_t n) zram_reset_stat(z); } +static int zram_get_devnum(struct zram *z) +{ + int n; + + assert(z); + + if (sscanf(z->devname, "/dev/zram%d", &n) == 1) + return n; + return -EINVAL; +} + static struct zram *new_zram(const char *devname) { struct zram *z = xcalloc(1, sizeof(struct zram)); @@ -261,6 +275,50 @@ static int zram_used(struct zram *z) return 0; } +static int zram_has_control(struct zram *z) +{ + if (!z->control_probed) { + z->has_control = access(_PATH_SYS_CLASS "/zram-control/", F_OK) == 0 ? 1 : 0; + z->control_probed = 1; + DBG(fprintf(stderr, "zram-control: %s", z->has_control ? "yes" : "no")); + } + + return z->has_control; +} + +static int zram_control_add(struct zram *z) +{ + int n; + + if (!zram_has_control(z)) + return -ENOSYS; + + n = path_read_s32(_PATH_SYS_CLASS "/zram-control/hot_add"); + if (n < 0) + return n; + + DBG(fprintf(stderr, "hot-add: %d", n)); + zram_set_devname(z, NULL, n); + return 0; +} + +static int zram_control_remove(struct zram *z) +{ + char str[sizeof stringify_value(INT_MAX)]; + int n; + + if (!zram_has_control(z)) + return -ENOSYS; + + n = zram_get_devnum(z); + if (n < 0) + return n; + + DBG(fprintf(stderr, "hot-remove: %d", n)); + snprintf(str, sizeof(str), "%d", n); + return path_write_str(str, _PATH_SYS_CLASS "/zram-control/hot_remove"); +} + static struct zram *find_free_zram(void) { struct zram *z = new_zram(NULL); @@ -270,7 +328,7 @@ static struct zram *find_free_zram(void) for (i = 0; isfree == 0; i++) { DBG(fprintf(stderr, "find free: checking zram%zu", i)); zram_set_devname(z, NULL, i); - if (!zram_exist(z)) + if (!zram_exist(z) && zram_control_add(z) != 0) break; isfree = !zram_used(z); } @@ -281,7 +339,6 @@ static struct zram *find_free_zram(void) return z; } - static char *get_mm_stat(struct zram *z, size_t idx, int bytes) { struct sysfs_cxt *sysfs; @@ -630,6 +687,7 @@ int main(int argc, char **argv) warn(_("%s: failed to reset"), zram->devname); rc = 1; } + zram_control_remove(zram); free_zram(zram); optind++; } |