diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index f72342429a6d..a429cd40c761 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -114,6 +114,28 @@ waitDevice() { done } +# Create the mount point if required. +makeMountPoint() { + local device="$1" + local mountPoint="$2" + local options="$3" + + local IFS=, + + # If we're bind mounting a file, the mount point should also be a file. + if ! [ -d "$device" ]; then + for opt in $options; do + if [ "$opt" = bind ] || [ "$opt" = rbind ]; then + mkdir -p "$(dirname "/mnt-root$mountPoint")" + touch "/mnt-root$mountPoint" + return + fi + done + fi + + mkdir -m 0755 -p "/mnt-root$mountPoint" +} + # Mount special file systems. specialMount() { local device="$1" @@ -400,7 +422,7 @@ mountFS() { info "mounting $device on $mountPoint..." - mkdir -p "/mnt-root$mountPoint" + makeMountPoint "$device" "$mountPoint" "$optionsPrefixed" # For ZFS and CIFS mounts, retry a few times before giving up. # We do this for ZFS as a workaround for issue NixOS/nixpkgs#25383. diff --git a/nixos/tests/non-default-filesystems.nix b/nixos/tests/non-default-filesystems.nix index 03cc5bf709a4..6233e8d265d0 100644 --- a/nixos/tests/non-default-filesystems.nix +++ b/nixos/tests/non-default-filesystems.nix @@ -6,6 +6,31 @@ with import ../lib/testing-python.nix { inherit system pkgs; }; with pkgs.lib; { + bind = makeTest { + name = "non-default-filesystem-bind"; + + nodes.machine = { ... }: { + virtualisation.writableStore = false; + + virtualisation.fileSystems."/test-bind-dir/bind" = { + device = "/"; + neededForBoot = true; + options = [ "bind" ]; + }; + + virtualisation.fileSystems."/test-bind-file/bind" = { + depends = [ "/nix/store" ]; + device = builtins.toFile "empty" ""; + neededForBoot = true; + options = [ "bind" ]; + }; + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + ''; + }; + btrfs = makeTest { name = "non-default-filesystems-btrfs";