#!/bin/sh
#
# Copyright 2006  VMware, Inc. All rights reserved. 
# 
# Script to extract the kernel and initrd from a given vdisk.
# Can run only in the ESX Service Console. 
#

diskDev=
tmpDir=
kernelName=vmlinuz-2.4.21-37.0.2.ELvmnix
initrdName=initrd-2.4.21-37.0.2.ELvmnix.img

usage ()
{
   echo "Usage: $0 -v <vdiskfile> -o <outputdir>"
}

cleanup()
{
   if [ -n "$tmpDir" ]; then 
      umount $tmpDir >& /dev/null
      rm -rf $tmpDir >& /dev/null 
   fi
   if [ -n "$diskDev" ]; then 
      vsd -d -n $diskDev >& /dev/null 
   fi
}

main ()
{
   local vdiskFile=
   local outputDir=

   trap cleanup EXIT TERM KILL

   # Args.
   while getopts v:o: arg; do
      case "$arg" in
      "?") usage && exit 1;;
      "v") vdiskFile=$OPTARG ;;
      "o") outputDir=$OPTARG ;;
      esac
   done

   if [ ! -f "$vdiskFile" -o ! -d "$outputDir" ]; then
      echo "Invalid virtual disk or output directory."
      usage && exit 1 
   fi

   diskDev=`vsd -cu -f $vdiskFile 2>/dev/null`
   ret=$?
   if [ $ret -ne 0 ]; then
      echo "Failed to create vsd (err=$ret)."
      return 1
   fi
   if [ -z "$diskDev" ]; then
      echo "Couldn't determine disk mapping for vsd."
      return 1
   fi

   fileBase=`basename $vdiskFile` 
   tmpDir=`mktemp -t -d $fileBase.XXX` 
   if [ $? -ne 0 ]; then
      echo "Couldn't create tmpdir."
      return 1
   fi
   
   bootPart=`echo "showlabels" | nash --quiet | grep "$diskDev" | grep '/boot' | awk '{print $1}'`
   if [ -z "$bootPart" ]; then
      echo "Couldn't determine boot partition of vdisk $vdiskFile at $diskDev."
      return 1
   fi

   mount -r $bootPart $tmpDir 
   if [ $? -ne 0 ]; then
      echo "Couldn't mount boot partition of vdisk $vdiskFile at $diskDev."
      return 1
   fi
   
   if [ ! -f "$tmpDir/$kernelName" -o ! -f "$tmpDir/$initrdName" ]; then
      echo "Couldn't find kernel and initrd in $vdiskFile at $diskDev."
      return 1
   fi

   cp $tmpDir/$kernelName $outputDir/
   cp $tmpDir/$initrdName $outputDir/

   cleanup && trap - EXIT TERM KILL
   return 0
}
main $*
