#!/bin/bash
#================
# FILE          : linuxrc
#----------------
# PROJECT       : OpenSuSE KIWI Image System
# COPYRIGHT     : (c) 2006 SUSE LINUX Products GmbH. All rights reserved
#               :
# AUTHOR        : Marcus Schaefer <ms@suse.de>
#               :
# BELONGS TO    : Operating System images
#               :
# DESCRIPTION   : This file is changed to become the real
#               : linuxrc script which is used to prepare the
#               : operating system for the main image
#               :
#               :
# STATUS        : BETA
#----------------
#======================================
# Exports (General)...
#--------------------------------------
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
export IFS_ORIG=$IFS
export DEBUG=0

#======================================
# Exports (Booting)
#--------------------------------------
export DOMURD_MODULES="xennet xenblk"
export INITRD_MODULES="reiserfs"
export LOCAL_BOOT=no
export systemIntegrity="clean"

#======================================
# Exports (Configuration)
#--------------------------------------
export VMX_SYSTEM="/config.vmxsystem"
export LIVECD_CONFIG=$VMX_SYSTEM
export OEM_PARTITION_CONFIG="/config.oempartition"

#======================================
# Functions...
#--------------------------------------
. /include

#======================================
# Beautify Startup
#--------------------------------------
echo "Loading KIWI OEM Boot-System..."
echo "-------------------------------"

#======================================
# 1) Mounting local file systems
#--------------------------------------
mountSystemFilesystems &>/dev/null
closeKernelConsole

