#!/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
export ARCH=`arch`

#======================================
# Exports (Configuration)...
#--------------------------------------
export systemIntegrity=clean
export LIVECD_CONFIG="/cdrom/config.isoclient"
export LIVECD="/livecd"
export LOCAL_BOOT="no"

#======================================
# Exports kernel options
#--------------------------------------
export kernel_cmdline=($@)

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

#======================================
# Start logging
#--------------------------------------
errorLogStart

#======================================
# Update library path
#--------------------------------------
ldconfig

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

#======================================
# 2) probe for livecd_config in cmdline
#--------------------------------------
includeKernelParameters
if grep -i -q "livecd_config=[a-zA-Z0-9/]" /proc/cmdline; then
    export LIVECD_CONFIG=`sed 's/.*livecd_config=\([^ ]*\).*/\1/' /proc/cmdline`
fi
if grep -i -q "toram" /proc/cmdline; then
    export TORAM="true"
fi

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

#======================================
# 4) run udevd
#--------------------------------------
udevStart

#======================================
# 5) start boot shell and logging
#--------------------------------------
startShell

#======================================
# 6) Including required kernel modules
#--------------------------------------
probeDevices

#======================================
# 7) Mount the live image device
#--------------------------------------
if searchImageISODevice;then
    if [ ! -z "$mediacheck" ]; then
        runMediaCheck
    fi
    if [ ! -z "$kiwi_hybrid" ];then
        setupHybridPersistent
    fi
    kiwiMount "$biosBootDevice" "/cdrom" "-o ro" 1>&2
fi

#======================================
# 8) Load configuration
#--------------------------------------
importFile < $LIVECD_CONFIG
if [ ! -z "$HYBRID_RW" ];then
    if [ ! -z "$UNIONFS_CONFIG" ];then
        tmp_rwDevice=$(echo $UNIONFS_CONFIG | cut -d , -f 1)
        UNIONFS_CONFIG=$(
            echo $UNIONFS_CONFIG | sed -e s@$tmp_rwDevice@$HYBRID_RW@
        )
    else
        IMAGE=$(echo $IMAGE | sed -e s@/dev/ram1@$HYBRID_RW@)
    fi
fi

#======================================
# 9) Download RW part of the CD image
#--------------------------------------
for i in $(echo $IMAGE | tr , ' ');do
    field=0
    for n in $(echo $i | tr ';' ' ');do
    case $field in
        0) imageDevice=$n ; field=1 ;;
        1) imageName=$n   ; field=2 ;;
        2) imageVersion=$n
    esac
    done
    imageReadOnly="$imageName"
    imageReadOnly=$(echo $imageReadOnly | sed -e "s@\.${ARCH}\$@@")
    imageReadOnly="$imageReadOnly-read-only.$ARCH-$imageVersion"
    imageName="/cdrom/$imageName-$imageVersion"
    gzippName=$imageName.gz
    imageMD5s="$imageName.md5"
    if [ ! -z "$UNIONFS_CONFIG" ] || [ ! -z "$COMBINED_IMAGE" ];then
        continue
    fi
    while true;do
        read sum1 blocks blocksize zblocks zblocksize < $imageMD5s
        if ! validateSize;then
            systemException \
                "Not enough RAM available for this image" \
            "reboot"
        fi
        needBytes=$(gzip -l $gzippName|tail -n1|sed -e "s@ \+@:@g"|cut -f3 -d:)
        needMByte=$((needBytes / 1024 / 1024))
        if [ -x /usr/bin/dcounter ];then
            errorLogStop
            Echo -n "Loading $imageName [$imageDevice] "
            gzip -cd $gzippName |\
                dcounter -s $needMByte | dd of=$imageDevice &>/dev/null
            errorLogContinue
            echo
        else
            Echo "Loading $imageName [$imageDevice]..."
            gzip -cd $gzippName | dd of=$imageDevice
        fi
        dd if=$imageDevice bs=1024 |\
            head --bytes=$((blocks * blocksize)) |\
            md5sum - > /etc/ireal.md5
        read sum2 dumy < /etc/ireal.md5
        if test $sum1 = $sum2;then
            Echo "Image checksum test: fine :-)"
            break
        fi
        Echo "Image checksum test failed:"
        echo
        Echo -b "1) Data corruption while loading the image:"
        Echo -b "   will give it a new try..."
        echo
        Echo -b "2) ramdisk size is too small for the image:"
        Echo -b "   try to set the kernel parameter ramdisk_size=<size>"
        echo
        Echo "Retry to load image..."
        sleep 15
    done
    rm -f /etc/ireal.md5
