#!/bin/bash
################################################################################
# $Id: rc.readonly 84 2006-02-24 01:44:15Z makia $
################################################################################
#  Copyright (C) 2004 The Regents of the University of California.
#  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
#  Written by Makia Minich <makia@llnl.gov>
#  UCRL-CODE-155916
#  
#  This file is part of GeDI, a diskless image management tool.
#  For details, see <http://www.llnl.gov/linux/gedi/>.
#  
#  GeDI is free software; you can redistribute it and/or modify it under
#  the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
#  
#  GeDI is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
#  details.
#  
#  You should have received a copy of the GNU General Public License along
#  with GeDI; if not, write to the Free Software Foundation, Inc.,
#  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
################################################################################
#
# /linuxrc - This is the blood and guts to start up your diskless system.
#

# Set the path
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

setup_unionfs()
{
   # Load the unionfs module.
   insmod /lib/modules/`uname -r`/kernel/fs/unionfs/unionfs.ko

   # Mount the filesystems into /unionfs
   mount -n -t tmpfs -o mode=755,size=128m none /unionfs/writeable
   mount -n -t unionfs -o dirs=/unionfs/writeable=rw:/=nfsro none /mnt
   mount -n --move /unionfs/writeable /mnt/unionfs/writeable
}

setup_ramfs()
{
   # First, we'll mount a writeable ramdisk

   for dir in /etc /var /dev ; do
      [ "$dir" != /var ] && size=",size=120m" || size=''
      echo -n "Binding $dir to ramdisk:"
      echo -n " mount" && mount -n -t tmpfs -o mode=755$size none /mnt
      # Now, we'll make exact copies into the ramdisk.
      echo -n " rsync" && rsync -arz $dir/ /mnt/
      # And then bind-mount over the real thing.
      echo -n " bind" && mount -n --bind /mnt $dir
      echo " umount" && umount /mnt 2>/dev/null
   done
}

if ( ! (echo "" > /etc/.gedi) > /dev/null 2>&1 ) ; then
   # If things aren't writeable, we'll make them so.
   if [ -f /lib/modules/`uname -r`/kernel/fs/unionfs/unionfs.ko ] ; then
      echo "Enabling unionfs"
      setup_unionfs

      # Now, we'll chroot into the filesystem and call linuxrc again.
      cd /mnt
      pivot_root . unionfs/readonly
      exec chroot . sh -c "exec /linuxrc \"$@\""
   else
      echo "Unionfs is disabled - executing bind mounts"

      # First, we'll get /etc and /var setup to be writeable.
      setup_ramfs

      # Now that things are writeable, let's restart linuxrc.
      exec /linuxrc "$@"
   fi
else
   # Otherwise, we'll setup the network files and call init.

   # Setting up networking
   if [ ! -f /etc/sysconfig/network ] ; then
      if [ -f /proc/cmdline ] ; then
         . /proc/cmdline
      else
         mount /proc
         . /proc/cmdline
         umount /proc
      fi

      echo "Setting up network files"
      echo "NETWORKING=yes" > /etc/sysconfig/network
      echo "FORWARD_IPV4=no" >> /etc/sysconfig/network

      if [ -f /etc/hosts ] ; then
         HOSTNAME=$ipconf_hostname
         if [ "$HOST_PRE" ] ; then
            HOSTNAME=$(echo $HOSTNAME | sed "s/^$HOST_PRE//")
         fi

         echo "HOSTNAME=$HOSTNAME" >> /etc/sysconfig/network
         hostname $HOSTNAME
      fi
   fi
   mount -n -t rpc_pipefs sunrpc /var/lib/nfs/rpc_pipefs > /dev/null 2>&1
fi

# This little section searches the filesystem to find out where init lives.
for loc in /sbin /usr/sbin /bin /usr/bin ; do
   if [ -x $loc/init ] ; then
      init=$loc/init
      break
   fi
done
if [ -z "$init" ] ; then
   echo "Cannot find init"
   exit
fi 

echo "Starting init"
[ ! -f /dev/console ] && mknod /dev/console c 5 1
exec ${init} "$@" </dev/console >/dev/console 2>&1
