#!/bin/sh source /etc/initrd.defaults backup() { echo -ne "\033[0G\033[0K" } parse_opt() { case "$1" in *\=*) echo "$1" | cut -f2 -d= ;; esac } error_shell() { echo MSG="$*" if [ "$MSG" == "" ]; then MSG="Fatal error!" fi /bin/splasherror "$MSG" if [ "$DEBUG" == "" ] && cat /proc/cmdline|grep test >/dev/null; then echo "You are testing a kernel-upgrade, but something went wrong!" echo "The normal (working) kernel should be started again." echo "Press enter for a shell, or wait 60 seconds before normal reboot..." if ! read -t 60 BLA; then reboot fi fi echo "Starting shell: " setsid cttyhack sh } debug_shell() { echo echo "[ Debug mode, next step: $* ]" setsid cttyhack sh } modules_scan() { local MODS [ -d /etc/modules/${1} ] || touch /etc/modules/${1} MODS=`cat /etc/modules/${1}` for x in ${MODS} do echo -ne "Scanning for ${x}... \c" if ! modprobe ${x} 2>/dev/null 1>/dev/null; then echo -e "${BAD} FAILED!${NORMAL}" fi backup done } #use hwsetup to detect the other modules hwinstall() { echo -ne "${BOLD} ::${NORMAL} " hwsetup -p -n -a -v|while read bla; do read bla class read bla bus read bla device read bla driver read bla desc if test "$driver" != "ignore"; then if test "$driver" != "unknown"; then if ! echo "$driver"|grep ' '>/dev/null; then echo -ne "${BOLD} ::${NORMAL} $desc: $BOLD$driver..."; if OUTPUT=`modprobe $driver 2>&1`; then echo -e "$GOOD OK $NORMAL" else echo -e "$WARN skipped $NORMAL" fi fi fi fi done } check_xfs() { echo -ne "${BOLD} ::${NORMAL} Mounting $@..." #first replay the log by mounting it mkdir /.mnt 2>/dev/null mount -o inode32 $1 /.mnt 2>/dev/null if [ -e /.mnt/.cleanshutdown ]; then umount /.mnt 2>/dev/null echo -n "(last shutdown was clean) " else umount /.mnt 2>/dev/null echo -n "Last shutdown was not clean, checking..." #Check for xfs error's #Dont use xfs_check, since it requires too much memory for big filesystems (>2TB) if ! xfs_repair -n $1 >/dev/null 2>/dev/null; then echo -en "${WARN}Reparing..." #try a 'normal' repair if ! /sbin/xfs_repair $1 >/dev/null 2>/dev/null; then echo -n "flushing journal..." #try a repair by flushing the log if ! /sbin/xfs_repair -L $1 >/dev/null 2> /dev/null; then #its broken! echo -e "${BAD} FAILED!${NORMAL}" error_shell "Filesystem error, please fix manually!" fi fi fi fi echo -e " ${GOOD}OK${NORMAL}" } random() { echo -n $RANDOM } #cleanup the initrd environment, before exiting cleanupinitrd() { #if support environment is active, leave the initrd alone if [ "$SUP" == "" ]; then #unmount and kill everything, so the initrd is unused from now on. killall -9 udevd v86d udhcpc 2>/dev/null #we keep our IP! #umount /proc/bus/usb 2>/dev/null #umount /sys 2>/dev/null #umount /proc 2>/dev/null #umount /dev/pts 2>/dev/null #umount /dev 2>/dev/null fi } boot_image() { ###################################### find MEDIA and mount it under /newroot/mnt/cdrom splashstep "Searching boot image" #prepare /newroot #NOTE: the live image will be mounted under /newroot/mnt/live, and then there will be symlinks to it. mkdir /newroot mount -t tmpfs tmpfs /newroot mkdir -p /newroot/dev /newroot/mnt /newroot/tmp /newroot/initrd #the installer-cdrom or usbstick is mounted here. If NET_SERVER is specified, it mounts the server here. mkdir /newroot/mnt/cdrom #the live-environment image that needs to be started is mounted here: mkdir /newroot/mnt/live #network mode if [ "$NET_SERVER" ]; then #network mode splashinfo "Preparing to boot from network image" if [ "$NET_PASS_ASK" ]; then while true; do splashmode verbose splashinfo "Please enter password for user $NET_USER at share $NET_SERVER ..." echo -n "Password: " read NET_PASS mount.cifs "$NET_SERVER" /newroot/mnt/cdrom -o user=$NET_USER,pass=$NET_PASS,noserverino && break echo "Error while connecting, please try again." done else echo " Mounting samba share $NET_SERVER with user $NET_USER..." mount.cifs "$NET_SERVER" /newroot/mnt/cdrom -o user=$NET_USER,pass=$NET_PASS,noserverino || error_shell "Error while connecting to server" fi #cdrom/usb install mode else #loadusb-storage and wait for usbstick detection modprobe usb-storage modprobe vfat udevadm settle #scan all removable devices, also USB sticks FOUND=0 SLEPT=0 while [ "$FOUND" == "0" ]; do for x in `ls -d /sys/block/*/device | sed 's#/device$##' | sed 's#/sys/block#/dev#' | grep -v fd0` do echo -en " Identifying $x: " VOLNAME=`volname $x` 2>/dev/null echo -n "[ $VOLNAME ] " if echo $VOLNAME | grep "^Syn-3 installer" >/dev/null; then echo -n "mounting..." mount -r ${x} /newroot/mnt/cdrom > /dev/null 2>&1 mount -r ${x}1 /newroot/mnt/cdrom > /dev/null 2>&1 if [ -e /newroot/mnt/cdrom/$BOOTIMAGE ]; then FOUND=1 echo -e " ${GOOD}OK${NORMAL}" break else echo -e " ${WARN}NOT FOUND${NORMAL}" fi umount /newroot/mnt/cdrom >/dev/null 2>&1 else echo "skipped" fi done if [ "$FOUND" == "0" ] && [ "$SLEPT" == "0" ]; then echo "Waiting for usb storage devices to settle and trying again..." sleep 15 SLEPT=1 else break; fi done #something bad happend while searching installer media if [ "$FOUND" = "0" ] then error_shell "Can't find boot media! ( Please mount it under /newroot/mnt/cdrom )" fi fi # from this point on, the media is mounted under /newroot/mnt/cdrom ################################################# mount bootimage or copy bootimage to a block device? if [ "$INSTALL_DEVICE" != "" ]; then splashstep "Copying install image $BOOTIMAGE to $INSTALL_DEVICE ..." gunzip -c /newroot/mnt/cdrom/$BOOTIMAGE > $INSTALL_DEVICE || error_shell "Error while copying install image" sync reboot -f else splashstep "Opening $BOOTIMAGE ..." mount -o loop,ro /newroot/mnt/cdrom/$BOOTIMAGE /newroot/mnt/live || error_shell "Error while opening boot image" fi ################################################## prepare live environment #NOTE: We dont mount the live environment over /newroot, but use symlinks and copying instead. # This way its writable AND we can access all the stuff thats already mounted. (cdrom, network mounts) splashstep #link to all readonly stuff: for x in bin sbin lib boot usr opt do ln -s "/mnt/live/${x}" "/newroot/${x}" done #copy stuff that needs to be modified (cd /newroot/mnt/live; cp -a etc root home var /newroot) #copy over the dev tree #NO: we use a bindmount #cp -a /dev /newroot ################################################ start live image splashstep "Starting boot image" #pivot to the bootimage, never to return from it: if [ "$PIVOTIMAGE" ]; then cleanupinitrd #swap system root to newroot cd /newroot pivot_root . initrd #everything prepared, it's time to handover control to the 'real' system export CONSOLE=/dev/tty1 exec /sbin/init error_shell "Can't start the init system!" echo "Can't start the init system!" #chroot to the bootimage and continue booting when it returns else #we can only run one udevd: mkdir /newroot/dev 2>/dev/null mount -o bind /dev /newroot/dev #start it if ! chroot /newroot "/sbin/init" ; then error_shell "Error while running live image! Please reboot." fi umount /newroot/dev fi if [ ! -e /newroot/INSTALLOK ]; then error_shell "Installation failed!" fi ################################################ cleanup #restore splash splashmode silent splashstep "Closing boot image" cd / umount -d /newroot/mnt/live umount /newroot/mnt/cdrom umount /newroot sync }