done
CDUmount

#======================================
# 10) Get filesystem type
#--------------------------------------
if [ -z "$UNIONFS_CONFIG" ] && [ -e "$imageDevice" ];then
    probeFileSystem $imageDevice
    if [ "$FSTYPE" = "luks" ];then
        luksOpen $imageDevice
        imageDevice=$luksDeviceOpened
        probeFileSystem $imageDevice
        export haveLuks=yes
    fi
    resizeFilesystem $imageDevice
fi

#======================================
# 11) Check for swap space
#--------------------------------------
swapSpace=$(searchSwapSpace)
if [ ! -z "$swapSpace" ];then
    Echo "Found swap space on: $swapSpace"
fi

#======================================
# 12) Mount OS image to /mnt
#--------------------------------------
runHook premount
if [ -z "$UNIONFS_CONFIG" ] && [ -z "$COMBINED_IMAGE" ];then
    #======================================
    # 12.1) mount RW part and CD to /mnt
    #--------------------------------------
    if ! mount $imageDevice /mnt >/dev/null;then
        systemException "Failed to mount RW root filesystem" "reboot"
    fi
    cdopt=$(CDMountOption $biosBootDevice)
    mountOrCopyLiveCD
    #======================================
    # 12.2) Create RO Link list
    #--------------------------------------
    cd /mnt
    if [ ! -d $LIVECD/read-only-system ];then
        Echo "Mounting compressed read only tree..."
        rosys="/read-only"
        rosrc="$LIVECD/$imageReadOnly"
        mkdir -p $rosys
        if ! kiwiMount $rosrc $rosys "-o loop";then
            systemException "Failed to mount RO root filesystem" "reboot"
        fi
        Echo "Creating live media links..."
        for dir in bin boot lib lib64 opt sbin usr;do
            ln -s read-only/$dir $dir
        done
    else
        Echo "Creating live media links..."
        for dir in bin boot lib lib64 opt sbin usr;do
            if [ -d $LIVECD/read-only-system/$dir ];then
                ln -s $LIVECD/read-only-system/$dir $dir
            fi
        done
    fi
    cd /
else
    #======================================
    # 12.1) mount CD to /mnt and unify
    #--------------------------------------
    if [ ! -z "$COMBINED_IMAGE" ]; then
        Echo "Mounting compressed split tree..."
        imageReadOnly=$(echo $imageReadOnly | sed -e "s/-read-only//")
    else
        Echo "Mounting compressed unified tree..."
    fi
    cdopt=$(CDMountOption $biosBootDevice)
    mountOrCopyLiveCD
    if ! mountSystem /dev/loop1 $LIVECD/$imageReadOnly;then
        systemException "Failed to mount root filesystem" "reboot"
    fi
fi
validateRootTree
runHook postmount

#======================================
# 13) Create system dependant files
#--------------------------------------
setupDefaultFstab /config
updateRootDeviceFstab /config $imageDevice
if [ ! -z "$swapSpace" ];then
    updateSwapDeviceFstab /config $swapSpace
fi

#======================================
# 14) copy system dependant files
#--------------------------------------
setupConfigFiles

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

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

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

#======================================
# 18) copy initrd files to image
#--------------------------------------
importBranding
cp /usr/sbin/setctsid /mnt/usr/sbin
cp /usr/sbin/klogconsole /mnt/usr/sbin
cp /preinit /mnt
cp /include /mnt

#======================================
# 19) kill boot shell
#--------------------------------------
killShell

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

#======================================
# 21) Unmount initrd / system init
#--------------------------------------
bootImage
