diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index d551466f52e..63005b26f6f 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -111,8 +111,8 @@ let copy_bin_and_libs ${pkgs.utillinux}/sbin/blkid # Copy dmsetup and lvm. - copy_bin_and_libs ${pkgs.lvm2}/sbin/dmsetup - copy_bin_and_libs ${pkgs.lvm2}/sbin/lvm + copy_bin_and_libs ${getBin pkgs.lvm2}/bin/dmsetup + copy_bin_and_libs ${getBin pkgs.lvm2}/bin/lvm # Add RAID mdadm tool. copy_bin_and_libs ${pkgs.mdadm}/sbin/mdadm @@ -235,7 +235,7 @@ let --replace cdrom_id ${extraUtils}/bin/cdrom_id \ --replace ${pkgs.coreutils}/bin/basename ${extraUtils}/bin/basename \ --replace ${pkgs.utillinux}/bin/blkid ${extraUtils}/bin/blkid \ - --replace ${pkgs.lvm2}/sbin ${extraUtils}/bin \ + --replace ${getBin pkgs.lvm2}/bin ${extraUtils}/bin \ --replace ${pkgs.mdadm}/sbin ${extraUtils}/sbin \ --replace ${pkgs.bash}/bin/sh ${extraUtils}/bin/sh \ --replace ${udev} ${extraUtils} diff --git a/nixos/modules/tasks/lvm.nix b/nixos/modules/tasks/lvm.nix index d56a8a2f63a..b8f7a01e44e 100644 --- a/nixos/modules/tasks/lvm.nix +++ b/nixos/modules/tasks/lvm.nix @@ -1,17 +1,70 @@ { config, lib, pkgs, ... }: with lib; - -{ - - ###### implementation - - config = mkIf (!config.boot.isContainer) { - - environment.systemPackages = [ pkgs.lvm2 ]; - - services.udev.packages = [ pkgs.lvm2 ]; - +let + cfg = config.services.lvm; +in { + options.services.lvm = { + package = mkOption { + type = types.package; + default = if cfg.dmeventd.enable then pkgs.lvm2_dmeventd else pkgs.lvm2; + internal = true; + defaultText = "pkgs.lvm2"; + description = '' + This option allows you to override the LVM package that's used on the system + (udev rules, tmpfiles, systemd services). + Defaults to pkgs.lvm2, or pkgs.lvm2_dmeventd if dmeventd is enabled. + ''; + }; + dmeventd.enable = mkEnableOption "the LVM dmevent daemon"; + boot.thin.enable = mkEnableOption "support for booting from ThinLVs"; }; + config = mkMerge [ + (mkIf (!config.boot.isContainer) { + environment.etc."tmpfiles.d/lvm2.conf".source = "${cfg.package}/lib/tmpfiles.d/lvm2.conf"; + environment.systemPackages = [ cfg.package ]; + systemd.packages = [ cfg.package ]; + + # TODO: update once https://github.com/NixOS/nixpkgs/pull/93006 was merged + services.udev.packages = [ cfg.package.out ]; + }) + (mkIf cfg.dmeventd.enable { + systemd.sockets."dm-event".wantedBy = [ "sockets.target" ]; + systemd.services."lvm2-monitor".wantedBy = [ "sysinit.target" ]; + + environment.etc."lvm/lvm.conf".text = '' + dmeventd/executable = "${cfg.package}/bin/dmeventd" + ''; + }) + (mkIf cfg.boot.thin.enable { + boot.initrd = { + kernelModules = [ "dm-snapshot" "dm-thin-pool" ]; + + extraUtilsCommands = '' + copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/pdata_tools + copy_bin_and_libs ${pkgs.thin-provisioning-tools}/bin/thin_check + ''; + }; + + environment.etc."lvm/lvm.conf".text = '' + global/thin_check_executable = "${pkgs.thin-provisioning-tools}/bin/thin_check" + ''; + }) + (mkIf (cfg.dmeventd.enable || cfg.boot.thin.enable) { + boot.initrd.preLVMCommands = '' + mkdir -p /etc/lvm + cat << EOF >> /etc/lvm/lvm.conf + ${optionalString cfg.boot.thin.enable '' + global/thin_check_executable = "$(command -v thin_check)" + ''} + ${optionalString cfg.dmeventd.enable '' + dmeventd/executable = "$(command -v false)" + activation/monitoring = 0 + ''} + EOF + ''; + }) + ]; + } diff --git a/nixos/tests/installer.nix b/nixos/tests/installer.nix index eef9abebf9f..22132073142 100644 --- a/nixos/tests/installer.nix +++ b/nixos/tests/installer.nix @@ -64,7 +64,7 @@ let # a test script fragment `createPartitions', which must create # partitions and filesystems. testScriptFun = { bootLoader, createPartitions, grubVersion, grubDevice, grubUseEfi - , grubIdentifier, preBootCommands, extraConfig + , grubIdentifier, preBootCommands, postBootCommands, extraConfig , testSpecialisationConfig }: let iface = if grubVersion == 1 then "ide" else "virtio"; @@ -216,6 +216,7 @@ let machine = create_machine_named("boot-after-rebuild-switch") ${preBootCommands} machine.wait_for_unit("network.target") + ${postBootCommands} machine.shutdown() # Tests for validating clone configuration entries in grub menu @@ -238,6 +239,7 @@ let with subtest("Set grub to boot the second configuration"): machine.succeed("grub-reboot 1") + ${postBootCommands} machine.shutdown() # Reboot Machine @@ -252,12 +254,13 @@ let with subtest("We should find a file named /etc/gitconfig"): machine.succeed("test -e /etc/gitconfig") + ${postBootCommands} machine.shutdown() ''; makeInstallerTest = name: - { createPartitions, preBootCommands ? "", extraConfig ? "" + { createPartitions, preBootCommands ? "", postBootCommands ? "", extraConfig ? "" , extraInstallerConfig ? {} , bootLoader ? "grub" # either "grub" or "systemd-boot" , grubVersion ? 2, grubDevice ? "/dev/vda", grubIdentifier ? "uuid", grubUseEfi ? false @@ -335,7 +338,7 @@ let }; testScript = testScriptFun { - inherit bootLoader createPartitions preBootCommands + inherit bootLoader createPartitions preBootCommands postBootCommands grubVersion grubDevice grubIdentifier grubUseEfi extraConfig testSpecialisationConfig; }; @@ -552,16 +555,26 @@ in { + " mkpart primary 2048M -1s" # PV2 + " set 2 lvm on", "udevadm settle", + "sleep 1", "pvcreate /dev/vda1 /dev/vda2", + "sleep 1", "vgcreate MyVolGroup /dev/vda1 /dev/vda2", + "sleep 1", "lvcreate --size 1G --name swap MyVolGroup", + "sleep 1", "lvcreate --size 2G --name nixos MyVolGroup", + "sleep 1", "mkswap -f /dev/MyVolGroup/swap -L swap", "swapon -L swap", "mkfs.xfs -L nixos /dev/MyVolGroup/nixos", "mount LABEL=nixos /mnt", ) ''; + postBootCommands = '' + assert "loaded active" in machine.succeed( + "systemctl list-units 'lvm2-pvscan@*' -ql --no-legend | tee /dev/stderr" + ) + ''; }; # Boot off an encrypted root partition with the default LUKS header format diff --git a/pkgs/os-specific/linux/lvm2/default.nix b/pkgs/os-specific/linux/lvm2/default.nix index 8db4be94e4e..8bfdb37360d 100644 --- a/pkgs/os-specific/linux/lvm2/default.nix +++ b/pkgs/os-specific/linux/lvm2/default.nix @@ -1,48 +1,72 @@ -{ stdenv, fetchgit, fetchpatch, pkgconfig, systemd, udev, utillinux, libuuid +{ stdenv +, fetchpatch +, fetchurl +, pkgconfig +, utillinux +, libuuid , thin-provisioning-tools, libaio -, enable_dmeventd ? false }: +, enableCmdlib ? false +, enableDmeventd ? false +, udev ? null +, nixosTests +}: -let - version = "2.03.01"; -in +# configure: error: --enable-dmeventd requires --enable-cmdlib to be used as well +assert enableDmeventd -> enableCmdlib; -stdenv.mkDerivation { - pname = "lvm2"; - inherit version; +stdenv.mkDerivation rec { + pname = "lvm2" + stdenv.lib.optionalString enableDmeventd "with-dmeventd"; + version = "2.03.09"; - src = fetchgit { - url = "git://sourceware.org/git/lvm2.git"; - rev = "v${builtins.replaceStrings [ "." ] [ "_" ] version}"; - sha256 = "0jlaswf1srdxiqpgpp97j950ddjds8z0kr4pbwmal2za2blrgvbl"; + src = fetchurl { + url = "https://mirrors.kernel.org/sourceware/lvm2/LVM2.${version}.tgz"; + sha256 = "0xdr9qbqw6kja267wmx6ajnfv1nhw056gpxx9v2qmfh3bj6qnfn0"; }; - configureFlags = [ - "--disable-readline" - "--enable-udev_rules" - "--enable-udev_sync" - "--enable-pkgconfig" - "--enable-cmdlib" - ] ++ stdenv.lib.optional enable_dmeventd " --enable-dmeventd" - ++ stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ - "ac_cv_func_malloc_0_nonnull=yes" - "ac_cv_func_realloc_0_nonnull=yes" - ]; - nativeBuildInputs = [ pkgconfig ]; buildInputs = [ udev libuuid thin-provisioning-tools libaio ]; - preConfigure = - '' - sed -i /DEFAULT_SYS_DIR/d Makefile.in - sed -i /DEFAULT_PROFILE_DIR/d conf/Makefile.in - '' + stdenv.lib.optionalString (systemd != null) '' - substituteInPlace scripts/lvm2_activation_generator_systemd_red_hat.c \ - --replace /usr/bin/udevadm ${systemd}/bin/udevadm - ''; + configureFlags = [ + "--disable-readline" + "--enable-pkgconfig" + "--with-default-locking-dir=/run/lock/lvm" + "--with-default-run-dir=/run/lvm" + "--with-systemdsystemunitdir=${placeholder "out"}/lib/systemd/system" + ] ++ stdenv.lib.optionals (!enableCmdlib) [ + "--bindir=${placeholder "bin"}/bin" + "--sbindir=${placeholder "bin"}/bin" + "--libdir=${placeholder "lib"}/lib" + ] ++ stdenv.lib.optional enableCmdlib "--enable-cmdlib" + ++ stdenv.lib.optionals enableDmeventd [ + "--enable-dmeventd" + "--with-dmeventd-pidfile=/run/dmeventd/pid" + "--with-default-dm-run-dir=/run/dmeventd" + ] ++ stdenv.lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ + "ac_cv_func_malloc_0_nonnull=yes" + "ac_cv_func_realloc_0_nonnull=yes" + ] ++ + stdenv.lib.optionals (udev != null) [ + "--enable-udev_rules" + "--enable-udev_sync" + ]; + + preConfigure = '' + sed -i /DEFAULT_SYS_DIR/d Makefile.in + sed -i /DEFAULT_PROFILE_DIR/d conf/Makefile.in + substituteInPlace scripts/lvm2_activation_generator_systemd_red_hat.c \ + --replace /usr/bin/udevadm /run/current-system/systemd/bin/udevadm + # https://github.com/lvmteam/lvm2/issues/36 + substituteInPlace udev/69-dm-lvm-metad.rules.in \ + --replace "(BINDIR)/systemd-run" /run/current-system/systemd/bin/systemd-run + + substituteInPlace make.tmpl.in --replace "@systemdsystemunitdir@" "$out/lib/systemd/system" + substituteInPlace libdm/make.tmpl.in --replace "@systemdsystemunitdir@" "$out/lib/systemd/system" + ''; + + postConfigure = '' + sed -i 's|^#define LVM_CONFIGURE_LINE.*$|#define LVM_CONFIGURE_LINE ""|g' ./include/configure.h + ''; - # https://github.com/NixOS/nixpkgs/pull/52597 - # gcc: error: ../../device_mapper/libdevice-mapper.a: No such file or directory - enableParallelBuilding = false; patches = stdenv.lib.optionals stdenv.hostPlatform.isMusl [ (fetchpatch { @@ -64,30 +88,41 @@ stdenv.mkDerivation { doCheck = false; # requires root + makeFlags = stdenv.lib.optionals (udev != null) [ + "SYSTEMD_GENERATOR_DIR=$(out)/lib/systemd/system-generators" + ]; + # To prevent make install from failing. installFlags = [ "OWNER=" "GROUP=" "confdir=$(out)/etc" ]; # Install systemd stuff. - #installTargets = "install install_systemd_generators install_systemd_units install_tmpfiles_configuration"; + installTargets = [ "install" ] ++ stdenv.lib.optionals (udev != null) [ + "install_systemd_generators" + "install_systemd_units" + "install_tmpfiles_configuration" + ]; - postInstall = - '' - substituteInPlace $out/lib/udev/rules.d/13-dm-disk.rules \ - --replace $out/sbin/blkid ${utillinux}/sbin/blkid - '' + stdenv.lib.optionalString (systemd != null) '' - # Systemd stuff - mkdir -p $out/etc/systemd/system $out/lib/systemd/system-generators - cp scripts/blk_availability_systemd_red_hat.service $out/etc/systemd/system - cp scripts/lvm2_activation_generator_systemd_red_hat $out/lib/systemd/system-generators - ''; + # only split bin and lib out from out if cmdlib isn't enabled + outputs = [ + "out" + "dev" + "man" + ] ++ stdenv.lib.optionals (enableCmdlib != true) [ + "bin" + "lib" + ]; + + postInstall = stdenv.lib.optionalString (enableCmdlib != true) '' + moveToOutput lib/libdevmapper.so $lib + ''; + + passthru.tests.installer = nixosTests.installer.lvm; meta = with stdenv.lib; { homepage = "http://sourceware.org/lvm2/"; description = "Tools to support Logical Volume Management (LVM) on Linux"; platforms = platforms.linux; license = with licenses; [ gpl2 bsd2 lgpl21 ]; - maintainers = with maintainers; [raskin]; - inherit version; - downloadPage = "ftp://sources.redhat.com/pub/lvm2/"; + maintainers = with maintainers; [ raskin ajs124 ]; }; } diff --git a/pkgs/os-specific/linux/lvm2/default.upstream b/pkgs/os-specific/linux/lvm2/default.upstream deleted file mode 100644 index 1e5aaf5ab5c..00000000000 --- a/pkgs/os-specific/linux/lvm2/default.upstream +++ /dev/null @@ -1,4 +0,0 @@ -url ftp://sources.redhat.com/pub/lvm2/ -version_link '[.]tgz$' -version '.*[^0-9.][^.]*[.]([0-9.]+)[.].*' '\1' -do_overwrite () { do_overwrite_just_version; } diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 6cd260467f4..690c785a346 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -557,6 +557,7 @@ mapAliases ({ surf-webkit2 = surf; # added 2017-04-02 sup = throw "deprecated in 2019-09-10: abandoned by upstream"; system_config_printer = system-config-printer; # added 2016-01-03 + systemd_with_lvm2 = throw "obsolete, enabled by default via the lvm module"; # added 2020-07-12 systool = sysfsutils; # added 2018-04-25 tahoelafs = tahoe-lafs; # added 2018-03-26 tangogps = foxtrotgps; # added 2020-01-26 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4f007ffaba9..29d6ef654e5 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -16817,9 +16817,7 @@ in directvnc = callPackage ../os-specific/linux/directvnc { }; - dmraid = callPackage ../os-specific/linux/dmraid { - lvm2 = lvm2.override {enable_dmeventd = true;}; - }; + dmraid = callPackage ../os-specific/linux/dmraid { lvm2 = lvm2_dmeventd; }; drbd = callPackage ../os-specific/linux/drbd { }; @@ -17522,6 +17520,10 @@ in lsscsi = callPackage ../os-specific/linux/lsscsi { }; lvm2 = callPackage ../os-specific/linux/lvm2 { }; + lvm2_dmeventd = callPackage ../os-specific/linux/lvm2 { + enableDmeventd = true; + enableCmdlib = true; + }; mbpfan = callPackage ../os-specific/linux/mbpfan { }; @@ -17840,14 +17842,6 @@ in # standalone cryptsetup generator for systemd systemd-cryptsetup-generator = callPackage ../os-specific/linux/systemd/cryptsetup-generator.nix { }; - # In nixos, you can set systemd.package = pkgs.systemd_with_lvm2 to get - # LVM2 working in systemd. - systemd_with_lvm2 = pkgs.appendToName "with-lvm2" (pkgs.lib.overrideDerivation pkgs.systemd (p: { - postInstall = p.postInstall + '' - cp "${pkgs.lvm2}/lib/systemd/system-generators/"* $out/lib/systemd/system-generators - ''; - })); - systemd-wait = callPackage ../os-specific/linux/systemd-wait { }; sysvinit = callPackage ../os-specific/linux/sysvinit { };