#======================================
# 2) Prepare module load support 
#--------------------------------------
touch /etc/modules.conf
touch /lib/modules/*/modules.dep

#======================================
# 3) run udevd
#--------------------------------------
udevStart

#======================================
# 4) start boot shell
#--------------------------------------
startBlogD
startShell
errorLogStart
openKernelConsole

#======================================
# 5) Including required kernel modules
#--------------------------------------
# sleep for a while as I don't know a device to listen on
# I should be sure all possible devices exist. If there is
# a better way to make sure _now_ is the best time to search
# a disk please fixme
# ---
probeDevices
for module in ehci-hcd uhci-hcd usb_storage sg sd_mod BusLogic;do
	modprobe $module >/dev/null 2>&1
done
Echo "Waiting for devices to settle..."
sleep 5

#======================================
# 6) Include proc/cmdline information
#--------------------------------------
includeKernelParameters
if \
	[ ! -z $UNIONFS_CONFIG ] || [ "$COMBINED_IMAGE" = "local" ] ||\
	[ ! -z $KIWI_RECOVERY ]
then
	# /.../
	# if the unionfs/combined information is already in place at this
	# stage it comes from the cmdline data which means we are not
	# booting from CD/DVD USB stick but want to boot the local system
	# This also applies if we use an oem system with the recovery
	# feature enabled
	# ----
	export LOCAL_BOOT="yes"
fi
if [ $LOCAL_BOOT = "yes" ];then
	export deviceRoot=$root
	export deviceDisk=`getDiskDevice $deviceRoot | sed -e s"@[0-9]@@g"`
	if [ ! -z "$UNIONFS_CONFIG" ];then
		setupUnionFS "$deviceDisk"2 "$deviceDisk"1 aufs
	fi
	if [ ! -z "$deviceRecovery" ];then
		export deviceRecovery=$deviceDisk"4"
	fi
fi

#======================================
# 7) Search disks, prefer removable one
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	if [ ! -f $VMX_SYSTEM ];then
		# /.../
		# installed system: Find the boot device which is flagged
		# in the BIOS as 0x80:
		# ----
		# During first boot of the installed system there is only
		# one partition and this initrd is going to be replaced by
		# a later mkinitrd call for unified systems the kiwi initrd
		# is used and the kernel parameters of this initrd defines
		# the missing information.
		# ----
		# Additionally the partition table is different
		# for unified systems. Therefore we check if the second
		# partition is a squashfs/cromfs partition and change the root
		# partition name accordingly
		# ----
		if [ -f $OEM_PARTITION_CONFIG ];then
			Echo "Including oem partition info file"
			importFile < $OEM_PARTITION_CONFIG
		fi
		Echo "Searching for boot device..."
		export deviceDisk=`searchBIOSBootDevice`
		if [ -z "$deviceDisk" ];then
			systemException \
				"Couldn't find any boot device... abort" \
			"reboot"
		fi
		export deviceSwap=$deviceDisk"2"
		if [ -z "$OEM_WITHOUTHOME" ];then
			export deviceHome=$deviceDisk"3"
		fi
		probeFileSystem $deviceDisk"1"
		if isFSTypeReadOnly;then
			if [ -z "$COMBINED_IMAGE" ];then
				Echo "Unified system detected, adapting root partition"
				setupUnionFS "$deviceDisk"2 "$deviceDisk"1 aufs
			fi
			export deviceRoot=$deviceDisk"1"
			export deviceSwap=$deviceDisk"3"
		else
			export deviceRoot=$deviceDisk"1"
		fi
		Echo "Using root partition $deviceRoot on disk $deviceDisk"
	else
		# /.../
		# installation mode: find a usable disk to install the image
		# on. The image is a virtual disk with one partition
		# ----
		Echo "Searching harddrive for installation"
		hwinfo=/usr/sbin/hwinfo
		export deviceDisks=`$hwinfo --disk |\
			grep "Device File:" | cut -f2 -d: | cut -f1 -d"("`
		export deviceDisks=`echo $deviceDisks`
		if [ -z $deviceDisks ];then
			systemException \
				"No hard disk device(s) found... abort" \
			"reboot"
		fi
		Echo "Found following hard disk device(s)"
		count=0
		for i in $deviceDisks;do
			Echo -b "Disk $count -> $i"
			deviceArray[$count]=$i
			count=`expr $count + 1`
		done
		while true;do
			Echo -n "Enter device name to select disk for installation: "
			read deviceInput
			count=0
			for deviceDisk in $deviceDisks;do
				if [ ${deviceArray[$count]} = $deviceInput ];then
					break 2
				fi
				count=`expr $count + 1`
			done
			Echo "Given device is not in the list !"
		done
		Echo "Entering installation mode for disk: $deviceDisk"
	fi
fi

#======================================
# 8) Check for vmx system
#--------------------------------------
if [ -f $VMX_SYSTEM ] && [ $LOCAL_BOOT = "no" ];then
	#======================================
	# 8.1) import vmx configuration file
	#--------------------------------------
	importFile < $VMX_SYSTEM
	#======================================
	# 8.2) check version of installed OS
	#--------------------------------------
	deviceRoot=$deviceDisk"2"
	probeFileSystem $deviceRoot
	if test "$FSTYPE" = "unknown";then
		deviceRoot="$deviceDisk"1
		probeFileSystem $deviceRoot
	fi
	if [ -z "$COMBINED_IMAGE" ];then
		if isFSTypeReadOnly;then
			setupUnionFS "$deviceDisk"2 "$deviceDisk"1 aufs
		fi
	fi
	Echo "Try mounting installed system to check version"
	mountSystem $deviceRoot; updateNeeded
	umountSystem
	if test `getSystemIntegrity 1` = "fine";then
		Echo "Base system is up to date... reboot"
		/sbin/reboot -f -i >/dev/null 2>&1
	fi
	#======================================
	# 8.3) mount CD/DVD/USB stick
	#--------------------------------------
	USBStickDevice
	if [ $stickFound = 0 ];then
		Echo "Search for USB stick failed, checking CD/DVD drive"
		CDMount
	else
		Echo "Found Stick: $stickDevice -> $stickSerial"
		mkdir -p /cdrom && mount $stickDevice /cdrom
	fi
	#======================================
	# 8.4) install disk system
	#--------------------------------------
	# /.../
	# install virtual disk image from the CD/DVD onto the
	# real disk. All data on the disk will be lost
	# ----
	imageZipped="uncompressed"
	imageDevice=$deviceDisk
	field=0
	IFS=";" ; for n in $IMAGE;do
	case $field in
		0) field=1 ;; 
		1) imageName=$n   ; field=2 ;;
		2) imageVersion=$n;
	esac
	done
	imageName="/cdrom/$imageName"
	echo $imageName | grep -qE ".gz$"
	if [ $? = 0 ];then
		imageZipped="compressed"
	fi
	IFS=" "
	if test "$imageZipped" = "compressed"; then
		Echo "Compressed image found"
		test ! -p /dev/compressed_image && mkfifo /dev/compressed_image
		cat /dev/compressed_image | gzip -d > $imageDevice 2>/dev/null &
		imageDevice_orig=$imageDevice
		imageName_orig=$imageName
		imageDevice="/dev/compressed_image"
		imageName="$imageName.gz"
	fi
	Echo "Loading $imageName [$imageDevice]..."
	if ! dd bs=32k if=$imageName of=$imageDevice >/dev/null 2>&1; then
		systemException \
			"Failed to install image: $imageName -> $imageDevice" \
		"reboot"
	fi
	if test "$imageZipped" = "compressed"; then
		imageDevice=$imageDevice_orig
		imageName=$imageName_orig
		rm -f /dev/compressed_image
	fi
	#======================================
	# 8.5) Umount the CD/DVD
	#--------------------------------------
	umount /cdrom
	#======================================
	# 8.6) reread partition table
	#--------------------------------------
	blockdev --rereadpt $deviceDisk
	deviceTest="$deviceDisk"1
	if ! waitForStorageDevice $deviceTest;then
		systemException \
			"Partition $deviceTest doesn't appear... fatal !" \
		"reboot"
	fi
	#======================================
	# 8.7) find new root partition
	#--------------------------------------
	unset UNIONFS_CONFIG
	deviceRoot=$deviceDisk"1"
	probeFileSystem $deviceRoot
	Echo "Filesystem of root system is: $FSTYPE -> $deviceRoot"
	if [ -z "$COMBINED_IMAGE" ];then
		if isFSTypeReadOnly;then
			setupUnionFS "$deviceDisk"2 "$deviceDisk"1 aufs
		fi
	fi
	#======================================
	# 8.8) Create md5 version info file
	#--------------------------------------
	unset RELOAD_IMAGE
	if ! mountSystem $deviceRoot;then
		systemException \
			"Couldn't mount installed system... abort" \
		"reboot"
	fi
	updateNeeded initialize
	field=0
	IFS=";" ; for n in $IMAGE;do
	case $field in
		0) field=1 ;;
		1) imageName=$n   ; field=2 ;;
		2) imageVersion=$n
	esac
	done
	atversion="$imageName-$imageVersion"
	versionFile="/mnt/etc/ImageVersion-$atversion"
	md5sum=`getSystemMD5Status 1`
	echo "$atversion $md5sum" > $versionFile
	umountSystem
	#======================================
	# 8.9) reboot system
	#--------------------------------------
	if [ $stickFound = 0 ];then
		Echo "NOTE: Please remove the installation CD before reboot !"
		CDEject
	else
		Echo "NOTE: Please unplug the USB stick before reboot !"
	fi
	systemException \
		"System installation has finished" \
	"reboot"
fi

#======================================
# 9) Probe filesystem of disk device
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	probeFileSystem $deviceRoot
	if [ $FSTYPE = "unknown" ];then
		systemException \
			"Couldn't determine filesystem type... abort" \
		"reboot"
	fi
fi

#======================================
# 10) repartition the disk device
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	#======================================
	# 10.1 calculate amount of swap space
	#--------------------------------------
	mem_size=`grep MemTotal: /proc/meminfo | tr -dc '[0-9]'`
	swapsize=$(( $mem_size *2 / 1024 ))
	recoMByte=0
	if [ ! -z "$OEM_SWAPSIZE" ];then
		swapsize=$OEM_SWAPSIZE
	fi
	if [ ! -z "$OEM_WITHOUTSWAP" ];then
		swapsize=0
	fi
	if [ ! -z "$OEM_RECOVERY" ];then
		mkdir -p /reco-root
		if ! mount $deviceRoot /reco-root >/dev/null;then
			systemException "Failed to mount root device" "reboot"
		fi
		if [ ! -f /reco-root/recovery.tar.gz ];then
			systemException "Can't find recovery archive" "reboot"
		fi
		recoBytes=`du --bytes /reco-root/recovery.tar.gz | cut -f1`
		recoMByte=`expr $recoBytes / 1048576`
		recoMByte=`expr $recoMByte \* 15 / 10`
		umount /reco-root && rmdir /reco-root
	fi
	Echo "Filesystem of root system is: $FSTYPE -> $deviceRoot"
	if test ! -z $COMBINED_IMAGE;then
		#====================================== 
		# 10.2 no recovery support in this mode
		#--------------------------------------
		unset OEM_RECOVERY
		#====================================== 
		# 10.2 check for read-write partition
		#--------------------------------------
		if ! partitionSize $deviceDisk"2" &>/dev/null;then
			Echo "No read-write partition in this split image"
			DONT_PARTITION=1
		fi
		#======================================
		# 10.3 calculate new partition 3 size
		#--------------------------------------
		if [ -z "$DONT_PARTITION" ];then
			swapXMBytes=$swapsize
			diskXMBytes=`partitionSize $deviceDisk`
			diskXMBytes=`expr $diskXMBytes / 1024`
			disk1MBytes=`partitionSize "$deviceDisk"1`
			disk1MBytes=`expr $disk1MBytes / 1024`
			disk2MBytes=`partitionSize "$deviceDisk"2`
			disk2MBytes=`expr $disk2MBytes / 1024`
			diskXLBytes=`expr $diskXMBytes - $disk1MBytes - $disk2MBytes`
			diskXABytes=`expr $diskXLBytes - $swapXMBytes`
			if [ $diskXABytes -lt 50 ];then
				# /.../
				# Very small disk which we will not re-partition
				# ----
				Echo "Disk is too small, will not re-partition it"
				DONT_PARTITION=1
			else
				disk2MBytes=`expr $disk2MBytes + $diskXABytes`
			fi
		fi
		if [ -z "$DONT_PARTITION" ];then
			#======================================
			# 10.4 write new partition table
			#--------------------------------------
			# /.../
			# Explanation of the partition commands used within the
			# here document below:
			# ----
			# d               # delete xda partition
			# 2               # [ 2 ]
			# n               # create xda partition at same place than xda2
			# p               # primary
			# 2               # [ 2 ]
			#                 # accept old xda3 start block
			# +"disk2MBytes"M # accept new RW device size of disk blocks - swap
			# n               # create xda swap partition
			# p               # primary
			# 3               # [ 3 ]
			#                 # accept start block
			#                 # accept end block
			# t               # change swap system id
			# 3               # [ 3 ]
			# 82              # Linux Swap
			# w               # write partition table
			# ----
			input=/part.input
			rm -f $input
			if [ $swapsize = 0 ];then
				for cmd in d 2 n p 2 . +"$disk2MBytes"M w;do
					if [ $cmd = "." ];then
						echo >> $input
						continue
					fi
					echo $cmd >> $input
				done
			else
				for cmd in d 2 n p 2 . +"$disk2MBytes"M n p 3 . . t 3 82 w;do
					if [ $cmd = "." ];then
						echo >> $input
						continue
					fi
					echo $cmd >> $input
				done
			fi
			Echo "Repartition the disk according to current geometry"
			fdisk $deviceDisk < $input 1>&2
			if test $? != 0; then
				systemException "Failed to create partition table" "reboot"
			fi
		fi
		#======================================
		# 10.5 Update new device names
		#--------------------------------------
		export deviceRoot=$deviceDisk"1"
		export deviceSwap=$deviceDisk"3"
		export deviceIOWR=$deviceDisk"2"

		#======================================
		# 10.6 Activate swap space
		#--------------------------------------
		if partitionSize $deviceSwap &>/dev/null;then
			Echo "Activating swap space on $deviceSwap"
			if ! mkswap $deviceSwap >/dev/null 2>&1;then
				systemException "Failed to create swap signature" "reboot"
			fi
		fi
	else
		if ! isFSTypeReadOnly;then
			#======================================
			# 10.2 write new partition table
			#--------------------------------------
			# /.../
			# Explanation of the partition commands used within the
			# here document below:
			# ----
			# d              # delete xda partition [ 1 ]
			# n              # create xda partition at same place than xda1
			# p              # primary
			# 2              # [ 2 ]
			# 1              # accept old xda1 start block for xda2
			# +10240M        # accept new root device size of 10GB
			# n              # create xda swap partition
			# p              # primary
			# 1              # [ 1 ]
			#                # accept start block
			# +"$swapsize"M  # accept new swapsize
			# n              # create xda3 home partition
			# p              # primary
			# 3              # [ 3 ]
			#                # accept start block
			#                # accept end block, complete disk
			# t              # change swap system id
			# 1              # [ 1 ]
			# 82             # Linux Swap
			# w              # write partition table
			# ----
			input=/part.input
			rm -f $input
			diskXMBytes=`partitionSize $deviceDisk`
			diskPMBytes=`partitionSize $deviceDisk"1"`
			diskPMBytes=`expr $diskPMBytes / 1024`
			diskXMBytes=`expr $diskXMBytes / 1024`
			disk1MBytes=10240
			# /.../
			# set OEM_SYSTEMSIZE if available, else try to
			# use 10GB system size
			# ----
			if [ ! -z "$OEM_SYSTEMSIZE" ];then
				disk1MBytes=$OEM_SYSTEMSIZE
			fi
			# /.../
			# prevent /home and recovery partition if requested
			# system size is bigger than the whole disk
			# ----
			if [ $disk1MBytes -gt $diskXMBytes ];then
				export OEM_WITHOUTHOME=1
				unset OEM_RECOVERY
				recoMByte=0
			fi
			# /.../
			# recalculate system size if no /home partition
			# will be used. size is whole disk minus swap
			# minus recovery
			# ----
			if [ ! -z "$OEM_WITHOUTHOME" ];then
				disk1MBytes=`expr $diskXMBytes - $swapsize - $recoMByte`
			fi
			# /.../
			# check if requested system size is bigger than
			# the existing system partition
			# ----
			if [ $disk1MBytes -lt $diskPMBytes ];then
				# /.../
				# Requested system partition size is smaller than
				# existing partition, will not re-partition
				# ----
				Echo "Current system partition is bigger than requested size"
				Echo "Disk won't be re-partitioned"
				OEM_WITHOUTHOME=1
				DONT_PARTITION=1
				unset OEM_RECOVERY
			fi
			if [ -z "$DONT_PARTITION" ];then
				if [ ! -z "$OEM_WITHOUTHOME" ];then
					#======================================
					# 10.2.1 without /home partition
					#--------------------------------------
					if [ -z "$OEM_WITHOUTSWAP" ];then
						#======================================
						# 10.2.1.1 with swap partition
						#--------------------------------------
						if [ -z "$OEM_RECOVERY" ];then
							#======================================
							# 10.2.1.1.1 without recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 1 . . \
								t 1 82 w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						else
							#======================================
							# 10.2.1.1.2 with recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 4 . +"$recoMByte"M \
								n p 1 . . \
								t 1 82 w
						do
							if [ $cmd = "." ];then
								echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						fi
					else
						#======================================
						# 10.2.1.2 without swap partition
						#--------------------------------------
						if [ -z "$OEM_RECOVERY" ];then
							#======================================
							# 10.2.1.2.1 without recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 . . w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						else
							#======================================
							# 10.2.1.2.2 with recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 4 . . w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						fi
					fi
				else
					#======================================
					# 10.2.2 with /home partition
					#--------------------------------------
					if [ -z "$OEM_WITHOUTSWAP" ];then
						#======================================
						# 10.2.2.1 with swap partition
						#--------------------------------------
						if [ -z "$OEM_RECOVERY" ];then
							#======================================
							# 10.2.2.1.1 without recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 1 . +"$swapsize"M \
								n p 3 . . \
								t 1 82 w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						else
							#======================================
							# 10.2.2.1.2 with recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 1 . +"$swapsize"M \
								n p 4 . +"$recoMByte"M \
								n p 3 . . \
								t 1 82 w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						fi
					else
						#======================================
						# 10.2.2.2 without swap partition
						#--------------------------------------
						if [ -z "$OEM_RECOVERY" ];then
							#======================================
							# 10.2.2.2.1 without recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 3 . . w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						else
							#======================================
							# 10.2.2.2.2 with recovery partition
							#--------------------------------------
							for cmd in \
								d n p 2 1 +"$disk1MBytes"M \
								n p 4 . +"$recoMByte"M \
								n p 3 . . w
							do
								if [ $cmd = "." ];then
									echo >> $input
									continue
								fi
								echo $cmd >> $input
							done
						fi
					fi
				fi
				Echo "Repartition the disk according to current geometry"
				fdisk $deviceDisk < $input 1>&2
				if test $? != 0; then
					systemException "Failed to create partition table" "reboot"
				fi
			fi
			#======================================
			# 10.3 Update new device names
			#--------------------------------------
			if [ -z "$DONT_PARTITION" ];then
				export deviceRoot=$deviceDisk"2"
				export deviceSwap=$deviceDisk"1"
			else
				export deviceRoot=$deviceDisk"1"
			fi
			if [ -z "$OEM_WITHOUTHOME" ];then
				export deviceHome=$deviceDisk"3"
			fi
			if [ ! -z "$OEM_RECOVERY" ];then
				export deviceRecovery=$deviceDisk"4"
			fi
			#======================================
			# 10.4 Activate swap space
			#--------------------------------------
			if partitionSize $deviceSwap &>/dev/null;then
				Echo "Activating swap space on $deviceSwap"
				if ! mkswap $deviceSwap >/dev/null 2>&1;then
					systemException "Failed to create swap signature" "reboot"
				fi
			fi
			#======================================
			# 10.5 Create home file system
			#--------------------------------------
			if [ -z "$OEM_WITHOUTHOME" ];then
				Echo "Creating Home filesystem on $deviceHome"
				if ! mke2fs -j -q $deviceHome >/dev/null 2>&1;then
					systemException "Failed to create Home fs" "reboot"
				fi
			fi
			#======================================
			# 10.6 Create recovery file system
			#--------------------------------------
			if [ ! -z "$OEM_RECOVERY" ];then
				Echo "Creating Recovery filesystem on $deviceRecovery"
				if ! mke2fs -j -q $deviceRecovery >/dev/null 2>&1;then
					systemException "Failed to create Recovery fs" "reboot"
				fi
			fi
			#======================================
			# 10.7 Setup recovery contents
			#--------------------------------------
			if [ ! -z "$OEM_RECOVERY" ];then
				Echo "Setting up recovery archive..."
				mkdir -p /reco-root
				if ! mount $deviceRoot /reco-root >/dev/null;then
					systemException "Failed to mount root device" "reboot"
				fi
				mkdir -p /reco-save
				if ! mount $deviceRecovery /reco-save >/dev/null;then
					systemException "Failed to mount recovery device" "reboot"
				fi
				if ! mv /reco-root/recovery.tar.gz /reco-save >/dev/null;then
					systemException "Failed to move recovery archive" "reboot"
				fi
				mkdir /reco-save/boot
				if ! cp /reco-root/boot/initrd.vmx /reco-save/boot/initrd;then
					systemException "Failed to copy recovery initrd" "reboot"
				fi
				if ! cp /reco-root/boot/linux.vmx /reco-save/boot/vmlinuz;then
					systemException "Failed to copy recovery kernel" "reboot"
				fi
				umount /reco-save && rmdir /reco-save
				umount /reco-root && rmdir /reco-root
			fi
		else
			#====================================== 
			# 10.2 no recovery support in this mode
			#--------------------------------------
			unset OEM_RECOVERY
			#======================================
			# 10.2 calculate end block - swapspace
			#--------------------------------------
			swapXMBytes=$swapsize
			diskXMBytes=`partitionSize $deviceDisk`
			diskXMBytes=`expr $diskXMBytes / 1024`
			disk1MBytes=`partitionSize "$deviceDisk"1`
			disk1MBytes=`expr $disk1MBytes / 1024`
			disk2MBytes=`expr $diskXMBytes - $disk1MBytes - $swapsize`
			if [ $disk2MBytes -lt 100 ];then
				# /.../
				# Very small disk which we will not re-partition
				# ----
				Echo "Disk is too small, will not re-partition it"
				DONT_PARTITION=1
			fi
			if [ -z "$DONT_PARTITION" ];then
				#======================================
				# 10.3 write new partition table
				#--------------------------------------
				# /.../
				# Explanation of the partition commands used within the
				# here document below:
				# ----
				# d               # delete xda partition
				# 2               # [ 2 ]
				# n               # create xda partition at same place than xda2
				# p               # primary
				# 2               # [ 2 ]
				#                 # accept old xda2 start block
				# +"disk2MBytes"M # accept new RW device size
				# n               # create xda swap partition
				# p               # primary
				# 3               # [ 3 ]
				#                 # accept start block
				#                 # accept end block
				# t               # change swap system id
				# 3               # [ 3 ]
				# 82              # Linux Swap
				# w               # write partition table
				# ----
				input=/part.input
				rm -f $input
				if [ $swapsize = 0 ];then
					for cmd in d 2 n p 2 . +"$disk2MBytes"M w; do
						if [ $cmd = "." ];then
							echo >> $input
							continue
						fi
						echo $cmd >> $input
					done
				else
					for cmd in d 2 n p 2 . +"$disk2MBytes"M n p 3 . . t 3 82 w
					do
						if [ $cmd = "." ];then
							echo >> $input
							continue
						fi
						echo $cmd >> $input
					done
				fi
				Echo "Repartition the disk according to current geometry"
				fdisk $deviceDisk < $input 1>&2
				if test $? != 0; then
					systemException "Failed to create partition table" "reboot"
				fi
			fi
			#======================================
			# 10.4 Update new device names
			#--------------------------------------
			export deviceRoot=$deviceDisk"1"
			export deviceSwap=$deviceDisk"3"
			export deviceIOWR=$deviceDisk"2"

			#======================================
			# 10.5 Activate swap space
			#--------------------------------------
			if partitionSize $deviceSwap &>/dev/null;then
				Echo "Activating swap space on $deviceSwap"
				if ! mkswap $deviceSwap >/dev/null 2>&1;then
					systemException "Failed to create swap signature" "reboot"
				fi
			fi
		fi
	fi
fi

#======================================
# 11) Resize filesystem to full space
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	deviceResize=$deviceRoot
	fstypeRootFS=$FSTYPE
	if [ ! -z $COMBINED_IMAGE ];then
		deviceResize=$deviceIOWR
		KIWI_INITRD_PARAMS="COMBINED_IMAGE=local"
		probeFileSystem $deviceResize
		export KIWI_INITRD_PARAMS
	fi
	if isFSTypeReadOnly && [ -z "$COMBINED_IMAGE" ];then
		deviceResize=$deviceIOWR
		setupUnionFS "$deviceDisk"2 "$deviceDisk"1 aufs
		KIWI_INITRD_PARAMS="UNIONFS_CONFIG=yes"
		probeFileSystem $deviceResize
		export KIWI_INITRD_PARAMS
	fi
	if [ ! -z "$deviceResize" ] && partitionSize $deviceResize &>/dev/null;then
		if [ ! -z "$OEM_RECOVERY" ];then
			KIWI_INITRD_PARAMS="$KIWI_INITRD_PARAMS LOCAL_BOOT=yes"
			KIWI_INITRD_PARAMS="$KIWI_INITRD_PARAMS deviceRecovery=yes"
			export KIWI_INITRD_PARAMS
		fi
		if [ "$FSTYPE" = "reiserfs" ];then
			Echo "Resize Reiser filesystem to full partition space..."
			resize_reiserfs -q $deviceResize
			INITRD_MODULES="$INITRD_MODULES reiserfs"
		fi
		if [ "$FSTYPE" = "ext2" ];then
			Echo "Resize EXT2 filesystem to full partition space..."
			resize2fs -f -F -p $deviceResize
			Echo "Checking EXT2 filesystem..."
			e2fsck -y -f $deviceResize
			INITRD_MODULES="$INITRD_MODULES ext2"
		fi
		if [ "$FSTYPE" = "ext3" ];then
			Echo "Resize EXT3 filesystem to full partition space..."
			resize2fs -f -F -p $deviceResize
			Echo "Checking EXT3 filesystem..."
			e2fsck -y -f $deviceResize
			INITRD_MODULES="$INITRD_MODULES ext3"
		fi
	fi
	FSTYPE=$fstypeRootFS
fi

#======================================
# 12) Mount system
#--------------------------------------
if ! mountSystem $deviceRoot;then
	systemException "Failed to mount root filesystem" "reboot"
fi
validateRootTree

#======================================
# 13) Recover system if requested
#--------------------------------------
if [ ! -z "$KIWI_RECOVERY" ];then
	Echo -n "Do you want to start the System-Recovery ? [y/n]: "; read runReco
	if [ ! $runReco = "y" ];then
		systemException "System-Recovery not started" "reboot"
	fi
	Echo "Starting System-Recovery..."
	#======================================
	# 13.1) mount recovery partition
	#--------------------------------------
	mkdir -p /reco-save
	if ! mount $deviceRecovery /reco-save >/dev/null;then
		systemException "Failed to mount recovery device" "reboot"
	fi
	#======================================
	# 13.2) restore root archive
	#--------------------------------------
	Echo "Restoring base operating system..."
	cd /mnt
	if ! tar -xvf /reco-save/recovery.tar.gz 1>&2;then
		systemException "Failed to restore recovery archive" "reboot"
	fi
	#======================================
	# 13.3) restore boot files
	#--------------------------------------
	Echo "Restoring boot files..."
	for i in etc/fstab etc/sysconfig/kernel etc/sysconfig/bootloader;do
		if ! cp /reco-save/$i /mnt/$i;then
			systemException "Failed to restore $i" "reboot"
		fi
	done
	for i in `setupBootLoaderFiles`;do
		if ! cp /reco-save/$i /mnt/$i;then
			systemException "Failed to restore $i" "reboot"
		fi
	done
	for i in /reco-save/boot/grub/*;do
		if echo $i | grep -q .system;then
			sysbase=`echo ${i%%.system}`
			sysbase=`echo $sysbase | cut -f3- -d/`
			cp $i /mnt/$sysbase
		fi
	done
	#======================================
	# 13.4) umount recovery and boot
	#--------------------------------------
	umount $deviceRecovery
	export deviceDisk=`echo $deviceRoot | tr -d "[:digit:]"`
fi

#======================================
# 14) get installed kernels
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	kernelList /mnt
fi

#======================================
# 15) setup ird/kernel links for union
#--------------------------------------
if [ $LOCAL_BOOT = "no" ] && isFSTypeReadOnly;then
	# /.../
	# we are using a special root setup with aufs. In this case
	# we can't use the SuSE Linux initrd but must stick to the
	# kiwi boot system.
	# ----
	kiwiMount "$deviceDisk"2 "/mnt"
	pushd /mnt/boot >/dev/null
	IFS="," ; for i in $KERNEL_LIST;do
		if test -z "$i";then
			continue
		fi
		kernel=`echo $i | cut -f1 -d:`
		initrd=`echo $i | cut -f2 -d:`
		rm -f $initrd && ln -s initrd.vmx $initrd
		rm -f $kernel && ln -s linux.vmx  $kernel
		break
	done
	IFS=$IFS_ORIG
	popd >/dev/null
	umount /mnt
fi

#======================================
# 16) Create system dependant files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	export HAVE_SWAP=0
	setupDefaultFstab /config
	if partitionSize $deviceSwap &>/dev/null;then
		updateSwapDeviceFstab /config $deviceSwap
		HAVE_SWAP=1
	fi
	if [ -z "$UNIONFS_CONFIG" ] && [ -z "$COMBINED_IMAGE" ]; then
		echo "$deviceRoot / $FSTYPE defaults 0 0" >> /config/etc/fstab
		if [ -z "$OEM_WITHOUTHOME" ] && [ -z "$DONT_PARTITION" ];then
			if [ `ls /mnt/home/ | wc -l` != 0 ]; then
				Echo "Found non empty home/ directory !"
				Echo "Moving home/ data to home partition $deviceHome"
				mount $deviceHome /mnt/mnt && mv /mnt/home/* /mnt/mnt
				umount /mnt/mnt
			fi
			Echo "Activate home partition $deviceHome in fstab"
			echo "$deviceHome /home ext3 defaults 0 0" >> /config/etc/fstab
		fi
	fi
	if [ -z "$UNIONFS_CONFIG" ] && [ -z "$COMBINED_IMAGE" ]; then
		Echo "Creating boot loader configuration"
		if [ -z "$OEM_BOOT_TITLE" ];then
			export OEM_BOOT_TITLE="OEM"
		fi
		if [ ! -z $OEM_RECOVERY ];then
			OEM_RECOVERY=${deviceDisk}4
		fi
		bootid=`echo $deviceRoot | tr -d "[:alpha:]//"`
		bootid=`expr $bootid - 1`
		setupBootLoader \
			/mnt /config $bootid $deviceRoot $OEM_BOOT_TITLE $deviceSwap
	fi
	setupKernelModules /config
fi

#======================================
# 17) copy system dependant files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	setupConfigFiles
fi

#======================================
# 18) copy recovery related files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ] && [ ! -z "$OEM_RECOVERY" ];then
	IFS=$IFS_ORIG
	Echo "Setting up recovery configuration files..."
	mkdir -p /reco-save
	if ! mount $deviceRecovery /reco-save >/dev/null;then
		systemException "Failed to mount recovery device" "reboot"
	fi
	mkdir -p /reco-save/etc/sysconfig
	if ! cp /mnt/etc/fstab /reco-save/etc;then
		systemException "Failed to copy recovery fstab" "reboot"
	fi
	if ! cp /mnt/etc/sysconfig/kernel /reco-save/etc/sysconfig;then
		systemException "Failed to copy recovery sysconfig/kernel" "reboot"
	fi
	if ! cp /mnt/etc/sysconfig/bootloader /reco-save/etc/sysconfig;then
		systemException "Failed to copy recovery sysconfig/bootloader" "reboot"
	fi
	for i in `setupBootLoaderFiles`;do
		bootdir=`dirname $i` && mkdir -p /reco-save/$bootdir
		if ! cp /mnt/$i /reco-save/$i;then
			systemException "Failed to copy recovery $i" "reboot"
		fi
	done
	Echo "Installing boot loader into recovery partition"
	setupBootLoaderRecovery /mnt /reco-save OEM
	umount /reco-save && rmdir /reco-save
	installBootLoaderRecovery
fi

#======================================
# 19) update system dependant files
#--------------------------------------
setupInittab /mnt

#======================================
# 20) setup real root device
#--------------------------------------
echo 256 > /proc/sys/kernel/real-root-dev

#======================================
# 21) umount system filesystems
#--------------------------------------
umountSystemFilesystems

#======================================
# 22) copy initrd files to image
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	importBranding
fi
cp /preinit /mnt
cp /include /mnt

#======================================
# 23) kill boot shell
#--------------------------------------
killShell
killBlogD

#======================================
# 24) Activate new root
#--------------------------------------
activateImage

#======================================
# 25 Unmount initrd / system init
#--------------------------------------
bootImage $@
