#!/bin/bash
# Author: Steven Shiau <steven _at_ nchc org tw>
# License: GPL
# Description: Program to dump AoE image to DRBL server.

DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl/}"

. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
[ -e /etc/drbl/drbl-ocs.conf ] && . /etc/drbl/drbl-ocs.conf
[ -e $DRBL_SCRIPT_PATH/sbin/ocs-functions ] && . $DRBL_SCRIPT_PATH/sbin/ocs-functions

#
prog="$(basename $0)"
#
USAGE() {
   echo "Usage: $prog [OPTION] disk_device image_name"
   language_help_prompt_by_idx_no
   echo "-x, --interactive     Interactive mode to input parameters."
   echo "Ex:" 
   echo "To dump /dev/hda as an image with name prefix winaoe:"
   echo "  $prog /dev/hda winaoe"
   echo "To use interactive mode, run:"
   echo "  $prog -x"
}
#
check_if_digits() {
  local var_="$1"
  local prompt_="$2"
  if [ -n "$(echo ${var_} | grep -iE "[^[:digit:]]")" ]; then
    [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
    echo "${prompt_} \"${var_}\""
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    echo "$msg_program_stop"
    exit 1
  fi
}

##############
#### main ####
##############
#
while [ $# -gt 0 ]; do
  case "$1" in
    -l|--language)
            shift
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      specified_lang="$1"
              shift
            fi
	    ;;
    -x|--interactive) 
	    run_mode="interactive"
	    shift;;
    -*)     echo "${0}: ${1}: invalid option" >&2
            USAGE >& 2
            exit 2 ;;
    *)      break ;;
  esac
done
#
device=$1
img_name_prefix=$2

#
ask_and_load_lang_set $specified_lang

# check DIA
check_DIA_set_ESC $DIA

# Stop local mounting service
[ -e /etc/init.d/mkswapfile ] && /etc/init.d/mkswapfile stop

#
if [ "$run_mode" = "interactive" ]; then
  # Since we borrow the function from clonezilla, we'd better to change some title here:
  msg_nchc_clonezilla_orig="$msg_nchc_clonezilla"
  msg_nchc_clonezilla="DRBL"
  # To get device
  get_target_hd_name_from_local_machine "$msg_local_source_disk \n$msg_linux_disk_naming $msg_press_space_to_mark_selection"
  device="/dev/$target_hd"
  # To get SAN Boot image name
  get_target_dir_name_when_saving  # get $target_dir
  img_name_prefix="$target_dir"
  # Return to original one.
  msg_nchc_clonezilla="$msg_nchc_clonezilla_orig"
