#!/bin/bash
################################################################################
# Filename: ./src/base/bin/qrm-boot-image
# 
# 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 boot-image script

QRM_SERVER_BASE_DIR=${QRM_SERVER_BASE_DIR:-`readlink /etc/init.d/qrm-server | sed -e "s#/qrm/etc/init.d/qrm-server##g"`}
QRM_UNWANTED_MODULES="cops.o ipddp.o ltpc.o hdlcdrv.o airo_cs.o aironet4500_cs.o airo.o axnet_cs.o fmvj18x_cs.o ibmtr_cs.o netwave_cs.o nmclan_cs.o pcnet_cs.o ray_cs.o smc91c92_cs.o wavelan_cs.o wvlan_cs.o xirc2ps_cs.o xircom_cb.o xircom_tulip_cb.o ppp_async.o ppp_deflate.o ppp_generic.o ppp_synctty.o wavelan.o wd.o winbond-840.o airo_cs.o airo.o hermes.o orinoco_cs.o orinoco.o orinoco_plx.o orinoco_old_cs.o cops.ko ipddp.ko ltpc.ko hdlcdrv.ko airo_cs.ko aironet4500_cs.ko airo.ko axnet_cs.ko fmvj18x_cs.ko ibmtr_cs.ko netwave_cs.ko nmclan_cs.ko pcnet_cs.ko ray_cs.ko smc91c92_cs.ko wavelan_cs.ko wvlan_cs.ko xirc2ps_cs.ko xircom_cb.ko xircom_tulip_cb.ko ppp_async.ko ppp_deflate.ko ppp_generic.ko ppp_synctty.ko wavelan.ko wd.ko winbond-840.ko airo_cs.ko airo.ko hermes.ko orinoco_cs.ko orinoco.ko orinoco_plx.ko orinoco_old_cs.ko de600.ko de620.ko defxx.ko depca.ko hp100.ko hp.ko hp-plus.ko ne2k-pci.ko ne3210.ko ne.ko netwave_cs.ko ipw2100.ko proteon.ko skisa.ko"
QRM_INITRD="$QRM_SERVER_BASE_DIR/qrm/etc/templates/initrd-qrm.tgz"
QRM_INITRD_OPTERON="$QRM_SERVER_BASE_DIR/qrm/etc/templates/initrd-opteron.tgz"
QRM_LINUXRC="$QRM_SERVER_BASE_DIR/qrm/etc/templates/linuxrc"
QRM_BOOT_IMAGE_LOCATION=/

# include common Qrm functions
. $QRM_SERVER_BASE_DIR/qrm/include/qrm-functions
. $QRM_SERVER_BASE_DIR/qrm/include/qrm-server-functions
qrm_get_server_config 1>/dev/null

function usage() {
	echo "Usage $0 <create/clone/remove/validate/list>"
	echo
	echo "      $0 create"
	echo "                   -k/--kernel-version <kernel-version-to-create-from>"
	echo "                   -b/--boot-image <boot-image-name>"
	echo "                   -y/--physical-name <physical-name>"
	echo "                   [-l/--location <path-to-/boot-and-/lib> or <path-to-kernel-rpm-package>]"
	echo "                   [-i/--ip <ip-address-of-a-remote-system>]"
	echo "                   [-f/--flags <Linux|Numa>]"
	echo "                   [-t/--tmpdir <tmpdir>]"
	echo "                   [-m/--with-module <kernel-module-to-include>]"
	echo "                   [-a/--arch <Opteron|Any|Xeon|i686>]"
	echo "                   [-s/--special_support <ISCSI>]"
	echo "                   [-h/--hugemem]"
	echo "                   [--smp]"
	echo "                   [-c/--comments <comments>]"
	echo "                   [-o/--only-physical]"
	echo "                   [--help]"
	echo
	echo "      $0 remove"
	echo "                   -b/--boot-image <name-of-the-boot-image>"
	echo "                   [-y/--physical-name <physical-name>]"
	echo "                   [--help]"
	echo
	echo "      $0 validate"
	echo "                   -b/--boot-image <name-of-the-boot-image>"
	echo "                   [-y/--physical-name <physical-name>]"
	echo "                   [-f/--fix]"
	echo "                   [--help]"
	echo
	echo "      $0 clone"
	echo "                   -b/--boot-image <name-of-the-boot-image>"
	echo "                   -n/--new-boot-image <name-of-the-new-boot-image>"
	echo "                   [-y/--physical-name <physical-name>]"
	echo "                   [-t/--tmpdir <tmpdir>]"
	echo "                   [-m/--with-module <kernel-module-to-include>]"
	echo "                   [-a/--arch <Opteron|Any|Xeon|i686>]"
	echo "                   [-s/--special_support <ISCSI>]"
	echo "                   [-h/--hugemem]"
	echo "                   [--smp]"
	echo "                   [-c/--comments <comments>]"
	echo "                   [--help]"
	echo
	echo "      $0 list"
	echo
	echo "      $0 --help"
	echo
}


function check_tmp_on_tmpfs() {
	if [ $QRM_TEMP == "/tmp" ] || [ $QRM_TEMP == "/tmp/" ];then
		TMPFS=`mount |grep "/tmp" |grep tmpfs |awk {'print $5'}`
		if [ "$TMPFS" == "tmpfs" ];then
			echo "Error: /tmp is mounted as tmpfs filesystem"
			echo "Error: Please umount /tmp"
			return 6
		fi
	fi
}


