#!/bin/bash
################################################################################
# Filename: ./src/base/etc/templates/linuxrc
# 
# The contents of this file are subject to the Qlusters Public License
# Version 1.1 (the License); you may not use this file except in compliance
# with the License.
# You may obtain a copy of the License at
# http://www.openqrm.org/content/view/33/69/.
# 
# Software distributed under the License is distributed on an AS IS basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
# the specific language governing rights and limitations under the License.
# 
# The Original Code is openQRM.
# 
# The Initial Developer of the Original Code is Qlusters Corporation. Portions
# created by Qlusters Corporation are Copyright (C) 2003-2005. All Rights
# Reserved.
# 
# Contributor(s):
# 
# Description:
# 
# Comments:
################################################################################
# qrm linuxrc
#


# starts an emergency console (qrm-execd)
function start_emergency_console() {
	# be sure to stop the regular qrm-services before
	killall -9 qrm-execd 1>/dev/null 2>&1
	killall -9 qrm-tcp-monitor 1>/dev/null 2>&1
	killall -9 qrm-infod 1>/dev/null 2>&1
	# start just qrm-execd
	mkdir -p $QRM_NODES_BASE_DIR/qrm/
	mount -t tmpfs none $QRM_NODES_BASE_DIR/qrm/
	cd $QRM_NODES_BASE_DIR/qrm/
	run_services qrm-emergency-console
	cd /
	echo "ERROR: Node is in error-state. Started remote-emergency-console service."
	exit 1
}



function createfstab() {
 ETC="/mnt/etc"
 FSTAB="fstab"
 FSTAB_QRM="/mnt/var/qrm/conf/fstab-qrm"
 FSTABSTATIC="fstab-static"
 CURRENT=`pwd`
 local OLD_IFS=$IFS

 cd $ETC

 # check for backup
 if [ ! -h $FSTAB ] && [ -f $FSTAB ]; then
  echo "found 'real' fstab file, backing it up to $FSTAB.org"
  mv -f $FSTAB $FSTAB.org 1>/dev/null 2>&1
  > $FSTAB_QRM
  ln -sf /var/qrm/conf/fstab-qrm $FSTAB
 else
  echo "found dynamic fstab-qrm + fstab symlink"
  > $FSTAB_QRM
 fi

 # header
 echo "# NOTICE : this file is created dynamically by the Qrm-server" >> $FSTAB_QRM
 echo "# if you want to add mount-points here add then to :" >> $FSTAB_QRM
 echo "# 	$ETC/$FSTABSTATIC" >> $FSTAB_QRM
 echo "# This file is being added to the $ETC/$FSTAB after dynamic creation" >> $FSTAB_QRM
 echo "" >> $FSTAB_QRM

 # create / entry
 if [ "$STORAGE_TYPE_INTERFACE" == "nfs" ]; then
  echo "adding nfsroot entry for / as 0.0.0.0:$FILESYSTEM_IMAGE_IDENTIFIER"
  echo "0.0.0.0:$FILESYSTEM_IMAGE_IDENTIFIER   /   nfs  defaults   0 0" >> $FSTAB_QRM
 elif [ "$STORAGE_TYPE_INTERFACE" == "iscsi" ]; then
  echo "adding iscsi-root-device $myroothdpartition"
  echo "$myroothdpartition       /   $ISCSI_ROOT_FS_TYPE  defaults   0 0" >> $FSTAB_QRM

  # other disks to change ?
  if cat $FSTAB.org | grep " / " | awk {' print $1 '} | grep -v LABEL 1>/dev/null 2>&1; then
   LOCALROOTDISK=`cat $FSTAB.org | grep " / " | awk {' print $1 '} | grep -v LABEL | grep -v ^# | sed -e "s/[0-9].*//" | head -n 1`
   LOCALROOTBOOTPARTITION=`cat $FSTAB.org | grep " / " | awk {' print $1 '} | grep -v LABEL | grep -v ^# | head -n 1`
   echo "found local rootdisk $LOCALROOTDISK in $FSTAB.org / bootpartiton $LOCALROOTBOOTPARTITION"
   IFS=$'\n'
   for ADDDISK in `grep ^$LOCALROOTDISK.* $FSTAB.org | grep -v $LOCALROOTBOOTPARTITION | awk {' print $1 '}`; do
    DISKPARTITIONNUMBER=`echo $ADDDISK | sed -e "s/[a-z]//g" | sed -e "s/\///g"`
    HARDDISK=`echo $ADDDISK | sed -e "s/\/dev\///"`
    if grep ^$ADDDISK $FSTAB.org | grep swap 1>/dev/null 2>&1 && [ "$FILESYSTEM_IMAGE_IS_SHARED" == "true" ]; then
     echo "NOT adding swap device for shared image"
    else
     echo "found disk to adjust $ADDDISK harddisk $HARDDISK partiton number $DISKPARTITIONNUMBER"
     grep ^$ADDDISK $FSTAB.org | sed -e "s/$HARDDISK/$myroothd$DISKPARTITIONNUMBER/" >> $FSTAB_QRM
    fi
   done
   IFS=$OLD_IFS
  fi
 fi

 # create common entries
 echo "none         /dev/pts     devpts   gid=5,mode=620     0 0" >> $FSTAB_QRM
 echo "none         /proc        proc     defaults           0 0" >> $FSTAB_QRM
 echo "none         /dev/shm     tmpfs    defaults           0 0" >> $FSTAB_QRM
 echo "/dev/fd0     /mnt/floppy  auto     noauto,owner,kudzu 0 0" >> $FSTAB_QRM

 # gather for cdroms
 IFS=$'\n'
 for IDEDEVICES in `ls /proc/ide`; do
  if grep cdrom /proc/ide/$IDEDEVICES/media 1>/dev/null 2>&1; then
   echo "found cdrom at $IDEDEVICES"
   mkdir -p /mnt/cdrom$LOOP 1>/dev/null 2>&1
   echo "/dev/$IDEDEVICES     /mnt/cdrom$LOOP   udf,iso9660 noauto,owner,kudzu,ro 0 0" >> $FSTAB_QRM
   LOOP=$(( LOOP +1 ))
  fi
 done
 IFS=$OLD_IFS

 # fstab-static ?
 if [ -f $FSTABSTATIC ]; then
  echo "found $FSTABSTATIC, adding to $FSTAB_QRM"
  echo "" >> $FSTAB_QRM
  echo "# added static part starting here" >> $FSTAB_QRM
  cat $FSTABSTATIC >> $FSTAB_QRM
 fi

 cd $CURRENT
 return 0

}


# function to adjust the network/netfs init script to directly exit fine during stop
# needed because otherwise system with a network based root-filesystem would loose /
function adjust_net_init() {
local OLD_IFS=$IFS
NEW_LINE='\
'
IFS=' '
INIT_SCRIPTS_TO_ADJUST="/mnt/etc/init.d/network /mnt/etc/init.d/portmap /mnt/etc/init.d/netfs /mnt/etc/rc.d/init.d/network /mnt/etc/rc.d/init.d/portmap /mnt/etc/rc.d/init.d/netfs"
	for INIT_SCRIPT in $INIT_SCRIPTS_TO_ADJUST; do
		if [ -f $INIT_SCRIPT ]; then
			if ! grep -A1 "stop)" $INIT_SCRIPT | grep -v ^# | grep "exit 0" 1>/dev/null; then
				echo "Adjusting init script $INIT_SCRIPT"
				TMP_FILE=`mktemp -q /tmp/XXXXXX`
				cat $INIT_SCRIPT | grep -v ^# | sed -e "s/stop).*/stop) ${NEW_LINE}     exit 0/" > $TMP_FILE
				mv $TMP_FILE $INIT_SCRIPT
				chmod +x $INIT_SCRIPT
			else
				echo "Init script $INIT_SCRIPT already adjusted"
			fi
		fi
	done
	IFS=$OLD_IFS
	# add qrm to inittab
	cp -f /mnt/etc/inittab /mnt/etc/inittab.org
	if grep -q ^qrm /mnt/etc/inittab; then
		TMP_FILE=`mktemp -q /tmp/XXXXXX`
		cat /mnt/etc/inittab | sed -e "s#^qrm.*#qrm:0123456:once:$QRM_NODES_BASE_DIR/qrm/sbin/qrm-runlevel#g" > $TMP_FILE
		mv $TMP_FILE /mnt/etc/inittab
	else
		echo "qrm:123456:once:$QRM_NODES_BASE_DIR/qrm/sbin/qrm-runlevel" >> /mnt/etc/inittab
	fi
	return 0

}

