Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/ash
- targetRoot=/mnt-root
- console=tty1
- export LD_LIBRARY_PATH=/nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/lib
- export PATH=/nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin:/nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/sbin
- fail() {
- if [ -n "$panicOnFail" ]; then exit 1; fi
- # If starting stage 2 failed, allow the user to repair the problem
- # in an interactive shell.
- cat <<EOF
- An error occurred in stage 1 of the boot process, which must mount the
- root filesystem on \`$targetRoot' and then start stage 2. Press one
- of the following keys:
- EOF
- if [ -n "$allowShell" ]; then cat <<EOF
- i) to launch an interactive shell
- f) to start an interactive shell having pid 1 (needed if you want to
- start stage 2's init manually)
- EOF
- fi
- cat <<EOF
- r) to reboot immediately
- *) to ignore the error and continue
- EOF
- read reply
- if [ -n "$allowShell" -a "$reply" = f ]; then
- exec setsid /nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/ash -c "/nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/ash < /dev/$console >/dev/$console 2>/dev/$console"
- elif [ -n "$allowShell" -a "$reply" = i ]; then
- echo "Starting interactive shell..."
- setsid /nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/ash -c "/nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/ash < /dev/$console >/dev/$console 2>/dev/$console" || fail
- elif [ "$reply" = r ]; then
- echo "Rebooting..."
- reboot -f
- else
- echo "Continuing..."
- fi
- }
- trap 'fail' 0
- # Print a greeting.
- echo
- echo "[1;32m<<< NixOS Stage 1 >>>[0m"
- echo
- # Mount special file systems.
- mkdir -p /etc
- touch /etc/fstab # to shut up mount
- touch /etc/mtab # to shut up mke2fs
- mkdir -p /proc
- mount -t proc proc /proc
- mkdir -p /sys
- mount -t sysfs sysfs /sys
- mount -t devtmpfs -o "size=5%" devtmpfs /dev
- mkdir -p /run
- mount -t tmpfs -o "mode=0755,size=25%" tmpfs /run
- # Process the kernel command line.
- export stage2Init=/init
- for o in $(cat /proc/cmdline); do
- case $o in
- console=*)
- set -- $(IFS==; echo $o)
- params=$2
- set -- $(IFS=,; echo $params)
- console=$1
- ;;
- init=*)
- set -- $(IFS==; echo $o)
- stage2Init=$2
- ;;
- boot.trace|debugtrace)
- # Show each command.
- set -x
- ;;
- boot.shell_on_fail)
- allowShell=1
- ;;
- boot.debug1|debug1) # stop right away
- allowShell=1
- fail
- ;;
- boot.debug1devices) # stop after loading modules and creating device nodes
- allowShell=1
- debug1devices=1
- ;;
- boot.debug1mounts) # stop after mounting file systems
- allowShell=1
- debug1mounts=1
- ;;
- boot.panic_on_fail|stage1panic=1)
- panicOnFail=1
- ;;
- root=*)
- # If a root device is specified on the kernel command
- # line, make it available through the symlink /dev/root.
- # Recognise LABEL= and UUID= to support UNetbootin.
- set -- $(IFS==; echo $o)
- if [ $2 = "LABEL" ]; then
- root="/dev/disk/by-label/$3"
- elif [ $2 = "UUID" ]; then
- root="/dev/disk/by-uuid/$3"
- else
- root=$2
- fi
- ln -s "$root" /dev/root
- ;;
- esac
- done
- # Load the required kernel modules.
- mkdir -p /lib
- ln -s /nix/store/jap5gy43p1cg73cb4aknpl6jbs2x7wv1-kernel-modules-shrunk/lib/modules /lib/modules
- echo /nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/modprobe > /proc/sys/kernel/modprobe
- for i in btrfs crc32c dm_mod; do
- echo "loading module $(basename $i)..."
- modprobe $i || true
- done
- # Create device nodes in /dev.
- echo "running udev..."
- mkdir -p /etc/udev
- ln -sfn /nix/store/bndvjw25b57m7jx5bbg7g1yam5dk4cv8-udev-rules /etc/udev/rules.d
- mkdir -p /dev/.mdadm
- systemd-udevd --daemon
- udevadm trigger --action=add
- udevadm settle || true
- # Load boot-time keymap before any LVM/LUKS initialization
- /nix/store/d94yl3ab8nh76q9px1c66i4spg42d60b-extra-utils/bin/busybox loadkmap < "/nix/store/13rkissmw7kc3wmjlsc89q23x6n4hi93-boottime-keymap"
- # XXX: Use case usb->lvm will still fail, usb->luks->lvm is covered
- # Wait for luksRoot to appear, e.g. if on a usb drive.
- # XXX: copied and adapted from stage-1-init.sh - should be
- # available as a function.
- if ! test -e /dev/sda7; then
- echo -n "waiting 10 seconds for device /dev/sda7 to appear..."
- for try in $(seq 10); do
- sleep 1
- if test -e /dev/sda7; then break; fi
- echo -n .
- done
- echo "ok"
- fi
- open_normally() {
- cryptsetup luksOpen /dev/sda7 root \
- }
- # open luksRoot and scan for logical volumes
- open_normally
- echo "starting device mapper and LVM..."
- lvm vgchange -ay
- if test -n "$debug1devices"; then fail; fi
- btrfs device scan
- # Try to resume - all modules are loaded now, and devices exist
- if test -e /sys/power/tuxonice/resume; then
- if test -n "$(cat /sys/power/tuxonice/resume)"; then
- echo 0 > /sys/power/tuxonice/user_interface/enabled
- echo 1 > /sys/power/tuxonice/do_resume || echo "failed to resume..."
- fi
- fi
- if test -n "" -a -e /sys/power/resume -a -e /sys/power/disk; then
- echo "" > /sys/power/resume 2> /dev/null || echo "failed to resume..."
- echo shutdown > /sys/power/disk
- fi
- # Return true if the machine is on AC power, or if we can't determine
- # whether it's on AC power.
- onACPower() {
- ! test -d "/proc/acpi/battery" ||
- ! ls /proc/acpi/battery/BAT[0-9]* > /dev/null 2>&1 ||
- ! cat /proc/acpi/battery/BAT*/state | grep "^charging state" | grep -q "discharg"
- }
- # Check the specified file system, if appropriate.
- checkFS() {
- # local device="$1"
- # local fsType="$2"
- # Only check block devices.
- # if [ ! -b "$device" ]; then return 0; fi
- # Don't check ROM filesystems.
- # if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi
- # If we couldn't figure out the FS type, then skip fsck.
- # if [ "$fsType" = auto ]; then
- # echo 'cannot check filesystem with type "auto"!'
- # return 0
- # fi
- # Optionally, skip fsck on journaling filesystems. This option is
- # a hack - it's mostly because e2fsck on ext3 takes much longer to
- # recover the journal than the ext3 implementation in the kernel
- # does (minutes versus seconds).
- # if test -z "" -a \
- # \( "$fsType" = ext3 -o "$fsType" = ext4 -o "$fsType" = reiserfs \
- # -o "$fsType" = xfs -o "$fsType" = jfs \)
- # then
- # return 0
- # fi
- # Don't run `fsck' if the machine is on battery power. !!! Is
- # this a good idea?
- # if ! onACPower; then
- # echo "on battery power, so no \`fsck' will be performed on \`$device'"
- # return 0
- # fi
- #
- # echo "checking $device..."
- #
- # fsckFlags=
- # if test "$fsType" != "btrfs"; then
- # fsckFlags="-V -a"
- # fi
- # fsck $fsckFlags "$device"
- # fsckResult=$?
- #
- # if test $(($fsckResult | 2)) = $fsckResult; then
- # echo "fsck finished, rebooting..."
- # sleep 3
- # reboot -f
- # fi
- # if test $(($fsckResult | 4)) = $fsckResult; then
- # echo "$device has unrepaired errors, please fix them manually."
- # fail
- # fi
- #
- # if test $fsckResult -ge 8; then
- # echo "fsck on $device failed."
- # fail
- # fi
- #
- # return 0
- }
- # Function for mounting a file system.
- mountFS() {
- local device="$1"
- local mountPoint="$2"
- local options="$3"
- local fsType="$4"
- if [ "$fsType" = auto ]; then
- fsType=$(blkid -o value -s TYPE "$device")
- if [ -z "$fsType" ]; then fsType=auto; fi
- fi
- echo "$device /mnt-root$mountPoint $fsType $options" >> /etc/fstab
- checkFS "$device" "$fsType"
- echo "mounting $device on $mountPoint..."
- mkdir -p "/mnt-root$mountPoint" || true
- # For CIFS mounts, retry a few times before giving up.
- local n=0
- while true; do
- mount "/mnt-root$mountPoint" && break
- if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
- echo "retrying..."
- n=$((n + 1))
- done
- }
- # Try to find and mount the root device.
- mkdir /mnt-root
- exec 3< /nix/store/nksi36abc4x178dzpg9k87v9lqk7gsbc-initrd-fsinfo
- while read -u 3 mountPoint; do
- read -u 3 device
- read -u 3 fsType
- read -u 3 options
- # !!! Really quick hack to support bind mounts, i.e., where the
- # "device" should be taken relative to /mnt-root, not /. Assume
- # that every device that starts with / but doesn't start with /dev
- # is a bind mount.
- pseudoDevice=
- case $device in
- /dev/*)
- ;;
- //*)
- # Don't touch SMB/CIFS paths.
- pseudoDevice=1
- ;;
- /*)
- device=/mnt-root$device
- ;;
- *)
- # Not an absolute path; assume that it's a pseudo-device
- # like an NFS path (e.g. "server:/path").
- pseudoDevice=1
- ;;
- esac
- # USB storage devices tend to appear with some delay. It would be
- # great if we had a way to synchronously wait for them, but
- # alas... So just wait for a few seconds for the device to
- # appear. If it doesn't appear, try to mount it anyway (and
- # probably fail). This is a fallback for non-device "devices"
- # that we don't properly recognise.
- if test -z "$pseudoDevice" -a ! -e $device; then
- echo -n "waiting for device $device to appear..."
- for try in $(seq 1 20); do
- sleep 1
- # also re-try lvm activation now that new block devices might have appeared
- lvm vgchange -ay
- # and tell udev to create nodes for the new LVs
- udevadm trigger --action=add
- if test -e $device; then break; fi
- echo -n "."
- done
- echo
- fi
- # Wait once more for the udev queue to empty, just in case it's
- # doing something with $device right now.
- udevadm settle || true
- mountFS "$device" "$mountPoint" "$options" "$fsType"
- done
- exec 3>&-
- # Stop udevd.
- udevadm control --exit || true
- # Kill any remaining processes, just to be sure we're not taking any
- # with us into stage 2. unionfs-fuse mounts require the unionfs process.
- pkill -9 -v '(1|unionfs)'
- if test -n "$debug1mounts"; then fail; fi
- # Restore /proc/sys/kernel/modprobe to its original value.
- echo /sbin/modprobe > /proc/sys/kernel/modprobe
- # Start stage 2. `switch_root' deletes all files in the ramfs on the
- # current root. Note that $stage2Init might be an absolute symlink,
- # in which case "-e" won't work because we're not in the chroot yet.
- if ! test -e "$targetRoot/$stage2Init" -o -L "$targetRoot/$stage2Init"; then
- echo "stage 2 init script ($targetRoot/$stage2Init) not found"
- fail
- fi
- mkdir -m 0755 -p $targetRoot/proc $targetRoot/sys $targetRoot/dev $targetRoot/run
- mount --move /proc $targetRoot/proc
- mount --move /sys $targetRoot/sys
- mount --move /dev $targetRoot/dev
- mount --move /run $targetRoot/run
- exec env -i $(type -P switch_root) "$targetRoot" "$stage2Init"
- fail # should never be reached
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement