1 { config, lib, pkgs, ... }:
5 cfg = config.services.lvm;
7 options.services.lvm = {
8 enable = mkEnableOption "lvm2" // {
16 defaultText = literalExpression "pkgs.lvm2";
18 This option allows you to override the LVM package that's used on the system
19 (udev rules, tmpfiles, systemd services).
20 Defaults to pkgs.lvm2, pkgs.lvm2_dmeventd if dmeventd or pkgs.lvm2_vdo if vdo is enabled.
23 dmeventd.enable = mkEnableOption "the LVM dmevent daemon";
24 boot.thin.enable = mkEnableOption "support for booting from ThinLVs";
25 boot.vdo.enable = mkEnableOption "support for booting from VDOLVs";
28 options.boot.initrd.services.lvm.enable = mkEnableOption "booting from LVM2 in the initrd" // {
30 *This will only be used when systemd is used in stage 1.*
32 Whether to enable booting from LVM2 in the initrd.
34 default = config.boot.initrd.systemd.enable && config.services.lvm.enable;
35 defaultText = lib.literalExpression "config.boot.initrd.systemd.enable && config.services.lvm.enable";
40 # minimal configuration file to make lvmconfig/lvm2-activation-generator happy
41 environment.etc."lvm/lvm.conf".text = "config {}";
44 systemd.tmpfiles.packages = [ cfg.package.out ];
45 environment.systemPackages = [ cfg.package ];
46 systemd.packages = [ cfg.package ];
48 services.udev.packages = [ cfg.package.out ];
50 (mkIf config.boot.initrd.services.lvm.enable {
51 # We need lvm2 for the device-mapper rules
52 boot.initrd.services.udev.packages = [ cfg.package ];
53 # The device-mapper rules want to call tools from lvm2
54 boot.initrd.systemd.initrdBin = [ cfg.package ];
55 boot.initrd.services.udev.binPackages = [ cfg.package ];
57 (mkIf cfg.dmeventd.enable {
58 systemd.sockets."dm-event".wantedBy = [ "sockets.target" ];
59 systemd.services."lvm2-monitor".wantedBy = [ "sysinit.target" ];
61 environment.etc."lvm/lvm.conf".text = ''
62 dmeventd/executable = "${cfg.package}/bin/dmeventd"
64 services.lvm.package = mkDefault pkgs.lvm2_dmeventd;
66 (mkIf cfg.boot.thin.enable {
68 kernelModules = [ "dm-snapshot" "dm-thin-pool" ];
70 systemd.initrdBin = lib.mkIf config.boot.initrd.services.lvm.enable [ pkgs.thin-provisioning-tools ];
72 extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable) ''
73 for BIN in ${pkgs.thin-provisioning-tools}/bin/*; do
74 copy_bin_and_libs $BIN
78 extraUtilsCommandsTest = mkIf (!config.boot.initrd.systemd.enable) ''
79 ls ${pkgs.thin-provisioning-tools}/bin/ | grep -v pdata_tools | while read BIN; do
80 $out/bin/$(basename $BIN) --help > /dev/null
85 environment.etc."lvm/lvm.conf".text = concatMapStringsSep "\n"
86 (bin: "global/${bin}_executable = ${pkgs.thin-provisioning-tools}/bin/${bin}")
87 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ];
89 environment.systemPackages = [ pkgs.thin-provisioning-tools ];
91 (mkIf cfg.boot.vdo.enable {
93 assertion = lib.versionAtLeast config.boot.kernelPackages.kernel.version "6.9";
94 message = "boot.vdo.enable requires at least kernel version 6.9";
99 kernelModules = [ "dm-vdo" ];
101 systemd.initrdBin = lib.mkIf config.boot.initrd.services.lvm.enable [ pkgs.vdo ];
103 extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable)''
104 ls ${pkgs.vdo}/bin/ | while read BIN; do
105 copy_bin_and_libs ${pkgs.vdo}/bin/$BIN
107 substituteInPlace $out/bin/vdorecover --replace "${pkgs.bash}/bin/bash" "/bin/sh"
108 substituteInPlace $out/bin/adaptlvm --replace "${pkgs.bash}/bin/bash" "/bin/sh"
111 extraUtilsCommandsTest = mkIf (!config.boot.initrd.systemd.enable)''
112 ls ${pkgs.vdo}/bin/ | grep -vE '(adaptlvm|vdorecover)' | while read BIN; do
113 $out/bin/$(basename $BIN) --help > /dev/null
119 services.lvm.package = mkOverride 999 pkgs.lvm2_vdo; # this overrides mkDefault
121 environment.systemPackages = [ pkgs.vdo ];
123 (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) {
124 boot.initrd.systemd.contents."/etc/lvm/lvm.conf".text = optionalString (config.boot.initrd.services.lvm.enable && cfg.boot.thin.enable) (concatMapStringsSep "\n"
125 (bin: "global/${bin}_executable = /bin/${bin}")
126 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ]
127 ) + "\n" + optionalString cfg.dmeventd.enable ''
128 dmeventd/executable = /bin/false
129 activation/monitoring = 0
132 boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) ''
134 cat << EOF >> /etc/lvm/lvm.conf
135 ${optionalString cfg.boot.thin.enable (
136 concatMapStringsSep "\n"
137 (bin: "global/${bin}_executable = $(command -v ${bin})")
138 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ]
141 ${optionalString cfg.dmeventd.enable ''
142 dmeventd/executable = "$(command -v false)"
143 activation/monitoring = 0