function xconfig() {
ETC="/mnt/etc/X11/"
XFCONF="XF86Config-4"
XFCONFOLD="XF86Config"
CURRENT=`pwd`

	cd $ETC
	# XF86Config-4
	if [ ! -h $XFCONF ] && [ -f $XFCONF ]; then
		echo "found 'real' XF86Config-4 file, backing it up to $XFCONF.org"
		mv -f $XFCONF $XFCONF.org 1>/dev/null 2>&1
		ln -sf /var/qrm/conf/XF86Config-4-qrm $XFCONF
	elif [ ! -f $XFCONF ] && [ ! -h $XFCONF ]; then
		echo "no 'real' XF86Config-4 file found. creating the link"
		ln -sf /var/qrm/conf/XF86Config-4-qrm $XFCONF
	else
		echo "found dynamic $XFCONF-qrm + $XFCONF symlink"
	fi
	# XF86Config
	if [ ! -h $XFCONFOLD ] && [ -f $XFCONFOLD ]; then
		echo "found 'real' XF86Config file, backing it up to $XFCONFOLD.org"
		mv -f $XFCONFOLD $XFCONFOLD.org 1>/dev/null 2>&1
		ln -sf /var/qrm/conf/XF86Config-4-qrm $XFCONFOLD
	elif [ ! -f $XFCONFOLD ] && [ ! -h $XFCONFOLD ]; then
		echo "no 'real' XF86Config file found. creating the link"
		ln -sf /var/qrm/conf/XF86Config-4-qrm $XFCONFOLD
	else
		echo "found dynamic $XFCONFOLD symlink"
	fi
	# copying the XF86Config-4 from the hw-detection
	cp -f /etc/X11/XF86Config-4 /mnt/var/qrm/conf/XF86Config-4-qrm
	cd $CURRENT
	return 0
}


# function to get the additional xen-kernel version for starting partitions
function xen_kernel_config() {
	# for xen
	if [ "$KERNEL_NAME" == "xen-2.4" ] || [ "$KERNEL_NAME" == "xen-2.6" ]; then
		xen_guest_kernel_version=`echo $kernel_version | sed -e "s/xen0/xenU/"`
		echo "getting the xen guest kernel, system.map + modules version $xen_guest_kernel_version"
		# get the guest kernel, system.map + modules
		cd /lib/modules
		tftp $qrm -g -r boot/modules-$KERNEL_NAME""U.tgz -l modules-$KERNEL_NAME""U.tgz
		tar -xzf modules-$KERNEL_NAME""U.tgz
		rm -f modules-$KERNEL_NAME""U.tgz
		cd /boot
		tftp $qrm -g -r boot/vmlinuz-$KERNEL_NAME""U -l vmlinuz-$KERNEL_NAME""U
		mv vmlinuz-$KERNEL_NAME""U vmlinuz-$xen_guest_kernel_version
		tftp $qrm -g -r boot/System.map-$KERNEL_NAME""U -l System.map-$KERNEL_NAME""U
		mv System.map-$KERNEL_NAME""U System.map-$xen_guest_kernel_version
		cd /

		# using hardcoded kernel version for the 2.4 + 2.6 xen-kernelx
		# to have both version available for starting partitions
		if [ "$KERNEL_NAME" == "xen-2.4" ]; then
			node_second_xen_kernel="xen-2.6U"
			node_second_xen_kernel_version="2.6.11-xenU"
		elif [ "$KERNEL_NAME" == "xen-2.6" ]; then
			node_second_xen_kernel="xen-2.4U"
			node_second_xen_kernel_version="2.4.30-xenU"
		fi
		echo "getting 2. xen guest kernel $node_second_xen_kernel version $node_second_xen_kernel_version"
		cd /lib/modules
		tftp $qrm -g -r boot/modules-$node_second_xen_kernel.tgz -l modules-$node_second_xen_kernel.tgz
		tar -xzf modules-$node_second_xen_kernel.tgz
		rm -f modules-$node_second_xen_kernel.tgz
		cd /boot
		tftp $qrm -g -r boot/vmlinuz-$node_second_xen_kernel -l vmlinuz-$node_second_xen_kernel
		mv vmlinuz-$node_second_xen_kernel vmlinuz-$node_second_xen_kernel_version
		tftp $qrm -g -r boot/System.map-$node_second_xen_kernel -l System.map-$node_second_xen_kernel
		mv System.map-$node_second_xen_kernel System.map-$node_second_xen_kernel_version
		cd /
	fi
}

function prepare_iscsi() {
	# iscsi
	echo "starting syslogd &&  klogd"
	syslogd &&  klogd

	echo "# created by qrm" > /etc/iscsi.conf
	echo "DiscoveryAddress=$STORAGE_SERVER_IP" >> /etc/iscsi.conf
	echo "TargetName=$ISCSI_TARGET_NAME" >> /etc/iscsi.conf
	echo "LUN=$ISCSI_LUN" >> /etc/iscsi.conf
	echo "" >> /etc/iscsi.conf

	echo "# created by qrm" > /etc/initiatorname.iscsi
	echo "InitiatorName=$ISCSI_INITIATOR" >> /etc/initiatorname.iscsi

	rm -f /dev/iscsictl 1>/dev/null 2>&1
	if echo $KERNEL_VERSION | grep 2.6 1>/dev/null; then
		mknod /dev/iscsictl c 253 0
	else
		mknod /dev/iscsictl c 254 0
	fi
	
	# old iscsi initiator
	if ls /lib/modules/$KERNEL_VERSION/misc/iscsi_sfnet* 1>/dev/null 2>&1; then
	
		if ! grep iscsi_sfnet /lib/modules/$KERNEL_VERSION/modules.dep 1>/dev/null 2>&1; then
			echo "iscsi_sfnet module not yet in modules.dep file. Adding it now"
			echo >> /lib/modules/$KERNEL_VERSION/modules.dep
			if echo $KERNEL_VERSION | grep 2.6 1>/dev/null; then
				echo "/lib/modules/$KERNEL_VERSION/misc/iscsi_sfnet.ko:" >> /lib/modules/$KERNEL_VERSION/modules.dep
			else
				echo "/lib/modules/$KERNEL_VERSION/misc/iscsi_sfnet.o:" >> /lib/modules/$KERNEL_VERSION/modules.dep
			fi
		fi
		if ! /etc/init.d/iscsi start; then
			set_node_error "ERROR: Iscsi could not started correctly"
			start_emergency_console
		fi
		
	# new initiator
	elif ls /lib/modules/$KERNEL_VERSION/misc/iscsi_if* 1>/dev/null 2>&1; then

		insmod /lib/modules/$KERNEL_VERSION/misc/iscsi_if.ko
		insmod /lib/modules/$KERNEL_VERSION/misc/iscsi_tcp.ko
		mkdir -p /var/db/iscsi/
		echo "starting iscsi-daemon"
		iscsid
		ISCSI_RECORD=`iscsiadm -m discovery --type sendtargets --portal $STORAGE_SERVER_IP:$ISCSI_PORT | grep $STORAGE_SERVER_IP:$ISCSI_PORT | awk {' print $1 '} | sed -e "s/\[//" | sed -e "s/\]//"`
		echo "Discovered $STORAGE_SERVER_IP:$ISCSI_PORT and got record $ISCSI_RECORD"
		if [ "$ISCSI_RECORD" != "" ]; then
		echo "connecting target ......."
			iscsiadm -m node --record $ISCSI_RECORD --login
		fi

	else
		set_node_error "ERROR: could not find out which iscsi-initiator should be started"
		start_emergency_console
	fi

	sleep 10
	ISCSIGATHERLOOP=1
	while (true); do
		myroothd=`grep "lun $ISCSI_LUN$" /var/log/messages | grep disk | sed -e "s/.*scsi disk//" | tail -n1 | awk {' print $1 '}`
		myroothdpartition="/dev/$myroothd$ISCSI_ROOT_PARTITION"
		if [ "$myroothd" != "" ]; then
			echo "found harddisk $myroothd, using $myroothdpartition as root-filesystem (using $ISCSI_ROOT_FS_TYPE)"
			export myroothd myroothdpartition
			break
		fi
		if (( $ISCSIGATHERLOOP > 5 )); then
			set_node_error "ERROR: Could not find the root harddisk to connect"
			start_emergency_console
		fi
		echo "retrying to gather for root harddisk to connect ($ISCSIGATHERLOOP time)"
		ISCSIGATHERLOOP=$(( ISCSIGATHERLOOP + 1 ))
		sleep 5
	done
	killall syslogd 1>/dev/null 2>&1
	killall klogd 1>/dev/null 2>&1
	return 0
}



