about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-05-26 13:26:48 +0000
committerAlyssa Ross <hi@alyssa.is>2023-05-26 13:26:48 +0000
commita92bc576b12c47e5f4e765b3ff9ee3545905ebbc (patch)
tree26213cadcb14839d8233d0461fd7d8d6ffe5dbf5
parentf91ee3065de91a3531329a674a45ddcb3467a650 (diff)
nixos/stage-1: support bind mounts of files
On my system, / is tmpfs, and /etc/machine-id is bind mounted from
/persist.
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh24
-rw-r--r--nixos/tests/non-default-filesystems.nix25
2 files changed, 48 insertions, 1 deletions
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index f72342429a6d9..a429cd40c7611 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 03cc5bf709a48..6233e8d265d0f 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";