Merge pull request #2543 from wizeman/u/zramswap
nixos: Add zram swap module
This commit is contained in:
commit
dceda93bd0
2 changed files with 139 additions and 0 deletions
138
nixos/modules/config/zram.nix
Normal file
138
nixos/modules/config/zram.nix
Normal file
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue