#!/bin/bash -ex
# 
# If we install the oem image on a hard disk instead of a flash disk
# we need to update the initrd on, say, /dev/sda1, so that it installs the
# kernel modules necessary to access the disk

# This ensures we exit with non-zero error value should *anything* fail
trap 'rc=$? ; [ $rc -eq 0 ] && exit $rc' EXIT 

# partition, e.g. /dev/sda1
PARTITION=$1

# First determine whether we're running in the host installer
# or on the host
if [ -e /opt/xensource/etc/initial-inventory ] ; then
    # on the host
    # See if the target disk is a USB device -- if so, nothing to do
    DISK=$(echo $PARTITION | sed 's/\(p\?[0-9][0-9]*\)$//')
    SYSFS_NODE=$(echo ${DISK} | sed -e 's,^/dev/,,' -e 's,/,!,' -e 's,^,/sys/block/,')
    if [ -d ${SYSFS_NODE} ] ; then
        if /usr/bin/udevinfo -a -p ${SYSFS_NODE} | /bin/egrep -q '^ *BUS=="usb"$' ; then
            # on USB -- nothing to do
            exit 0
        fi
    fi
fi

# Temporary mount point for partition
MNTPOINT="$(mktemp -d /tmp/mnt-XXXXXX)"

# Mount the partition
mount ${PARTITION} ${MNTPOINT}

# determine the xen kernel version
kernelversion_xen() {
    if [ -e ${MNTPOINT}/rootfs ] ; then
        ROOTFS_MNTPOINT=$(mktemp -d /tmp/mnt-XXXXXX)
        mount -oloop -t squashfs ${MNTPOINT}/rootfs ${ROOTFS_MNTPOINT}
    else
        ROOTFS_MNTPOINT=${MNTPOINT}
    fi
    KVER=$(basename `/bin/ls -1td ${ROOTFS_MNTPOINT}/lib/modules/2.6*xen`)
    if [ "${ROOTFS_MNTPOINT}" != "${MNTPOINT}" ] ; then
        umount ${ROOTFS_MNTPOINT}
        rmdir ${ROOTFS_MNTPOINT}
    fi
    echo "$KVER"
}

# determine the kdump kernel version
kernelversion_kdump() {
    if [ -e ${MNTPOINT}/rootfs ] ; then
        ROOTFS_MNTPOINT=$(mktemp -d /tmp/mnt-XXXXXX)
        mount -oloop -t squashfs ${MNTPOINT}/rootfs ${ROOTFS_MNTPOINT}
    else
        ROOTFS_MNTPOINT=${MNTPOINT}
    fi
    KVER=$(basename `/bin/ls -1td ${ROOTFS_MNTPOINT}/lib/modules/2.6*kdump`)
    if [ "${ROOTFS_MNTPOINT}" != "${MNTPOINT}" ] ; then
        umount ${ROOTFS_MNTPOINT}
        rmdir ${ROOTFS_MNTPOINT}
    fi
    echo "$KVER"
}

# build a redhat style initrd: usage mkinitrd_common <filename> <kernelversion>
mkinitrd_common() {
    OUTPUT="$1"
    KVER="$2"
    if [ -e ${MNTPOINT}/rootfs ] ; then
        # mkinitrd is only available in squashfs root filesystem
        ROOTFS_MNTPOINT=$(mktemp -d /tmp/mnt-XXXXXX)
        mount -oloop -t squashfs ${MNTPOINT}/rootfs ${ROOTFS_MNTPOINT}
    else
        ROOTFS_MNTPOINT=${MNTPOINT}
    fi
    mount -t tmpfs none ${ROOTFS_MNTPOINT}/mnt 
    mount -t tmpfs none ${ROOTFS_MNTPOINT}/var/tmp
    mount -t sysfs none ${ROOTFS_MNTPOINT}/sys
    mount -t tmpfs none ${ROOTFS_MNTPOINT}/dev
    tar -C /dev -c . | tar -C ${ROOTFS_MNTPOINT}/dev -x
    FSLABEL=$(dumpe2fs ${PARTITION} | sed -ne 's/Filesystem volume name:[[:space:]]*//p')
    echo "LABEL=${FSLABEL}  /  ext3  defaults,ro  0  0" >${ROOTFS_MNTPOINT}/mnt/fstab
    chroot ${ROOTFS_MNTPOINT} /sbin/mkinitrd --theme=/usr/share/citrix-splash --fstab=/mnt/fstab \
	--with=usb-storage --with=ext3 --with=zlib_inflate --with=squashfs --shell=tash /mnt/initrd ${KVER}
    mv ${ROOTFS_MNTPOINT}/mnt/initrd "${OUTPUT}"
    umount ${ROOTFS_MNTPOINT}/dev
    umount ${ROOTFS_MNTPOINT}/sys
    umount ${ROOTFS_MNTPOINT}/var/tmp
    umount ${ROOTFS_MNTPOINT}/mnt
    if [ "${ROOTFS_MNTPOINT}" != "${MNTPOINT}" ] ; then
        umount ${ROOTFS_MNTPOINT}
        rmdir ${ROOTFS_MNTPOINT}
    fi
}

# Build the initrd loaded at boot
mkinitrd_xen() {
    KVER=$(kernelversion_xen)
    mkinitrd_common ${MNTPOINT}/boot/initrd ${KVER}
}

# Build the initrd loaded on panic
mkinitrd_kdump() {
    KVER=$(kernelversion_kdump)
    mkinitrd_common ${MNTPOINT}/boot/initrd-${KVER}.img ${KVER}
}

# Build the initrds
mkinitrd_xen
mkinitrd_kdump

if losetup -a >/dev/null 2>&1 ; then
    LOOPS=$(losetup -a | sed -ne 's#\(^/dev/loop[0-9]*\):.*('${MNTPOINT}'.*$#\1#p')
    for LOOP in ${LOOPS} ; do
        losetup -d ${LOOP}
    done
fi

umount ${MNTPOINT}
rmdir ${MNTPOINT}

exit 0
