#!/bin/sh
#
#
#         Date: 2010-Jul-27 (Mon, for NORD Linux) right before 28/28/28
#		The purpose of this script is to handle
#               various important special situations which arise
#		before 'init' can safely handle them.  In particular,
#		mounting of a separate /etc apart from the root FS
#		or mounting of a "guest vol" with a system "base vol".
#		Switching these after normal 'init' gets control
#		is much more complicated than to intercept here.
#
#

#
# default can be overridden when the "run root" gets mounted
#BASEDIRS="lib lib64 bin sbin usr"
#BASEDIRS="lib lib64 bin sbin usr boot"
BASEDIRS="lib lib64 bin sbin usr boot opt"

#
# why default command search path still lacks "sbin"
# after all these years is a mystery to me ... just fix it ...
PATH=/usr/sbin:/sbin:/usr/bin:/bin ; export PATH

Z="INIT+VOL"

#
# assume a usable root is mounted ... some utilities needed now:
#	mount, umount, xargs, grep, tail, awk, cat, uname
#

#
# we will need /proc
umount /proc 1> /dev/null 2> /dev/null
mount -t proc proc /proc 1> /dev/null 2> /dev/null

#
# so check that it is mounted
if [ ! -r /proc/cmdline ] ; then
  echo "$Z: '/proc/cmdline' missing or not readable"
  exec /sbin/init $* ; fi

#
# load additional filesystem drivers
modprobe ext3 1> /dev/null 2> /dev/null

#
# first try to mount a writeable /etc ... very carefully
_ETCFS=`cat /proc/cmdline | xargs -n 1 | grep '^etc=' \
                        | tail -1 | awk -F'=' '{print $2}'`
if [ ! -z "$_ETCFS" ] ; then
  echo "$Z: using private /etc from '$_ETCFS'"
  echo "+ fsck -y $_ETCFS"
          fsck -y $_ETCFS
  echo "+ mount -n $_ETCFS /etc"
          mount -n $_ETCFS /etc ; RC=$?
  echo "$Z: now exitting to standard INIT"
  if [ $RC -eq 0 ] ; then exec /sbin/init $* ; fi
fi

#
# extract the "run root" or "guest vol" from the boot parms
_RUNFS=`cat /proc/cmdline | xargs -n 1 | grep '^runroot=' \
                        | tail -1 | awk -F'=' '{print $2}'`
if [ -z "$_RUNFS" ] ; then
_RUNFS=`cat /proc/cmdline | xargs -n 1 | grep '^rwroot=' \
				  | awk -F'=' '{print $2}'`
fi

if [ -z "$_RUNFS" ] ; then
  echo "$Z: no guest vol indicated - exiting to normal 'init'"
  cd / ; exec /sbin/init $*
fi
echo "$Z: using guest vol '$_RUNFS'"

#
# we presume that the booted root has an "mnt" mount point directory
echo "+ mount -r $_RUNFS /mnt"
        mount -r $_RUNFS /mnt ; RC=$?
if [ $RC -ne 0 ] ; then
  echo "$Z: 'mount' failed"
  exec /sbin/init $* ; fi

#
# two cases left and both use a system "base vol" ... tag that vol
UNAMES=`uname -s`
UNAMEM=`uname -m | sed 's#^i.86$#i386#'`
SYSTEM=$UNAMES-$UNAMEM

#
# check that /mnt/$SYSTEM is available as a mount point for the pivot
if [ ! -d /mnt/$SYSTEM ] ; then
  echo "$Z: '$SYSTEM' mount point not available on '$_RUNFS'"
  exec /sbin/init $* ; fi

#
# get a list of directories which were mounted by the INITRD
ROOTDIRS=`grep -v ' / ' /proc/mounts \
  | awk '{print $2}' | grep -v '/mnt' | sed 's#^/##'`

#
# conditionally source a "guestvol" config file
if [ -r /mnt/etc/sysconfig/guestvol ] ; then
  . /mnt/etc/sysconfig/guestvol ; fi

#
# if a link then skip or if directory then bind
for D in $BASEDIRS $ROOTDIRS ; do
  if [ ! -d /$D ] ; then continue ; fi
  if [ -h /mnt/$D ] ; then continue ; fi
  echo "+ mount -o bind /$D /mnt/$D"
          mount -o bind /$D /mnt/$D
done

#
# now pivot the run-time root into position
echo "+ pivot_root /mnt /mnt/$SYSTEM"
        pivot_root /mnt /mnt/$SYSTEM ; RC=$?
if [ $RC -ne 0 ] ; then
  echo "$Z: 'pivot_root' failed"
  exec /sbin/init $* ; fi

#
# clean-up filesystems hanging off old root which got moved
for D in $ROOTDIRS ; do
  echo "+ umount /$SYSTEM/$D"
          umount /$SYSTEM/$D
done

#
# if all else fails then run normal 'init' ...
echo "$Z: now exitting to standard INIT"
cd / ; exec /sbin/init $*




