You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

124 lines
3.5 KiB

{ config, pkgs, utils, ... }:
with pkgs.lib;
with utils;
{
###### interface
options = {
swapDevices = mkOption {
default = [];
example = [
{ device = "/dev/hda7"; }
{ device = "/var/swapfile"; }
{ label = "bigswap"; }
];
description = ''
The swap devices and swap files. These must have been
initialised using <command>mkswap</command>. Each element
should be an attribute set specifying either the path of the
swap device or file (<literal>device</literal>) or the label
of the swap device (<literal>label</literal>, see
<command>mkswap -L</command>). Using a label is
recommended.
'';
type = types.listOf types.optionSet;
options = {config, options, ...}: {
options = {
device = mkOption {
example = "/dev/sda3";
type = types.uniq types.string;
description = "Path of the device.";
};
label = mkOption {
example = "swap";
type = types.uniq types.string;
description = ''
Label of the device. Can be used instead of <varname>device</varname>.
'';
};
size = mkOption {
default = null;
example = 2048;
type = types.nullOr types.int;
description = ''
If this option is set, device is interpreted as the
path of a swapfile that will be created automatically
with the indicated size (in megabytes) if it doesn't
exist.
'';
};
priority = mkOption {
default = null;
example = 2048;
type = types.nullOr types.int;
description = ''
Specify the priority of the swap device. Priority is a value between 0 and 32767.
Higher numbers indicate higher priority.
null lets the kernel choose a priority, which will show up as a negative value.
'';
};
};
config = {
device =
if options.label.isDefined then
"/dev/disk/by-label/${config.label}"
else
mkNotdef;
};
};
};
};
config = mkIf ((length config.swapDevices) != 0) {
system.requiredKernelConfig = with config.lib.kernelConfig; [
(isYes "SWAP")
];
# Create missing swapfiles.
# FIXME: support changing the size of existing swapfiles.
systemd.services =
let
createSwapDevice = sw:
assert sw.device != "";
let device' = escapeSystemdPath sw.device; in
nameValuePair "mkswap-${escapeSystemdPath sw.device}"
{ description = "Initialisation of Swapfile ${sw.device}";
wantedBy = [ "${device'}.swap" ];
before = [ "${device'}.swap" ];
path = [ pkgs.utillinux ];
script =
''
if [ ! -e "${sw.device}" ]; then
fallocate -l ${toString sw.size}M "${sw.device}" ||
dd if=/dev/zero of="${sw.device}" bs=1M count=${toString sw.size}
mkswap ${sw.device}
fi
'';
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
serviceConfig.Type = "oneshot";
};
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null) config.swapDevices));
};
}