at 23.11-pre 5.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4let 5 cfg = config.services.lvm; 6in { 7 options.services.lvm = { 8 enable = mkEnableOption (lib.mdDoc "lvm2") // { 9 default = true; 10 }; 11 12 package = mkOption { 13 type = types.package; 14 default = pkgs.lvm2; 15 internal = true; 16 defaultText = literalExpression "pkgs.lvm2"; 17 description = lib.mdDoc '' 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. 21 ''; 22 }; 23 dmeventd.enable = mkEnableOption (lib.mdDoc "the LVM dmevent daemon"); 24 boot.thin.enable = mkEnableOption (lib.mdDoc "support for booting from ThinLVs"); 25 boot.vdo.enable = mkEnableOption (lib.mdDoc "support for booting from VDOLVs"); 26 }; 27 28 options.boot.initrd.services.lvm.enable = (mkEnableOption (lib.mdDoc "enable booting from LVM2 in the initrd")) // { 29 visible = false; 30 }; 31 32 config = mkMerge [ 33 ({ 34 # minimal configuration file to make lvmconfig/lvm2-activation-generator happy 35 environment.etc."lvm/lvm.conf".text = "config {}"; 36 }) 37 (mkIf cfg.enable { 38 systemd.tmpfiles.packages = [ cfg.package.out ]; 39 environment.systemPackages = [ cfg.package ]; 40 systemd.packages = [ cfg.package ]; 41 42 services.udev.packages = [ cfg.package.out ]; 43 44 # We need lvm2 for the device-mapper rules 45 boot.initrd.services.udev.packages = lib.mkIf config.boot.initrd.services.lvm.enable [ cfg.package ]; 46 # The device-mapper rules want to call tools from lvm2 47 boot.initrd.systemd.initrdBin = lib.mkIf config.boot.initrd.services.lvm.enable [ cfg.package ]; 48 boot.initrd.services.udev.binPackages = lib.mkIf config.boot.initrd.services.lvm.enable [ cfg.package ]; 49 }) 50 (mkIf cfg.dmeventd.enable { 51 systemd.sockets."dm-event".wantedBy = [ "sockets.target" ]; 52 systemd.services."lvm2-monitor".wantedBy = [ "sysinit.target" ]; 53 54 environment.etc."lvm/lvm.conf".text = '' 55 dmeventd/executable = "${cfg.package}/bin/dmeventd" 56 ''; 57 services.lvm.package = mkDefault pkgs.lvm2_dmeventd; 58 }) 59 (mkIf cfg.boot.thin.enable { 60 boot.initrd = { 61 kernelModules = [ "dm-snapshot" "dm-thin-pool" ]; 62 63 systemd.initrdBin = lib.mkIf config.boot.initrd.services.lvm.enable [ pkgs.thin-provisioning-tools ]; 64 65 extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable) '' 66 for BIN in ${pkgs.thin-provisioning-tools}/bin/*; do 67 copy_bin_and_libs $BIN 68 done 69 ''; 70 71 extraUtilsCommandsTest = mkIf (!config.boot.initrd.systemd.enable) '' 72 ls ${pkgs.thin-provisioning-tools}/bin/ | grep -v pdata_tools | while read BIN; do 73 $out/bin/$(basename $BIN) --help > /dev/null 74 done 75 ''; 76 }; 77 78 environment.etc."lvm/lvm.conf".text = concatMapStringsSep "\n" 79 (bin: "global/${bin}_executable = ${pkgs.thin-provisioning-tools}/bin/${bin}") 80 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ]; 81 82 environment.systemPackages = [ pkgs.thin-provisioning-tools ]; 83 }) 84 (mkIf cfg.boot.vdo.enable { 85 boot = { 86 initrd = { 87 kernelModules = [ "kvdo" ]; 88 89 systemd.initrdBin = lib.mkIf config.boot.initrd.services.lvm.enable [ pkgs.vdo ]; 90 91 extraUtilsCommands = mkIf (!config.boot.initrd.systemd.enable)'' 92 ls ${pkgs.vdo}/bin/ | while read BIN; do 93 copy_bin_and_libs ${pkgs.vdo}/bin/$BIN 94 done 95 substituteInPlace $out/bin/vdorecover --replace "${pkgs.bash}/bin/bash" "/bin/sh" 96 substituteInPlace $out/bin/adaptLVMVDO.sh --replace "${pkgs.bash}/bin/bash" "/bin/sh" 97 ''; 98 99 extraUtilsCommandsTest = mkIf (!config.boot.initrd.systemd.enable)'' 100 ls ${pkgs.vdo}/bin/ | grep -vE '(adaptLVMVDO|vdorecover)' | while read BIN; do 101 $out/bin/$(basename $BIN) --help > /dev/null 102 done 103 ''; 104 }; 105 extraModulePackages = [ config.boot.kernelPackages.kvdo ]; 106 }; 107 108 services.lvm.package = mkOverride 999 pkgs.lvm2_vdo; # this overrides mkDefault 109 110 environment.systemPackages = [ pkgs.vdo ]; 111 }) 112 (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) { 113 boot.initrd.systemd.contents."/etc/lvm/lvm.conf".text = optionalString (config.boot.initrd.services.lvm.enable && cfg.boot.thin.enable) (concatMapStringsSep "\n" 114 (bin: "global/${bin}_executable = /bin/${bin}") 115 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ] 116 ) + "\n" + optionalString cfg.dmeventd.enable '' 117 dmeventd/executable = /bin/false 118 activation/monitoring = 0 119 ''; 120 121 boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) '' 122 mkdir -p /etc/lvm 123 cat << EOF >> /etc/lvm/lvm.conf 124 ${optionalString cfg.boot.thin.enable ( 125 concatMapStringsSep "\n" 126 (bin: "global/${bin}_executable = $(command -v ${bin})") 127 [ "thin_check" "thin_dump" "thin_repair" "cache_check" "cache_dump" "cache_repair" ] 128 ) 129 } 130 ${optionalString cfg.dmeventd.enable '' 131 dmeventd/executable = "$(command -v false)" 132 activation/monitoring = 0 133 ''} 134 EOF 135 ''; 136 }) 137 ]; 138 139}