#!/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) 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

#======================================
# 6) Including required kernel modules
#--------------------------------------
probeDevices
for module in ehci-hcd uhci-hcd usb_storage sg sd_mod BusLogic;do
	modprobe $module >/dev/null 2>&1
done

#======================================
# 7) Search disks, prefer removable one
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	if [ ! -f $VMX_SYSTEM ];then
		# /.../
		# installed system: Check for a root device to mount and
		# prefer a USB stick if there is any. Otherwise check for
		# first partition of a disk device. 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 disk and root partition"
		USBStickDevice
		if [ $stickFound = 0 ];then
			deviceFound=0
			for deviceRoot in /dev/sda1 /dev/hda1;do
				if mount $deviceRoot /mnt &>/dev/null;then
					deviceFound=1
					umount /mnt
					break
				fi
			done
			if [ $deviceFound = 0 ];then
				systemException \
					"Couldn't find any disk device... abort" \
				"reboot"
			fi
			export deviceDisk=`echo $deviceRoot | tr -d [0-9]`
			export deviceSwap="$deviceDisk"2
			if [ -z "$OEM_WITHOUTHOME" ];then
				export deviceHome="$deviceDisk"3
			fi
		else
			Echo "USB stick found, prefer root on stick"
			export deviceDisk=$stickRoot
			export deviceSwap="$deviceDisk"2
			if [ -z "$OEM_WITHOUTHOME" ];then
				export deviceHome="$deviceDisk"3
			fi
		fi
		probeFileSystem "$deviceDisk"1
		if isFSTypeReadOnly;then
			if [ -z "$COMBINED_IMAGE" ];then
				Echo "Unified system detected, adapting root partition"
				export UNIONFS_CONFIG="$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"
		Echo "Waiting for devices to settle..."
		# ...
		# 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
		# ---
		sleep 5
		hwinfo="/usr/sbin/hwinfo --disk"
		export deviceDisks=`$hwinfo |\
			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
			export UNIONFS_CONFIG="$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
	waitForStorageDevice $deviceTest
	if ! sfdisk -s $deviceTest &>/dev/null;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
			export UNIONFS_CONFIG="$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.bz2 ];then
			systemException "Can't find recovery archive" "reboot"
		fi
		recoBytes=`du --bytes /reco-root/recovery.tar.bz2 | 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 ! sfdisk -s "$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=`sfdisk -s $deviceDisk`
			diskXMBytes=`expr $diskXMBytes / 1024`
			disk1MBytes=`sfdisk -s "$deviceDisk"1`
			disk1MBytes=`expr $disk1MBytes / 1024`
			disk2MBytes=`sfdisk -s "$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 fdisk 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
			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
			Echo "Repartition the disk according to current geometry"
			fdisk $deviceDisk < $input >/dev/null 2>&1
			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 sfdisk -s $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 fdisk 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=`sfdisk -s $deviceDisk`
			diskPMBytes=`sfdisk -s $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 "Disk is too small, will not re-partition it"
				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 without recovery partition
							#--------------------------------------
							for cmd in \
								d n p 4 . +"$recoMByte"M \
								n p 2 . . 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 >/dev/null 2>&1
				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 sfdisk -s $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.bz2 /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
				if ! cp /reco-root/boot/message /reco-save/boot;then
					systemException "Failed to copy message file" "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=`sfdisk -s $deviceDisk`
			diskXMBytes=`expr $diskXMBytes / 1024`
			disk1MBytes=`sfdisk -s "$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 fdisk 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
				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
				Echo "Repartition the disk according to current geometry"
				fdisk $deviceDisk < $input >/dev/null 2>&1
				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 sfdisk -s $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
	if [ ! -z $COMBINED_IMAGE ];then
		deviceResize=$deviceIOWR
		KIWI_INITRD_PARAMS="COMBINED_IMAGE=local"
		export KIWI_INITRD_PARAMS
	fi
	if isFSTypeReadOnly && [ -z "$COMBINED_IMAGE" ];then
		deviceResize=$deviceIOWR
		export UNIONFS_CONFIG="$deviceDisk"2,"$deviceDisk"1,aufs
		KIWI_INITRD_PARAMS="UNIONFS_CONFIG=\"$UNIONFS_CONFIG\""
		KIWI_INITRD_PARAMS="$KIWI_INITRD_PARAMS deviceRoot=\"$deviceRoot\""
		export KIWI_INITRD_PARAMS
	fi
	if [ ! -z "$deviceResize" ] && sfdisk -s $deviceResize &>/dev/null;then
		if [ ! -z "$OEM_RECOVERY" ];then
			KIWI_INITRD_PARAMS="$KIWI_INITRD_PARAMS LOCAL_BOOT=yes"
			KIWI_INITRD_PARAMS="$KIWI_INITRD_PARAMS deviceRoot=$deviceRoot"
			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
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
	# TODO restore recovery data
	systemException "*** system restore not yet implemented ***" "reboot"
fi

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

#======================================
# 15) Create system dependant files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	export HAVE_SWAP=0
	setupDefaultFstab /config
	if sfdisk -s $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
		if [ $HAVE_SWAP -eq 1 ];then
			setupBootLoader \
				/mnt /config 1 ${deviceDisk}2 $OEM_BOOT_TITLE $deviceSwap
		else
			setupBootLoader \
				/mnt /config 0 ${deviceDisk}1 $OEM_BOOT_TITLE
		fi
	fi
	setupKernelModules /config
fi

#======================================
# 16) copy system dependant files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ];then
	cd /config
	find . -type d | while read d ; do  mkdir -p /mnt/$d ; done
	find . -type f | while read f ; do  cp $f /mnt/$f ; done
	cd /
	rm -rf /config
fi

#======================================
# 17) copy recovery related files
#--------------------------------------
if [ $LOCAL_BOOT = "no" ] && [ ! -z "$OEM_RECOVERY" ];then
	Echo "Setting up recovery configuration files..."
	mkdir /reco-save
	if ! mount $deviceRecovery /reco-save >/dev/null;then
		systemException "Failed to mount recovery device" "reboot"
	fi
	if ! cp /mnt/etc/fstab /reco-save/etc;then
		systemException "Failed to copy recovery fstab" "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
	umount /reco-save && rmdir /reco-save
fi

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

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

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

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

#======================================
# 22) Activate new root
#--------------------------------------
Echo "Activating Image: [$deviceDisk]"
reopenKernelConsole
/sbin/udevsettle --timeout=30
mount --move /dev /mnt/dev
udevKill

#======================================
# 23) call preinit phase
#--------------------------------------
Echo "Calling preinit phase..."
cd /mnt
/mnt/sbin/pivot_root . mnt >/dev/null 2>&1
if test $? != 0;then
	PIVOT=false
	cleanInitrd && mount --move . / && chroot . ./preinit
	chroot . rm -f  ./preinit
	chroot . rm -f  ./include
	chroot . rm -rf ./image
else
	PIVOT=true
	./preinit
	rm -f  ./preinit
	rm -f  ./include
	rm -rf ./image
fi

#======================================
# 24 Unmount initrd / system init
#--------------------------------------
echo " "
echo "Booting into final System..."
echo "----------------------------"
export IFS=$IFS_ORIG
if [ ! -z "$OEM_REBOOT" ];then
	mount -n -o remount,ro / 2>/dev/null
	Echo "Reboot requested... rebooting now"
	/sbin/reboot -f -i >/dev/null 2>&1
fi
mount -n -o remount,rw / 2>/dev/null
if [ $PIVOT = "true" ];then
	exec < dev/console >dev/console 2>&1
	exec umount -n -l /mnt
else
	exec < dev/console >dev/console 2>&1
	exec chroot . /sbin/init $@
fi

