diff --git a/test/boot-stage-1-init.sh b/test/boot-stage-1-init.sh index a2e958d91f6..1299599a94e 100644 --- a/test/boot-stage-1-init.sh +++ b/test/boot-stage-1-init.sh @@ -6,11 +6,13 @@ fail() { exec @shell@ } + # Print a greeting. echo echo "<<< NixOS Stage 1 >>>" echo + # Set the PATH. export PATH=/empty for i in @path@; do @@ -20,6 +22,7 @@ for i in @path@; do fi done + # Mount special file systems. mkdir /etc # to shut up mount touch /etc/fstab # idem @@ -28,52 +31,68 @@ mount -t proc none /proc mkdir /sys mount -t sysfs none /sys + # Create device nodes in /dev. source @makeDevices@ + # Load some kernel modules. export MODULE_DIR=@modules@/lib/modules/ modprobe ide-generic modprobe ide-disk modprobe ide-cd -# Try to find and mount the installation CD. -# Mount the installation CD. +# Try to find and mount the root device. mkdir /mnt -mkdir /mnt/cdrom +mkdir /mnt/root -echo "probing for the NixOS installation CD..." +echo "mounting the root device..." -for i in /sys/devices/*/*/media; do - if test "$(cat $i)" = "cdrom"; then +if test -n "@autoDetectRootDevice@"; then - # Hopefully `drivename' matches the device created in /dev. - devName=/dev/$(cat $(dirname $i)/drivename) + # Look for the root device by label. + echo "probing for the NixOS installation CD..." - echo " in $devName..." + for i in /sys/devices/*/*/media; do + if test "$(cat $i)" = "cdrom"; then - if mount -o ro -t iso9660 $devName /mnt/cdrom; then - if test -e "/mnt/cdrom/@cdromLabel@"; then - found=1 - break + # Hopefully `drivename' matches the device created in /dev. + devName=/dev/$(cat $(dirname $i)/drivename) + + echo " in $devName..." + + if mount -o ro -t iso9660 $devName /mnt/root; then + if test -e "/mnt/root/@rootLabel@"; then + found=1 + break + fi + umount /mnt/root fi - umount /mnt/cdrom - fi - fi -done + fi + done -if test -z "$found"; then - echo "CD not found!" + if test -z "$found"; then + echo "CD not found!" + fail + fi + +else + + # Hard-coded root device. + mount -o ro "@rootDevice@" /mnt/root + + # Testing. fail + fi # Start stage 2. # !!! Note: we can't use pivot_root here (the kernel gods have # decreed), but we could use run-init from klibc, which deletes all # files in the initramfs, remounts the target root on /, and chroots. -cd /mnt/cdrom +cd /mnt/root mount --move . / umount /proc # cleanup umount /sys diff --git a/test/boot-stage-1.nix b/test/boot-stage-1.nix index 0f714a6d599..bb52b3f8354 100644 --- a/test/boot-stage-1.nix +++ b/test/boot-stage-1.nix @@ -6,13 +6,25 @@ { genericSubstituter, shell, staticTools , module_init_tools, extraUtils, modules -, cdromLabel ? "" + +, # Whether to find root device automatically using its label. + autoDetectRootDevice + +, # If not scanning, the root must be specified explicitly. + rootDevice + + # If scanning, we need a disk label. +, rootLabel }: +assert !autoDetectRootDevice -> rootDevice != ""; +assert autoDetectRootDevice -> rootLabel != ""; + genericSubstituter { src = ./boot-stage-1-init.sh; isExecutable = true; - inherit shell modules cdromLabel; + inherit shell modules; + inherit autoDetectRootDevice rootDevice rootLabel; path = [ staticTools module_init_tools diff --git a/test/rescue-cd.nix b/test/rescue-cd.nix new file mode 100644 index 00000000000..defeeb48ece --- /dev/null +++ b/test/rescue-cd.nix @@ -0,0 +1,63 @@ +let + + # The label used to identify the installation CD. + cdromLabel = "NIXOS"; + +in + + # Build boot scripts for the CD that find the CD-ROM automatically. + with import ./rescue-system.nix { + autoDetectRootDevice = true; + rootLabel = cdromLabel; + }; + + +rec { + + + # Since the CD is read-only, the mount points must be on disk. + cdMountPoints = pkgs.stdenv.mkDerivation { + name = "mount-points"; + builder = builtins.toFile "builder.sh" " + source $stdenv/setup + mkdir $out + cd $out + mkdir proc sys tmp etc dev var mnt nix nix/var + touch $out/${cdromLabel} + "; + }; + + + # Create an ISO image containing the isolinux boot loader, the + # kernel, the initrd produced above, and the closure of the stage 2 + # init. + rescueCD = import ./make-iso9660-image.nix { + inherit (pkgs) stdenv cdrtools; + isoName = "nixos.iso"; + + contents = [ + { source = pkgs.syslinux + "/lib/syslinux/isolinux.bin"; + target = "isolinux/isolinux.bin"; + } + { source = ./isolinux.cfg; + target = "isolinux/isolinux.cfg"; + } + { source = pkgs.kernel + "/vmlinuz"; + target = "isolinux/vmlinuz"; + } + { source = initialRamdisk + "/initrd"; + target = "isolinux/initrd"; + } + { source = cdMountPoints; + target = "/"; + } + ]; + + init = bootStage2; + + bootable = true; + bootImage = "isolinux/isolinux.bin"; + }; + + +} diff --git a/test/rescue-system.nix b/test/rescue-system.nix index b435d10f57f..890e3cfdf82 100644 --- a/test/rescue-system.nix +++ b/test/rescue-system.nix @@ -1,4 +1,8 @@ -{system ? __currentSystem}: +{ system ? __currentSystem +, autoDetectRootDevice ? false +, rootDevice ? "" +, rootLabel ? "" +}: rec { @@ -20,10 +24,6 @@ rec { }; - # The label used to identify the installation CD. - cdromLabel = "NIXOS"; - - # Determine the set of modules that we need to mount the root FS. modulesClosure = import ./modules-closure.nix { inherit (pkgs) stdenv kernel module_init_tools; @@ -49,7 +49,7 @@ rec { inherit (pkgs) genericSubstituter; inherit (pkgsDiet) module_init_tools; inherit extraUtils; - inherit cdromLabel; + inherit autoDetectRootDevice rootDevice rootLabel; modules = modulesClosure; shell = stdenvLinuxStuff.bootstrapTools.bash; staticTools = stdenvLinuxStuff.staticTools; @@ -113,49 +113,4 @@ rec { }; - # Since the CD is read-only, the mount points must be on disk. - cdMountPoints = pkgs.stdenv.mkDerivation { - name = "mount-points"; - builder = builtins.toFile "builder.sh" " - source $stdenv/setup - mkdir $out - cd $out - mkdir proc sys tmp etc dev var mnt nix nix/var - touch $out/${cdromLabel} - "; - }; - - - # Create an ISO image containing the isolinux boot loader, the - # kernel, the initrd produced above, and the closure of the stage 2 - # init. - rescueCD = import ./make-iso9660-image.nix { - inherit (pkgs) stdenv cdrtools; - isoName = "nixos.iso"; - - contents = [ - { source = pkgs.syslinux + "/lib/syslinux/isolinux.bin"; - target = "isolinux/isolinux.bin"; - } - { source = ./isolinux.cfg; - target = "isolinux/isolinux.cfg"; - } - { source = pkgs.kernel + "/vmlinuz"; - target = "isolinux/vmlinuz"; - } - { source = initialRamdisk + "/initrd"; - target = "isolinux/initrd"; - } - { source = cdMountPoints; - target = "/"; - } - ]; - - init = bootStage2; - - bootable = true; - bootImage = "isolinux/isolinux.bin"; - }; - - }