Loading nixos/modules/system/etc/etc-activation.nix +4 −3 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ system.activationScripts.etc = lib.stringAfter [ "users" "groups" "specialfs" ] config.system.build.etcActivationCommands; } Loading Loading @@ -48,7 +49,7 @@ boot.initrd.systemd = { mounts = [ { where = "/run/etc-metadata"; where = "/run/nixos-etc-metadata"; what = "/etc-metadata-image"; type = "erofs"; options = "loop,ro"; Loading Loading @@ -83,7 +84,7 @@ "relatime" "redirect_dir=on" "metacopy=on" "lowerdir=/run/etc-metadata::/etc-basedir" "lowerdir=/run/nixos-etc-metadata::/etc-basedir" ] ++ lib.optionals config.system.etc.overlay.mutable [ "rw" Loading Loading @@ -113,7 +114,7 @@ unitConfig = { RequiresMountsFor = [ "/sysroot/nix/store" "/run/etc-metadata" "/run/nixos-etc-metadata" ]; DefaultDependencies = false; }; Loading nixos/modules/system/etc/etc.nix +78 −56 Original line number Diff line number Diff line Loading @@ -250,23 +250,44 @@ in ); in if config.system.etc.overlay.enable then #bash '' # This script atomically remounts /etc when switching configuration. On a (re-)boot # this should not run because /etc is mounted via a systemd mount unit # instead. To a large extent this mimics what composefs does. Because # This script atomically remounts /etc when switching configuration. # On a (re-)boot this should not run because /etc is mounted via a # systemd mount unit instead. # The activation script can also be called in cases where we didn't have # an initrd though, like for instance when using nixos-enter, # so we cannot assume that /etc has already been mounted. # # To a large extent this mimics what composefs does. Because # it's relatively simple, however, we avoid the composefs dependency. # Since this script is not idempotent, it should not run when etc hasn't # changed. if [[ ! $IN_NIXOS_SYSTEMD_STAGE1 ]] && [[ "${config.system.build.etc}/etc" != "$(readlink -f /run/current-system/etc)" ]]; then echo "remounting /etc..." tmpMetadataMount=$(mktemp --directory -t nixos-etc-metadata.XXXXXXXXXX) ${lib.optionalString config.system.etc.overlay.mutable '' # These directories are usually created in initrd, # but we need to create them here when we didn't we're called directly, # for instance by nixos-enter mkdir --parents /.rw-etc/upper /.rw-etc/work chmod --recursive 0755 /.rw-etc ''} tmpMetadataMount=$(TMPDIR="/run" mktemp --directory -t nixos-etc-metadata.XXXXXXXXXX) mount --type erofs -o ro ${config.system.build.etcMetadataImage} $tmpMetadataMount # There was no previous /etc mounted. This happens when we're called # directly without an initrd, like with nixos-enter. if ! mountpoint -q /etc; then mount --type overlay overlay \ --options lowerdir=$tmpMetadataMount::${config.system.build.etcBasedir},${etcOverlayOptions} \ /etc else # Mount the new /etc overlay to a temporary private mount. # This needs the indirection via a private bind mount because you # cannot move shared mounts. tmpEtcMount=$(mktemp --directory -t nixos-etc.XXXXXXXXXX) tmpEtcMount=$(TMPDIR="/run" mktemp --directory -t nixos-etc.XXXXXXXXXX) mount --bind --make-private $tmpEtcMount $tmpEtcMount mount --type overlay overlay \ --options lowerdir=$tmpMetadataMount::${config.system.build.etcBasedir},${etcOverlayOptions} \ Loading Loading @@ -313,15 +334,16 @@ in # Unmount the temporary mount umount --lazy "$tmpEtcMount" rmdir "$tmpEtcMount" fi # Unmount old metadata mounts # For some reason, `findmnt /tmp --submounts` does not show the nested # mounts. So we'll just find all mounts of type erofs and filter on the # name of the mountpoint. findmnt --type erofs --list --kernel --output TARGET | while read -r mountPoint; do if [[ "$mountPoint" =~ ^/tmp/nixos-etc-metadata\..{10}$ && if [[ ("$mountPoint" =~ ^/run/nixos-etc-metadata\..{10}$ || "$mountPoint" =~ ^/run/nixos-etc-metadata$ ) && "$mountPoint" != "$tmpMetadataMount" ]]; then umount --lazy $mountPoint umount --lazy "$mountPoint" rmdir "$mountPoint" fi done Loading nixos/tests/activation/etc-overlay-immutable.nix +10 −6 Original line number Diff line number Diff line Loading @@ -39,8 +39,8 @@ '' newergen = machine.succeed("realpath /run/current-system/specialisation/newer-generation/bin/switch-to-configuration").rstrip() with subtest("/run/etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/etc-metadata")) with subtest("/run/nixos-etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/nixos-etc-metadata")) with subtest("No temporary files leaked into stage 2"): machine.succeed("[ ! -e /etc-metadata-image ]") Loading Loading @@ -91,10 +91,14 @@ machine.succeed(f"{newergen} switch") tmpMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc\\..*' | wc -l").rstrip() metaMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc-metadata\\..*' | wc -l").rstrip() tmpMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc\\..*'").rstrip() print(tmpMounts) metaMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc-metadata.*'").rstrip() print(metaMounts) assert tmpMounts == "0", f"Found {tmpMounts} remaining tmpmounts" assert metaMounts == "1", f"Found {metaMounts} remaining metamounts" numOfTmpMounts = len(tmpMounts.splitlines()) numOfMetaMounts = len(metaMounts.splitlines()) assert numOfTmpMounts == 0, f"Found {numOfTmpMounts} remaining tmpmounts" assert numOfMetaMounts == 1, f"Found {numOfMetaMounts} remaining metamounts" ''; } nixos/tests/activation/etc-overlay-mutable.nix +10 −6 Original line number Diff line number Diff line Loading @@ -27,8 +27,8 @@ '' newergen = machine.succeed("realpath /run/current-system/specialisation/newer-generation/bin/switch-to-configuration").rstrip() with subtest("/run/etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/etc-metadata")) with subtest("/run/nixos-etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/nixos-etc-metadata")) with subtest("No temporary files leaked into stage 2"): machine.succeed("[ ! -e /etc-metadata-image ]") Loading Loading @@ -68,10 +68,14 @@ machine.succeed(f"{newergen} switch") assert machine.succeed("cat /etc/newergen") == "newergen" tmpMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc\\..*' | wc -l").rstrip() metaMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc-metadata\\..*' | wc -l").rstrip() tmpMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc\\..*'").rstrip() print(tmpMounts) metaMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc-metadata.*'").rstrip() print(metaMounts) assert tmpMounts == "0", f"Found {tmpMounts} remaining tmpmounts" assert metaMounts == "1", f"Found {metaMounts} remaining metamounts" numOfTmpMounts = len(tmpMounts.splitlines()) numOfMetaMounts = len(metaMounts.splitlines()) assert numOfTmpMounts == 0, f"Found {numOfTmpMounts} remaining tmpmounts" assert numOfMetaMounts == 1, f"Found {numOfMetaMounts} remaining metamounts" ''; } pkgs/by-name/ni/nixos-enter/nixos-enter.sh +3 −2 Original line number Diff line number Diff line Loading @@ -58,10 +58,11 @@ if [[ ! -e $mountPoint/etc/NIXOS ]]; then exit 126 fi mkdir -p "$mountPoint/dev" "$mountPoint/sys" chmod 0755 "$mountPoint/dev" "$mountPoint/sys" mkdir -p "$mountPoint/dev" "$mountPoint/sys" "$mountPoint/proc" chmod 0755 "$mountPoint/dev" "$mountPoint/sys" "$mountPoint/proc" mount --rbind /dev "$mountPoint/dev" mount --rbind /sys "$mountPoint/sys" mount --rbind /proc "$mountPoint/proc" # modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52 chroot_add_resolv_conf() { Loading Loading
nixos/modules/system/etc/etc-activation.nix +4 −3 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ system.activationScripts.etc = lib.stringAfter [ "users" "groups" "specialfs" ] config.system.build.etcActivationCommands; } Loading Loading @@ -48,7 +49,7 @@ boot.initrd.systemd = { mounts = [ { where = "/run/etc-metadata"; where = "/run/nixos-etc-metadata"; what = "/etc-metadata-image"; type = "erofs"; options = "loop,ro"; Loading Loading @@ -83,7 +84,7 @@ "relatime" "redirect_dir=on" "metacopy=on" "lowerdir=/run/etc-metadata::/etc-basedir" "lowerdir=/run/nixos-etc-metadata::/etc-basedir" ] ++ lib.optionals config.system.etc.overlay.mutable [ "rw" Loading Loading @@ -113,7 +114,7 @@ unitConfig = { RequiresMountsFor = [ "/sysroot/nix/store" "/run/etc-metadata" "/run/nixos-etc-metadata" ]; DefaultDependencies = false; }; Loading
nixos/modules/system/etc/etc.nix +78 −56 Original line number Diff line number Diff line Loading @@ -250,23 +250,44 @@ in ); in if config.system.etc.overlay.enable then #bash '' # This script atomically remounts /etc when switching configuration. On a (re-)boot # this should not run because /etc is mounted via a systemd mount unit # instead. To a large extent this mimics what composefs does. Because # This script atomically remounts /etc when switching configuration. # On a (re-)boot this should not run because /etc is mounted via a # systemd mount unit instead. # The activation script can also be called in cases where we didn't have # an initrd though, like for instance when using nixos-enter, # so we cannot assume that /etc has already been mounted. # # To a large extent this mimics what composefs does. Because # it's relatively simple, however, we avoid the composefs dependency. # Since this script is not idempotent, it should not run when etc hasn't # changed. if [[ ! $IN_NIXOS_SYSTEMD_STAGE1 ]] && [[ "${config.system.build.etc}/etc" != "$(readlink -f /run/current-system/etc)" ]]; then echo "remounting /etc..." tmpMetadataMount=$(mktemp --directory -t nixos-etc-metadata.XXXXXXXXXX) ${lib.optionalString config.system.etc.overlay.mutable '' # These directories are usually created in initrd, # but we need to create them here when we didn't we're called directly, # for instance by nixos-enter mkdir --parents /.rw-etc/upper /.rw-etc/work chmod --recursive 0755 /.rw-etc ''} tmpMetadataMount=$(TMPDIR="/run" mktemp --directory -t nixos-etc-metadata.XXXXXXXXXX) mount --type erofs -o ro ${config.system.build.etcMetadataImage} $tmpMetadataMount # There was no previous /etc mounted. This happens when we're called # directly without an initrd, like with nixos-enter. if ! mountpoint -q /etc; then mount --type overlay overlay \ --options lowerdir=$tmpMetadataMount::${config.system.build.etcBasedir},${etcOverlayOptions} \ /etc else # Mount the new /etc overlay to a temporary private mount. # This needs the indirection via a private bind mount because you # cannot move shared mounts. tmpEtcMount=$(mktemp --directory -t nixos-etc.XXXXXXXXXX) tmpEtcMount=$(TMPDIR="/run" mktemp --directory -t nixos-etc.XXXXXXXXXX) mount --bind --make-private $tmpEtcMount $tmpEtcMount mount --type overlay overlay \ --options lowerdir=$tmpMetadataMount::${config.system.build.etcBasedir},${etcOverlayOptions} \ Loading Loading @@ -313,15 +334,16 @@ in # Unmount the temporary mount umount --lazy "$tmpEtcMount" rmdir "$tmpEtcMount" fi # Unmount old metadata mounts # For some reason, `findmnt /tmp --submounts` does not show the nested # mounts. So we'll just find all mounts of type erofs and filter on the # name of the mountpoint. findmnt --type erofs --list --kernel --output TARGET | while read -r mountPoint; do if [[ "$mountPoint" =~ ^/tmp/nixos-etc-metadata\..{10}$ && if [[ ("$mountPoint" =~ ^/run/nixos-etc-metadata\..{10}$ || "$mountPoint" =~ ^/run/nixos-etc-metadata$ ) && "$mountPoint" != "$tmpMetadataMount" ]]; then umount --lazy $mountPoint umount --lazy "$mountPoint" rmdir "$mountPoint" fi done Loading
nixos/tests/activation/etc-overlay-immutable.nix +10 −6 Original line number Diff line number Diff line Loading @@ -39,8 +39,8 @@ '' newergen = machine.succeed("realpath /run/current-system/specialisation/newer-generation/bin/switch-to-configuration").rstrip() with subtest("/run/etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/etc-metadata")) with subtest("/run/nixos-etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/nixos-etc-metadata")) with subtest("No temporary files leaked into stage 2"): machine.succeed("[ ! -e /etc-metadata-image ]") Loading Loading @@ -91,10 +91,14 @@ machine.succeed(f"{newergen} switch") tmpMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc\\..*' | wc -l").rstrip() metaMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc-metadata\\..*' | wc -l").rstrip() tmpMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc\\..*'").rstrip() print(tmpMounts) metaMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc-metadata.*'").rstrip() print(metaMounts) assert tmpMounts == "0", f"Found {tmpMounts} remaining tmpmounts" assert metaMounts == "1", f"Found {metaMounts} remaining metamounts" numOfTmpMounts = len(tmpMounts.splitlines()) numOfMetaMounts = len(metaMounts.splitlines()) assert numOfTmpMounts == 0, f"Found {numOfTmpMounts} remaining tmpmounts" assert numOfMetaMounts == 1, f"Found {numOfMetaMounts} remaining metamounts" ''; }
nixos/tests/activation/etc-overlay-mutable.nix +10 −6 Original line number Diff line number Diff line Loading @@ -27,8 +27,8 @@ '' newergen = machine.succeed("realpath /run/current-system/specialisation/newer-generation/bin/switch-to-configuration").rstrip() with subtest("/run/etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/etc-metadata")) with subtest("/run/nixos-etc-metadata/ is mounted"): print(machine.succeed("mountpoint /run/nixos-etc-metadata")) with subtest("No temporary files leaked into stage 2"): machine.succeed("[ ! -e /etc-metadata-image ]") Loading Loading @@ -68,10 +68,14 @@ machine.succeed(f"{newergen} switch") assert machine.succeed("cat /etc/newergen") == "newergen" tmpMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc\\..*' | wc -l").rstrip() metaMounts = machine.succeed("find /tmp -maxdepth 1 -type d -regex '/tmp/nixos-etc-metadata\\..*' | wc -l").rstrip() tmpMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc\\..*'").rstrip() print(tmpMounts) metaMounts = machine.succeed("find /run -maxdepth 1 -type d -regex '/run/nixos-etc-metadata.*'").rstrip() print(metaMounts) assert tmpMounts == "0", f"Found {tmpMounts} remaining tmpmounts" assert metaMounts == "1", f"Found {metaMounts} remaining metamounts" numOfTmpMounts = len(tmpMounts.splitlines()) numOfMetaMounts = len(metaMounts.splitlines()) assert numOfTmpMounts == 0, f"Found {numOfTmpMounts} remaining tmpmounts" assert numOfMetaMounts == 1, f"Found {numOfMetaMounts} remaining metamounts" ''; }
pkgs/by-name/ni/nixos-enter/nixos-enter.sh +3 −2 Original line number Diff line number Diff line Loading @@ -58,10 +58,11 @@ if [[ ! -e $mountPoint/etc/NIXOS ]]; then exit 126 fi mkdir -p "$mountPoint/dev" "$mountPoint/sys" chmod 0755 "$mountPoint/dev" "$mountPoint/sys" mkdir -p "$mountPoint/dev" "$mountPoint/sys" "$mountPoint/proc" chmod 0755 "$mountPoint/dev" "$mountPoint/sys" "$mountPoint/proc" mount --rbind /dev "$mountPoint/dev" mount --rbind /sys "$mountPoint/sys" mount --rbind /proc "$mountPoint/proc" # modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52 chroot_add_resolv_conf() { Loading