# Version history
#
# 0.2: Initial version by Reinhard Partmann
# 0.2a: Changed the XML file settings by Pascal de Wild
# 0.3: add check if running under ESX and in troubleshooting mode and
#      bc is not available
#      code cleanup
#
# 0.4: parameters added
#      1st filename      ex: sata_nv     for sata_nv.xml od sata_nv.o
#      2nd PCI-DeviceID  037f
# 0.5  redesign.
# 0.6  bugfix thanks jims_tx
#
# TODO
#


VERSION="0.5"
VENDOR_ID="10de"
# 8086 .. INTeL
# 10de .. NVidia
# 1166 .. ServerWorks
# 1095 .. SIL/CMD
DEVICE_ID="037f"
DEVICE_NAME="MCP55 SATA Controller"
#-------------------------
VENDOR_FILENAME=""
DEBUG=1
RETURN_VAL=""
###############################################################################
###############################################################################
#                     C O N S T A N T S                                       #
###############################################################################
                    # define some colors
black='\E[30;40m'
red='\E[31;40m'
green='\E[32;40m'
yellow='\E[33;40m'
blue='\E[34;40m'
magenta='\E[35;40m'
cyan='\E[36;40m'
white='\E[37;40m'
###############################################################################
####          subroutines                                                  ####
###############################################################################
function colorReset ()       #  Reset text attributes to normal
{                            #+ without clearing screen.
 tput sgr0
 return 0
}
###############################################################################
function cecho ()             # Color-echo.
                              # Argument $1 = message
                              # Argument $2 = color
{
local default_msg="No message passed."
                              #Doesn't really need to be a local variable.
 message=${1:-$default_msg}   # Defaults to default message.
 color=${2:-$white}           # Defaults to black, if not specified.
 echo -e "$color$message"
 # echo -n "$message"

 colorReset                   # Reset to normal.
return 0
}
###############################################################################
function debug_echo() {
 if [ -z "$1" ]
 then
  echo "DEBUG_ERROR: NO Parameter"
  return 1
 else
   if [ "$DEBUG" == "1" ]
   then
     cecho "DEBUG: $1" $red >&2
   fi
 fi
return 0
}
###############################################################################
function usage() {
echo "USAGE: gosata.sh "
echo "  Edit the following lines for your system"
echo "  VENDOR_ID=xxxx "
echo "         where xxxx is the VendorID of your SATA Controller"
echo "         with the vendorID we select the correct filename.[o|xml]"
echo "  DEVICE_ID=yyyy "
echo "         where yyyy is the DeviceID of your SATA controller"
echo
}
###############################################################################
function vendorID2name() {
case $VENDOR_ID in
 8086) # intel
       echo "INTeL ..."
       VENDOR_FILENAME="ata_piix"
       DEVICE_ID_REPLACE="2920"
     ;;
 10de) # nvidia
       echo "NVidia ..."
       VENDOR_FILENAME="sata_nv"
       DEVICE_ID_REPLACE="037e"  #  0267
     ;;
 1166) # ServerWorks
       echo "ServerWorks ..."
       VENDOR_FILENAME="sata_svw"
       DEVICE_ID_REPLACE="0240"
     ;;
 1095) # SIL / CMD Technology
       echo "SIL/CMD Technology..."
       VENDOR_FILENAME="sata_sil"
       DEVICE_ID_REPLACE="3112"
     ;;
 *) #
       cecho "ERROR: VENDOR not found!  exiting..." $red
       VENDOR_FILENAME="notfound"
       exit
     ;;
