diff options
Diffstat (limited to 'nixos/modules/system/boot')
-rw-r--r-- | nixos/modules/system/boot/loader/grub/grub.nix | 17 | ||||
-rw-r--r-- | nixos/modules/system/boot/loader/grub/install-grub.pl | 15 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-1-init.sh | 26 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-1.nix | 32 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-2-init.sh | 36 | ||||
-rw-r--r-- | nixos/modules/system/boot/stage-2.nix | 3 | ||||
-rw-r--r-- | nixos/modules/system/boot/systemd-unit-options.nix | 2 |
7 files changed, 61 insertions, 70 deletions
diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index 0640ec306e18..61c34cc2f034 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -341,7 +341,7 @@ in default = false; type = types.bool; description = '' - Whether GRUB should be build against libzfs. + Whether GRUB should be built against libzfs. ZFS support is only available for GRUB v2. This option is ignored for GRUB v1. ''; @@ -351,7 +351,7 @@ in default = false; type = types.bool; description = '' - Whether GRUB should be build with EFI support. + Whether GRUB should be built with EFI support. EFI support is only available for GRUB v2. This option is ignored for GRUB v1. ''; @@ -425,13 +425,20 @@ in { path = "/boot"; inherit (cfg) devices; inherit (efi) efiSysMountPoint; } ]; - system.build.installBootLoader = pkgs.writeScript "install-grub.sh" ('' + system.build.installBootLoader = + let + install-grub-pl = pkgs.substituteAll { + src = ./install-grub.pl; + inherit (pkgs) utillinux; + btrfsprogs = pkgs.btrfs-progs; + }; + in pkgs.writeScript "install-grub.sh" ('' #!${pkgs.stdenv.shell} set -e export PERL5LIB=${makePerlPath (with pkgs.perlPackages; [ FileSlurp XMLLibXML XMLSAX ListCompare ])} ${optionalString cfg.enableCryptodisk "export GRUB_ENABLE_CRYPTODISK=y"} '' + flip concatMapStrings cfg.mirroredBoots (args: '' - ${pkgs.perl}/bin/perl ${./install-grub.pl} ${grubConfig args} $@ + ${pkgs.perl}/bin/perl ${install-grub-pl} ${grubConfig args} $@ '')); system.build.grub = grub; @@ -500,7 +507,7 @@ in imports = - [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ]) + [ (mkRemovedOptionModule [ "boot" "loader" "grub" "bootDevice" ] "") (mkRenamedOptionModule [ "boot" "copyKernels" ] [ "boot" "loader" "grub" "copyKernels" ]) (mkRenamedOptionModule [ "boot" "extraGrubEntries" ] [ "boot" "loader" "grub" "extraEntries" ]) (mkRenamedOptionModule [ "boot" "extraGrubEntriesBeforeNixos" ] [ "boot" "loader" "grub" "extraEntriesBeforeNixOS" ]) diff --git a/nixos/modules/system/boot/loader/grub/install-grub.pl b/nixos/modules/system/boot/loader/grub/install-grub.pl index 4fa157641a4a..06eece5025f8 100644 --- a/nixos/modules/system/boot/loader/grub/install-grub.pl +++ b/nixos/modules/system/boot/loader/grub/install-grub.pl @@ -12,8 +12,10 @@ require List::Compare; use POSIX; use Cwd; +# system.build.toplevel path my $defaultConfig = $ARGV[1] or die; +# Grub config XML generated by grubConfig function in grub.nix my $dom = XML::LibXML->load_xml(location => $ARGV[0]); sub get { my ($name) = @_; return $dom->findvalue("/expr/attrs/attr[\@name = '$name']/*/\@value"); } @@ -97,6 +99,8 @@ sub PathInMount { } return 1; } + +# Figure out what filesystem is used for the directory with init/initrd/kernel files sub GetFs { my ($dir) = @_; my $bestFs = Fs->new(device => "", type => "", mount => ""); @@ -136,7 +140,10 @@ my $driveid = 1; sub GrubFs { my ($dir) = @_; my $fs = GetFs($dir); - my $path = "/" . substr($dir, length($fs->mount)); + my $path = substr($dir, length($fs->mount)); + if (substr($path, 0, 1) ne "/") { + $path = "/$path"; + } my $search = ""; if ($grubVersion > 1) { @@ -169,7 +176,7 @@ sub GrubFs { $search = $types{$fsIdentifier} . ' '; # Based on the type pull in the identifier from the system - my ($status, @devInfo) = runCommand("blkid -o export @{[$fs->device]}"); + my ($status, @devInfo) = runCommand("@utillinux@/bin/blkid -o export @{[$fs->device]}"); if ($status != 0) { die "Failed to get blkid info for @{[$fs->mount]} on @{[$fs->device]}"; } @@ -182,7 +189,7 @@ sub GrubFs { # BTRFS is a special case in that we need to fix the referrenced path based on subvolumes if ($fs->type eq 'btrfs') { - my ($status, @id_info) = runCommand("btrfs subvol show @{[$fs->mount]}"); + my ($status, @id_info) = runCommand("@btrfsprogs@/bin/btrfs subvol show @{[$fs->mount]}"); if ($status != 0) { die "Failed to retrieve subvolume info for @{[$fs->mount]}\n"; } @@ -190,7 +197,7 @@ sub GrubFs { if ($#ids > 0) { die "Btrfs subvol name for @{[$fs->device]} listed multiple times in mount\n" } elsif ($#ids == 0) { - my ($status, @path_info) = runCommand("btrfs subvol list @{[$fs->mount]}"); + my ($status, @path_info) = runCommand("@btrfsprogs@/bin/btrfs subvol list @{[$fs->mount]}"); if ($status != 0) { die "Failed to find @{[$fs->mount]} subvolume id from btrfs\n"; } diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh index 65d1dcb61681..abab5f20baac 100644 --- a/nixos/modules/system/boot/stage-1-init.sh +++ b/nixos/modules/system/boot/stage-1-init.sh @@ -59,22 +59,24 @@ echo echo "[1;32m<<< NixOS Stage 1 >>>[0m" echo - -# Mount special file systems. +# Make several required directories. mkdir -p /etc/udev touch /etc/fstab # to shut up mount -touch /etc/mtab # to shut up mke2fs +ln -s /proc/mounts /etc/mtab # to shut up mke2fs touch /etc/udev/hwdb.bin # to shut up udev touch /etc/initrd-release -mkdir -p /proc -mount -t proc proc /proc -mkdir -p /sys -mount -t sysfs sysfs /sys -mount -t devtmpfs -o "size=@devSize@" devtmpfs /dev -mkdir -p /run -mount -t tmpfs -o "mode=0755,size=@runSize@" tmpfs /run -mkdir /dev/pts -mount -t devpts devpts /dev/pts + +# Mount special file systems. +specialMount() { + local device="$1" + local mountPoint="$2" + local options="$3" + local fsType="$4" + + mkdir -m 0755 -p "$mountPoint" + mount -n -t "$fsType" -o "$options" "$device" "$mountPoint" +} +source @earlyMountScript@ # Log the script output to /dev/kmsg or /run/log/stage-1-init.log. mkdir -p /tmp diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix index 9be7ad4ae077..513c121347b1 100644 --- a/nixos/modules/system/boot/stage-1.nix +++ b/nixos/modules/system/boot/stage-1.nix @@ -3,7 +3,7 @@ # the modules necessary to mount the root file system, then calls the # init in the root file system to start the second boot stage. -{ config, lib, pkgs, ... }: +{ config, lib, utils, pkgs, ... }: with lib; @@ -23,6 +23,12 @@ let }; + # The initrd only has to mount `/` or any FS marked as necessary for + # booting (such as the FS containing `/nix/store`, or an FS needed for + # mounting `/`, like `/` on a loopback). + fileSystems = filter utils.fsNeededForBoot config.system.build.fileSystems; + + # Some additional utilities needed in stage 1, like mount, lvm, fsck # etc. We don't want to bring in all of those packages, so we just # copy what we need. Instead of using statically linked binaries, @@ -71,7 +77,7 @@ let ln -sf kmod $out/bin/modprobe # Copy resize2fs if needed. - ${optionalString (any (fs: fs.autoResize) (attrValues config.fileSystems)) '' + ${optionalString (any (fs: fs.autoResize) fileSystems) '' # We need mke2fs in the initrd. copy_bin_and_libs ${pkgs.e2fsprogs}/sbin/resize2fs ''} @@ -128,21 +134,6 @@ let ''; # */ - # The initrd only has to mount / or any FS marked as necessary for - # booting (such as the FS containing /nix/store, or an FS needed for - # mounting /, like / on a loopback). - # - # We need to guarantee that / is the first filesystem in the list so - # that if and when lustrateRoot is invoked, nothing else is mounted - fileSystems = let - filterNeeded = filter - (fs: fs.mountPoint != "/" && (fs.neededForBoot || elem fs.mountPoint [ "/nix" "/nix/store" "/var" "/var/log" "/var/lib" "/etc" ])); - filterRoot = filter - (fs: fs.mountPoint == "/"); - allFileSystems = attrValues config.fileSystems; - in (filterRoot allFileSystems) ++ (filterNeeded allFileSystems); - - udevRules = pkgs.stdenv.mkDerivation { name = "udev-rules"; allowedReferences = [ extraUtils ]; @@ -199,7 +190,9 @@ let inherit udevRules extraUtils modulesClosure; - inherit (config.boot) resumeDevice devSize runSize; + inherit (config.boot) resumeDevice; + + inherit (config.system.build) earlyMountScript; inherit (config.boot.initrd) checkJournalingFS preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules; @@ -405,9 +398,8 @@ in }; config = mkIf (!config.boot.isContainer) { - assertions = [ - { assertion = any (fs: fs.mountPoint == "/") (attrValues config.fileSystems); + { assertion = any (fs: fs.mountPoint == "/") fileSystems; message = "The ‘fileSystems’ option does not specify your root file system."; } { assertion = let inherit (config.boot) resumeDevice; in diff --git a/nixos/modules/system/boot/stage-2-init.sh b/nixos/modules/system/boot/stage-2-init.sh index c5a14f0766d5..704150e77d72 100644 --- a/nixos/modules/system/boot/stage-2-init.sh +++ b/nixos/modules/system/boot/stage-2-init.sh @@ -37,12 +37,16 @@ fi # Likewise, stage 1 mounts /proc, /dev and /sys, so if we don't have a # stage 1, we need to do that here. if [ ! -e /proc/1 ]; then - mkdir -m 0755 -p /proc - mount -n -t proc proc /proc - mkdir -m 0755 -p /dev - mount -t devtmpfs devtmpfs /dev - mkdir -m 0755 -p /sys - mount -t sysfs sysfs /sys + specialMount() { + local device="$1" + local mountPoint="$2" + local options="$3" + local fsType="$4" + + mkdir -m 0755 -p "$mountPoint" + mount -n -t "$fsType" -o "$options" "$device" "$mountPoint" + } + source @earlyMountScript@ fi @@ -87,11 +91,6 @@ done # More special file systems, initialise required directories. -if ! mountpoint -q /dev/shm; then - mkdir -m 0755 /dev/shm - mount -t tmpfs -o "rw,nosuid,nodev,size=@devShmSize@" tmpfs /dev/shm -fi -mkdir -m 0755 -p /dev/pts [ -e /proc/bus/usb ] && mount -t usbfs usbfs /proc/bus/usb # UML doesn't have USB by default mkdir -m 01777 -p /tmp mkdir -m 0755 -p /var /var/log /var/lib /var/db @@ -112,14 +111,6 @@ rm -f /etc/{group,passwd,shadow}.lock rm -rf /nix/var/nix/gcroots/tmp /nix/var/nix/temproots -# Create a tmpfs on /run to hold runtime state for programs such as -# udev (if stage 1 hasn't already done so). -if ! mountpoint -q /run; then - rm -rf /run - mkdir -m 0755 -p /run - mount -t tmpfs -o "mode=0755,size=@runSize@" tmpfs /run -fi - # Create a ramfs on /run/keys to hold secrets that shouldn't be # written to disk (generally used for NixOps, harmless elsewhere). if ! mountpoint -q /run/keys; then @@ -150,13 +141,6 @@ if [ -n "@useHostResolvConf@" -a -e /etc/resolv.conf ]; then cat /etc/resolv.conf | resolvconf -m 1000 -a host fi - -# Create /var/setuid-wrappers as a tmpfs. -rm -rf /var/setuid-wrappers -mkdir -m 0755 -p /var/setuid-wrappers -mount -t tmpfs -o "mode=0755" tmpfs /var/setuid-wrappers - - # Log the script output to /dev/kmsg or /run/log/stage-2-init.log. # Only at this point are all the necessary prerequisites ready for these commands. exec {logOutFd}>&1 {logErrFd}>&2 diff --git a/nixos/modules/system/boot/stage-2.nix b/nixos/modules/system/boot/stage-2.nix index b67f42a017e6..7e4ec2a4a670 100644 --- a/nixos/modules/system/boot/stage-2.nix +++ b/nixos/modules/system/boot/stage-2.nix @@ -20,10 +20,9 @@ let src = ./stage-2-init.sh; shellDebug = "${pkgs.bashInteractive}/bin/bash"; isExecutable = true; - inherit (config.boot) devShmSize runSize; inherit (config.nix) readOnlyStore; inherit (config.networking) useHostResolvConf; - ttyGid = config.ids.gids.tty; + inherit (config.system.build) earlyMountScript; path = [ pkgs.coreutils pkgs.utillinux diff --git a/nixos/modules/system/boot/systemd-unit-options.nix b/nixos/modules/system/boot/systemd-unit-options.nix index f2a22e4ada8a..f4892244de47 100644 --- a/nixos/modules/system/boot/systemd-unit-options.nix +++ b/nixos/modules/system/boot/systemd-unit-options.nix @@ -309,7 +309,7 @@ in rec { }; startAt = mkOption { - type = types.str; + type = with types; either str (listOf str); default = ""; example = "Sun 14:00:00"; description = '' |