summaryrefslogtreecommitdiffstats
path: root/sys-utils/zramctl.c
diff options
context:
space:
mode:
authorKarel Zak2016-05-11 12:43:40 +0200
committerKarel Zak2016-05-11 12:43:40 +0200
commit627258104b936eeaaa19e8f21650f28378b661c8 (patch)
tree4f4e7b4ab62d33e8dbb31e034b276b20593bda9c /sys-utils/zramctl.c
parentlibfdisk: use fdisk_add_partition() for unused partno (diff)
downloadkernel-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.c64
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++;
}