esac
}
###############################################################################
function esx_troubleshoot() {
echo "check ifrunning on an ESX host : "
if [ -f /usr/bin/vmware ]
 then
    isESX=`vmware -v | grep "VMware ESX Server 3\." | wc -l| tr -d [:space:]`
    echo "isESX: $isESX"
    #[ -f /etc/motd ] ||
      if [ $isESX == "1" ]
       then
        isESXfailsafe=`grep "ESX.*Server.*troubleshooting.*mode" /etc/motd | wc -l| tr -d [:space:]`
        echo "isESXfailsafe: $isESXfailsafe"

        if [ $isESXfailsafe == "1" ]
         then
              # here we assume we are running on a VMware ESX Server
              # in NOT troubleshooting mode
              BOOT_PREFIX="/boot"
              ROOT_PREFIX=""
              BOOT_MOUNTED=`mount |grep "boot" |wc -l| tr -d [:space:]`
              debug_echo "BOOT_MOUNTED $BOOT_MOUNTED"

               if [ $BOOT_MOUNTED == "0" ]
                then
                 debug_echo "0==BOOT_MOUNTED $BOOT_MOUNTED"
                 debug_echo "mount /boot"
                 mount /boot
                else
                 debug_echo "1==BOOT_MOUNTED $BOOT_MOUNTED"
               fi
         #else
         #     # here we assume we are running on a VMware ESX Server
         #     echo "You should do this in the ESX troubleshooting mode!"
         #     exit
        fi
     fi
 else
     # here we assume we are NOT running on a VMware ESX Server
     # because we booted a Linux LiveCD
     isESX=0
     debug_echo "isESX: $isESX"
     echo "mounting.."
     BOOT_PREFIX="/mnt/eboot"
     ROOT_PREFIX="/mnt/eroot"

     mount /dev/sda1 $BOOT_PREFIX
     mount /dev/sda2 $ROOT_PREFIX
     echo ""
     mount | grep sda
     echo ""
fi
}
###############################################################################
function update_initrd(){
      echo "copying original initrd file..."
    #echo "mkdir -p $ROOT_PREFIX/tmp/initrd/extracted"
      mkdir -p $ROOT_PREFIX/tmp/initrd/extracted

    # here vars to use either /boot or /mnt/eboot
    #echo "cp $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img $ROOT_PREFIX/tmp/initrd/initrd-2.4.21-47.0.1.ELvmnix.img.gz"
      cp -f $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img.old
      mv -f $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img $ROOT_PREFIX/tmp/initrd/initrd-2.4.21-47.0.1.ELvmnix.img.gz
      cd $ROOT_PREFIX/tmp/initrd

      echo "unpacking & mounting original initrd file..."
      gunzip -v -f initrd-2.4.21-47.0.1.ELvmnix.img.gz
      mount initrd-2.4.21-47.0.1.ELvmnix.img extracted -t ext2 -o loop

      cd extracted/etc/vmware
      echo "changing simple.map..."
    #echo "10de:037f 0000:0000 sata_nv.o" >> simple.map
      echo "adding  $VENDOR_ID:$DEVICE_ID to simple.map"
      echo "$VENDOR_ID:$DEVICE_ID 0000:0000 sata_nv.o" >> simple.map
      cp simple.map /root/simple.map
      cd ../../..
      umount extracted

      echo "replacing original initrd file..."
      gzip -v --best initrd-2.4.21-47.0.1.ELvmnix.img
      cp -f initrd-2.4.21-47.0.1.ELvmnix.img.gz /root/initrd-2.4.21-47.0.1.ELvmnix.img
      rm -f $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img
      mv -f initrd-2.4.21-47.0.1.ELvmnix.img.gz $BOOT_PREFIX/initrd-2.4.21-47.0.1.ELvmnix.img

}
###############################################################################
function update_xml(){
# decided not to calculate, which is error prone,
# "bc" is not available in the ESX COS, XML:Simple for perl is also not there
# bash aritmetic caused some errors asin the forum mentioned
# and as we dont need to insert a full section,
# because none fitted to our controller
# just reuse a existing one but the description is then wrong
  echo "patching xml files..."
  cd   $ROOT_PREFIX/etc/vmware/pciid
  mv   $VENDOR_FILENAME.xml $ROOT_PREFIX/tmp/$VENDOR_FILENAME.xml.org
  sed -e "s/$DEVICE_ID_REPLACE/$DEVICE_ID/g" $ROOT_PREFIX/tmp/$VENDOR_FILENAME.xml.org > $VENDOR_FILENAME.xml

}
###############################################################################
function update_initd(){
  echo "generating init.d file..."
  rm -f $ROOT_PREFIX/etc/init.d/rp-esxcfg-pciid-boot
  touch $ROOT_PREFIX/etc/init.d/rp-esxcfg-pciid-boot

cat >> $ROOT_PREFIX/etc/init.d/rp-esxcfg-pciid-boot << EOF1
#!/bin/bash
esxcfg-pciid
sleep 5
rm -f /etc/rc3.d/S99rp-esxcfg-pciid-boot
EOF1

  chmod a+x $ROOT_PREFIX/etc/init.d/rp-esxcfg-pciid-boot
  cd $ROOT_PREFIX/etc/rc3.d/
  rm -f S99rp-esxcfg-pciid-boot
  ln -s ../init.d/rp-esxcfg-pciid-boot S99rp-esxcfg-pciid-boot

}
###############################################################################

###############################################################################
###############################################################################
####   int main()                                                          ####
###############################################################################
alias cp=cp
alias mv=mv
alias rm=rm
# during install
# dest:  /boot    /mnt/sysimage/boot     /dev/sda1
# dest:  /        /mnt/sysimage          /dev/sda2

clear
colorReset
cecho "SATA BootFix for VMware ESX Server $version by Reinhard Partmann" $yellow


if [ $VENDOR_ID == "0" ] || [ $DEVICE_ID == "0" ]; then
 usage
 exit
fi

# are we running within COS of ESX and troubleshooting mode
esx_troubleshoot

# get the filename which have to be processed
vendorID2name    #echo "vendorID2name->return: $?"
echo "VENDOR_FILENAME: $VENDOR_FILENAME"
echo "DEVICE_ID: $DEVICE_ID"
echo "DEVICE_ID_REPLACE: $DEVICE_ID_REPLACE"
echo ""



echo "creating temp directories..."
mkdir -p /mnt/eboot
mkdir -p /mnt/eroot

#->update init ram disk core next reboot

#->update description files
update_xml

#->update next boot behaviour
if [ $isESXfailsafe == "1" ]
       then
         esxcfg-pciid
#        initrd is updated by the next command
         esxcfg-boot -r
       else
# when booting a LiveCD the esx command´s are not available.
         update_initrd
         update_initd
fi

###############################################################################
echo "cleanup..."
cd /
rm -f -r $ROOT_PREFIX/tmp/initrd

echo "$isESX"
if [ $isESX == "0" ]
 then
   echo "unmount try -- isESX: $isESX"
   cd /
   umount $BOOT_PREFIX
   umount $ROOT_PREFIX
fi

#do it manually! ;-)
#rm -f -r /mnt/eboot
#rm -f -r /mnt/eroot
echo "DONE."
echo "happy ESXing..."



