Change:
Describe the bug Shell script has hardcoded paths to required tools like , and . Those paths ( in these cases) do not exist on NixOS. To Reproduce a non-critical drive, e.g. a USB stick. to unmount and deactivate (from lvm, dm, md, vdo layers) it. Expected behavior Device should be unmounted and unmapped, leaving only the block device. It should no longer be mounted or participate in software RAID etc. Screenshots Additional context This script failing could cause problems with e.g. shutdowns on systems with software RAID. Notify maintainers Metadata system: host os: multi-user?: sandbox: version: nixpkgs: Maintainer information: Sorry, my first bug report and I don't know what to fill in here.
We could just replace them with the proper store paths during the build, but that lead to closure bloat to a dependency cycle/infinite recursion when pulling in (not ) or
I'm guessing the purpose of the hardcoded paths is to avoid searching drives it may have already deactivated. Some of them are tested for and optional, including mdadm, vdo, multipathd and lvm. Perhaps they could check the path or use /run/current-system/sw/bin? mountpoint, umount, findmnt, lsblk and sort aren't tested for. Are those acceptable as dependencies? They appear to be in util-linux and coreutils. I am unfamiliar with the intricacies of how a weak dependency or alternatives could be handled in Nix, and not sure when it's critical that this script in particular not use the search path.
It should already find , since that's the same store path and it tries to find it in "". The problem with just adding into the search path is that that's impure. It relies on how NixOS works and while and are most likely in there (on NixOS), they're not guaranteed to be.
It's not clear to me where the loop comes from. It seems to me could depend on and without damage (though if the bloat of pulling in non-minimal packages is too much, one could spin off ; Debian has it in the package, for instance). For the others, I guess it's more complicated and would involve something like a use flag. I didn't find , but and don't seem to depend on , so they wouldn't loop (at first glance). As a side note, I consider it a distinct bug that the script fails to take its failure into account; this would typically be handled by . At the moment, it's a tool that doesn't work unless run in an FHS environment, but it appears nothing (except me, planning to make a disk management tool) tried to use it, so perhaps it's not as severe as I first thought.
There's a dependency cycle for , because depends (optionally, but on by default) on , (opt. but default) on and depends on . depends on (because it needs blkid), therefore creating the same dependency cycle.
We could maybe split this script into a separate package or output. It's not packages yet, AFAIK. :+1: although I'd say that's an upstream issue. There is a systemd service () which invokes it, but that's probably not used by anyone.
I marked this as stale due to inactivity. &rarr;
I think it's fine for an ad-hoc script that users run to pick things from $PATH - at least if we're talking about certain tools that should be available in a default system. Similarly, we also invoke from (or ) instead of hardcoding it to the systemd package.
Probably. AFAIR the problem is that the script hardcodes and though. Feel free to review my attempt at fixing this in

Discussion:
, fetchurl , pkg-config , util-linux <ins> , coreutils </ins> , libuuid , libaio <ins> , substituteAll </ins> , enableCmdlib ? false , enableDmeventd ? false , udevSupport ? !stdenv.hostPlatform.isStatic, udev ? null , onlyLib ? stdenv.hostPlatform.isStatic , enableVDO ? false, vdo ? null <ins> , enableMdadm ? false, mdadm ? null , enableMultipath ? false, multipath-tools ? null </ins> , nixosTests }:

substituteInPlace make.tmpl.in --replace "@systemdsystemunitdir@" "$out/lib/systemd/system" '' + lib.optionalString (lib.versionAtLeast version "2.03") '' substituteInPlace libdm/make.tmpl.in --replace "@systemdsystemunitdir@" "$out/lib/systemd/system" <ins> substituteInPlace scripts/blk_availability_systemd_red_hat.service.in  --replace '/usr/bin/true' '${coreutils}/bin/true' </ins> ''; postConfigure = '' sed -i 's|^#define LVM_CONFIGURE_LINE.*$|#define LVM_CONFIGURE_LINE "<removed>"|g' ./include/configure.h ''; <del> patches = lib.optionals (lib.versionOlder version "2.03.15") [ </del> <ins> patches = [ # fixes paths to and checks for tools (substituteAll (let optionalTool = cond: pkg: if cond then pkg else "/run/current-system/sw"; in { src = ./fix-blkdeactivate.patch; inherit coreutils; util_linux = util-linux; mdadm = optionalTool enableMdadm mdadm; multipath_tools = optionalTool enableMultipath multipath-tools; vdo = optionalTool enableVDO vdo; })) ] ++ lib.optionals (lib.versionOlder version "2.03.15") [ </ins> # Musl fixes from Alpine. ./fix-stdio-usage.patch (fetchpatch {

<ins> diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in index 7c517b87b..e51a33778 100644 --- a/scripts/blkdeactivate.sh.in +++ b/scripts/blkdeactivate.sh.in @@ -34,11 +34,11 @@ TOOL=blkdeactivate DEV_DIR="/dev" SYS_BLK_DIR="/sys/block" -MDADM="/sbin/mdadm" -MOUNTPOINT="/bin/mountpoint" -MPATHD="/sbin/multipathd" -UMOUNT="/bin/umount" -VDO="/bin/vdo" +MDADM="@mdadm@/bin/mdadm" +MOUNTPOINT="@util_linux@/bin/mountpoint" +MPATHD="@multipath_tools@/bin/multipathd" +UMOUNT="@util_linux@/bin/umount" +VDO="@vdo@/bin/vdo" sbindir="@SBINDIR@" DMSETUP="$sbindir/dmsetup" @@ -48,7 +48,7 @@ if "$UMOUNT" --help | grep -- "--all-targets" >"$DEV_DIR/null"; then UMOUNT_OPTS="--all-targets " else UMOUNT_OPTS="" -	FINDMNT="/bin/findmnt -r --noheadings -u -o TARGET" +	FINDMNT="@util_linux@/bin/findmnt -r --noheadings -u -o TARGET" FINDMNT_READ="read -r mnt" fi DMSETUP_OPTS="" @@ -57,10 +57,10 @@ MDADM_OPTS="" MPATHD_OPTS="" VDO_OPTS="" -LSBLK="/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT" +LSBLK="@util_linux@/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT" LSBLK_VARS="local devtype local kname local name local mnt" LSBLK_READ="read -r devtype kname name mnt" -SORT_MNT="/bin/sort -r -u -k 4" +SORT_MNT="@coreutils@/bin/sort -r -u -k 4" # Do not show tool errors by default (only done/skipping summary # message provided by this script) and no verbose mode by default. @@ -102,6 +102,7 @@ declare -A SKIP_VG_LIST=() # (list is an associative array!) # declare -A SKIP_UMOUNT_LIST=(["/"]=1  +                             ["/nix"]=1 ["/nix/store"]=1  ["/lib"]=1 ["/lib64"]=1  ["/bin"]=1 ["/sbin"]=1  ["/var"]=1 ["/var/log"]=1  </ins>

# which depends on lvm2 again.  But we only need the libudev part # which does not depend on cryptsetup. udev = systemdMinimal; <ins> # break the cyclic dependency: # util-linux (non-minimal) depends (optionally, but on by default) on systemd, # systemd (optionally, but on by default) on cryptsetup and cryptsetup depends on lvm2 util-linux = util-linuxMinimal; </ins> }; lvm2-2_02 = callPackage ../os-specific/linux/lvm2/2_02.nix { udev = systemdMinimal;