lvm_vg: add lvm thinpool/thinlv support

Co-authored-by: ajs124 <git@ajs124.de>
This commit is contained in:
Matthew_Cash 2024-06-24 23:29:25 -07:00 committed by mergify[bot]
parent dd4d1663cc
commit b6a1262796
3 changed files with 102 additions and 5 deletions

71
example/lvm-thin.nix Normal file
View file

@ -0,0 +1,71 @@
{
disko.devices = {
disk = {
vdb = {
type = "disk";
device = "/dev/vdb";
content = {
type = "gpt";
partitions = {
ESP = {
size = "500M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"defaults"
];
};
};
primary = {
size = "100%";
content = {
type = "lvm_pv";
vg = "mainpool";
};
};
};
};
};
};
lvm_vg = {
mainpool = {
type = "lvm_vg";
lvs = {
thinpool = {
size = "100M";
lvm_type = "thin-pool";
};
root = {
size = "10M";
lvm_type = "thinlv";
pool = "thinpool";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
home = {
size = "10M";
lvm_type = "thinlv";
pool = "thinpool";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/home";
};
};
raw = {
size = "10M";
};
};
};
};
};
}

View file

@ -1,4 +1,10 @@
{ config, options, lib, diskoLib, ... }: { config, options, lib, diskoLib, ... }:
let
# Load kernel modules to ensure device mapper types are available
kernelModules = lib.filter (x: x != "") (map
(lv: lib.optionalString (lv.lvm_type != null && lv.lvm_type != "thinlv") "dm-${lv.lvm_type}")
(lib.attrValues config.lvs));
in
{ {
options = { options = {
name = lib.mkOption { name = lib.mkOption {
@ -21,7 +27,7 @@
}; };
priority = lib.mkOption { priority = lib.mkOption {
type = lib.types.int; type = lib.types.int;
default = if (lib.hasInfix "100%" lv.config.size) then 9001 else 1000; default = (if lv.config.lvm_type == "thin-pool" then 501 else 1000) + (if lib.hasInfix "100%" lv.config.size then 251 else 0);
defaultText = lib.literalExpression '' defaultText = lib.literalExpression ''
if (lib.hasInfix "100%" lv.config.size) then 9001 else 1000 if (lib.hasInfix "100%" lv.config.size) then 9001 else 1000
''; '';
@ -33,7 +39,7 @@
}; };
lvm_type = lib.mkOption { lvm_type = lib.mkOption {
# TODO: add raid10 # TODO: add raid10
type = lib.types.nullOr (lib.types.enum [ "mirror" "raid0" "raid1" "raid4" "raid5" "raid6" ]); # TODO add all lib.types type = lib.types.nullOr (lib.types.enum [ "mirror" "raid0" "raid1" "raid4" "raid5" "raid6" "thin-pool" "thinlv" ]); # TODO add all lib.types
default = null; # maybe there is always a default type? default = null; # maybe there is always a default type?
description = "LVM type"; description = "LVM type";
}; };
@ -42,6 +48,11 @@
default = [ ]; default = [ ];
description = "Extra arguments"; description = "Extra arguments";
}; };
pool = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Name of pool LV that this LV belongs to";
};
content = diskoLib.partitionType { parent = config; device = "/dev/${config.name}/${lv.config.name}"; }; content = diskoLib.partitionType { parent = config; device = "/dev/${config.name}/${lv.config.name}"; };
}; };
})); }));
@ -67,6 +78,7 @@
sortedLvs = lib.sort (a: b: a.priority < b.priority) (lib.attrValues config.lvs); sortedLvs = lib.sort (a: b: a.priority < b.priority) (lib.attrValues config.lvs);
in in
'' ''
${lib.concatMapStringsSep "\n" (k: ''modprobe "${k}"'') kernelModules}
readarray -t lvm_devices < <(cat "$disko_devices_dir"/lvm_${config.name}) readarray -t lvm_devices < <(cat "$disko_devices_dir"/lvm_${config.name})
if ! vgdisplay "${config.name}" >/dev/null; then if ! vgdisplay "${config.name}" >/dev/null; then
vgcreate ${config.name} \ vgcreate ${config.name} \
@ -76,9 +88,12 @@
if ! lvdisplay '${config.name}/${lv.name}'; then if ! lvdisplay '${config.name}/${lv.name}'; then
lvcreate \ lvcreate \
--yes \ --yes \
${if lib.hasInfix "%" lv.size then "-l" else "-L"} ${lv.size} \ ${if (lv.lvm_type == "thinlv") then "-V"
else if lib.hasInfix "%" lv.size then "-l" else "-L"} \
${lv.size} \
-n ${lv.name} \ -n ${lv.name} \
${lib.optionalString (lv.lvm_type != null) "--type=${lv.lvm_type}"} \ ${lib.optionalString (lv.lvm_type == "thinlv") "--thinpool=${lv.pool}"} \
${lib.optionalString (lv.lvm_type != null && lv.lvm_type != "thinlv") "--type=${lv.lvm_type}"} \
${toString lv.extraArgs} \ ${toString lv.extraArgs} \
${config.name} ${config.name}
fi fi
@ -110,7 +125,7 @@
_config = lib.mkOption { _config = lib.mkOption {
internal = true; internal = true;
readOnly = true; readOnly = true;
default = default = [ { boot.initrd.kernelModules = kernelModules; } ] ++
map map
(lv: [ (lv: [
(lib.optional (lv.content != null) lv.content._config) (lib.optional (lv.content != null) lv.content._config)

11
tests/lvm-thin.nix Normal file
View file

@ -0,0 +1,11 @@
{ pkgs ? import <nixpkgs> { }
, diskoLib ? pkgs.callPackage ../lib { }
}:
diskoLib.testLib.makeDiskoTest {
inherit pkgs;
name = "lvm-thin";
disko-config = ../example/lvm-thin.nix;
extraTestScript = ''
machine.succeed("mountpoint /home");
'';
}