add btrfs swap support

This commit is contained in:
Aleksander Heintz 2023-09-12 23:03:16 +02:00 committed by mergify[bot]
parent 548962c50b
commit 72bc152626
6 changed files with 84 additions and 1 deletions

View file

@ -45,6 +45,25 @@
};
# This subvolume will be created but not mounted
"/test" = { };
# Subvolume for the swapfile
"/swap" = {
mountpoint = "/.swapvol";
swap = {
swapfile.size = "20M";
swapfile2.size = "20M";
swapfile2.path = "rel-path";
};
};
};
mountpoint = "/partition-root";
swap = {
swapfile = {
size = "20M";
};
swapfile1 = {
size = "20M";
};
};
};
};

View file

@ -48,6 +48,10 @@
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "noatime" ];
};
"/swap" = {
mountpoint = "/.swapvol";
swap.swapfile.size = "20M";
};
};
};
};

View file

@ -192,7 +192,7 @@ let
|| lib.hasSuffix "Hook" n
|| isAttrsOfSubmodule o
# TODO don't hardcode diskoLib.subType options.
|| n == "content" || n == "partitions" || n == "datasets"
|| n == "content" || n == "partitions" || n == "datasets" || n == "swap"
);
in
lib.toShellVars

View file

@ -1,4 +1,40 @@
{ config, options, diskoLib, lib, rootMountPoint, parent, device, ... }:
let
swapType = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
options = {
size = lib.mkOption {
type = lib.types.strMatching "^([0-9]+[KMGTP])?$";
description = "Size of the swap file (e.g. 2G)";
};
path = lib.mkOption {
type = lib.types.str;
default = name;
description = "Path to the swap file (relative to the mountpoint)";
};
};
}));
default = { };
description = "Swap files";
};
swapConfig = { mountpoint, swap }:
{
swapDevices = builtins.map
(file: {
device = "${mountpoint}/${file.path}";
})
(lib.attrValues swap);
};
swapCreate = mountpoint: swap:
lib.concatMapStringsSep
"\n"
(file: ''btrfs filesystem mkswapfile --size ${file.size} "${mountpoint}/${file.path}"'')
(lib.attrValues swap);
in
{
options = {
type = lib.mkOption {
@ -50,6 +86,7 @@
default = null;
description = "Location to mount the subvolume to.";
};
swap = swapType;
};
}));
default = { };
@ -60,6 +97,7 @@
default = null;
description = "A path to mount the BTRFS filesystem to.";
};
swap = swapType;
_parent = lib.mkOption {
internal = true;
default = parent;
@ -75,12 +113,21 @@
inherit config options;
default = ''
mkfs.btrfs ${config.device} ${toString config.extraArgs}
${lib.optionalString (config.swap != {}) ''
(
MNTPOINT=$(mktemp -d)
mount ${device} "$MNTPOINT" -o subvol=/
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
${swapCreate "$MNTPOINT" config.swap}
)
''}
${lib.concatMapStrings (subvol: ''
(
MNTPOINT=$(mktemp -d)
mount ${config.device} "$MNTPOINT" -o subvol=/
trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT
btrfs subvolume create "$MNTPOINT"/${subvol.name} ${toString subvol.extraArgs}
${swapCreate "$MNTPOINT/${subvol.name}" subvol.swap}
)
'') (lib.attrValues config.subvolumes)}
'';
@ -141,6 +188,14 @@
options = config.mountOptions;
};
})
(map
(subvol: swapConfig {
inherit (subvol) mountpoint swap;
})
(lib.attrValues config.subvolumes))
(swapConfig {
inherit (config) mountpoint swap;
})
];
description = "NixOS configuration";
};

View file

@ -11,6 +11,10 @@ diskoLib.testLib.makeDiskoTest {
machine.succeed("btrfs subvolume list / | grep -qs 'path test$'");
machine.succeed("btrfs subvolume list / | grep -qs 'path nix$'");
machine.succeed("btrfs subvolume list / | grep -qs 'path home$'");
machine.succeed("test -e /.swapvol/swapfile");
machine.succeed("test -e /.swapvol/rel-path");
machine.succeed("test -e /partition-root/swapfile");
machine.succeed("test -e /partition-root/swapfile1");
'';
}

View file

@ -9,5 +9,6 @@ diskoLib.testLib.makeDiskoTest {
machine.succeed("cryptsetup isLuks /dev/vda2");
machine.succeed("btrfs subvolume list / | grep -qs 'path nix$'");
machine.succeed("btrfs subvolume list / | grep -qs 'path home$'");
machine.succeed("test -e /.swapvol/swapfile");
'';
}