···
1
+
{ config, lib, pkgs, ... }:
7
+
cfg = config.zramSwap;
9
+
devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
11
+
modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
27
+
Enable in-memory compressed swap space provided by the zram kernel
28
+
module. It is recommended to enable only for kernel 3.14 or higher.
32
+
numDevices = mkOption {
36
+
Number of zram swap devices to create. It should be equal to the
37
+
number of CPU cores your system has.
41
+
memoryPercent = mkOption {
45
+
Maximum amount of memory that can be used by the zram swap devices
46
+
(as a percentage of your total memory). Defaults to 1/2 of your total
51
+
priority = mkOption {
55
+
Priority of the zram swap devices. It should be a number higher than
56
+
the priority of your disk-based swap devices (so that the system will
57
+
fill the zram swap devices before falling back to disk swap).
65
+
config = mkIf cfg.enable {
67
+
system.requiredKernelConfig = with config.lib.kernelConfig; [
71
+
# Disabling this for the moment, as it would create and mkswap devices twice,
72
+
# once in stage 2 boot, and again when the zram-reloader service starts.
73
+
# boot.kernelModules = [ "zram" ];
75
+
boot.extraModprobeConfig = ''
76
+
options zram num_devices=${toString cfg.numDevices}
79
+
services.udev.extraRules = ''
80
+
KERNEL=="zram[0-9]*", ENV{SYSTEMD_WANTS}="zram-init-%k.service", TAG+="systemd"
85
+
createZramInitService = dev:
86
+
nameValuePair "zram-init-${dev}" {
87
+
description = "Init swap on zram-based device ${dev}";
88
+
bindsTo = [ "dev-${dev}.swap" ];
89
+
after = [ "dev-${dev}.device" "zram-reloader.service" ];
90
+
requires = [ "dev-${dev}.device" "zram-reloader.service" ];
91
+
before = [ "dev-${dev}.swap" ];
92
+
requiredBy = [ "dev-${dev}.swap" ];
95
+
RemainAfterExit = true;
96
+
ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
102
+
PATH=${pkgs.procps}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin
104
+
# Calculate memory to use for zram
105
+
totalmem=$(free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/ *.*//')
106
+
mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
108
+
echo $mem > /sys/class/block/${dev}/disksize
109
+
${pkgs.utillinux}/sbin/mkswap /dev/${dev}
111
+
restartIfChanged = false;
113
+
in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
115
+
description = "Reload zram kernel module when number of devices changes";
118
+
RemainAfterExit = true;
119
+
ExecStartPre = "${modprobe} -r zram";
120
+
ExecStart = "${modprobe} zram";
121
+
ExecStop = "${modprobe} -r zram";
123
+
restartTriggers = [ cfg.numDevices ];
124
+
restartIfChanged = true;
131
+
device = "/dev/${dev}";
132
+
priority = cfg.priority;
134
+
in map useZramSwap devices;