else
  # In old version we use 3 parameters, now only 2. We have to show warning message if mornot 2.
  if [ "$#" -ne 2 ]; then
      [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
      echo "You must assign 2 parameters. No more, no less!!!"
      [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
      USAGE
      echo "$msg_program_stop"
      exit 1
  fi
fi

#
for i in device img_name_prefix; do
  eval var_tmp=\$$i
  if [ -z "$var_tmp" ]; then
    [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
    echo "$i is nothing!"
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    USAGE
    echo "$msg_program_stop"
    exit 1
  fi
done

# Check if the image name contains reserved characters
if [ -n "$(echo $img_name_prefix | grep -iE "aoe-[[:digit:]]+-[[:digit:]]+")" ]; then
  img_name_p1="$(echo $img_name_prefix | sed -e "s/aoe-[[:digit:]]*-[[:digit:]]*//g")"
  img_name_p2="$(echo $img_name_prefix | sed -e "s/$img_name_p1//g")"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "The input name contains reserved characters: $img_name_p2"
  echo "Please reassign the input name without $img_name_p2"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo "$msg_program_stop"
  exit 1
fi

#
mkdir -p $sanboot_img_dump_dir

# Find the size of disk we want to dump
# Ref: http://www.etherboot.org/wiki/sanboot/transfer
# Disk /dev/sda: 160.0 GB, 160041885696 bytes
# 255 heads, 63 sectors/track, 19457 cylinders
# Units = cylinders of 16065 * 512 = 8225280 bytes
# 
#    Device Boot      Start         End      Blocks   Id  System
# /dev/sda1   *           1       11519    92526336    7  HPFS/NTFS
# /dev/sda2           11520       12735     9767520   83  Linux
# /dev/sda3           12736       12978     1951897+  82  Linux swap / Solaris
# /dev/sda4           12979       19457    52042567+   5  Extended
# /dev/sda5           12979       19457    52042536   83  Linux

bs="$(LC_ALL=C fdisk -l $device | grep -iE '^Units = cylinders' | awk -F'=' '{print $3}' | sed -e 's/bytes//g' -e 's/[[:space:]]//g')"
check_if_digits "$bs" "Oops... The cylinder size was not found correctly! The one we found is"
# Find the largest cylinder in the "End" column. By doing this, we can dump multiple partitions.
count="$(LC_ALL=C fdisk -l $device | grep -A10000 -Ei "Device[[:space:]]*Boot" | grep -vEi "Device[[:space:]]*Boot" | sed -e "s/*//g" | awk -F' ' '{print $3}' | sort -rn | head -n 1)"
check_if_digits "$count" "Oops... A correct number of cylinders was not found! The one we found is"
disk_size="$(echo "scale=2; $count * $bs /1000/1000/1000" | bc -l) GB" # unit: GB

for i in bs count; do
 eval var_tmp=\$$i
 if [ -z "$var_tmp" ]; then
   [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
   echo "$i is nothing!"
   [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
   USAGE
   echo "$msg_program_stop"
   exit 1
 fi
 if [ -n "$(echo $var_tmp | grep -iE '[^[:digit:]]')" ]; then
   [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
   echo "$i not digits!"
   [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
   echo "$msg_program_stop"
   exit 1
 fi
done

# Assign vbladed <shelf> <slot> to image name. Find a free one
# Here we will set the file name as IMAGENMAE.aoe-<shelf>-<slot>, e.g. image1.aoe-1-1
shelf_no=""
slot_no=""
for i in `seq 0 $aoe_shelf_max`; do
  for j in `seq 0 $aoe_slot_max`; do
    if [ -z "$(unalias ls &>/dev/null; ls -alFh $sanboot_img_dump_dir/*.aoe-$i-$j-for-* 2>/dev/null)" ]; then
        shelf_no=$i
	slot_no=$j
    fi
    [ -n "$slot_no" ] && break
  done
  [ -n "$shelf_no" ] && break
done
echo "Available AoE shelf #: $shelf_no, slot #:$slot_no"

# MAC address of the ethx linked to drbl server
ethx_link_2_drbl="$(get-port-link-2-drbl-srv)"
if [ -n "$ethx_link_2_drbl" ]; then
  # To avoid strange character ":" in the file name, we use "-"
  mac_add="$(drbl-get-macadd $ethx_link_2_drbl | tr "[A-Z]" "[a-z]" | tr ":" "-")"
else
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "The ethernet port connected to DRBL server was NOT found!"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "$msg_program_stop"
  exit 1
fi
aoe_img_name="${img_name_prefix}.aoe-${shelf_no}-${slot_no}-for-${mac_add}"
#
echo "Disk $device partition table:"
echo ================================================
LC_ALL=C fdisk -l $device
echo ================================================
echo "Dumping $device (size: $disk_size) as image $sanboot_img_dump_dir/$aoe_img_name on server by:"
echo dd if=$device of=$sanboot_img_dump_dir/${aoe_img_name} bs=$bs count=$count
echo "$msg_this_might_take_several_minutes... "
trigger_dd_status_report "$device" "$disk_size" &
dd_report_sig_pid=$!
start_time="$(date +%s%N)"
dd if=$device of=$sanboot_img_dump_dir/${aoe_img_name} bs=$bs count=$count
end_time="$(date +%s%N)"
kill -9 $dd_report_sig_pid &>/dev/null
echo "done!"
