* Boot into a fully functional stage 2.

* Stage 2 init: handle non-read-only roots.

svn path=/nixu/trunk/; revision=7014
This commit is contained in:
Eelco Dolstra 2006-11-13 11:41:27 +00:00
parent 0b26af2188
commit 49f8402876
11 changed files with 90 additions and 32 deletions

View file

@ -83,9 +83,6 @@ else
# Hard-coded root device. # Hard-coded root device.
mount -o ro "@rootDevice@" /mnt/root mount -o ro "@rootDevice@" /mnt/root
# Testing.
fail
fi fi
# Start stage 2. # Start stage 2.
@ -96,6 +93,7 @@ cd /mnt/root
mount --move . / mount --move . /
umount /proc # cleanup umount /proc # cleanup
umount /sys umount /sys
exec chroot . /init
exec chroot . @stage2Init@
fail fail

View file

@ -15,6 +15,10 @@
# If scanning, we need a disk label. # If scanning, we need a disk label.
, rootLabel , rootLabel
, # The path of the stage 2 init to call once we've mounted the root
# device.
stage2Init ? "/init"
}: }:
assert !autoDetectRootDevice -> rootDevice != ""; assert !autoDetectRootDevice -> rootDevice != "";
@ -31,4 +35,9 @@ genericSubstituter {
extraUtils extraUtils
]; ];
makeDevices = ./make-devices.sh; 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
} }

View file

