summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
authorMichael Raskin <7c6f434c@mail.ru>2014-06-12 13:01:29 +0400
committerMichael Raskin <7c6f434c@mail.ru>2014-06-12 13:01:29 +0400
commitdceda93bd02321657a9efdcb70c4d8217b55448b (patch)
treeeb1fd9e306ed3ffafbb003ac0966c883339f413b /nixos/modules
parent8dca1caeb9a726d4a323241fc84c9bc292bcde21 (diff)
parentcd1b48bc3541a800f49ca154b475796f4241dc3f (diff)
downloadnixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar.gz
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar.bz2
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar.lz
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar.xz
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.tar.zst
nixlib-dceda93bd02321657a9efdcb70c4d8217b55448b.zip
Merge pull request #2543 from wizeman/u/zramswap
nixos: Add zram swap module
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/config/zram.nix138
-rw-r--r--nixos/modules/module-list.nix1
2 files changed, 139 insertions, 0 deletions
diff --git a/nixos/modules/config/zram.nix b/nixos/modules/config/zram.nix
new file mode 100644
index 000000000000..22b74847f871
--- /dev/null
+++ b/nixos/modules/config/zram.nix
@@ -0,0 +1,138 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.zramSwap;
+
+  devices = map (nr: "zram${toString nr}") (range 0 (cfg.numDevices - 1));
+
+  modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    zramSwap = {
+
+      enable = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Enable in-memory compressed swap space provided by the zram kernel
+          module. It is recommended to enable only for kernel 3.14 or higher.
+        '';
+      };
+
+      numDevices = mkOption {
+        default = 4;
+        type = types.int;
+        description = ''
+          Number of zram swap devices to create. It should be equal to the
+          number of CPU cores your system has.
+        '';
+      };
+
+      memoryPercent = mkOption {
+        default = 50;
+        type = types.int;
+        description = ''
+          Maximum amount of memory that can be used by the zram swap devices
+          (as a percentage of your total memory). Defaults to 1/2 of your total
+          RAM.
+        '';
+      };
+
+      priority = mkOption {
+        default = 5;
+        type = types.int;
+        description = ''
+          Priority of the zram swap devices. It should be a number higher than
+          the priority of your disk-based swap devices (so that the system will
+          fill the zram swap devices before falling back to disk swap).
+        '';
+      };
+
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    system.requiredKernelConfig = with config.lib.kernelConfig; [
+      (isModule "ZRAM")
+    ];
+
+    # Disabling this for the moment, as it would create and mkswap devices twice,
+    # once in stage 2 boot, and again when the zram-reloader service starts.
+    # boot.kernelModules = [ "zram" ];
+
+    boot.extraModprobeConfig = ''
+      options zram num_devices=${toString cfg.numDevices}
+    '';
+
+    services.udev.extraRules = ''
+      KERNEL=="zram[0-9]*", ENV{SYSTEMD_WANTS}="zram-init-%k.service", TAG+="systemd"
+    '';
+
+    systemd.services =
+      let
+        createZramInitService = dev:
+          nameValuePair "zram-init-${dev}" {
+            description = "Init swap on zram-based device ${dev}";
+            bindsTo = [ "dev-${dev}.swap" ];
+            after = [ "dev-${dev}.device" "zram-reloader.service" ];
+            requires = [ "dev-${dev}.device" "zram-reloader.service" ];
+            before = [ "dev-${dev}.swap" ];
+            requiredBy = [ "dev-${dev}.swap" ];
+            serviceConfig = {
+              Type = "oneshot";
+              RemainAfterExit = true;
+              ExecStop = "${pkgs.stdenv.shell} -c 'echo 1 > /sys/class/block/${dev}/reset'";
+            };
+            script = ''
+              set -u
+              set -o pipefail
+
+              PATH=${pkgs.procps}/bin:${pkgs.gnugrep}/bin:${pkgs.gnused}/bin
+
+              # Calculate memory to use for zram
+              totalmem=$(free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/  *.*//')
+              mem=$(((totalmem * ${toString cfg.memoryPercent} / 100 / ${toString cfg.numDevices}) * 1024))
+
+              echo $mem > /sys/class/block/${dev}/disksize
+              ${pkgs.utillinux}/sbin/mkswap /dev/${dev}
+            '';
+            restartIfChanged = false;
+          };
+      in listToAttrs ((map createZramInitService devices) ++ [(nameValuePair "zram-reloader"
+        {
+          description = "Reload zram kernel module when number of devices changes";
+          serviceConfig = {
+            Type = "oneshot";
+            RemainAfterExit = true;
+            ExecStartPre = "${modprobe} -r zram";
+            ExecStart = "${modprobe} zram";
+            ExecStop = "${modprobe} -r zram";
+          };
+          restartTriggers = [ cfg.numDevices ];
+          restartIfChanged = true;
+        })]);
+
+    swapDevices =
+      let
+        useZramSwap = dev:
+          {
+            device = "/dev/${dev}";
+            priority = cfg.priority;
+          };
+      in map useZramSwap devices;
+
+  };
+
+}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index a6e0e0186695..cae2e61c2cf2 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -21,6 +21,7 @@
   ./config/timezone.nix
   ./config/unix-odbc-drivers.nix
   ./config/users-groups.nix
+  ./config/zram.nix
   ./hardware/all-firmware.nix
   ./hardware/cpu/intel-microcode.nix
   ./hardware/cpu/amd-microcode.nix