#! /bin/sh
#
# Copyright (c) 2001-2002 SuSE Linux AG, Nuernberg, Germany.
# All rights reserved.
#
# /etc/init.d/boot.localfs
#
### BEGIN INIT INFO
# Provides:          boot.localfs
# Required-Start:    boot.rootfsck
# Should-Start: boot.ibmsis boot.md boot.lvm dasd_devfs_compat boot.scsidev
# Required-Stop:
# Default-Start:     B
# Default-Stop:
# Description:       check and mount local filesystems except /
### END INIT INFO

. /etc/rc.status

# to get max number of parallel fsck processes
. /etc/sysconfig/boot
. /etc/sysconfig/kernel

if [ -f /etc/sysconfig/dump ]; then
	. /etc/sysconfig/dump
fi

export FSCK_MAX_INST

# helper shell function
#
reverse ()
{
    local _line
    while read -r _line ; do
	reverse
	echo "$_line"
	break
    done
}

rc_reset

case "$1" in
  start)
	# rootfs is mounted rw, lvm et al should be up now
	# updated blkid
	if [ -x /sbin/blkid ] ; then
	    /sbin/blkid > /dev/null
	fi
	#
	# If we use a serial console, don't use the fsck progress bar
	#
	FSCK_PROGRESSBAR="-V"
        [ -x /sbin/showconsole ] && [ "`/sbin/showconsole`" = "/dev/tty1" ] && FSCK_PROGRESSBAR="-C"
	#
	# do fsck and start sulogin, if it fails.
	#
	FSCK_RETURN=0
	if test ! -f /fastboot -a -z "$fastboot" ; then
	    FSCK_FORCE=""
	    test -f /forcefsck && FSCK_FORCE="-f"
	        echo "Checking file systems..."
	        fsck $FSCK_PROGRESSBAR -R -A -a $FSCK_FORCE -t noopts=hotplug
	        # A return code of 1 indicates that file system errors
	        # were corrected, but that the boot may proceed.
	        # A return code of 2 or larger indicates failure.
	        FSCK_RETURN=$?
		test $FSCK_RETURN -lt 4
		rc_status -v1 -r
		if test $FSCK_RETURN -gt 1 -a $FSCK_RETURN -lt 4 ; then
		    # if appropriate, switch bootsplash to verbose 
		    # mode to make text messages visible.
		    test -f /proc/splash && echo "verbose" > /proc/splash
		    echo
		    echo "fsck succeed, but reboot is required."
		    echo
		    sleep 1
		    sync
		    reboot -f
		elif test $FSCK_RETURN -gt 3; then
		    # if appropriate, switch bootsplash to verbose 
		    # mode to make text messages visible.
		    test -f /proc/splash && echo "verbose" > /proc/splash
		    # Stop blogd since we reboot after sulogin
		    test -x /sbin/blogd && killproc -QUIT /sbin/blogd
		    if test -x /etc/init.d/kbd ; then
			/etc/init.d/kbd start
		    fi
	            echo
	            echo "fsck failed for at least one filesystem (not /)."
		    echo "Please repair manually and reboot."
		    echo "The root file system is is already mounted read-write."
	            echo
	            echo "Attention: Only CONTROL-D will reboot the system in this"
	            echo "maintanance mode. shutdown or reboot will not work."
	            echo
	            PS1="(repair filesystem) # "
	            export PS1
	            /sbin/sulogin /dev/console

	            # if the user has mounted something rw, this should be umounted
	            echo "Unmounting file systems (ignore error messages)"
	            umount -avn

	            # on umsdos fs this would lead to an error message.
		    # so direct errors to /dev/null
	            mount -no remount,ro / 2> /dev/null

	            sync
	            reboot -f
	        fi
	        if test $FSCK_RETURN -gt 0; then
	            sync
		    touch /fsck_corrected_errors
		fi
	fi

	#
	# clean up
	#
	rm -f /etc/mtab* /etc/nologin /nologin /fastboot /forcefsck /success

	# update modules.dep if needed
	echo -n "Setting up kernel module dependencies (if required)"
	/sbin/update-modules.dep -r
	rc_status -v -r

	#
	# Mount local filesystems in '/etc/fstab' (and create an entry
	# for / and /proc).
	#
	echo "Mounting local file systems..."
	mount -fv -t proc proc /proc
	mount -fv -t sysfs sysfs /sys
	if [ -n "$DEV_ON_TMPFS" -a "$DEV_ON_TMPFS" != "yes" ] ; then
	    mount -fv -t tmpfs initramdevs /dev
	fi
	mount -fv -t tmpfs tmpfs /dev/shm
	rc_status
	optpts="-o mode=0620,gid=5"
	mount -fv -t devpts $optpts devpts /dev/pts
	rc_status
	mount -av -t nonfs,noproc,nodevpts,nosmbfs -O no_netdev
	rc_status -v1 -r
	;;
    stop)
	mounts=/etc/fstab
	test -r /proc/mounts && mounts=/proc/mounts

	# move to intermezzo package ?
	# First umount intermezzo filesystems
	test -x /usr/sbin/umountizo -a ! -z "`grep -i intermezzo <$mounts`" && /usr/sbin/umountizo >/dev/null 2>&1

	reverse < $mounts | \
	while read des fs type rest; do
	    case "$des"  in
	        ""|\#*)    continue ;;
	        /dev/loop*)
	                   umount $fs
	                   losetup $des &> /dev/null
	                   test $? -eq 0 && losetup -d $des ;;
	    esac
	    case "$fs"   in
	        /proc)     continue ;;
	        /dev/pts)  continue ;;
	        /dev)      continue ;;
	        /dev/shm)  continue ;;
	    esac
	    case "$type" in
	        proc)      umount -t proc     $fs ;;
	        devpts)    umount -t devpts   $fs ;;
	        devfs)     umount -t devfs    $fs ;;
	        tmpfs)     umount -t tmpfs    $fs ;;
	        usbfs)     umount -t usbfs    $fs ;;
	        usbdevfs)  umount -t usbdevfs $fs ;;
	    esac
	done

	while read major minor blocks name ; do
	    des=/dev/$name
	    case "$name" in
		""|\#*)    continue ;;
		loop*)
		           des=/dev/loop/${name#loop}
		           losetup $des &> /dev/null
		           test $? -eq 0 && losetup -d $des
			   des=/dev/$name
		           losetup $des &> /dev/null
		           test $? -eq 0 && losetup -d $des
	    esac
	done < /proc/partitions

	UMOUNT_FAILED=false
	echo "Unmounting file systems"
	umount -avt noproc,nonfs,nosmbfs || {
	    rc_status
	    UMOUNT_FAILED=true
	}
	rc_status -v1 -r

	if test "$UMOUNT_FAILED" = true ; then
	    echo "Oops: umount failed :-(  --  trying to remount readonly..."
	    mounts=/etc/fstab
	    test -r /proc/mounts && mounts=/proc/mounts
	    # Use cat and a pipe because umount changes
	    # /proc/mounts during direct read call
	    cat $mounts | \
	    while read des fs type rest; do
	        case "$des" in ""|\#*) continue ;; esac
	        case "$type" in
	            swap)     continue ;; # No umount on swap devices
	            proc)     continue ;; # Required
	            nfs)      continue ;; # Avoid hanging reboot/halt
	            smbfs)    continue ;; # Avoid hanging reboot/halt
	        esac
	        mount -v -n -o remount,ro $fs
	    done

	    echo "extra sync..."
	    sync; sync
	    echo "... hope now it's ok to reboot."
	fi
	;;
    restart)
	rc_failed 3
	rc_status -v
	;;
    status)
	rc_failed 4
	rc_status -v
	;;
    *)
	echo "Usage: $0 {start|stop|status|restart}"
	exit 1
	;;
esac

rc_exit