function manage_shared_and_private() {
	local OLD_IFS=$IFS
	if [ "$FILESYSTEM_IMAGE_IS_SHARED" == "true" ] && [ -f /mnt/private/shared.conf ]; then
		. /mnt/private/shared.conf
		#Creating nessesary default  directories
	if [ ${VE_ID} == "0" ];then
		custom_node=/mnt/private/$VE_ID/$CS_ID/custom
	else
		custom_node=/mnt/private/$VE_ID/$CS_VEM/custom
	fi
		if [ ! -d $custom_node ]; then
			echo "Creating node customization"
			mkdir -p $custom_node
			if [ -x /mnt/private/$VE_ID/init_vem ] && [ ${VE_ID} == "0" ]; then
				/mnt/private/$VE_ID/init_vem $VE_ID $CS_ID
			elif [ -x /mnt/private/$VE_ID/init_vem ]; then
				/mnt/private/$VE_ID/init_vem $VE_ID $CS_VEM
			fi
		fi
		echo "Mounting /mnt/custom/node"
		mkdir -p /mnt/custom/node
		/bin/mount -o bind $custom_node /mnt/custom/node
		custom_ve=/mnt/private/$VE_ID/custom
		if [ ! -d $custom_ve ]; then
			echo "Creating virtual-environment  customization"
			mkdir -p $custom_ve
		fi
		echo "Mounting /mnt/custom/ve"
		mkdir -p /mnt/custom/ve
		/bin/mount -o bind $custom_ve /mnt/custom/ve
	
		# Mounting original root directory to permit later remounting of nesseasry 
		# parts participating in private_exclude list
		shared="/mnt/private/shared_dir"
		if [ ! -d $shared ]; then
			mkdir -p $shared
		fi
		echo "Mounting original orig /mnt/"
		/bin/mount -o bind /mnt/ $shared

		#Monting basic private directories
		IFS=' '
		for DIR in $private_list_basic; do

			if [ ${VE_ID} == "0" ];then
        	private_dir="/mnt/private/${VE_ID}/${CS_ID}/${DIR}"
			else
					private_dir="/mnt/private/${VE_ID}/${CS_VEM}/${DIR}"
			fi
			if [ ! -d $private_dir ]; then
				echo "Creating private dir $private_dir"
				mkdir -p $private_dir
				if [ "$DIR" == "/var" ]; then
					echo "Populating $DIR"
					/bin/cp -aR /mnt/${DIR}/* $private_dir
				fi
			fi
			
			echo "Mounting $DIR"
			/bin/mount -o bind $private_dir /mnt/$DIR

			if [ "$DIR" == "/var" ]; then
			    #Taking care of /var specific parametrers
 			    /bin/chown 0:0 /mnt/${DIR}
			    /bin/chmod 755 /mnt/${DIR}
			else
			    #No need tp populate tmp or log directory
			    /bin/chown 0:0 /mnt/${DIR}
			    /bin/chmod 777 /mnt/${DIR}
			    /bin/chmod +t /mnt/${DIR}
			fi
		done

		#Mounting additional private directories
		local OLD_IFS=$IFS
		for item in $private_list_additional; do
			IFS="|"
			opt=($item)
			DIR=${opt[0]}
			ch_own=${opt[1]}
			ch_mod1=${opt[2]}
			ch_mod2=${opt[3]}
			if [ ${VE_ID} == "0" ];then
				private_dir="/mnt/private/${VE_ID}/${CS_ID}/${DIR}"
			else
				private_dir="/mnt/private/${VE_ID}/${CS_VEM}/${DIR}"
			fi
			if [ ! -d $private_dir ]; then
			    echo "Creating private dir $private_dir"
				mkdir -p $private_dir
			    if ls /mnt/$DIR/* 1>/dev/null 2>&1; then
					echo  "Populating $DIR"
					cp -aR /mnt/${DIR}/* $private_dir
				fi
			fi
			echo "Mounting $DIR"
			/bin/mount -o bind $private_dir /mnt/${DIR}
			/bin/chown $ch_own /mnt/${DIR}
			/bin/chmod $ch_mod1 /mnt/${DIR}
			if [ ! -z $ch_mod2 ]; then
				/bin/chmod $ch_mod1 /mnt/${DIR}
			fi
		done
		IFS=$OLD_IFS

		#Mounting to be excluded from private directories 
		for DIR in $private_list_excludes; do
			if [ ${VE_ID} == "0" ];then
				dir_mnt_point=/mnt/private/${VE_ID}/${CS_ID}/${DIR}
			else
				dir_mnt_point=/mnt/private/${VE_ID}/${CS_VEM}/${DIR}
			fi
			if [ ! -d $dir_mnt_point ]; then
				mkdir -p $dir_mnt_point
			fi
			echo "Mounting dir ${DIR} as shared"
			/bin/mount -o bind ${shared}/${DIR} /mnt/${DIR}
		done
	fi
	IFS=$OLD_IFS
	return 0
}



function manage_var_run() {
	VAR_LOOP=0
	local OLD_IFS=$IFS
	IFS=$'\n'
	echo "peparing /var/run"
	# gather dirs in /var/run
	for var_run_dir in `ls -al /mnt/var/run | grep ^d`; do
		IFS=$OLD_IFS
		VAR_ARRAY=($var_run_dir)
		VAR_DIR=${VAR_ARRAY[8]}
		if [ "$VAR_DIR" != "." ] && [ "$VAR_DIR" != ".." ]; then
			VAR_USER=${VAR_ARRAY[2]}
			VAR_GROUP=${VAR_ARRAY[3]}
			VAR_RUN_DIR[$VAR_LOOP]="$VAR_DIR $VAR_USER $VAR_GROUP"
			VAR_LOOP=$(( VAR_LOOP + 1 ))
		fi
	done
	# mount in tempfs
	mount -n -t tmpfs none /mnt/var/run
	rm -f /mnt/var/log/wtmp
	ln -s -f ../run/wtmp /mnt/var/log/wtmp
	touch /mnt/var/run/wtmp
	chmod 0664 /mnt/var/run/wtmp
	# recreate the directory structure
	for (( d=0;d<$VAR_LOOP;d++)); do
		VAR_ARRAY=(${VAR_RUN_DIR[$d]})
		VAR_DIR=${VAR_ARRAY[0]}
		VAR_USER=${VAR_ARRAY[1]}
		VAR_GROUP=${VAR_ARRAY[2]}
		mkdir -p /mnt/var/run/$VAR_DIR
		chown $VAR_USER:$VAR_GROUP /mnt/var/run/$VAR_DIR 1>/dev/null 2>&1
	done
	IFS=$OLD_IFS
	return 0
}



function set_install_status() {
	local STATUS_MSG=$1
	$QRM_NODES_BASE_DIR/qrm/bin/qrm-cli event add -k Image.Install.Status -t imageName=$FILESYSTEM_IMAGE_NAME -t message="$STATUS_MSG" --internal_vm_id $CS_ID
	echo "$STATUS_MSG"
}

function set_install_error() {
	local ERROR_MSG=$1
	$QRM_NODES_BASE_DIR/qrm/bin/qrm-cli event add -k Image.Install.Error -t imageName=$FILESYSTEM_IMAGE_NAME -t message="$ERROR_MSG" --internal_vm_id $CS_ID
	echo "$ERROR_MSG"
}



# configures the filesystem-image services
function qrm_filesystem_image_configure_services() {
	local OLD_IFS=$IFS
	DISTRIBUTION=`get_linux_distribution`
	if [ -f "$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/$DISTRIBUTION" ]; then
		DISTRIBUTION_SPECIFIC_FUNCTIONS=$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/$DISTRIBUTION
	else
		DISTRIBUTION_SPECIFIC_FUNCTIONS=$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/generic
	fi
	. $DISTRIBUTION_SPECIFIC_FUNCTIONS
	echo "starting service configuration"
	if [ -z "$QRM_KEEP_SERVICES" ]; then
		echo "Applying default base-services configuration"
		ALLSERVICES=`_services_list | awk {' print $1 '} | grep -v : | grep -v qrm`
		if [ "$QRM_NODES_LOG_DIR" == "syslog" ]; then
			QRM_FILESYSTEM_BACKUP_DIR=/var/log/backup/$FILESYSTEM_IMAGE_NAME/
		else
			QRM_FILESYSTEM_BACKUP_DIR=$QRM_NODES_LOG_DIR/backup/$FILESYSTEM_IMAGE_NAME/
		fi
		mkdir -p $QRM_FILESYSTEM_BACKUP_DIR
		echo ". $QRM_NODES_BASE_DIR/qrm/include/qrm-functions" >> $QRM_FILESYSTEM_BACKUP_DIR/services-backup.conf
		echo ". $DISTRIBUTION_SPECIFIC_FUNCTIONS" >> $QRM_FILESYSTEM_BACKUP_DIR/services-backup.conf
		IFS=$'\n'
		for SERVICE in $ALLSERVICES; do
			if ! _image_base_services | grep $SERVICE 1>/dev/null; then
				# switch off
				_services_disable $SERVICE
				# backup
				echo "_services_enable $SERVICE" >> $QRM_FILESYSTEM_BACKUP_DIR/services-backup.conf
			fi
		done
		IFS=$OLD_IFS
		chmod +x $QRM_FILESYSTEM_BACKUP_DIR/services-backup.conf
		echo "Configured the filesystem-image with the base-services"
		echo "Original service configuration for $FILESYSTEM_IMAGE_NAME backed up in $QRM_FILESYSTEM_BACKUP_DIR/"
	else
		echo "Staying with the current service configuration"
	fi
	# remove the qrm-server service in any way from the filesystem-image
	_services_remove qrm-server 1>/dev/null 2>&1
	IFS=$OLD_IFS
	return 0
}


# configures the filesystem-image network
function qrm_filesystem_image_configure_network() {
	local OLD_IFS=$IFS
	DISTRIBUTION=`get_linux_distribution`
	if [ -f "$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/$DISTRIBUTION" ]; then
		DISTRIBUTION_SPECIFIC_FUNCTIONS=$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/$DISTRIBUTION
	else
		DISTRIBUTION_SPECIFIC_FUNCTIONS=$QRM_NODES_BASE_DIR/qrm/include/dist_specific.d/generic
	fi
	. $DISTRIBUTION_SPECIFIC_FUNCTIONS
	echo "starting network configuration"
	if [ -z "$QRM_KEEP_NETWORKING" ]; then
		echo "Removing current network interface configuration"
		if [ "$QRM_NODES_LOG_DIR" == "syslog" ]; then
			QRM_FILESYSTEM_BACKUP_DIR=/var/log/backup/$FILESYSTEM_IMAGE_NAME/
		else
			QRM_FILESYSTEM_BACKUP_DIR=$QRM_NODES_LOG_DIR/backup/$FILESYSTEM_IMAGE_NAME/
		fi
		mkdir -p $QRM_FILESYSTEM_BACKUP_DIR
		IFS=$'\n'
	 	for INTERFACECONF in `_image_list_network_interfaces`; do
			INTERFACE=`echo $INTERFACECONF | sed -e "s/\/.*ifcfg-//"`
			echo "Removing configuration for $INTERFACE (backed up in $QRM_FILESYSTEM_BACKUP_DIR/)"
			/bin/mv $INTERFACECONF $QRM_FILESYSTEM_BACKUP_DIR/
		done
		IFS=$OLD_IFS
	else
		echo "Keeping network configuration for filesystem-image $FILESYSTEM_IMAGE_NAME"
	fi
	if [ ! -z "$QRM_FILESYSTEM_IMAGE_HOSTNAME" ]; then
		echo "Setting hostname to $QRM_FILESYSTEM_IMAGE_HOSTNAME for filesystem-image $FILESYSTEM_IMAGE_NAME"
		_image_set_hostname
	fi
	IFS=$OLD_IFS
	return 0
}






function qrm_prepare_private() {

	local root=$1;shift
	local excludes=$1;shift
	local additions=$*
	local log=""
	local OLD_IFS=$IFS
	
	#Setting the default values we always want to use
	PRIVATE_LIST_BASIC="$PRIVATE_LIST_BASIC /var /tmp"
	if [ ! -z "$QRM_NODES_LOG_DIR" ] && [ "$QRM_NODES_LOG_DIR" != "/tmp" ] && [ "$QRM_NODES_LOG_DIR" != "/tmp/" ] && [ "$QRM_NODES_LOG_DIR" != "syslog" ]; then
		PRIVATE_LIST_BASIC="$PRIVATE_LIST_BASIC $QRM_NODES_LOG_DIR"
	fi
	
	IFS=":"
	PRIVATE_LIST_EXCLUDES=($excludes)
	IFS=$OLD_IFS

	if [ ! -d $root/custom ]; then
		mkdir -p $root/custom/node $root/custom/ve
	fi
	if [ ! -d $root/private ]; then
		mkdir $root/private
	fi

	#Now for each directory we want to make private we need to determine
	#its mode for future mount 
	unset PRIVATE_LIST_ADDITIONS
	IFS=" "
	for dir in ${additions[*]}; do
		if [ ! -d $dir ]; then
			mkdir -p $dir
		fi
		mode=`stat $dir | grep Uid | awk '{print $2}' | sed s'/[a-zA-Z\/\(\)-]//g'`
		PRIVATE_LIST_ADDITIONS="$PRIVATE_LIST_ADDITIONS $dir|0:0|$mode"
	done

	echo "private_list_basic=\"$PRIVATE_LIST_BASIC\""              >$root/private/shared.conf
	echo "private_list_additional=\"$PRIVATE_LIST_ADDITIONS\""     >> $root/private/shared.conf
	echo "private_list_excludes=\"${PRIVATE_LIST_EXCLUDES[*]}\""   >> $root/private/shared.conf
	IFS=$OLD_IFS


}



function install_image() {

	# required parameter :
	# INSTALL_IMAGE (true/false)
	# INSTALL_FROM_TARGET_IP_ADDRESS  (ip of the sources system)
	# INSTALL_FROM_TARGET_PATH (path to image)

	local OLD_IFS=$IFS
	echo "preparing $QRM_NODES_BASE_DIR/qrm/"
	mkdir -p $QRM_NODES_BASE_DIR/qrm/
	mount -t tmpfs none $QRM_NODES_BASE_DIR/qrm/
	cd $QRM_NODES_BASE_DIR/qrm/
	run_services initrd
	cd /

	# sending starting event
	export QRM_SERVER_IP=${qrm}
	export PORT
	set_install_status "Starting the Installation"

	source_root=/mnt/source
	target_root=/mnt/target
	mkdir -p $source_root
	mkdir -p $target_root
	
	if [ "$INSTALL_FROM_TARGET_IP_ADDRESS" == "" ]; then
		set_install_error "No install target ip address given (INSTALL_FROM_TARGET_IP_ADDRESS)"
		start_emergency_console
	fi
	INSTALL_FROM_TARGET_PATH=${INSTALL_FROM_TARGET_PATH:-"/"}
	
	echo "Mounting source from $INSTALL_FROM_TARGET_IP_ADDRESS:$INSTALL_FROM_TARGET_PATH by nfs"
	if ! mount -t nfs -o ro $INSTALL_FROM_TARGET_IP_ADDRESS:$INSTALL_FROM_TARGET_PATH $source_root; then
		set_install_error "Could not mount source from $INSTALL_FROM_TARGET_IP_ADDRESS:$INSTALL_FROM_TARGET_PATH by nfs"
		start_emergency_console
	fi
	set_install_status "Mounted source from $INSTALL_FROM_TARGET_IP_ADDRESS:$INSTALL_FROM_TARGET_PATH by nfs"

	# iterate through additional mounts
	source_size=$( df -m $source_root | tail -n 1 | awk '{ print $3 }')

	if [ "$STORAGE_TYPE_INTERFACE" == "iscsi" ] ; then
		#start iscsi magic
		set_install_status "Starting iscsi"
		prepare_iscsi

		if fdisk -l /dev/$myroothd 2>&1 | grep "doesn't contain a valid" >/dev/null 2>&1; then
			set_install_error "No valid partiton table on iscsi-device /dev/$myroothd"
			start_emergency_console
		fi

		set_install_status "Creating partition table. " 
		#TODO use cfdisk, or sfdisk for better reliability
		echo -e "d\n4\nd\n3\nd\n2\nd\n1\nn\np\n1\n\n\nw\n" > /tmp/fdisk.input
		fdisk /dev/$myroothd < /tmp/fdisk.input > /dev/null 2>&1
		if [ $? != 0 ] ; then
			set_install_error "Fdisk of device /dev/$myroothd appears to have failed"
			start_emergency_console
		fi

		# setting partitions statically for now
		myrootpartition=1

		set_install_status "Creating filesystem on /dev/${myroothd}${myrootpartition}"
		if [ "$ISCSI_ROOT_FS_TYPE" == "ext2" ]; then
			mke2fs /dev/${myroothd}${myrootpartition}
		elif [ "$ISCSI_ROOT_FS_TYPE" == "ext3" ]; then
			mke2fs -j /dev/${myroothd}${myrootpartition}
		elif [ "$ISCSI_ROOT_FS_TYPE" == "reiserfs" ]; then
			set_install_error "Filesystem type $ISCSI_ROOT_FS_TYPE is not supported yet"
			start_emergency_console
		else
			set_install_error "Filesystem type $ISCSI_ROOT_FS_TYPE is not supported yet"
			start_emergency_console
		fi		

		set_install_status "Mounting iscsi device /dev/${myroothd}${myrootpartition} as target"
		if ! mount -t $ISCSI_ROOT_FS_TYPE -o rw /dev/${myroothd}${myrootpartition} /mnt/target; then
			set_install_error "Could not mount the iscsi device /dev/${myroothd}${myrootpartition}"
			start_emergency_console
		fi
		if ! cat /proc/mounts | grep "/mnt/target" > /dev/null 2>&1; then
			set_install_error "There were problems mounting /dev/${myroothd}${myrootpartition}"
			start_emergency_console
		fi
		target_size=$(df -m $target_root| tail -n 1 | awk '{ print $4 }')

	elif [ "$STORAGE_TYPE_INTERFACE" == "nfs" ] ; then
		if ! mount -t nfs -o rw $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER /mnt/target; then
			set_install_error "Could not mount $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER by nfs"
			start_emergency_console
		fi
		target_size=$(df -m $target_root| tail -n 1 | awk '{ print $4 }')
	fi # End target mounting

	if [ $source_size -gt $target_size ] ; then
		set_install_status "WARNING: Source size is greater than target size (${source_size}M > ${target_size}M) (-> ignore in case of image-cloning)"
		# this can be no problem e.g. in case of cloning from an existing filesystem-image stored on a nfs-server
	else
		echo "Source size : ${source_size}M"
		echo "Target size : ${target_size}M"
		set_install_status "Starting populating the image"
	fi

	IFS=' '
	# excludes configured by QRM_FILESYSTEM_IMAGE_EXCLUDES
	for i in $QRM_FILESYSTEM_IMAGE_EXCLUDES; do
		if [ -d /mnt/source/$i ]; then
			EXCLUDE_PATH=`echo $i | sed -e "s#^/##"`
			# include excluded dir
			exclude_list="$exclude_list --exclude $EXCLUDE_PATH/*"
		fi
	done
	# exclude the automounts
	QRM_FILESYSTEM_DEFAULT_EXCLUDES="/media/cdrom /media/cdrom1 /media/floppy /proc /sys /sysfs"
	for i in $QRM_FILESYSTEM_DEFAULT_EXCLUDES; do
		if [ -d /mnt/source/$i ]; then
			EXCLUDE_PATH=`echo $i | sed -e "s#^/##"`
			# not include dir because of eventual automount
			exclude_list="$exclude_list --exclude $EXCLUDE_PATH"
			mkdir -p /mnt/target/$EXCLUDE_PATH
		fi
	done
	IFS=$OLD_IFS

	# preparing the progressbar
	PROGRESS=`mktemp -q /mnt/target/XXXXXX`
	touch $PROGRESS
	echo -n "."
	tail -f $PROGRESS | while read LINE; do \
	if [ "$loop" == 1000 ]; then  \
		echo -n ".";  \
		loop=0; \
		fi;   \
		loop=$(( loop +1 ));  \
	done &
	TAIL_PID=`ps ax | grep "tail -f $PROGRESS" | grep -v grep | awk {' print $1 '}`

	# running rsync
	rsync_cmd="/bin/rsync -aHvS --numeric-ids $exclude_list /mnt/source/* /mnt/target/"
	echo "$rsync_cmd" > /tmp/rsync-cmd
	echo "exit \$?" >> /tmp/rsync-cmd
	chmod +x /tmp/rsync-cmd

	if ! /tmp/rsync-cmd 1>$PROGRESS; then
		kill $TAIL_PID 1>/dev/null 2>&1
		/bin/rm -f $PROGRESS
		set_install_error "Could not transfer the filesystem-image content"
		start_emergency_console
	fi
	kill $TAIL_PID 1>/dev/null 2>&1
	/bin/rm -f $PROGRESS
	echo

	# prepare target
	set_install_status "Preparing target as image"
	cd /mnt/target
	rm -rf var/log/*
	cd etc
	rm -f mtab qrm/easymigration.conf
	ln -sf ../proc/mounts mtab
	# export rootfs var for the distribution specific functions
	export QRM_FILESYSTEM_IMAGE_ROOT_FS=/mnt/target/
	
	# create private/shared dirs
	# configured by QRM_FILESYSTEM_IMAGE_PRIVATE_EXCLUDE + QRM_FILESYSTEM_IMAGE_PRIVATE_ADD
	qrm_prepare_private /mnt/target "$QRM_FILESYSTEM_IMAGE_PRIVATE_EXCLUDE" $QRM_FILESYSTEM_IMAGE_PRIVATE_ADD

	# service config
	if ! qrm_filesystem_image_configure_services; then
		set_install_error "The service configuration on the filesystem-image failed"
		start_emergency_console
	fi
	# network config
	if ! qrm_filesystem_image_configure_network; then
		set_install_error "The network configuration on the filesystem-image failed"
		start_emergency_console
	fi
	cd /

	# for all iscsi images stop the iscsi-daemon, keeps old_root busy
	killall iscsid 1>/dev/null 2>&1

	# TODO iterate through and unmount source
	umount /mnt/source
	umount /mnt/target	

	# stopping qrm-services, restarting them at init 3
	killall -9 qrm-execd 1>/dev/null 2>&1
	killall -9 qrm-tcp-monitor 1>/dev/null 2>&1
	killall -9 qrm-infod 1>/dev/null 2>&1
	umount $QRM_NODES_BASE_DIR/qrm/ 1>/dev/null 2>&1

	# sending starting event
	set_install_status "Installation finished"
	return 0
}



function manage_dev() {

	local needed_inodes
	local devices_tgz=/mnt/private/dev.tar

	# only prepare a dev dir in tmpfs is the storage can not handle special (linux) files

	if [ -f ${devices_tgz} ] ;then
		echo "preparing dev directory - fix dev permissions"
		
		needed_inodes=$(tar tf ${devices_tgz} | wc -l)
		needed_inodes=$((needed_inodes+2000))

    		mount -n -o nr_inodes=${needed_inodes} -t tmpfs none /mnt/dev

		if ! tar -C /mnt -xf ${devices_tgz}; then
			echo "ERROR: Could not prepare /dev directory. Please add more RAM and try again."
			return 1
		fi
		mount -o bind /mnt/dev /mnt/dev
		return 0
	fi
}



function manage_modules() {
	local OLD_IFS=$IFS
	echo "preparing modules directory"
	if [ ! -d /mnt/lib/modules/ ]; then
		mkdir -p /mnt/lib/modules/
	fi
	if [ -d /mnt/lib/modules/$KERNEL_VERSION ] && [ ! -h /mnt/lib/modules/$KERNEL_VERSION ]; then
		# found the same kernel version as real directory. Backing it up
		/bin/mv /mnt/lib/modules/$KERNEL_VERSION /mnt/lib/modules/$KERNEL_VERSION.org 1>/dev/null 2>&1
	fi
	# find old qrm link
	IFS=$'\n'
	for n in `ls /mnt/lib/modules/`; do
		if readlink /mnt/lib/modules/$n 2>/dev/null | grep "/var/qrm/modules" 1>/dev/null 2>&1; then
			CURRENT_MODULES_VERSION=$n
		fi
	done
	# if current = kernel version we do not need to move the modules
	if [ "$CURRENT_MODULES_VERSION" != "$KERNEL_VERSION" ] || [ ! -d /mnt/var/qrm/modules/ ]; then
		# clean up
		mkdir -p /mnt/var/qrm/modules/
		/bin/rm -rf /mnt/var/qrm/modules/*
		/bin/rm -f /lib/modules/$KERNEL_VERSION/build
		/bin/rm -f /lib/modules/$KERNEL_VERSION/source
		# moving the modules
		if ! /bin/mv /lib/modules/$KERNEL_VERSION/* /mnt/var/qrm/modules/; then
			return 1
		fi
		# removing the old link
		/bin/rm -f /mnt/lib/modules/$CURRENT_MODULES_VERSION
		# creating new symlink for the modules
		ln -sf /var/qrm/modules/ /mnt/lib/modules/$KERNEL_VERSION
	fi
	umount /lib/modules
	IFS=$OLD_IFS
	return 0
}



# start main

export SHELL=/bin/bash

PATH=/sbin:/bin:/usr/bin:/usr/sbin
export PATH

mount -t proc proc /proc
mkdir -p /tmp

if grep sysfs /proc/filesystems 1>/dev/null 2>&1; then
	echo "Mounting sysfs"
	mount -t sysfs none /sys
fi

NICS="`ifconfig -a|grep eth| cut -f1 -d ' '`"
cd /proc/sys/net/ipv4/conf
for i in all default $NICS
do
 echo 1 > $i/arp_filter
 echo 1 > $i/rp_filter
done
cd /

# load network card modules
echo "Loading network card modules"
depmod -a 1>/dev/null 2>&1
hwsetup -p

#below is needed for pivot_root to work
echo 0x0100 > /proc/sys/kernel/real-root-dev

export `eval cat /proc/cmdline`
MYIP="`echo $ip | cut -d : -f1`"
MYBOOTSERVER="`echo $ip | cut -d : -f2`"
MYGATEWAY="`echo $ip | cut -d : -f3`"
MYNETMASK="`echo $ip | cut -d : -f4`"
MYBROADCAST="`ipcalc --broadcast $MYIP $MYNETMASK | cut -f2 -d =`"
MYNODEPARAMETER="/var/qrm/conf/node-parameter.conf"
NICLOOP="0"
NICS="`ifconfig -a|grep eth| cut -f1 -d ' '`"
QRM_MAC_ADDRESS=`echo $BOOTIF | sed -e "s/^01-//" | sed -e "s/-/:/g"`
QRM_INTERFACE=`ifconfig -a | grep -i "$QRM_MAC_ADDRESS" | awk {' print $1 '}`
PORT=8080

# check network cards
if [ -z "$NICS" ]; then
	echo "ERROR: No network cards found!"
	exit 1
fi
if [ -z "$QRM_INTERFACE" ]; then
	echo "ERROR: Kernel does not have the support for the network card $QRM_MAC_ADDRESS !"
	exit 1
fi

# portmap setup
ifconfig lo 127.0.0.1 up
portmap
echo 6 > /proc/sys/kernel/printk

echo "bringing up $QRM_INTERFACE:qrm with $MYIP/$MYNETMASK/$MYBROADCAST"
ifconfig $QRM_INTERFACE down 2>&1 >/dev/null
ifconfig $QRM_INTERFACE up 0.0.0.0 2>&1 >/dev/null
ifconfig $QRM_INTERFACE:qrm $MYIP netmask $MYNETMASK broadcast $MYBROADCAST up 2>&1 >/dev/null
if [ "$MYGATEWAY" != "0.0.0.0" ]; then
        route add default gw $MYGATEWAY 2>&1 >/dev/null
fi
# resolve comp. system type
if [ -n "$vmid" ]; then
        CS_TYPE=vm
        CS_ID=$vmid
else
        CS_TYPE=node
        CS_ID=$nodeid
fi
export CS_TYPE

echo "CSID: $CS_ID ,  CS_TYPE: $CS_TYPE"

mkdir -p `dirname $MYNODEPARAMETER`

arping -f -q -w 3 ${qrm}

RETRYMSG=

# node id 0 -> new node
if [ "$nodeid" == "0" ]; then
        while (true); do
# send new-node event
                echo "${RETRYMSG}sending new-node event to ${qrm}:${PORT}"
		wget -q -O "$MYNODEPARAMETER" "http://${qrm}:${PORT}/monitor/submit.do?command=node_event&event=new_node&agent=$CS_TYPE&mac=$QRM_MAC_ADDRESS&ip=$MYIP"
                N_ID=`cat $MYNODEPARAMETER | grep CS_ID`
                if test "$N_ID" != ""; then
                        break
                fi
                sleep 10
                RETRYMSG="re"
        done
else

        while (true); do
                # nodes-parameter
                echo "${RETRYMSG}getting nodes-parameters from ${qrm}:${PORT}"
                # send starting_system, and get node params back
				wget -q -O "$MYNODEPARAMETER" "http://${qrm}:${PORT}/monitor/submit.do?command=node_event&event=starting_system&agent=$CS_TYPE&id=$CS_ID&mac=$QRM_MAC_ADDRESS&ip=$MYIP"
                N_ID=`cat $MYNODEPARAMETER | grep CS_ID`
                if test "$N_ID" != ""; then
                        break
                fi
                if cat $MYNODEPARAMETER | grep "node not found" 1>/dev/null; then
                        echo "WARNING: Node not found in the database. Sending new node event to ${qrm}:${PORT}"
						wget -q -O "$MYNODEPARAMETER" "http://${qrm}:${PORT}/monitor/submit.do?command=node_event&event=new_node&agent=$CS_TYPE&mac=$QRM_MAC_ADDRESS&ip=$MYIP"
		                N_ID=`cat $MYNODEPARAMETER | grep CS_ID`
        		        if test "$N_ID" != ""; then
                		        break
                		fi
                fi
                RETRYMSG="re-"
                sleep 10
        done
fi
. $MYNODEPARAMETER
export QRM_NODES_BASE_DIR=${QRM_NODES_BASE_DIR:-/usr}
echo "successfully got nodes-parameters from QRM-server at ${qrm}:${PORT}"

echo "sending starting_processes"
current_uptime=`cat /proc/uptime | cut -d'.' -f 1`
MESSAGEDATA="command=node_event&event=starting_processes&id=$CS_ID&ve_id=$VE_ID&agent=$CS_TYPE&uptime=$current_uptime&ip=$MYIP&mac=$QRM_MAC_ADDRESS"
wget -q -O /dev/null "http://${qrm}:${PORT}/monitor/submit.do?$MESSAGEDATA"

# source functions
. $QRM_NODES_BASE_DIR/qrm/include/qrm-functions
. $QRM_NODES_BASE_DIR/qrm/include/qrm-nodes-functions


# idle section 
if [ -z "$FILESYSTEM_IMAGE_NAME" ]; then
	echo "running idle node configuration"
	IDLEHOSTNAME="idle$CS_ID"
	/bin/hostname $IDLEHOSTNAME
	echo "starting syslogd &&  klogd"
	syslogd &&  klogd
	touch /etc/initrd
	echo idle-initrd >> /etc/initrd	
	echo "preparing $QRM_NODES_BASE_DIR/qrm/"
	mkdir -p $QRM_NODES_BASE_DIR/qrm/
	mount -t tmpfs none $QRM_NODES_BASE_DIR/qrm/
	cd $QRM_NODES_BASE_DIR/qrm/
	run_services initrd
	cd /
	# exit here for idle images
	echo "finished idle node configuration"
	exit
fi


# hardware detection / x-configuration
echo "starting the hardware detection"
# preparing /lib/modules
mount -t tmpfs none /lib/modules
cd /lib/modules
tftp $qrm -g -r boot/modules-$KERNEL_NAME.tgz -l modules-$KERNEL_NAME.tgz
tar -xzf modules-$KERNEL_NAME.tgz
rm -f modules-$KERNEL_NAME.tgz
export KERNEL_VERSION=`ls`
# preparing /boot
mkdir -p /boot
mount -t tmpfs none /boot
cd /boot
tftp $qrm -g -r boot/vmlinuz-$KERNEL_NAME -l vmlinuz-$KERNEL_NAME
mv vmlinuz-$KERNEL_NAME vmlinuz-$KERNEL_VERSION
tftp $qrm -g -r boot/System.map-$KERNEL_NAME -l System.map-$KERNEL_NAME
mv System.map-$KERNEL_NAME System.map-$KERNEL_VERSION
cd /


# xen pre-configuration
xen_kernel_config

# start hardware-detection and pre-configuration
depmod -a 1>/dev/null 2>&1
hwsetup -p
mkxf86config.sh

# install if requested
if [ "$INSTALL_IMAGE" == "true" ]; then
	install_image
fi

# decide from where to boot
if [ "$STORAGE_TYPE_INTERFACE" == "local" ]; then

	# local hd
	LOCAL_ROOT_FS_TYPE=`echo $FILESYSTEM_IMAGE_IDENTIFIER | cut -d'/' -f 1 | cut -d':' -f 1`
	LOCAL_ROOT_DEVICE=`echo $FILESYSTEM_IMAGE_IDENTIFIER | cut -d'/' -f 4- | awk {' print $1 '}`
	echo "mounting local $LOCAL_ROOT_FS_TYPE device $LOCAL_ROOT_DEVICE as new root-fs"
	mount -t $LOCAL_ROOT_FS_TYPE -o rw $LOCAL_ROOT_DEVICE /mnt
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not mount the local root-filesystem $LOCAL_ROOT_DEVICE"
		start_emergency_console
	fi
	# creating old_root
	mkdir -p /mnt/old_root
	mkdir -p /mnt/$QRM_NODES_BASE_DIR/qrm/
	# copying node parameter
	mkdir -p /mnt/`dirname $MYNODEPARAMETER`
	cp $MYNODEPARAMETER /mnt/$MYNODEPARAMETER
	# for udev systems with empty /dev
	if [ ! -e /mnt/dev/console ]; then
		cp -a /dev/console /mnt/dev/
	fi
	umount /mnt
	mount -t $LOCAL_ROOT_FS_TYPE -o ro $LOCAL_ROOT_DEVICE /mnt
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not re-mount the local root-filesystem $LOCAL_ROOT_DEVICE"
		start_emergency_console
	fi

 elif [ "$STORAGE_TYPE_INTERFACE" == "nfs" ]; then

	# the modules needed for nfs
	insmod /lib/modules/$KERNEL_VERSION/sunrpc.* 1>/dev/null 2>/dev/null
	insmod /lib/modules/$KERNEL_VERSION/lockd.* 1>/dev/null 2>/dev/null
	insmod /lib/modules/$KERNEL_VERSION/nfs.* 1>/dev/null 2>/dev/null

	# nfsroot
	echo "mounting $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER by nfs"
	mount -t nfs -o rw $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER /mnt
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not mount the remote root-filesystem $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER by nfs"
		start_emergency_console
	fi
	# creating old_root
	mkdir -p /mnt/old_root
	mkdir -p /mnt/$QRM_NODES_BASE_DIR/qrm/

	# for udev systems with empty /dev
	if [ ! -e /mnt/dev/console ]; then
		cp -a /dev/console /mnt/dev/
	fi
	# shared/private/custom dirs
	manage_shared_and_private
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not create shared/private directories on the filesystem-image"
		start_emergency_console
	fi
	mkdir -p /mnt/`dirname $MYNODEPARAMETER`
	cp -f $MYNODEPARAMETER /mnt/$MYNODEPARAMETER
	# manage dev
	manage_dev
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not create /dev-directory"
		start_emergency_console
	fi
	# prepare kernel modules
	manage_modules
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not configure the kernel modules"
		start_emergency_console
	fi

	# pre-configure
	manage_var_run
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Erros while creating /var/run"
		start_emergency_console
	fi
	# manage fstab
	createfstab
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not prepare the sytems /etc/fstab"
		start_emergency_console
	fi
	# making the network never stop
	adjust_net_init
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Erros while adjusting network init-scripts"
		start_emergency_console
	fi
	# configure X
	xconfig
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not configure X"
		start_emergency_console
	fi
	# remount
	echo "re-mounting $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER read-only"
	mount -t nfs -o remount,ro $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER /mnt
	if [ $? != 0 ] ; then
		set_node_error "ERROR: Could not re-mount the remote root-filesystem $STORAGE_SERVER_IP:$FILESYSTEM_IMAGE_IDENTIFIER by nfs"
		start_emergency_console
	fi


elif [ "$STORAGE_TYPE_INTERFACE" == "iscsi" ]; then
	prepare_iscsi
	if [ -z "$ISCSI_IS_CRYPTED" ]; then
		# regular
		mount -t $ISCSI_ROOT_FS_TYPE -o rw $myroothdpartition /mnt
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not mount the iscsi root-filesystem $myroothdpartition"
			start_emergency_console
		fi
		# creating old_root
		mkdir -p /mnt/old_root
		mkdir -p /mnt/$QRM_NODES_BASE_DIR/qrm/
		# for udev systems with empty /dev
		if [ ! -e /mnt/dev/console ]; then
			cp -a /dev/console /mnt/dev/
		fi

		# shared/private/custom dirs
		manage_shared_and_private
		mkdir -p /mnt/`dirname $MYNODEPARAMETER`
		cp -f $MYNODEPARAMETER /mnt/$MYNODEPARAMETER
		
		# prepare kernel modules
		manage_modules
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not configure the kernel modules"
			start_emergency_console
		fi
		# manage fstab
		createfstab
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not prepare the sytems /etc/fstab"
			start_emergency_console
		fi
		# making the network never stop
		adjust_net_init
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Erros while adjusting network init-scripts"
			start_emergency_console
		fi
		# configure X
		xconfig
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not configure X"
			start_emergency_console
		fi
		# remount ro
		umount /mnt
		mount -t $ISCSI_ROOT_FS_TYPE -o ro $myroothdpartition /mnt
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not re-mount the iscsi root-filesystem $myroothdpartition"
			start_emergency_console
		fi
		# manage dev
		manage_dev
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not create /dev-directory"
			start_emergency_console
		fi
	
 else
	
		# encrypted
		echo "losetup the encrypted device"
		echo "$image_iscsicryptedpassword" | losetup.enc -p 0 -e aes -S $image_iscsicryptedseed /dev/loop0 $myroothdpartition
		# journaling filesystems are not save on losetup devices
		ISCSI_ROOT_FS_TYPE=ext2
		echo "mounting encrypted loop device (fstype $ISCSI_ROOT_FS_TYPE)"
		mount.enc -t $ISCSI_ROOT_FS_TYPE -o rw /dev/loop0 /mnt
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not mount the iscsi root-filesystem $myroothdpartition"
			start_emergency_console
		fi

		# creating old_root
		mkdir -p /mnt/old_root
		mkdir -p /mnt/$QRM_NODES_BASE_DIR/qrm/
		# for udev systems with empty /dev
		if [ ! -e /mnt/dev/console ]; then
			cp -a /dev/console /mnt/dev/
		fi
		# shared/private/custom dirs
		manage_shared_and_private
		mkdir -p /mnt/`dirname $MYNODEPARAMETER`
		cp -f $MYNODEPARAMETER /mnt/$MYNODEPARAMETER
		# prepare kernel modules
		manage_modules
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not configure the kernel modules"
			start_emergency_console
		fi
		# manage fstab
		createfstab
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not prepare the sytems /etc/fstab"
			start_emergency_console
		fi
		# making the network never stop
		adjust_net_init
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Erros while adjusting network init-scripts"
			start_emergency_console
		fi
		# configure X
		xconfig
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not configure X"
			start_emergency_console
		fi
		# remount ro
		umount.enc /mnt
		mount.enc -t $ISCSI_ROOT_FS_TYPE -o ro /dev/loop0 /mnt
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not re-mount the iscsi root-filesystem $myroothdpartition"
			start_emergency_console
		fi
		# manage dev
		manage_dev
		if [ $? != 0 ] ; then
			set_node_error "ERROR: Could not create /dev-directory"
			start_emergency_console
		fi



	fi

	# for all iscsi images stop the iscsi-daemon, keeps old_root busy
	echo "stopping iscsid daemon"
	killall iscsid 1>/dev/null 2>&1


else
	# not supported yet
	set_node_error "ERROR: $STORAGE_TYPE_INTERFACE is not supported yet"
	start_emergency_console
fi

echo "preparing boot directory"
needed=`du -sm /boot/ | awk {' print $1 '}`
needed=$((needed+1))
mount -o size=${needed}m -t tmpfs none /mnt/boot
mv /boot/* /mnt/boot/
umount /boot

echo "preparing $QRM_NODES_BASE_DIR/qrm/"
# 1 mb for qrm files
mount -o size=1m -t tmpfs none /mnt/$QRM_NODES_BASE_DIR/qrm/
mkdir -p /mnt/$QRM_NODES_BASE_DIR/qrm/include /mnt/$QRM_NODES_BASE_DIR/qrm/sbin
/bin/cp -f $QRM_NODES_BASE_DIR/qrm/include/qrm-functions $QRM_NODES_BASE_DIR/qrm/include/qrm-nodes-functions /mnt/$QRM_NODES_BASE_DIR/qrm/include/
/bin/cp -f $QRM_NODES_BASE_DIR/qrm/sbin/qrm-runlevel /mnt/$QRM_NODES_BASE_DIR/qrm/sbin/
cd /

if [ "$STORAGE_TYPE_INTERFACE" == "nfs" ]; then
	# prepare for nfsroot
	echo "Preparing nfsroot filesystem"
	QRM_PREPARE_NFS_ROOT_SCRIPT="/mnt/$QRM_NODES_BASE_DIR/qrm/sbin/qrm-prepare-nfsroot"
	echo "#!/bin/bash" > $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "if [ -x /etc/init.d/portmap ]; then" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "	/etc/init.d/portmap start 1>/dev/null 2>&1" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "fi" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "if [ -x /etc/init.d/nfslock ]; then" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "	/etc/init.d/nfslock start 1>/dev/null 2>&1" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	echo "fi" >> $QRM_PREPARE_NFS_ROOT_SCRIPT
	chmod +x $QRM_PREPARE_NFS_ROOT_SCRIPT
	export QRM_PREPARE_NFS_ROOT="$QRM_NODES_BASE_DIR/qrm/sbin/qrm-prepare-nfsroot && "
fi

OLD_IFS=$IFS
IFS=$'\n'
for SWPSPACE in `cat /proc/partitions |grep '[0-9]' | awk '{print $4}'`; do
	if echo $SWPSPACE | grep '[0-9]' 1>/dev/null; then
		if swapon /dev/${SWPSPACE} 1>/dev/null 2>&1; then
			echo "Activating swap on /dev/${SWPSPACE}"
		fi
	fi
done
IFS=$OLD_IFS

# clean up, so that we will be able to umount initrd
killall portmap   # portmap keeps old root busy
umount /proc

# pivot root
cd /mnt

## encrypted ?
if [ -z "$ISCSI_IS_CRYPTED" ]; then
	pivot_root . old_root
else
	pivot_root.enc . old_root
fi

exec chroot . sh -c "exec $QRM_PREPARE_NFS_ROOT /sbin/init" <dev/console >dev/console 2>&1

# vim:ts=2:sw=2:sts=0
