- #!/bin/busybox sh
- rescue_shell() {
- echo "$@"
- echo "Something went wrong. Dropping you to a shell."
- /bin/busybox --install -s
- exec /bin/sh
- }
- # allow the use of UUIDs or filesystem lables
- uuidlabel_root() {
- for cmd in $(/bin/cat /proc/cmdline) ; do
- case $cmd in
- root=*)
- type=$(echo $cmd | /bin/cut -d= -f2)
- echo "Mounting rootfs"
- if [ $type == "LABEL" ] || [ $type == "UUID" ] ; then
- uuid=$(echo $cmd | /bin/cut -d= -f3)
- /bin/mount -o ro $(findfs "$type"="$uuid") /mnt/root
- else
- /bin/mount -o ro $(echo $cmd | cut -d= -f2) /mnt/root
- fi
- ;;
- esac
- done
- }
- check_filesystem() {
- # most of code coming from /etc/init.d/fsck
- local fsck_opts= check_extra= RC_UNAME=$(uname -s)
- # FIXME : get_bootparam forcefsck
- if [ -e /forcefsck ]; then
- fsck_opts="$fsck_opts -f"
- check_extra="(check forced)"
- fi
- echo "Checking local filesystem $check_extra : $1"
- if [ "$RC_UNAME" = Linux ]; then
- fsck_opts="$fsck_opts -C0 -T"
- fi
- trap : INT QUIT
- # using our own fsck, not the builtin one from busybox
- /sbin/fsck -p $fsck_opts $1
- ret_val=$?
- case $ret_val in
- 0) return 0;;
- 1) echo "Filesystem repaired"; return 0;;
- 2|3) if [ "$RC_UNAME" = Linux ]; then
- echo "Filesystem repaired, but reboot needed"
- reboot -f
- else
- rescue_shell "Filesystem still have errors; manual fsck required"
- fi;;
- 4) if [ "$RC_UNAME" = Linux ]; then
- rescue_shell "Fileystem errors left uncorrected, aborting"
- else
- echo "Filesystem repaired, but reboot needed"
- reboot
- fi;;
- 8) echo "Operational error"; return 0;;
- 16) echo "Use or Syntax Error"; return 16;;
- 32) echo "fsck interrupted";;
- 127) echo "Shared Library Error"; sleep 20; return 0;;
- *) echo $ret_val; echo "Some random fsck error - continuing anyway"; sleep 20; return 0;;
- esac
- # rescue_shell can't find tty so its broken
- rescue_shell
- }
- # start for real here
- # temporarily mount proc and sys
- /bin/mount -t proc none /proc
- /bin/mount -t sysfs none /sys
- /bin/mount -t devtmpfs none /dev
- /bin/mount -t devpts -o rw,nosuid,noexec,relatime,gid=5,mode=620 devpts /dev/pts
- # disable kernel messages from popping onto the screen
- ###echo 0 > /proc/sys/kernel/printk
- # clear the screen
- ###clear
- # LVM for everything
- # lvm runs as whatever its called as
- #ln -s /sbin/lvm.static /sbin/vgchange
- # start the vg volume group - /home and everything for portage - need not die here
- /sbin/vgchange -ay vg || rescue_shell "vgchange failed"
- # get here with logical volumes available
- # mounting rootfs on /mnt/root
- uuidlabel_root || rescue_shell "Error with uuidlabel_root"
- # space separated list of mountpoints that ...
- # mountpoints="/usr /var"
- # ... we want to find in /etc/fstab ...
- #ln -s /mnt/root/etc/fstab /etc/fstab
- # ... to check filesystems and mount our devices.
- #for m in $mountpoints ; do
- #echo $m
- # check_filesystem $m
- # echo "Mounting $m"
- # # mount the device and ...
- # mount $m || rescue_shell "Error while mounting $m"
- # # ... move the tree to its final location
- # mount --move $m "/mnt/root"$m || rescue_shell "Error while moving $m"
- #done
- echo "All done. Switching to real root."
- # clean up. The init process will remount proc sys and dev later
- /bin/umount /proc
- /bin/umount /sys
- /bin/umount /dev/pts
- /bin/umount /dev
- # switch to the real root and execute init
- exec /sbin/switch_root /mnt/root /sbin/init