diff --git a/test/boot-stage-1-init.sh b/test/boot-stage-1-init.sh index 1299599a94ee..3e93571ebdaf 100644 --- a/test/boot-stage-1-init.sh +++ b/test/boot-stage-1-init.sh @@ -83,9 +83,6 @@ else # Hard-coded root device. mount -o ro "@rootDevice@" /mnt/root - # Testing. - fail - fi # Start stage 2. @@ -96,6 +93,7 @@ cd /mnt/root mount --move . / umount /proc # cleanup umount /sys -exec chroot . /init + +exec chroot . @stage2Init@ fail diff --git a/test/boot-stage-1.nix b/test/boot-stage-1.nix index bb52b3f83545..ef1ebfc72255 100644 --- a/test/boot-stage-1.nix +++ b/test/boot-stage-1.nix @@ -15,6 +15,10 @@ # If scanning, we need a disk label. , rootLabel + +, # The path of the stage 2 init to call once we've mounted the root + # device. + stage2Init ? "/init" }: assert !autoDetectRootDevice -> rootDevice != ""; @@ -31,4 +35,9 @@ genericSubstituter { extraUtils ]; makeDevices = ./make-devices.sh; + + # We only want the path of the stage 2 init, we don't want it as a + # dependency (since then it the stage 2 init would end up in the + # initrd). + stage2Init = toString stage2Init; # !!! doesn't work } diff --git a/test/boot-stage-2-init.sh b/test/boot-stage-2-init.sh index be54926aabce..edf3e9c0dbf7 100644 --- a/test/boot-stage-2-init.sh +++ b/test/boot-stage-2-init.sh @@ -2,11 +2,13 @@ # !!! copied from stage 1; remove duplication + # Print a greeting. echo echo "<<< NixOS Stage 2 >>>" echo + # Set the PATH. export PATH=/empty for i in @path@; do @@ -16,49 +18,70 @@ for i in @path@; do fi done -# Mount special file systems. -mount -t tmpfs none /etc -n # to shut up mount -touch /etc/fstab # idem + +# Mount special file systems, initialise required directories. + +if test -z "@readOnlyRoot@"; then + #rootDev=$(grep "/dev/.* / " /proc/mounts | sed 's/^\([^ ]*\) .*/\1/') + mount -o remount,rw /dontcare / # !!! check for failure +fi + +needWritableDir() { + if test -n "@readOnlyRoot@"; then + mount -t tmpfs none $1 $3 + chmod $2 $1 + else + mkdir -m $2 -p $1 + fi +} + +needWritableDir /etc 0755 -n # to shut up mount + +test -e /etc/fstab || touch /etc/fstab # idem + mount -t proc none /proc mount -t sysfs none /sys -mount -t tmpfs none /dev -mount -t tmpfs none /tmp -mount -t tmpfs none /var -mount -t tmpfs none /nix/var +needWritableDir /dev 0755 +needWritableDir /tmp 01777 +needWritableDir /var 0755 +needWritableDir /nix/var 0755 + +mkdir -m 0755 -p /nix/var/nix/db +mkdir -m 0755 -p /nix/var/nix/gcroots +mkdir -m 0755 -p /nix/var/nix/temproots -mkdir -p /nix/var/nix/db -mkdir -p /nix/var/nix/gcroots -mkdir -p /nix/var/nix/temproots # Ensure that the module tools can find the kernel modules. export MODULE_DIR=@kernel@/lib/modules/ -# Create device nodes in /dev. -#source @makeDevices@ # Start udev. udevd --daemon + # Let udev create device nodes for all modules that have already been # loaded into the kernel (or for which support is built into the # kernel). udevtrigger udevsettle # wait for udev to finish + # Start syslogd. -mkdir -p /var/run +mkdir -m 0755 -p /var/run #mkdir -p /var/log #touch /var/log/messages echo "*.* /dev/tty10" > /etc/syslog.conf echo "syslog 514/udp" > /etc/services # required, even if we don't use it @sysklogd@/sbin/syslogd & + # Try to load modules for all PCI devices. for i in /sys/bus/pci/devices/*/modalias; do echo "Trying to load a module for $(basename $(dirname $i))..." modprobe $(cat $i) done + # Bring up the network devices. modprobe af_packet for i in $(cd /sys/class/net && ls -d *); do @@ -71,18 +94,26 @@ for i in $(cd /sys/class/net && ls -d *); do fi done + # login/su absolutely need this. -touch /etc/login.defs +test -e /etc/login.defs || touch /etc/login.defs + # Enable a password-less root login. -echo "root::0:0:root:/:@shell@" > /etc/passwd -echo "root:*:0" > /etc/group +if ! test -e /etc/passwd; then + echo "root::0:0:root:/:@shell@" > /etc/passwd +fi +if ! test -e /etc/group; then + echo "root:*:0" > /etc/group +fi + # Set up inittab. for i in $(seq 1 6); do echo "$i:2345:respawn:@mingetty@/sbin/mingetty --noclear tty$i" >> /etc/inittab done + # Show a nice greeting on each terminal. cat > /etc/issue < $out"; + "source $stdenv/setup; nix-store -qR $nix > $out"; + buildInputs = [nix]; inherit nix; }; } diff --git a/test/make-iso9660-image.nix b/test/make-iso9660-image.nix index f08aac3abc5d..861b229b8a4d 100644 --- a/test/make-iso9660-image.nix +++ b/test/make-iso9660-image.nix @@ -1,4 +1,4 @@ -{ stdenv, cdrtools +{ stdenv, cdrtools, nix # The file name of the resulting ISO image. , isoName ? "cd.iso" @@ -31,7 +31,7 @@ assert bootable -> bootImage != ""; stdenv.mkDerivation { name = "iso9660-image"; builder = ./make-iso9660-image.sh; - buildInputs = [cdrtools]; + buildInputs = [cdrtools nix]; inherit isoName packages init bootable bootImage; sources = map ({source, target}: source) contents; targets = map ({source, target}: target) contents; diff --git a/test/make-iso9660-image.sh b/test/make-iso9660-image.sh index 17f44e78ff01..774fbb8a90ec 100644 --- a/test/make-iso9660-image.sh +++ b/test/make-iso9660-image.sh @@ -13,7 +13,7 @@ done # !!! Just as with make-initrd.nix, the call to Nix here needs to be # fixed. -packagesClosure=$(/nix/bin/nix-store -qR $packages $init) +packagesClosure=$(nix-store -qR $packages $init) for i in $packagesClosure; do graftList="$graftList ${i:1}=$i" diff --git a/test/rescue-cd.nix b/test/rescue-cd.nix index 002288bea870..ddb6a7cb6772 100644 --- a/test/rescue-cd.nix +++ b/test/rescue-cd.nix @@ -9,12 +9,14 @@ in with import ./rescue-system.nix { autoDetectRootDevice = true; rootLabel = cdromLabel; + stage2Init = "/init"; + readOnlyRoot = true; }; rec { - inherit nixosInstaller; # !!! debug + inherit nixosInstaller bootStage1; # !!! debug # Since the CD is read-only, the mount points must be on disk. @@ -34,7 +36,7 @@ rec { # kernel, the initrd produced above, and the closure of the stage 2 # init. rescueCD = import ./make-iso9660-image.nix { - inherit (pkgs) stdenv cdrtools; + inherit (pkgs) stdenv cdrtools nix; isoName = "nixos.iso"; contents = [ diff --git a/test/rescue-system.nix b/test/rescue-system.nix index 40ec535c6b17..b2050fb14aee 100644 --- a/test/rescue-system.nix +++ b/test/rescue-system.nix @@ -2,6 +2,8 @@ , autoDetectRootDevice ? false , rootDevice ? "" , rootLabel ? "" +, stage2Init +, readOnlyRoot }: rec { @@ -50,6 +52,7 @@ rec { inherit (pkgsDiet) module_init_tools; inherit extraUtils; inherit autoDetectRootDevice rootDevice rootLabel; + inherit stage2Init; modules = modulesClosure; shell = stdenvLinuxStuff.bootstrapTools.bash; staticTools = stdenvLinuxStuff.staticTools; @@ -110,6 +113,8 @@ rec { ]; mingetty = pkgs.mingettyWrapper; + + inherit readOnlyRoot; }; diff --git a/test/system-configuration.nix b/test/system-configuration.nix index ef04dc1badc9..531dc0d5cb85 100644 --- a/test/system-configuration.nix +++ b/test/system-configuration.nix @@ -7,14 +7,17 @@ let # don't want GRUB to be installed). grubDevice = "/dev/hda"; -in - - # Build boot scripts for the CD that find the CD-ROM automatically. - with import ./rescue-system.nix { + # Build boot scripts. + bootEnv = import ./rescue-system.nix { autoDetectRootDevice = false; inherit rootDevice; + stage2Init = "/init"; # !!! should be bootEnv.bootStage2; + readOnlyRoot = false; }; +in + +with bootEnv; rec { @@ -24,6 +27,7 @@ rec { builder = ./system-configuration.sh; inherit (pkgs) grub coreutils gnused gnugrep diffutils; inherit grubDevice; + inherit bootStage2; kernel = pkgs.kernel + "/vmlinuz"; initrd = initialRamdisk + "/initrd"; }; diff --git a/test/system-configuration.sh b/test/system-configuration.sh index 17d58f4d0cbe..d35811a84da5 100644 --- a/test/system-configuration.sh +++ b/test/system-configuration.sh @@ -23,6 +23,7 @@ export PATH=$coreutils/bin:$gnused/bin:$gnugrep/bin:$diffutils/bin if test -n "$grubDevice"; then $grub/sbin/grub-install "$grubDevice" --no-floppy --recheck cp -f $out/menu.lst /boot/grub/menu.lst + ln -sf $bootStage2 /init # !!! fix? fi EOF