2009-02-05 15:57:07 +00:00
|
|
|
|
#! @shell@
|
2006-11-02 22:48:01 +00:00
|
|
|
|
|
2009-06-10 16:29:48 +00:00
|
|
|
|
targetRoot=/mnt-root
|
2013-01-09 21:31:57 +00:00
|
|
|
|
console=tty1
|
2008-08-26 12:45:36 +00:00
|
|
|
|
|
2009-02-05 15:57:07 +00:00
|
|
|
|
export LD_LIBRARY_PATH=@extraUtils@/lib
|
2014-07-30 13:44:47 +00:00
|
|
|
|
export PATH=@extraUtils@/bin
|
|
|
|
|
ln -s @extraUtils@/bin /bin
|
2009-02-05 15:57:07 +00:00
|
|
|
|
|
2015-02-09 18:48:17 +00:00
|
|
|
|
# Stop LVM complaining about fd3
|
|
|
|
|
export LVM_SUPPRESS_FD_WARNINGS=true
|
2008-08-26 12:45:36 +00:00
|
|
|
|
|
2009-06-10 15:02:39 +00:00
|
|
|
|
fail() {
|
2010-01-04 18:04:57 +00:00
|
|
|
|
if [ -n "$panicOnFail" ]; then exit 1; fi
|
2011-09-13 18:49:50 +00:00
|
|
|
|
|
2009-06-10 15:02:39 +00:00
|
|
|
|
# If starting stage 2 failed, allow the user to repair the problem
|
|
|
|
|
# in an interactive shell.
|
|
|
|
|
cat <<EOF
|
|
|
|
|
|
2014-03-07 18:39:55 +00:00
|
|
|
|
An error occurred in stage 1 of the boot process, which must mount the
|
2009-06-10 15:02:39 +00:00
|
|
|
|
root filesystem on \`$targetRoot' and then start stage 2. Press one
|
2010-01-04 18:04:57 +00:00
|
|
|
|
of the following keys:
|
2009-06-10 15:02:39 +00:00
|
|
|
|
|
2013-01-09 21:31:57 +00:00
|
|
|
|
EOF
|
|
|
|
|
if [ -n "$allowShell" ]; then cat <<EOF
|
|
|
|
|
i) to launch an interactive shell
|
2009-06-10 15:02:39 +00:00
|
|
|
|
f) to start an interactive shell having pid 1 (needed if you want to
|
2013-01-09 21:31:57 +00:00
|
|
|
|
start stage 2's init manually)
|
|
|
|
|
EOF
|
|
|
|
|
fi
|
|
|
|
|
cat <<EOF
|
|
|
|
|
r) to reboot immediately
|
|
|
|
|
*) to ignore the error and continue
|
2009-06-10 15:02:39 +00:00
|
|
|
|
EOF
|
|
|
|
|
|
2009-08-10 09:20:05 +00:00
|
|
|
|
read reply
|
2011-09-13 18:49:50 +00:00
|
|
|
|
|
2013-01-09 21:31:57 +00:00
|
|
|
|
if [ -n "$allowShell" -a "$reply" = f ]; then
|
2015-02-13 10:20:29 +00:00
|
|
|
|
exec setsid @shell@ -c "exec @shell@ < /dev/$console >/dev/$console 2>/dev/$console"
|
2013-01-09 21:31:57 +00:00
|
|
|
|
elif [ -n "$allowShell" -a "$reply" = i ]; then
|
|
|
|
|
echo "Starting interactive shell..."
|
|
|
|
|
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
|
|
|
|
|
elif [ "$reply" = r ]; then
|
|
|
|
|
echo "Rebooting..."
|
|
|
|
|
reboot -f
|
|
|
|
|
else
|
|
|
|
|
echo "Continuing..."
|
|
|
|
|
fi
|
2008-08-16 00:59:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-05-21 19:26:07 +00:00
|
|
|
|
trap 'fail' 0
|
2008-08-08 17:07:04 +00:00
|
|
|
|
|
|
|
|
|
|
2006-11-02 22:48:01 +00:00
|
|
|
|
# Print a greeting.
|
2006-11-02 22:50:30 +00:00
|
|
|
|
echo
|
2009-11-06 21:51:28 +00:00
|
|
|
|
echo "[1;32m<<< NixOS Stage 1 >>>[0m"
|
2006-11-02 22:50:30 +00:00
|
|
|
|
echo
|
2006-11-02 22:48:01 +00:00
|
|
|
|
|
2006-11-12 18:48:47 +00:00
|
|
|
|
|
2006-11-03 00:36:08 +00:00
|
|
|
|
# Mount special file systems.
|
2014-12-18 16:41:36 +00:00
|
|
|
|
mkdir -p /etc/udev
|
2012-05-21 19:26:07 +00:00
|
|
|
|
touch /etc/fstab # to shut up mount
|
|
|
|
|
touch /etc/mtab # to shut up mke2fs
|
2014-12-19 13:38:33 +00:00
|
|
|
|
touch /etc/udev/hwdb.bin # to shut up udev
|
2014-05-21 13:19:01 +00:00
|
|
|
|
touch /etc/initrd-release
|
2006-11-27 01:35:34 +00:00
|
|
|
|
mkdir -p /proc
|
2014-06-05 11:10:35 +00:00
|
|
|
|
mount -t proc proc /proc
|
2006-11-27 01:35:34 +00:00
|
|
|
|
mkdir -p /sys
|
2014-06-05 11:10:35 +00:00
|
|
|
|
mount -t sysfs sysfs /sys
|
|
|
|
|
mount -t devtmpfs -o "size=@devSize@" devtmpfs /dev
|
2011-07-24 23:36:30 +00:00
|
|
|
|
mkdir -p /run
|
2014-06-05 11:10:35 +00:00
|
|
|
|
mount -t tmpfs -o "mode=0755,size=@runSize@" tmpfs /run
|
2006-11-03 00:36:08 +00:00
|
|
|
|
|
2013-07-23 18:43:11 +00:00
|
|
|
|
|
2006-11-24 00:04:29 +00:00
|
|
|
|
# Process the kernel command line.
|
2009-08-27 11:57:43 +00:00
|
|
|
|
export stage2Init=/init
|
2006-11-24 00:04:29 +00:00
|
|
|
|
for o in $(cat /proc/cmdline); do
|
|
|
|
|
case $o in
|
2013-01-09 21:31:57 +00:00
|
|
|
|
console=*)
|
|
|
|
|
set -- $(IFS==; echo $o)
|
|
|
|
|
params=$2
|
|
|
|
|
set -- $(IFS=,; echo $params)
|
|
|
|
|
console=$1
|
|
|
|
|
;;
|
2006-11-24 00:04:29 +00:00
|
|
|
|
init=*)
|
|
|
|
|
set -- $(IFS==; echo $o)
|
|
|
|
|
stage2Init=$2
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.trace|debugtrace)
|
2006-11-24 00:04:29 +00:00
|
|
|
|
# Show each command.
|
|
|
|
|
set -x
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.shell_on_fail)
|
2013-01-09 21:31:57 +00:00
|
|
|
|
allowShell=1
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.debug1|debug1) # stop right away
|
2013-01-09 21:31:57 +00:00
|
|
|
|
allowShell=1
|
2006-11-24 00:04:29 +00:00
|
|
|
|
fail
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.debug1devices) # stop after loading modules and creating device nodes
|
2013-01-09 21:31:57 +00:00
|
|
|
|
allowShell=1
|
2007-05-30 10:32:42 +00:00
|
|
|
|
debug1devices=1
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.debug1mounts) # stop after mounting file systems
|
2013-01-09 21:31:57 +00:00
|
|
|
|
allowShell=1
|
2007-05-30 10:32:42 +00:00
|
|
|
|
debug1mounts=1
|
|
|
|
|
;;
|
2013-01-09 21:49:26 +00:00
|
|
|
|
boot.panic_on_fail|stage1panic=1)
|
2010-01-04 18:04:57 +00:00
|
|
|
|
panicOnFail=1
|
|
|
|
|
;;
|
2010-08-07 14:16:18 +00:00
|
|
|
|
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
|
|
|
|
|
;;
|
2006-11-24 00:04:29 +00:00
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
|
nixos: Add system-wide option to set the hostid
The old boot.spl.hostid option was not working correctly due to an
upstream bug.
Instead, now we will create the /etc/hostid file so that all applications
(including the ZFS kernel modules, ZFS user-space applications and other
unrelated programs) pick-up the same system-wide host id. Note that glibc
(and by extension, the `hostid` program) also respect the host id configured in
/etc/hostid, if it exists.
The hostid option is now mandatory when using ZFS because otherwise, ZFS will
require you to force-import your ZFS pools if you want to use them, which is
undesirable because it disables some of the checks that ZFS does to make sure it
is safe to import a ZFS pool.
The /etc/hostid file must also exist when booting the initrd, before the SPL
kernel module is loaded, so that ZFS picks up the hostid correctly.
The complexity in creating the /etc/hostid file is due to having to
write the host ID as a 32-bit binary value, taking into account the
endianness of the machine, while using only shell commands and/or simple
utilities (to avoid exploding the size of the initrd).
2014-10-23 02:59:06 +00:00
|
|
|
|
# Set hostid before modules are loaded.
|
|
|
|
|
# This is needed by the spl/zfs modules.
|
|
|
|
|
@setHostId@
|
2006-11-24 00:04:29 +00:00
|
|
|
|
|
2009-12-15 16:38:20 +00:00
|
|
|
|
# Load the required kernel modules.
|
2012-05-21 19:26:07 +00:00
|
|
|
|
mkdir -p /lib
|
|
|
|
|
ln -s @modulesClosure@/lib/modules /lib/modules
|
2009-12-15 16:38:20 +00:00
|
|
|
|
echo @extraUtils@/bin/modprobe > /proc/sys/kernel/modprobe
|
|
|
|
|
for i in @kernelModules@; do
|
2008-08-08 17:07:04 +00:00
|
|
|
|
echo "loading module $(basename $i)..."
|
2015-09-28 18:28:51 +00:00
|
|
|
|
modprobe $i
|
2006-12-19 22:12:44 +00:00
|
|
|
|
done
|
2006-11-03 09:45:06 +00:00
|
|
|
|
|
2007-12-25 16:07:55 +00:00
|
|
|
|
|
2007-01-10 12:42:28 +00:00
|
|
|
|
# Create device nodes in /dev.
|
2009-12-15 16:38:20 +00:00
|
|
|
|
echo "running udev..."
|
2012-08-14 19:31:15 +00:00
|
|
|
|
mkdir -p /etc/udev
|
|
|
|
|
ln -sfn @udevRules@ /etc/udev/rules.d
|
2010-05-16 20:40:04 +00:00
|
|
|
|
mkdir -p /dev/.mdadm
|
2012-08-14 19:31:15 +00:00
|
|
|
|
systemd-udevd --daemon
|
2010-05-16 19:02:45 +00:00
|
|
|
|
udevadm trigger --action=add
|
2015-09-28 18:28:51 +00:00
|
|
|
|
udevadm settle
|
2007-01-10 12:42:28 +00:00
|
|
|
|
|
2011-12-28 21:46:45 +00:00
|
|
|
|
|
2012-08-12 14:54:31 +00:00
|
|
|
|
# Load boot-time keymap before any LVM/LUKS initialization
|
|
|
|
|
@extraUtils@/bin/busybox loadkmap < "@busyboxKeymap@"
|
|
|
|
|
|
|
|
|
|
|
2011-12-28 21:46:45 +00:00
|
|
|
|
# XXX: Use case usb->lvm will still fail, usb->luks->lvm is covered
|
|
|
|
|
@preLVMCommands@
|
|
|
|
|
|
|
|
|
|
|
2010-01-10 16:32:30 +00:00
|
|
|
|
echo "starting device mapper and LVM..."
|
2010-01-10 19:00:29 +00:00
|
|
|
|
lvm vgchange -ay
|
2011-09-13 18:49:50 +00:00
|
|
|
|
|
2007-05-30 10:32:42 +00:00
|
|
|
|
if test -n "$debug1devices"; then fail; fi
|
|
|
|
|
|
2007-01-10 12:42:28 +00:00
|
|
|
|
|
2009-06-18 16:47:00 +00:00
|
|
|
|
@postDeviceCommands@
|
|
|
|
|
|
|
|
|
|
|
2010-08-14 20:12:05 +00:00
|
|
|
|
# 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
|
|
|
|
|
|
2014-09-24 01:04:26 +00:00
|
|
|
|
if test -e /sys/power/resume -a -e /sys/power/disk; then
|
|
|
|
|
if test -n "@resumeDevice@"; then
|
|
|
|
|
resumeDev="@resumeDevice@"
|
2015-03-05 15:06:51 +00:00
|
|
|
|
resumeInfo="$(udevadm info -q property "$resumeDev" )"
|
2014-09-24 01:04:26 +00:00
|
|
|
|
else
|
|
|
|
|
for sd in @resumeDevices@; do
|
|
|
|
|
# Try to detect resume device. According to Ubuntu bug:
|
|
|
|
|
# https://bugs.launchpad.net/ubuntu/+source/pm-utils/+bug/923326/comments/1
|
2015-05-11 15:32:53 +00:00
|
|
|
|
# when there are multiple swap devices, we can't know where the hibernate
|
|
|
|
|
# image will reside. We can check all of them for swsuspend blkid.
|
2015-07-30 21:29:38 +00:00
|
|
|
|
resumeInfo="$(test -e "$sd" && udevadm info -q property "$sd")"
|
2015-03-05 15:06:51 +00:00
|
|
|
|
if [ "$(echo "$resumeInfo" | sed -n 's/^ID_FS_TYPE=//p')" = "swsuspend" ]; then
|
2014-09-24 01:04:26 +00:00
|
|
|
|
resumeDev="$sd"
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
fi
|
2015-03-05 15:06:51 +00:00
|
|
|
|
if test -e "$resumeDev"; then
|
|
|
|
|
resumeMajor="$(echo "$resumeInfo" | sed -n 's/^MAJOR=//p')"
|
|
|
|
|
resumeMinor="$(echo "$resumeInfo" | sed -n 's/^MINOR=//p')"
|
|
|
|
|
echo "$resumeMajor:$resumeMinor" > /sys/power/resume 2> /dev/null || echo "failed to resume..."
|
2014-09-24 01:04:26 +00:00
|
|
|
|
fi
|
2010-08-14 20:12:05 +00:00
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
2008-11-28 12:03:56 +00:00
|
|
|
|
# Return true if the machine is on AC power, or if we can't determine
|
|
|
|
|
# whether it's on AC power.
|
2009-02-01 19:53:59 +00:00
|
|
|
|
onACPower() {
|
2009-06-10 15:02:39 +00:00
|
|
|
|
! 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"
|
2008-11-28 12:03:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-02-06 16:53:36 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
# Check the specified file system, if appropriate.
|
|
|
|
|
checkFS() {
|
2012-06-28 14:55:44 +00:00
|
|
|
|
local device="$1"
|
|
|
|
|
local fsType="$2"
|
2013-01-09 21:31:57 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
# Only check block devices.
|
2012-06-28 14:55:44 +00:00
|
|
|
|
if [ ! -b "$device" ]; then return 0; fi
|
2009-06-15 15:50:36 +00:00
|
|
|
|
|
|
|
|
|
# Don't check ROM filesystems.
|
2012-06-28 14:55:44 +00:00
|
|
|
|
if [ "$fsType" = iso9660 -o "$fsType" = udf ]; then return 0; fi
|
|
|
|
|
|
2014-08-02 22:50:28 +00:00
|
|
|
|
# Don't check resilient COWs as they validate the fs structures at mount time
|
|
|
|
|
if [ "$fsType" = btrfs -o "$fsType" = zfs ]; then return 0; fi
|
|
|
|
|
|
2015-02-16 18:41:08 +00:00
|
|
|
|
# Skip fsck for inherently readonly filesystems.
|
|
|
|
|
if [ "$fsType" = squashfs ]; then return 0; fi
|
|
|
|
|
|
2012-06-28 14:55:44 +00:00
|
|
|
|
# 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
|
2009-06-15 15:50:36 +00:00
|
|
|
|
|
2009-06-15 16:47:37 +00:00
|
|
|
|
# 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 "@checkJournalingFS@" -a \
|
2012-06-28 14:55:44 +00:00
|
|
|
|
\( "$fsType" = ext3 -o "$fsType" = ext4 -o "$fsType" = reiserfs \
|
2014-03-25 20:39:10 +00:00
|
|
|
|
-o "$fsType" = xfs -o "$fsType" = jfs -o "$fsType" = f2fs \)
|
2009-06-15 16:47:37 +00:00
|
|
|
|
then
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2011-09-13 18:49:50 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
# Don't run `fsck' if the machine is on battery power. !!! Is
|
|
|
|
|
# this a good idea?
|
|
|
|
|
if ! onACPower; then
|
2009-06-10 15:02:39 +00:00
|
|
|
|
echo "on battery power, so no \`fsck' will be performed on \`$device'"
|
2009-02-01 19:53:59 +00:00
|
|
|
|
return 0
|
|
|
|
|
fi
|
2009-06-15 15:50:36 +00:00
|
|
|
|
|
2012-06-28 14:55:44 +00:00
|
|
|
|
echo "checking $device..."
|
|
|
|
|
|
2013-05-13 18:25:48 +00:00
|
|
|
|
fsckFlags=
|
|
|
|
|
if test "$fsType" != "btrfs"; then
|
|
|
|
|
fsckFlags="-V -a"
|
|
|
|
|
fi
|
|
|
|
|
fsck $fsckFlags "$device"
|
2009-02-01 19:53:59 +00:00
|
|
|
|
fsckResult=$?
|
|
|
|
|
|
|
|
|
|
if test $(($fsckResult | 2)) = $fsckResult; then
|
|
|
|
|
echo "fsck finished, rebooting..."
|
|
|
|
|
sleep 3
|
2013-01-09 21:31:57 +00:00
|
|
|
|
reboot -f
|
2007-02-06 16:53:36 +00:00
|
|
|
|
fi
|
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
if test $(($fsckResult | 4)) = $fsckResult; then
|
|
|
|
|
echo "$device has unrepaired errors, please fix them manually."
|
|
|
|
|
fail
|
|
|
|
|
fi
|
2008-11-28 12:03:56 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
if test $fsckResult -ge 8; then
|
|
|
|
|
echo "fsck on $device failed."
|
|
|
|
|
fail
|
|
|
|
|
fi
|
2008-11-28 12:03:56 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
return 0
|
|
|
|
|
}
|
2008-11-28 12:03:56 +00:00
|
|
|
|
|
2007-02-06 16:53:36 +00:00
|
|
|
|
|
2009-02-01 19:53:59 +00:00
|
|
|
|
# Function for mounting a file system.
|
|
|
|
|
mountFS() {
|
|
|
|
|
local device="$1"
|
|
|
|
|
local mountPoint="$2"
|
|
|
|
|
local options="$3"
|
|
|
|
|
local fsType="$4"
|
|
|
|
|
|
2012-06-28 14:55:44 +00:00
|
|
|
|
if [ "$fsType" = auto ]; then
|
|
|
|
|
fsType=$(blkid -o value -s TYPE "$device")
|
|
|
|
|
if [ -z "$fsType" ]; then fsType=auto; fi
|
|
|
|
|
fi
|
|
|
|
|
|
2015-09-24 16:13:14 +00:00
|
|
|
|
# Filter out x- options, which busybox doesn't do yet.
|
|
|
|
|
local optionsFiltered="$(IFS=,; for i in $options; do if [ "${i:0:2}" != "x-" ]; then echo -n $i,; fi; done)"
|
|
|
|
|
|
|
|
|
|
echo "$device /mnt-root$mountPoint $fsType $optionsFiltered" >> /etc/fstab
|
2012-06-28 14:55:44 +00:00
|
|
|
|
|
|
|
|
|
checkFS "$device" "$fsType"
|
|
|
|
|
|
2015-09-24 16:13:14 +00:00
|
|
|
|
# Optionally resize the filesystem.
|
|
|
|
|
case $options in
|
|
|
|
|
*x-nixos.autoresize*)
|
|
|
|
|
if [ "$fsType" = ext2 -o "$fsType" = ext3 -o "$fsType" = ext4 ]; then
|
|
|
|
|
echo "resizing $device..."
|
|
|
|
|
resize2fs "$device"
|
|
|
|
|
fi
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2014-07-30 13:44:47 +00:00
|
|
|
|
# Create backing directories for unionfs-fuse.
|
|
|
|
|
if [ "$fsType" = unionfs-fuse ]; then
|
|
|
|
|
for i in $(IFS=:; echo ${options##*,dirs=}); do
|
|
|
|
|
mkdir -m 0700 -p /mnt-root"${i%=*}"
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
2012-06-28 14:55:44 +00:00
|
|
|
|
echo "mounting $device on $mountPoint..."
|
2009-06-10 15:02:39 +00:00
|
|
|
|
|
2015-09-28 18:28:51 +00:00
|
|
|
|
mkdir -p "/mnt-root$mountPoint"
|
2010-01-06 00:25:14 +00:00
|
|
|
|
|
|
|
|
|
# For CIFS mounts, retry a few times before giving up.
|
|
|
|
|
local n=0
|
|
|
|
|
while true; do
|
2012-08-06 18:05:35 +00:00
|
|
|
|
mount "/mnt-root$mountPoint" && break
|
2010-01-06 00:25:14 +00:00
|
|
|
|
if [ "$fsType" != cifs -o "$n" -ge 10 ]; then fail; break; fi
|
|
|
|
|
echo "retrying..."
|
|
|
|
|
n=$((n + 1))
|
|
|
|
|
done
|
2007-02-06 16:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2006-11-12 18:48:47 +00:00
|
|
|
|
# Try to find and mount the root device.
|
2015-06-13 13:02:41 +00:00
|
|
|
|
mkdir -p $targetRoot
|
2006-11-12 18:48:47 +00:00
|
|
|
|
|
2012-05-21 19:26:07 +00:00
|
|
|
|
exec 3< @fsInfo@
|
2008-08-08 23:01:30 +00:00
|
|
|
|
|
2012-05-21 19:26:07 +00:00
|
|
|
|
while read -u 3 mountPoint; do
|
|
|
|
|
read -u 3 device
|
|
|
|
|
read -u 3 fsType
|
|
|
|
|
read -u 3 options
|
2008-08-08 23:01:30 +00:00
|
|
|
|
|
|
|
|
|
# !!! Really quick hack to support bind mounts, i.e., where the
|
|
|
|
|
# "device" should be taken relative to /mnt-root, not /. Assume
|
2009-02-01 19:53:59 +00:00
|
|
|
|
# that every device that starts with / but doesn't start with /dev
|
|
|
|
|
# is a bind mount.
|
2009-06-22 14:44:48 +00:00
|
|
|
|
pseudoDevice=
|
2008-08-08 23:01:30 +00:00
|
|
|
|
case $device in
|
|
|
|
|
/dev/*)
|
|
|
|
|
;;
|
2009-06-18 16:47:00 +00:00
|
|
|
|
//*)
|
|
|
|
|
# Don't touch SMB/CIFS paths.
|
2009-06-22 14:44:48 +00:00
|
|
|
|
pseudoDevice=1
|
2009-06-18 16:47:00 +00:00
|
|
|
|
;;
|
2008-08-08 23:01:30 +00:00
|
|
|
|
/*)
|
|
|
|
|
device=/mnt-root$device
|
|
|
|
|
;;
|
2009-06-22 14:44:48 +00:00
|
|
|
|
*)
|
|
|
|
|
# Not an absolute path; assume that it's a pseudo-device
|
|
|
|
|
# like an NFS path (e.g. "server:/path").
|
|
|
|
|
pseudoDevice=1
|
|
|
|
|
;;
|
2008-08-08 23:01:30 +00:00
|
|
|
|
esac
|
2007-02-06 16:53:36 +00:00
|
|
|
|
|
2008-08-08 23:15:36 +00:00
|
|
|
|
# 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"
|
2009-06-22 14:44:48 +00:00
|
|
|
|
# that we don't properly recognise.
|
|
|
|
|
if test -z "$pseudoDevice" -a ! -e $device; then
|
2008-08-08 23:15:36 +00:00
|
|
|
|
echo -n "waiting for device $device to appear..."
|
2015-02-09 18:48:17 +00:00
|
|
|
|
try=20
|
|
|
|
|
while [ $try -gt 0 ]; do
|
2008-08-08 23:15:36 +00:00
|
|
|
|
sleep 1
|
2014-02-03 22:25:24 +00:00
|
|
|
|
# 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
|
2008-08-08 23:15:36 +00:00
|
|
|
|
if test -e $device; then break; fi
|
|
|
|
|
echo -n "."
|
2015-02-09 18:48:17 +00:00
|
|
|
|
try=$((try - 1))
|
2008-08-08 23:15:36 +00:00
|
|
|
|
done
|
|
|
|
|
echo
|
2015-02-09 18:48:17 +00:00
|
|
|
|
if [ $try -eq 0 ]; then
|
|
|
|
|
echo "Timed out waiting for device $device, trying to mount anyway."
|
|
|
|
|
fi
|
2008-08-08 23:15:36 +00:00
|
|
|
|
fi
|
|
|
|
|
|
2012-04-06 14:20:43 +00:00
|
|
|
|
# Wait once more for the udev queue to empty, just in case it's
|
|
|
|
|
# doing something with $device right now.
|
2015-09-28 18:28:51 +00:00
|
|
|
|
udevadm settle
|
2012-04-06 14:20:43 +00:00
|
|
|
|
|
2008-08-08 23:01:30 +00:00
|
|
|
|
mountFS "$device" "$mountPoint" "$options" "$fsType"
|
|
|
|
|
done
|
2006-11-03 00:36:08 +00:00
|
|
|
|
|
2012-08-07 14:05:33 +00:00
|
|
|
|
exec 3>&-
|
|
|
|
|
|
2008-01-24 16:56:09 +00:00
|
|
|
|
|
2009-06-18 16:03:18 +00:00
|
|
|
|
@postMountCommands@
|
|
|
|
|
|
|
|
|
|
|
2014-10-10 15:16:10 +00:00
|
|
|
|
# Emit a udev rule for /dev/root to prevent systemd from complaining.
|
2014-11-11 22:48:31 +00:00
|
|
|
|
if [ -e /mnt-root/iso ]; then
|
2015-09-28 18:28:51 +00:00
|
|
|
|
eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=/mnt-root/iso)
|
2014-11-11 22:48:31 +00:00
|
|
|
|
else
|
2015-09-28 18:28:51 +00:00
|
|
|
|
eval $(udevadm info --export --export-prefix=ROOT_ --device-id-of-file=$targetRoot)
|
2014-11-11 22:48:31 +00:00
|
|
|
|
fi
|
2014-10-10 15:16:10 +00:00
|
|
|
|
if [ "$ROOT_MAJOR" -a "$ROOT_MINOR" -a "$ROOT_MAJOR" != 0 ]; then
|
|
|
|
|
mkdir -p /run/udev/rules.d
|
|
|
|
|
echo 'ACTION=="add|change", SUBSYSTEM=="block", ENV{MAJOR}=="'$ROOT_MAJOR'", ENV{MINOR}=="'$ROOT_MINOR'", SYMLINK+="root"' > /run/udev/rules.d/61-dev-root-link.rules
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
2008-08-08 22:44:45 +00:00
|
|
|
|
# Stop udevd.
|
2015-09-28 18:28:51 +00:00
|
|
|
|
udevadm control --exit
|
2011-09-22 08:26:58 +00:00
|
|
|
|
|
|
|
|
|
# Kill any remaining processes, just to be sure we're not taking any
|
2014-05-21 13:19:01 +00:00
|
|
|
|
# with us into stage 2. But keep storage daemons like unionfs-fuse.
|
|
|
|
|
pkill -9 -v -f '@'
|
2008-08-08 22:44:45 +00:00
|
|
|
|
|
|
|
|
|
|
2007-05-30 10:32:42 +00:00
|
|
|
|
if test -n "$debug1mounts"; then fail; fi
|
|
|
|
|
|
2006-11-24 00:04:29 +00:00
|
|
|
|
|
2009-12-15 18:31:21 +00:00
|
|
|
|
# Restore /proc/sys/kernel/modprobe to its original value.
|
|
|
|
|
echo /sbin/modprobe > /proc/sys/kernel/modprobe
|
|
|
|
|
|
|
|
|
|
|
2010-06-01 15:53:24 +00:00
|
|
|
|
# Start stage 2. `switch_root' deletes all files in the ramfs on the
|
2012-06-22 17:51:42 +00:00
|
|
|
|
# current root. Note that $stage2Init might be an absolute symlink,
|
2010-06-01 15:53:24 +00:00
|
|
|
|
# in which case "-e" won't work because we're not in the chroot yet.
|
2014-11-12 23:25:03 +00:00
|
|
|
|
if ! test -e "$targetRoot/$stage2Init" -o ! -L "$targetRoot/$stage2Init"; then
|
2010-07-22 14:40:29 +00:00
|
|
|
|
echo "stage 2 init script ($targetRoot/$stage2Init) not found"
|
|
|
|
|
fail
|
|
|
|
|
fi
|
2009-06-10 15:02:39 +00:00
|
|
|
|
|
2011-07-24 23:36:30 +00:00
|
|
|
|
mkdir -m 0755 -p $targetRoot/proc $targetRoot/sys $targetRoot/dev $targetRoot/run
|
|
|
|
|
|
2012-07-25 02:04:28 +00:00
|
|
|
|
mount --move /proc $targetRoot/proc
|
|
|
|
|
mount --move /sys $targetRoot/sys
|
|
|
|
|
mount --move /dev $targetRoot/dev
|
|
|
|
|
mount --move /run $targetRoot/run
|
2010-06-01 15:53:24 +00:00
|
|
|
|
|
2013-01-23 10:51:58 +00:00
|
|
|
|
exec env -i $(type -P switch_root) "$targetRoot" "$stage2Init"
|
2008-08-16 00:59:12 +00:00
|
|
|
|
|
2009-06-10 15:02:39 +00:00
|
|
|
|
fail # should never be reached
|