@ -2,11 +2,13 @@
# !!! copied from stage 1; remove duplication # !!! copied from stage 1; remove duplication
# Print a greeting. # Print a greeting.
echo echo
echo "<<< NixOS Stage 2 >>>" echo "<<< NixOS Stage 2 >>>"
echo echo
# Set the PATH. # Set the PATH.
export PATH=/empty export PATH=/empty
for i in @path@; do for i in @path@; do
@ -16,49 +18,70 @@ for i in @path@; do
fi fi
done done
# Mount special file systems.
mount -t tmpfs none /etc -n # to shut up mount # Mount special file systems, initialise required directories.
touch /etc/fstab # idem
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 proc none /proc
mount -t sysfs none /sys mount -t sysfs none /sys
mount -t tmpfs none /dev needWritableDir /dev 0755
mount -t tmpfs none /tmp needWritableDir /tmp 01777
mount -t tmpfs none /var needWritableDir /var 0755
mount -t tmpfs none /nix/var 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. # Ensure that the module tools can find the kernel modules.
export MODULE_DIR=@kernel@/lib/modules/ export MODULE_DIR=@kernel@/lib/modules/
# Create device nodes in /dev.
#source @makeDevices@
# Start udev. # Start udev.
udevd --daemon udevd --daemon
# Let udev create device nodes for all modules that have already been # Let udev create device nodes for all modules that have already been
# loaded into the kernel (or for which support is built into the # loaded into the kernel (or for which support is built into the
# kernel). # kernel).
udevtrigger udevtrigger
udevsettle # wait for udev to finish udevsettle # wait for udev to finish
# Start syslogd. # Start syslogd.
mkdir -p /var/run mkdir -m 0755 -p /var/run
#mkdir -p /var/log #mkdir -p /var/log
#touch /var/log/messages #touch /var/log/messages
echo "*.* /dev/tty10" > /etc/syslog.conf echo "*.* /dev/tty10" > /etc/syslog.conf
echo "syslog 514/udp" > /etc/services # required, even if we don't use it echo "syslog 514/udp" > /etc/services # required, even if we don't use it
@sysklogd@/sbin/syslogd & @sysklogd@/sbin/syslogd &
# Try to load modules for all PCI devices. # Try to load modules for all PCI devices.
for i in /sys/bus/pci/devices/*/modalias; do for i in /sys/bus/pci/devices/*/modalias; do
echo "Trying to load a module for $(basename $(dirname $i))..." echo "Trying to load a module for $(basename $(dirname $i))..."
modprobe $(cat $i) modprobe $(cat $i)
done done
# Bring up the network devices. # Bring up the network devices.
modprobe af_packet modprobe af_packet
for i in $(cd /sys/class/net && ls -d *); do 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 fi
done done
# login/su absolutely need this. # login/su absolutely need this.
touch /etc/login.defs test -e /etc/login.defs || touch /etc/login.defs
# Enable a password-less root login. # Enable a password-less root login.
echo "root::0:0:root:/:@shell@" > /etc/passwd if ! test -e /etc/passwd; then
echo "root:*:0" > /etc/group echo "root::0:0:root:/:@shell@" > /etc/passwd
fi
if ! test -e /etc/group; then
echo "root:*:0" > /etc/group
fi
# Set up inittab. # Set up inittab.
for i in $(seq 1 6); do for i in $(seq 1 6); do
echo "$i:2345:respawn:@mingetty@/sbin/mingetty --noclear tty$i" >> /etc/inittab echo "$i:2345:respawn:@mingetty@/sbin/mingetty --noclear tty$i" >> /etc/inittab
done done
# Show a nice greeting on each terminal. # Show a nice greeting on each terminal.
cat > /etc/issue <<EOF cat > /etc/issue <<EOF
@ -93,6 +124,7 @@ You can log in as \`root'.
EOF EOF
# Additional path for the interactive shell. # Additional path for the interactive shell.
for i in @extraPath@; do for i in @extraPath@; do
PATH=$PATH:$i/bin PATH=$PATH:$i/bin
@ -106,11 +138,14 @@ export PATH=$PATH
export MODULE_DIR=$MODULE_DIR export MODULE_DIR=$MODULE_DIR
EOF EOF
# Set the host name. # Set the host name.
hostname nixos hostname nixos
# Start an interactive shell. # Start an interactive shell.
#exec @shell@ #exec @shell@
# Start init. # Start init.
exec init 2 exec init 2

View file

@ -2,12 +2,16 @@
, utillinux, kernel, sysklogd, mingetty, udev , utillinux, kernel, sysklogd, mingetty, udev
, module_init_tools, nettools, dhcp , module_init_tools, nettools, dhcp
, path ? [] , path ? []
, # Whether the root device is root only. If so, we'll mount a
# ramdisk on /etc, /var and so on.
readOnlyRoot
}: }:
genericSubstituter { genericSubstituter {
src = ./boot-stage-2-init.sh; src = ./boot-stage-2-init.sh;
isExecutable = true; isExecutable = true;
inherit shell kernel sysklogd mingetty; inherit shell kernel sysklogd mingetty readOnlyRoot;
path = [ path = [
coreutils coreutils
findutils findutils
@ -18,5 +22,4 @@ genericSubstituter {
dhcp dhcp
]; ];
extraPath = path; extraPath = path;
makeDevices = ./make-devices.sh;
} }

View file

@ -10,7 +10,8 @@ genericSubstituter {
nixClosure = stdenv.mkDerivation { nixClosure = stdenv.mkDerivation {
name = "closure"; name = "closure";
builder = builtins.toFile "builder.sh" builder = builtins.toFile "builder.sh"
"source $stdenv/setup; /nix/bin/nix-store -qR $nix > $out"; "source $stdenv/setup; nix-store -qR $nix > $out";
buildInputs = [nix];
inherit nix; inherit nix;
}; };
} }

View file

@ -1,4 +1,4 @@
{ stdenv, cdrtools { stdenv, cdrtools, nix
# The file name of the resulting ISO image. # The file name of the resulting ISO image.
, isoName ? "cd.iso" , isoName ? "cd.iso"
@ -31,7 +31,7 @@ assert bootable -> bootImage != "";
stdenv.mkDerivation { stdenv.mkDerivation {
name = "iso9660-image"; name = "iso9660-image";
builder = ./make-iso9660-image.sh; builder = ./make-iso9660-image.sh;
buildInputs = [cdrtools]; buildInputs = [cdrtools nix];
inherit isoName packages init bootable bootImage; inherit isoName packages init bootable bootImage;
sources = map ({source, target}: source) contents; sources = map ({source, target}: source) contents;
targets = map ({source, target}: target) contents; targets = map ({source, target}: target) contents;

View file

@ -13,7 +13,7 @@ done
# !!! Just as with make-initrd.nix, the call to Nix here needs to be # !!! Just as with make-initrd.nix, the call to Nix here needs to be
# fixed. # fixed.
packagesClosure=$(/nix/bin/nix-store -qR $packages $init) packagesClosure=$(nix-store -qR $packages $init)
for i in $packagesClosure; do for i in $packagesClosure; do
graftList="$graftList ${i:1}=$i" graftList="$graftList ${i:1}=$i"

View file

@ -9,12 +9,14 @@ in
with import ./rescue-system.nix { with import ./rescue-system.nix {
autoDetectRootDevice = true; autoDetectRootDevice = true;
rootLabel = cdromLabel; rootLabel = cdromLabel;
stage2Init = "/init";
readOnlyRoot = true;
}; };
rec { rec {
inherit nixosInstaller; # !!! debug inherit nixosInstaller bootStage1; # !!! debug
# Since the CD is read-only, the mount points must be on disk. # 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 # kernel, the initrd produced above, and the closure of the stage 2
# init. # init.
rescueCD = import ./make-iso9660-image.nix { rescueCD = import ./make-iso9660-image.nix {
inherit (pkgs) stdenv cdrtools; inherit (pkgs) stdenv cdrtools nix;
isoName = "nixos.iso"; isoName = "nixos.iso";
contents = [ contents = [

View file

@ -2,6 +2,8 @@
, autoDetectRootDevice ? false , autoDetectRootDevice ? false
, rootDevice ? "" , rootDevice ? ""
, rootLabel ? "" , rootLabel ? ""
, stage2Init
, readOnlyRoot
}: }:
rec { rec {
@ -50,6 +52,7 @@ rec {
inherit (pkgsDiet) module_init_tools; inherit (pkgsDiet) module_init_tools;
inherit extraUtils; inherit extraUtils;
inherit autoDetectRootDevice rootDevice rootLabel; inherit autoDetectRootDevice rootDevice rootLabel;
inherit stage2Init;
modules = modulesClosure; modules = modulesClosure;
shell = stdenvLinuxStuff.bootstrapTools.bash; shell = stdenvLinuxStuff.bootstrapTools.bash;
staticTools = stdenvLinuxStuff.staticTools; staticTools = stdenvLinuxStuff.staticTools;
@ -110,6 +113,8 @@ rec {
]; ];
mingetty = pkgs.mingettyWrapper; mingetty = pkgs.mingettyWrapper;
inherit readOnlyRoot;
}; };

View file

@ -7,14 +7,17 @@ let
# don't want GRUB to be installed). # don't want GRUB to be installed).
grubDevice = "/dev/hda"; grubDevice = "/dev/hda";
in # Build boot scripts.
bootEnv = import ./rescue-system.nix {
# Build boot scripts for the CD that find the CD-ROM automatically.
with import ./rescue-system.nix {
autoDetectRootDevice = false; autoDetectRootDevice = false;
inherit rootDevice; inherit rootDevice;
stage2Init = "/init"; # !!! should be bootEnv.bootStage2;
readOnlyRoot = false;
}; };
in
with bootEnv;
rec { rec {
@ -24,6 +27,7 @@ rec {
builder = ./system-configuration.sh; builder = ./system-configuration.sh;
inherit (pkgs) grub coreutils gnused gnugrep diffutils; inherit (pkgs) grub coreutils gnused gnugrep diffutils;
inherit grubDevice; inherit grubDevice;
inherit bootStage2;
kernel = pkgs.kernel + "/vmlinuz"; kernel = pkgs.kernel + "/vmlinuz";
initrd = initialRamdisk + "/initrd"; initrd = initialRamdisk + "/initrd";
}; };

View file

@ -23,6 +23,7 @@ export PATH=$coreutils/bin:$gnused/bin:$gnugrep/bin:$diffutils/bin
if test -n "$grubDevice"; then if test -n "$grubDevice"; then
$grub/sbin/grub-install "$grubDevice" --no-floppy --recheck $grub/sbin/grub-install "$grubDevice" --no-floppy --recheck
cp -f $out/menu.lst /boot/grub/menu.lst cp -f $out/menu.lst /boot/grub/menu.lst
ln -sf $bootStage2 /init # !!! fix?
fi fi
EOF EOF