# qrm_update_initrd_files
function qrm_update_initrd_files() {
	local DIR=$1
	if [ "$DIR" == "" ]; then
		return 1
	fi
	CURRENT=`pwd`
	
	echo "copying linuxrc + qrm-files to the initrd"
	if ! /bin/cp -f $QRM_LINUXRC $DIR/; then
		echo "ERROR: Could not update the linuxrc init file on the initrd"
		umount $DIR 1>/dev/null 2>&1
		return 1
	fi
	chmod +x $DIR/linuxrc
	
	mkdir -p $DIR/sbin
	cat >> $DIR/sbin/qrm_manage_shutdown << EOF
#!/bin/bash
export SHELL=/bin/bash

CONTEXT=\`echo \$0 | sed -e "s#.*\/##g"\`

# get config
. /var/qrm/conf/node-parameter.conf
QRM_INTERFACE=\`ifconfig | grep ":qrm " | awk {' print \$1 '}\`

	function save_shutdown_base() {
		\$QRM_NODES_BASE_DIR/qrm/etc/init.d/qrm-stop
		ifconfig \$QRM_INTERFACE down
	}

	function save_shutdown_halt() {
		/bin/umount -a -r 1>/dev/null 2>&1
	}

	function save_shutdown_reboot() {
		/sbin/reboot
	}


case "\$CONTEXT" in
	qrm_save_reboot)
					save_shutdown_base
					save_shutdown_reboot
					;;
	qrm_save_halt)
					save_shutdown_base
					save_shutdown_halt
					;;
				*)
					echo "Usage : Run as 'qrm_save_reboot' or 'qrm_save_halt' by sym-links"
					exit
esac

EOF
	chmod +x $DIR/sbin/qrm_manage_shutdown
	cd $DIR/sbin/
	ln -sf qrm_manage_shutdown qrm_save_reboot
	ln -sf qrm_manage_shutdown qrm_save_halt
	cd $CURRENT
	mkdir -p $DIR/$QRM_NODES_BASE_DIR/qrm/include $DIR/$QRM_NODES_BASE_DIR/qrm/sbin $DIR/$QRM_NODES_BASE_DIR/qrm/bin
	/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/include/qrm-functions $DIR/$QRM_NODES_BASE_DIR/qrm/include/qrm-functions
	/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/include/qrm-nodes-functions $DIR/$QRM_NODES_BASE_DIR/qrm/include/qrm-nodes-functions
	/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/sbin/qrm-runlevel $DIR/$QRM_NODES_BASE_DIR/qrm/sbin/
	/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli $DIR/$QRM_NODES_BASE_DIR/qrm/bin/
}



# qrm_check_initrd_files
function qrm_check_initrd_files() {
	local DIR=$1
	if [ "$DIR" == "" ]; then
		return 1
	fi

	# linuxrc
	if ! diff $QRM_LINUXRC $DIR/linuxrc; then
		echo "WARNING: linuxrc on the initrd is not up2date. Please use -f to fix it."
		return 1
	fi
	# manage-shutdown
	if [ ! -x $DIR/sbin/qrm_manage_shutdown ]; then
		echo "WARNING: qrm_manage_shutdown not found in the right place. Please use -f to fix it."
		return 1
	fi
	# functions
	for FUNCTION_FILE in qrm-functions qrm-nodes-functions; do
		if ! diff $QRM_SERVER_BASE_DIR/qrm/include/$FUNCTION_FILE $DIR/$QRM_NODES_BASE_DIR/qrm/include/$FUNCTION_FILE; then
			echo "WARNING: $FUNCTION_FILE on the initrd is not up2date. Please use -f to fix it."
			return 1
		fi
	done
	# run-level script
	if ! diff $QRM_SERVER_BASE_DIR/qrm/sbin/qrm-runlevel $DIR/$QRM_NODES_BASE_DIR/qrm/sbin/qrm-runlevel; then
		echo "WARNING: qrm-runlevel on the initrd is not up2date. Please use -f to fix it."
		return 1
	fi
	# qrm-cli
	if ! diff $QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli $DIR/$QRM_NODES_BASE_DIR/qrm/bin/qrm-cli; then
		echo "WARNING: qrm-cli on the initrd is not up2date. Please use -f to fix it."
		return 1
	fi
	echo "All QRM files are up2date on the initrd"
	return 0
}


# fixes/updates a boot-image
function qrm_fix_boot_image() {
	local TMPDIR=`mktemp -q -d $QRM_TEMP/XXXXXX` || return 1
	mkdir -p $TMPDIR/mnt
	/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz
	gunzip $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz
	if ! mount -o loop $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $TMPDIR/mnt; then
		echo "ERROR: Could not mount target boot-image $QRM_BOOT_IMAGE_NAME"
		return 1
	fi
	# update initrd files
	qrm_update_initrd_files $TMPDIR/mnt/
	
	umount $TMPDIR/mnt
	gzip $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img
	/bin/mv $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img
	/bin/rm -rf $TMPDIR/mnt
	rmdir $TMPDIR 1>/dev/null 2>&1
	return 0
}


# creates a boot-image
function qrm_create_boot_image() {
	CURRENT=`pwd`
	local MODULES_SUFFIX="o"
	if ! qrm_validate_input "$QRM_BOOT_IMAGE_NAME" || [ -z "$QRM_BOOT_IMAGE_KERNEL_VERSION" ]; then
		echo "Usage : export QRM_BOOT_IMAGE_NAME=<boot-image-name> && export QRM_BOOT_IMAGE_KERNEL_VERSION=<kernel-version> && QRM_BOOT_IMAGE_PHYSICAL_NAME=<physical-name> && qrm_create_boot_image"
		return 1
	fi
	if ! check_tmp_on_tmpfs;then
		return 6
	fi
	echo "Creating boot-image $QRM_BOOT_IMAGE_NAME from kernel version $QRM_BOOT_IMAGE_KERNEL_VERSION"
	# o or ko
	if echo $QRM_BOOT_IMAGE_KERNEL_VERSION | grep -w 2.6 1>/dev/null 2>&1; then
		MODULES_SUFFIX="ko"
	fi	
	
	# check for rpm at QRM_BOOT_IMAGE_LOCATION
	if [ ! -d "$QRM_BOOT_IMAGE_LOCATION" ] && [ -f "$QRM_BOOT_IMAGE_LOCATION" ] && file "$QRM_BOOT_IMAGE_LOCATION" | grep RPM 1>/dev/null; then
		local RPM_BOOT_IMAGE_DIR=`mktemp -q -d $QRM_TEMP/XXXXXX` || return 1
		mkdir -p $RPM_BOOT_IMAGE_DIR/boot-image
		cd $RPM_BOOT_IMAGE_DIR/boot-image
		if ! rpm2cpio $QRM_BOOT_IMAGE_LOCATION | cpio --extract --make-directories --no-absolute-filenames --preserve-modification-time 1>/dev/null 2>&1; then
			echo "Error during unpacking the RPM package"
			return 4
		else
			export QRM_BOOT_IMAGE_LOCATION="$RPM_BOOT_IMAGE_DIR/boot-image/"
			echo "Successfully unpacked RPM package at $QRM_BOOT_IMAGE_LOCATION"
		fi
	fi
	
	# check for creating a boot-image from a remote system
	if [ ! -z "$QRM_BOOT_IMAGE_IP_ADRESS" ]; then
		echo "Creating a Qrm boot-image from kernel and modules from system $QRM_BOOT_IMAGE_IP_ADRESS"
		echo "Transfering remote kernel + modules to local tmp directory"
		echo "You will now prompted for the password for user root@$QRM_BOOT_IMAGE_IP_ADRESS :"
		local REMOTE_BOOT_IMAGE_DIR=`mktemp -q -d $QRM_TEMP/XXXXXX` || return 1
		mkdir -p $REMOTE_BOOT_IMAGE_DIR/boot-image
		PROGRESS=`mktemp -q $QRM_TEMP/XXXXXX`
		touch $PROGRESS
		tail -F $PROGRESS | while read LINE; do	\
			if [ "$loop" == 100 ]; then	\
				echo -n ".";	\
				loop=0;	\
			fi;		\
			loop=$(( loop +1 ));	\
		done &
		TAIL_PID=`ps ax | grep "tail -F $PROGRESS" | grep -v grep | awk {' print $1 '}`
		if ! nice -n 19 $QRM_SERVER_BASE_DIR/qrm/bin/rsync -aHLrvRS --numeric-ids --rsh=ssh --progress --exclude "/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/build" --exclude "/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/source" "root@$QRM_BOOT_IMAGE_IP_ADRESS:/boot/*-$QRM_BOOT_IMAGE_KERNEL_VERSION /lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION" $REMOTE_BOOT_IMAGE_DIR/boot-image/ 1>$PROGRESS; then
			echo
			echo "ERROR: Could not transfer the boot-image content"
			/bin/rm -rf $REMOTE_BOOT_IMAGE_DIR/boot-image
			kill $TAIL_PID 1>/dev/null 2>&1
			/bin/rm -f $PROGRESS
			return 1
		fi			
		kill $TAIL_PID 1>/dev/null 2>&1
		/bin/rm -f $PROGRESS
		echo
		export QRM_BOOT_IMAGE_LOCATION="$REMOTE_BOOT_IMAGE_DIR/boot-image/"
	fi
	# checking
	KERNELFILE="$QRM_BOOT_IMAGE_LOCATION""boot/vmlinuz-$QRM_BOOT_IMAGE_KERNEL_VERSION"
	MODULESDIR="$QRM_BOOT_IMAGE_LOCATION""lib/modules"
	SYSTEMMAP="$QRM_BOOT_IMAGE_LOCATION""boot/System.map-$QRM_BOOT_IMAGE_KERNEL_VERSION"
	if [ "$QRM_BOOT_OPTERON_BOOT_IMAGE" == "1" ]; then
		echo "using opteron initrd $QRM_INITRD_OPTERON"
		QRM_INITRD=$QRM_INITRD_OPTERON
	fi	
	if [ ! -f "$KERNELFILE" ]; then
		echo "No such kernel ($KERNELFILE) for version $QRM_BOOT_IMAGE_KERNEL_VERSION!"
		echo "Please check the logfile at $QRM_BOOT_IMAGE_LOGFILE for errors"
		return 7
	fi
 	if [ ! -f "$SYSTEMMAP" ]; then
		echo "No such System.map ($SYSTEMMAP) for version $QRM_BOOT_IMAGE_KERNEL_VERSION!"
		echo "Please check the logfile at $QRM_BOOT_IMAGE_LOGFILE for errors"
		return 7
	fi
	if [ ! -d "$MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION" ]; then
		echo "No such module directory ($MODULESDIR) for version $QRM_BOOT_IMAGE_KERNEL_VERSION!"
		echo "Please check the logfile at $QRM_BOOT_IMAGE_LOGFILE for errors"
		return 7
	fi

	# copy the kernel
	echo "Copying kernelfile $KERNELFILE"
	/bin/cp -f $KERNELFILE $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/vmlinuz-$QRM_BOOT_IMAGE_PHYSICAL_NAME
	# copy the system map
	echo "Copying the System.map $SYSTEMMAP"
	/bin/cp -f $SYSTEMMAP $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/System.map-$QRM_BOOT_IMAGE_PHYSICAL_NAME
	# copy the modules
	echo "Creating modules package from $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION"
	/bin/rm -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/modules-$QRM_BOOT_IMAGE_PHYSICAL_NAME.tgz
	tar -C $MODULESDIR -czf $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/modules-$QRM_BOOT_IMAGE_PHYSICAL_NAME.tgz $QRM_BOOT_IMAGE_KERNEL_VERSION
	
	# create/update the initrd
	local TMPDIR=`mktemp -q -d $QRM_TEMP/XXXXXX`
	mkdir -p $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION $TMPDIR/mnt
	mkdir -p $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/net
	for MODULE in `find $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/net -type f | grep -v wireless`; do
		MODULE_NAME=`echo $MODULE | sed -e "s/.*\///"`
		if ! echo $QRM_UNWANTED_MODULES | grep $MODULE_NAME 1>/dev/null; then
			/bin/cp -f $MODULE $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
		fi
	done
	# zipped mods
	cd $TMPDIR/initrd/lib/modules//$QRM_BOOT_IMAGE_KERNEL_VERSION
	for GZMODS in `ls *.gz 2>/dev/null`; do
		gunzip $GZMODS
	done
	cd $CURRENT
	# addtional modules
	for MOD in $QRM_BOOT_MODULES; do
		MOD_LOCATION=`find $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/* -type f -name $MOD`
		if [ -z "$MOD_LOCATION" ]; then
			echo "WARNING: Could not find kernel module $MOD!"
		else
			echo echo "Found module $MOD_LOCATION and will use it"
			/bin/cp -f $MOD_LOCATION $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
		fi
	done
	# nfs
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/nfs/nfs.$MODULES_SUFFIX ]; then
		echo "Found nfs.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/nfs/nfs.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	#lockd
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/lockd/lockd.$MODULES_SUFFIX ]; then
		echo "Found lockd.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/lockd/lockd.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	#sunrpc
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/net/sunrpc/sunrpc.$MODULES_SUFFIX ]; then
		echo "found sunrpc.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/net/sunrpc/sunrpc.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# ext3
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/ext3/ext3.$MODULES_SUFFIX ]; then
		echo "Found ext3.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/ext3/ext3.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# jbd
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/jbd/jbd.$MODULES_SUFFIX ]; then
		echo "Found jbd.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/jbd/jbd.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# reiserfs
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/reiserfs/reiserfs.$MODULES_SUFFIX ]; then
		echo "Found reiserfs.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/fs/reiserfs/reiserfs.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# crc32
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/crc32.$MODULES_SUFFIX ]; then
		echo "Found crc32.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/crc32.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	elif [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/crc32.$MODULES_SUFFIX ]; then
		echo "Found crc32.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/crc32.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# crc32c
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/crc32c.$MODULES_SUFFIX ]; then
		echo "Found crc32c.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/crc32c.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	elif [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/crc32c.$MODULES_SUFFIX ]; then
		echo "Found crc32c.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/crc32c.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/	
	fi
	# libcrc
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/libcrc32c.$MODULES_SUFFIX ]; then
		echo "Found libcrc32c.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/lib/libcrc32c.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	elif [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/libcrc32c.$MODULES_SUFFIX ]; then
		echo "Found libcrc32c.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/libcrc32c.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/	
	fi
	# crypto aes
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/aes.$MODULES_SUFFIX ]; then
		echo "Found aes.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/crypto/aes.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# loop 
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/block/loop.$MODULES_SUFFIX ]; then
		echo "Found loop.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/block/loop.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
	fi
	# iscsi / current version
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/iscsi_sfnet.$MODULES_SUFFIX ]; then
		echo "Found iscsi_sfnet.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/iscsi_sfnet.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/scsi_transport_iscsi.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1		
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/ide-scsi.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/scsi_debug.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/scsi_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sd_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sg.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sr_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/st.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
	fi
	# iscsi / future version
	if [ -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/iscsi_if.$MODULES_SUFFIX ]; then
		echo "Found iscsi_if.$MODULES_SUFFIX module and will use it"
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/iscsi_if.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/misc/iscsi_tcp.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1		
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/ide-scsi.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/scsi_debug.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/scsi_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sd_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sg.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/sr_mod.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
		/bin/cp -f $MODULESDIR/$QRM_BOOT_IMAGE_KERNEL_VERSION/kernel/drivers/scsi/st.$MODULES_SUFFIX $TMPDIR/initrd/lib/modules/$QRM_BOOT_IMAGE_KERNEL_VERSION/ 1>/dev/null 2>&1
	fi

	# untar/unzip the template
	echo "unzipping the initrd-template"
	tar -C $TMPDIR/initrd/ -xzf $QRM_INITRD

	# update initrd files
	qrm_update_initrd_files $TMPDIR/initrd/

	echo "checking initrd-size"
	QRM_INITRD_SIZE=`du -s $TMPDIR/initrd/ | awk {' print $1 '}`
	QRM_INITRD_SIZE=$(( QRM_INITRD_SIZE + 16000 ))
	if (( $QRM_INITRD_SIZE > 32000 )); then
		echo "Could not create initrd! File-size limit for exceeds! ($QRM_INITRD_SIZE Kb requested)"
		return 1
	fi

	# creating the blockfile
	echo "creating the initrd file"
	dd if=/dev/zero of=$TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img bs=1k count=$QRM_INITRD_SIZE 1>/dev/null
	# creating the filesystem
	echo "creating the filesystem on the intird file"
	mkfs.ext2 -F $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img 1>/dev/null
	tune2fs -c 0 -i 0 $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img 1>/dev/null
	# mount
	echo "mounting initrd"
	mount -o loop $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $TMPDIR/mnt
	# move
	echo "transferring initrd content"
	/bin/mv $TMPDIR/initrd/* $TMPDIR/mnt/
	# umount
	echo "umounting initrd"
	umount $TMPDIR/mnt/
	echo "Zipping the initrd-template"
	gzip $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img 1>/dev/null

	/bin/mv -f $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img
	/bin/rm -rf $TMPDIR/initrd $TMPDIR/mnt/
	rmdir $TMPDIR 1>/dev/null 2>&1
	cd $CURRENT
	
	if [ ! -z "$REMOTE_BOOT_IMAGE_DIR" ]; then
		echo "Removing temporary boot-image location $REMOTE_BOOT_IMAGE_DIR/boot-image/"
		/bin/rm -rf $REMOTE_BOOT_IMAGE_DIR/boot-image/
		rmdir $REMOTE_BOOT_IMAGE_DIR 1>/dev/null 2>&1
	fi
	if [ ! -z "$RPM_BOOT_IMAGE_DIR" ]; then
		echo "Removing temporary boot-image location $RPM_BOOT_IMAGE_DIR/boot-image/"
		/bin/rm -rf $RPM_BOOT_IMAGE_DIR/boot-image/
		rmdir $RPM_BOOT_IMAGE_DIR 1>/dev/null 2>&1
	fi
	if [ ! -z "$QRM_CLONED" ]; then
		echo "Removing temporary boot-image location $QRM_CLONED/clone/"
		/bin/rm -rf $QRM_CLONED/clone/
		rmdir $QRM_CLONED/clone 1>/dev/null 2>&1
		rmdir $QRM_CLONED 1>/dev/null 2>&1
	fi
	unset REMOTE_BOOT_IMAGE_DIR RPM_BOOT_IMAGE_DIR QRM_CLONED
	return 0
}





# removes a boot-image
function qrm_remove_boot_image() {
	if ! qrm_validate_input "$QRM_BOOT_IMAGE_NAME" || [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
		echo "Usage : export QRM_BOOT_IMAGE_NAME=<boot-image-name> && export QRM_BOOT_IMAGE_PHYSICAL_NAME=<physical-name> && qrm_remove_boot_image"
		return 1
	fi
	echo "Removing boot-image $QRM_BOOT_IMAGE_NAME"
	if grep initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $QRM_SERVER_BASE_DIR/qrm/tftpboot/pxelinux.cfg/* 1>/dev/null 2>&1; then
		echo "Boot-image $QRM_BOOT_IMAGE_NAME is still in use!"
		return 1
	fi
	if [ "$QRM_BOOT_IMAGE_NAME" == "qrm" ]; then
		echo "Boot-image $QRM_BOOT_IMAGE_NAME must not being removed!"
		return 1
	fi

	# remove the boot-image files
	/bin/rm -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/modules-$QRM_BOOT_IMAGE_PHYSICAL_NAME.tgz $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/vmlinuz-$QRM_BOOT_IMAGE_PHYSICAL_NAME $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/System.map-$QRM_BOOT_IMAGE_PHYSICAL_NAME
	return 0
}


# checks existens of needed files + directories and uses depmod to verify the module dependencies
function qrm_validate_boot_image() {
	if ! qrm_validate_input "$QRM_BOOT_IMAGE_NAME" || [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
		echo "Usage : export QRM_BOOT_IMAGE_NAME=<boot-image-name> && export QRM_BOOT_IMAGE_PHYSICAL_NAME=<physical-name> && qrm_validate_boot_image"
		return 1
	fi
	if [ ! -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/vmlinuz-$QRM_BOOT_IMAGE_PHYSICAL_NAME ] 1>/dev/null; then
		echo "Kernel for boot-image $QRM_BOOT_IMAGE_NAME does not exists!"
		return 1
	fi
	if [ ! -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img ] 1>/dev/null; then
		echo "Initrd for boot-image $QRM_BOOT_IMAGE_NAME does not exists!"
		return 1
	fi
	if [ ! -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/System.map-$QRM_BOOT_IMAGE_PHYSICAL_NAME ] 1>/dev/null; then
		echo "System.map for boot-image $QRM_BOOT_IMAGE_NAME does not exists!"
		return 1
	fi
	if [ ! -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/modules-$QRM_BOOT_IMAGE_PHYSICAL_NAME.tgz ]  1>/dev/null; then
		echo "Moduels for boot-image $QRM_BOOT_IMAGE_NAME do not not exists!"
		return 1
	fi

	# check content
	if [ "$QRM_BOOT_IMAGE_FIX" != "1" ]; then
		local TMPDIR=`mktemp -q -d $QRM_TEMP/XXXXXX`
		mkdir -p $TMPDIR/mnt
		/bin/cp -f $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz
		gunzip $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img.gz
		if ! mount -o loop $TMPDIR/initrd-$QRM_BOOT_IMAGE_PHYSICAL_NAME.img $TMPDIR/mnt; then
			echo "ERROR: Could not mount the initrd to validate its contents"
			return 1
		fi
		if ! qrm_check_initrd_files $TMPDIR/mnt; then
				umount $TMPDIR/mnt
				/bin/rm -rf $TMPDIR
				return 1
		fi
		umount $TMPDIR/mnt
		/bin/rm -rf $TMPDIR
	fi

	# fix
	if [ "$QRM_BOOT_IMAGE_FIX" == "1" ]; then
		qrm_fix_boot_image
		RET=$?
		if [ "$RET" != "0" ]; then
			echo "Could not fix the boot-image $QRM_BOOT_IMAGE_NAME"
			return $QRET	
		fi
	fi
	return 0

}



function qrm_prepare_cloning() {
	local TMPDIR=`mktemp -q -d $QRM_TEMP/XXXXXX` || return 1
	mkdir -p $TMPDIR/clone/boot $TMPDIR/clone/lib/modules
	
	if ! tar -C $TMPDIR/clone/lib/modules -xzf $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/modules-$QRM_BOOT_IMAGE_PHYSICAL_NAME.tgz; then
		echo "ERROR: Could not unzip the modules package from boot-image $QRM_SOURCE_BOOT_IMAGE_NAME (physically named $QRM_BOOT_IMAGE_PHYSICAL_NAME)"
		return 1
	fi
	# get kernel version from modules dir
	QRM_BOOT_IMAGE_KERNEL_VERSION=`ls $TMPDIR/clone/lib/modules`

	# copy kernel + system.map
	if ! /bin/cp $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/vmlinuz-$QRM_BOOT_IMAGE_PHYSICAL_NAME $TMPDIR/clone/boot/vmlinuz-$QRM_BOOT_IMAGE_KERNEL_VERSION; then
		echo "ERROR: Could not copy the kernel for boot-image $QRM_SOURCE_BOOT_IMAGE_NAME (physically named $QRM_BOOT_IMAGE_PHYSICAL_NAME)"
		return 1
	fi
	if ! /bin/cp $QRM_SERVER_BASE_DIR/qrm/tftpboot/boot/System.map-$QRM_BOOT_IMAGE_PHYSICAL_NAME $TMPDIR/clone/boot/System.map-$QRM_BOOT_IMAGE_KERNEL_VERSION; then
		echo "ERROR: Could not copy the system.map for boot-image $QRM_SOURCE_BOOT_IMAGE_NAME (physically named $QRM_BOOT_IMAGE_PHYSICAL_NAME)"
		return 1
	fi

	QRM_CLONED=$TMPDIR
	QRM_BOOT_IMAGE_LOCATION=$TMPDIR/clone/
	export QRM_BOOT_IMAGE_KERNEL_VERSION QRM_BOOT_IMAGE_LOCATION QRM_CLONED
	# set the new physical name to the new boot-image name
	QRM_BOOT_IMAGE_PHYSICAL_NAME=$QRM_BOOT_IMAGE_NAME
	export QRM_BOOT_IMAGE_PHYSICAL_NAME
	return 0

}


function set_boot_image_log_end_time() {
	sync
	END_TIME=`date +"%m.%d.%Y_%H.%M.%S"`
	echo "$0 finished at $END_TIME" >> $1
}



# check if only sourced
if [ -z "$IS_SOURCED" ]; then

QRM_BOOT_IMAGE_LOGFILE=$QRM_SERVER_LOG_DIR/`basename $0`.log
mkdir -p $QRM_SERVER_LOG_DIR
exec 1> >(tee -a $QRM_BOOT_IMAGE_LOGFILE) 2> >(tee -a $QRM_BOOT_IMAGE_LOGFILE)
START_TIME=`date +"%m.%d.%Y_%H.%M.%S"`
echo "$0 started at $START_TIME" >> $QRM_BOOT_IMAGE_LOGFILE
trap "set_boot_image_log_end_time $QRM_BOOT_IMAGE_LOGFILE" SIGKILL
trap "set_boot_image_log_end_time $QRM_BOOT_IMAGE_LOGFILE" EXIT

# main
case "$1" in
	create)
		shift
		while [ $# -ne 0 ]; do
			case "$1" in
				-k | --kernel-version)
					QRM_BOOT_IMAGE_KERNEL_VERSION=$2
					;;
				-b | --boot-image)
					QRM_BOOT_IMAGE_NAME=$2
					;;
				-y | --physical-name)
					QRM_BOOT_IMAGE_PHYSICAL_NAME=$2
					shift
					;;
				-t | --tmpdir)
					check_optional_parameters -t $2
					if [ ! -d $2 ]; then
						echo "ERROR: No such tmp dir $2"
						exit 1
					fi
					QRM_TEMP=`pushd $2 > /dev/null; echo $PWD; popd > /dev/null`
					shift
					;; 				
				-m | --with-module)
					check_optional_parameters -m $2
					QRM_BOOT_MODULES="$QRM_BOOT_MODULES $2"
					shift
					;;
				-a | --arch)
					case "$2" in 
						Opteron|Any|Xeon|i686)
							QRM_BOOT_ARCH=$2
							;;
						*)
							echo "The arch flag is wrong. The only flags that allow are Opteron|Any|Xeon|i686"
							usage
							exit 6
							;;
					esac
					shift
					;;
				-l | --location)
					check_optional_parameters -l $2
					QRM_BOOT_IMAGE_LOCATION=$2
					;;
				-i | --ip)
					check_optional_parameters -i $2
					QRM_BOOT_IMAGE_IP_ADRESS=$2
					;;
				-c | --comments)
					check_optional_parameters -c $2
					QRM_BOOT_COMMENTS=$2
					shift
					;;
				-s | --special_support)
					check_optional_parameters -s $2
					QRM_OPTIONAL_BOOT_FLAGS="$QRM_OPTIONAL_BOOT_FLAGS -s $2"
					shift
					;;
				-f | --flags)
					case "$2" in
						Linux|Numa)
							QRM_BOOT_FLAGS=$2
							;;
						*)
							echo "We got wrong Flags. The only flags that allow are Linux|Numa"
							usage
							exit 6
							;;
					esac
					shift
 					;;
				-h | --hugemem)
					QRM_BOOT_HUGEMEM=--hugemem
					;;
				--smp)
					QRM_BOOT_SMP="--smp"
					;;
				-o | --only-physical)
					QRM_ONLY_PHYSICAL=true
					;;
				--help)
					usage
					exit 0
					;;
			esac
			shift
		done
		if [ -z "$QRM_BOOT_FLAGS" ];then
			QRM_BOOT_FLAGS=Linux
		fi
		if [ -z "$QRM_BOOT_ARCH" ];then
			QRM_BOOT_ARCH=i686
		fi
		if [ ! -z "$QRM_BOOT_SPECIAL_SUPPORT" ]; then
			QRM_OPTIONAL_BOOT_FLAGS="$QRM_OPTIONAL_BOOT_FLAGS -s $QRM_BOOT_SPECIAL_SUPPORT"
		fi
		if [ -z "$QRM_BOOT_IMAGE_KERNEL_VERSION" ] || [ -z "$QRM_BOOT_IMAGE_NAME" ] || [ -z "$QRM_BOOT_IMAGE_LOCATION" ] || [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
			usage
			exit 1
		else
			if qrm_create_boot_image; then
				RET=0
				if [ -z "$QRM_ONLY_PHYSICAL" ]; then
					echo "Adding the boot-image $QRM_BOOT_IMAGE_NAME to the qrm-server"
					if [ ! -z "$QRM_BOOT_COMMENTS" ];then
						$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel add -n $QRM_BOOT_IMAGE_NAME -k $QRM_BOOT_IMAGE_KERNEL_VERSION -y $QRM_BOOT_IMAGE_PHYSICAL_NAME -m $QRM_BOOT_FLAGS -a $QRM_BOOT_ARCH $QRM_OPTIONAL_BOOT_FLAGS $QRM_BOOT_HUGEMEM $QRM_BOOT_SMP -c "$QRM_BOOT_COMMENTS"
						RET=$?
					else
						$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel add -n $QRM_BOOT_IMAGE_NAME -k $QRM_BOOT_IMAGE_KERNEL_VERSION -y $QRM_BOOT_IMAGE_PHYSICAL_NAME -m $QRM_BOOT_FLAGS -a $QRM_BOOT_ARCH $QRM_OPTIONAL_BOOT_FLAGS $QRM_BOOT_HUGEMEM $QRM_BOOT_SMP
						RET=$?	
					fi
				fi
				# check return code
				case "$RET" in
					0)
						echo "Successfully created boot-image $QRM_BOOT_IMAGE_NAME"
						;;
					6)
						echo "Successfully created the boot-image $QRM_BOOT_IMAGE_NAME"
						echo "but could not create the boot-image's meta data."
						;;
					7)
						echo "Successfully created boot-image $QRM_BOOT_IMAGE_NAME but could"
						echo "not add it to the QRM-server database because it already exists."
						;;
					*)
						echo "ERROR: Could not create the boot-image. Error code is $RET"
				esac
				exit $RET
				
			else
				echo "ERROR: Could not create the boot-image"
				exit 1			
			fi
		fi
		;;

	remove)
		shift
                while [ $# -ne 0 ]; do
			case "$1" in
				-b | --boot-image)
					QRM_BOOT_IMAGE_NAME=$2
					;;
				-y | --physical-name)
					QRM_BOOT_IMAGE_PHYSICAL_NAME=$2
					shift
					;;
				--help)
					usage
					exit 0
					;;
			esac
			shift
		done
		if [ -z "$QRM_BOOT_IMAGE_NAME" ]; then
			usage
			exit 1
		fi
		if [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
			QRM_BOOT_IMAGE_PHYSICAL_NAME=`$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel list  | tail +3 |grep -w $QRM_BOOT_IMAGE_NAME |awk {' print $3 '}`
			if [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
				echo "ERROR: Could not find out the physical name of the boot-image $QRM_BOOT_IMAGE_NAME"
				echo "       Please give the physical name as a commandline parameter (-y)"
				exit 1
			fi
		fi
		if qrm_remove_boot_image; then
			$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel delete -n $QRM_BOOT_IMAGE_NAME
			RET=$?
			# check return code
			case "$RET" in
				0)
					echo "Successfully removed boot-image $QRM_BOOT_IMAGE_NAME"
					;;
				6)
					echo "Successfully removed the boot-image $QRM_BOOT_IMAGE_NAME"
					echo "but could not remove the boot-image's meta data."
					;;
				8)
					echo "Successfully removed the boot-image $QRM_BOOT_IMAGE_NAME but could"
					echo "not remove it from the QRM-server database because it is in use."
					;;
				*)
					echo "ERROR: Could not remove the boot-image. Error code is $RET"
			esac
			exit $RET
		else
			echo "ERROR: Could not remove the boot-image $QRM_BOOT_IMAGE_NAME"
			exit 1
		fi
		;;
	list)
		$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel list | tail +3 | awk {'print $1'} 
		exit $?
		;;
	validate)
		shift
                while [ $# -ne 0 ]; do
			case "$1" in
				-b | --boot-image)
					QRM_BOOT_IMAGE_NAME=$2
					;;
				-f | --fix)
					QRM_BOOT_IMAGE_FIX=1
					;;
				-y | --physical-name)
					QRM_BOOT_IMAGE_PHYSICAL_NAME=$2
					shift
					;;
				--help)
					usage
					exit 0
					;;
			esac
			shift
		done
		if [ -z "$QRM_BOOT_IMAGE_NAME" ]; then
			usage
			exit 1
		fi
		if [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
			QRM_BOOT_IMAGE_PHYSICAL_NAME=`$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel list | tail +3 |grep -w $QRM_BOOT_IMAGE_NAME |awk {' print $3 '}`
			if [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
				echo "ERROR: Could not find out the physical name of the boot-image $QRM_BOOT_IMAGE_NAME"
				echo "       Please give the physical name as a commandline parameter (-y)"
				exit 1
			fi
		fi
		if ! qrm_validate_boot_image; then
			echo "ERROR: The boot-image $QRM_BOOT_IMAGE_NAME is invalid."
			exit 1
		else
			if [[ "${QRM_BOOT_IMAGE_FIX}" ]]; then
				echo "Successfully validated and fixed the boot-image $QRM_BOOT_IMAGE_NAME"
			else
				echo "Successfully validated the boot-image $QRM_BOOT_IMAGE_NAME"
			fi
			exit 0			
		fi
		;;
	clone)
		shift
		while [ $# -ne 0 ]; do
			case "$1" in
				-b | --boot-image)
					QRM_SOURCE_BOOT_IMAGE_NAME=$2
					;;
				-n | --new-boot-image)
					QRM_BOOT_IMAGE_NAME=$2
					;;
				-y | --physical-name)
					QRM_BOOT_IMAGE_PHYSICAL_NAME=$2
					shift
					;;
				-t | --tmpdir)
					check_optional_parameters -t $2
					if [ ! -d $2 ]; then
						echo "ERROR: No such tmp dir $2"
						exit 1
					fi
					QRM_TEMP=`pushd $2 > /dev/null; echo $PWD; popd > /dev/null`
					shift
					;; 				
				-m | --with-module)
					check_optional_parameters -m $2
					QRM_BOOT_MODULES="$QRM_BOOT_MODULES $2"
					shift
					;;
				-a | --arch)
					case "$2" in 
						Opteron|Any|Xeon|i686)
							QRM_BOOT_ARCH=$2
							;;
						*)
							echo "The arch flag is wrong. The only flags that allow are Opteron|Any|Xeon|i686"
							usage
							exit 6
							;;
					esac
					shift
					;;
				-c | --comments)
					check_optional_parameters -c $2
					QRM_BOOT_COMMENTS=$2
					shift
					;;
				-s | --special_support)
					check_optional_parameters -s $2
					QRM_OPTIONAL_BOOT_FLAGS="$QRM_OPTIONAL_BOOT_FLAGS -s $2"
					shift
					;;
				-f | --flags)
					case "$2" in
						Linux|Numa)
							QRM_BOOT_FLAGS=$2
							;;
						*)
							echo "We got wrong Flags. The only flags that allow are Linux|Numa"
							usage
							exit 6
							;;
					esac
					shift
 					;;
				-h | --hugemem)
					QRM_BOOT_HUGEMEM=--hugemem
					;;
				--smp)
					QRM_BOOT_SMP="--smp"
					;;
				--help)
					usage
					exit 0
					;;
			esac
			shift
		done
		# check usage
		if [ -z "$QRM_BOOT_IMAGE_NAME" ] || [ -z "$QRM_SOURCE_BOOT_IMAGE_NAME" ]; then
			usage
			exit 1
		fi
		# check optional parameters
		if [ -z "$QRM_BOOT_FLAGS" ];then
			QRM_BOOT_FLAGS=Linux
		fi
		if [ -z "$QRM_BOOT_ARCH" ];then
			QRM_BOOT_ARCH=i686
		fi
		if [ ! -z "$QRM_BOOT_SPECIAL_SUPPORT" ]; then
			QRM_OPTIONAL_BOOT_FLAGS="$QRM_OPTIONAL_BOOT_FLAGS -s $QRM_BOOT_SPECIAL_SUPPORT"
		fi
		# check if source image exists
		if ! $QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel list | tail +3 | awk {' print $1 '} |grep -w $QRM_SOURCE_BOOT_IMAGE_NAME 1>/dev/null 2>&1; then
			echo "ERROR: Boot-image $QRM_SOURCE_BOOT_IMAGE_NAME does not exist"
			exit 1
		fi
		# check physical name
		if [ -z "$QRM_BOOT_IMAGE_PHYSICAL_NAME" ]; then
			QRM_BOOT_IMAGE_PHYSICAL_NAME=`$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel list  | tail +3 |grep -w $QRM_SOURCE_BOOT_IMAGE_NAME | awk {' print $3 '}`
		fi
		# prepare cloning
		if ! qrm_prepare_cloning; then
			echo "ERROR: Errors during preparing cloning"
			exit 1
		fi
		# check to have the kernel version
		if [ -z "$QRM_BOOT_IMAGE_KERNEL_VERSION" ]; then
			echo "ERROR: Could not find kernel version for boot-image $QRM_BOOT_IMAGE_NAME"
			exit 1
		fi
		# create the new boot-image from the source location
		if qrm_create_boot_image; then
			if [ ! -z "$QRM_BOOT_COMMENTS" ];then
				$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel add -n $QRM_BOOT_IMAGE_NAME -k $QRM_BOOT_IMAGE_KERNEL_VERSION -y $QRM_BOOT_IMAGE_PHYSICAL_NAME -m $QRM_BOOT_FLAGS -a $QRM_BOOT_ARCH $QRM_OPTIONAL_BOOT_FLAGS $QRM_BOOT_HUGEMEM $QRM_BOOT_SMP -c "$QRM_BOOT_COMMENTS"
				RET=$?
			else
				$QRM_SERVER_BASE_DIR/qrm/bin/qrm-cli kernel add -n $QRM_BOOT_IMAGE_NAME -k $QRM_BOOT_IMAGE_KERNEL_VERSION -y $QRM_BOOT_IMAGE_PHYSICAL_NAME -m $QRM_BOOT_FLAGS -a $QRM_BOOT_ARCH $QRM_OPTIONAL_BOOT_FLAGS $QRM_BOOT_HUGEMEM $QRM_BOOT_SMP
				RET=$?
			fi
			# check return code
			case "$RET" in
				0)
					echo "Successfully cloned the boot-image $QRM_SOURCE_BOOT_IMAGE_NAME to $QRM_BOOT_IMAGE_NAME"
					;;
				6)
					echo "Successfully cloned the boot-image $QRM_BOOT_IMAGE_NAME to $QRM_BOOT_IMAGE_NAME"
					echo "but could not create the boot-image's meta data."
					;;
				7)
					echo "Successfully cloned the boot-image $QRM_SOURCE_BOOT_IMAGE_NAME to $QRM_BOOT_IMAGE_NAME"
					echo "but could not add it to the QRM-server database because it already exists."
					;;
				*)
					echo "ERROR: Could not clone the boot-image. Error code is $RET"
			esac
			exit $RET
		else
			echo "ERROR: Could not clone the boot-image"
			exit 1			
		fi
		;;
	--help)
		usage
		exit 0
		;;
	*)
	usage
	exit 1
esac

fi


