# -*-Shell-script-*-
# 
# disk-functions: This file contains functions used xrnginstall  
#                 and panini/spirit to configure and access
#                 the 2nd pci block device/partition on a VM
#
# Copyright (c) 2014-2017 by Cisco Systems, Inc.
# All rights reserved.
#

/usr/bin/logger -p 0 -t udev  "(source: calvados/hostos_pkg/boot/scripts/Disk-functions) "

#Source function library
. /etc/init.d/spirit-functions
. /etc/init.d/spirit_pd.sh

readonly fs_sb_output=/tmp/fs_sb_output
readonly EXT2_FS_MAGIC_NUMBER=0xEF53

cmdline=$(cat /proc/cmdline)

PLATFORM=`echo $cmdline | sed 's/^.*platform=//' | cut -d" " -f1`
PLATFORM=$(override_platform_type ${PLATFORM}  $SIMULATION)
if [ "$PLATFORM" == "scapa" ]; then
    readonly DISK1_PV=ecu_disk1
else
    readonly DISK1_PV=pci_disk1
fi
readonly DISK1_LV=ssd_disk1_
readonly DISK1_LABEL=DISK_ONE

# Default size set for debug partition, 10M
readonly DEBUG_PART_SIZE_DEFAULT=10

# 5 sub-partitions: 1 for hostOS, 2 for Calvados VMs, 2 for XR VMs
# Note: The maximum length of a mkfs.ext4 volume label is 16 bytes.
#       When used (e.g., asr9k) Ensure "D1_XXXX_LV[X]_DISK1_LABEL" < 16
readonly D1_HOST_LV=hostos

D1_CVDS_LABEL_LV1=cd_1
D1_CVDS_LV1=calvados_1

D1_CVDS_LABEL_LV2=cd_2
D1_CVDS_LV2=calvados_2

readonly D1_XR_LV1=xr_1
readonly D1_XR_LV2=xr_2

declare -F pd_create_dummy_volumes >& /dev/null
   if [ $? -eq 0 ]; then
      readonly D1_NUM_LV=5
   else
      readonly D1_NUM_LV=3
   fi

function DFLOG {
    local msg=$1
    echo "$(date -R): $msg" >> /tmp/disk-functions.log
}
readonly -f DFLOG

# Check/repair filesystem.
# Args: $1-storage device name, $2-mount point
# Return: (error code returned by fsck)
function check_repair_fs {
    local dev=$1
    local mnt=$2
    local status=0

    echo "$FUNCNAME $dev $mnt called at $(date)" >&107

    DFLOG "Checking filesystem in $dev $mnt ..."
    #abort check if partition is already mounted
    local mount=`mount | grep "$dev"`
    if [ ! -z "$mount" ]; then
        DFLOG "Aborting fs check. Device $dev is mounted."
        # equivalent to fsck error code (8) for operational error
        return 8
    fi
    #only perform fsck on partition that is not clean
    local state=`dumpe2fs $dev 2>&107 | grep state | awk {'print $3'}`
    if [ "$state" != "clean" ]; then
        DFLOG "Filesystem is not clean trying to repair ..."
        fsck -y $dev
        status=$?
        if [ $status -eq 0 ]; then
            DFLOG "No errors found"
        fi
        if [ $status -eq 1 ]; then
            DFLOG "Errors were found and corrected"
        fi
        if [ $status -gt 1 ]; then
            DFLOG "Error encountered"
        fi
    else
        DFLOG "Filesystem is clean"
    fi
    return $status
}
readonly -f check_repair_fs

function check_fs_sb {
    local return_code=0
    local fs_mn=0
    local part=${1}

    dumpe2fs -h ${part}  > $fs_sb_output 2>&1
    if (( $? == 1 )); then
        return_code=1
    else
        fs_mn=$(grep "magic number" $fs_sb_output | awk '{print $4}')
        if (( $fs_mn != $EXT2_FS_MAGIC_NUMBER )); then
            return_code=2
        fi
    fi

    return $return_code
}
readonly -f check_fs_sb

function format_partition {
    local dev_name=${1} label=${2}

    # Reformat partition with an ext4 file system
    if [ "$PLATFORM" == "mystique" ]; then
        /sbin/mkfs.ext4 -L ${label} -b 4096 -O ^huge_file -vv ${dev_name}
        /sbin/tune2fs -c 0 -i 0 ${dev_name} 
    else
        /sbin/mkfs.ext4 -L ${label} -b 4096 -O ^huge_file -vv ${dev_name} >&107 2>&1
        /sbin/tune2fs -c 0 -i 0 ${dev_name} >&107 2>&1
    fi
    sync
}
readonly -f format_partition

# Format disk1 of calvados
function format_calvados_partition {
    local dev_name=/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_CVDS_LV1}
    local label=${DISK1_LABEL}

    # PI team to review and enable
    # if [[ $VIRT_METHOD == "lxc" ]]; then
    #    label = "${D1_CVDS_LABEL_LV1}_${DISK1_LABEL}"
    # fi
    # Reformat partition with an ext4 file system
    /sbin/mkfs.ext4 -L ${label} -b 4096 -O ^huge_file -vv ${dev_name} >&107 2>&1
    /sbin/tune2fs -c 0 -i 0 ${dev_name} >&107 2>&1
    sync
}
readonly -f format_calvados_partition

function check_fs_partition {
    local dev_name=${1} label=${2}

    check_fs_sb ${dev_name}
    # Even though super block is EXT4, redo mkfs.
    # The Partition label may have changed
    format_partition ${dev_name} ${label}
}

# Get size of the disk, in MB
# Parameter: disk (ex: /dev/sda)
# Return: $DISK_SIZE
function get_disk_size {
    local dev=${1}

    #
    # Handle optional disks
    #
    if [ ! -b $dev ]
    then
        let "DISK_SIZE=0"
        return
    fi

    max=$(fdisk -l ${dev} 2>&107 | grep "Disk ${dev}:"  | cut -d ',' -f2)
    max=${max%bytes}
    let "DISK_SIZE=$max/1000000"
}

function provision_disk_one {
  local args=$1
  local logvol_size
  local total_disk_size
  declare -a pdisks=($@)
  static_part=${STATIC_SEC_DISK_PARTITION[@]}
  # check for multiple disks
  local gotone

  for i in "${pdisks[@]}"
  do
      gotone=1

      secondary_disks="${secondary_disks} /dev/$i"
      dev=/dev/$i

      if [ ! -b "${dev}" ]; then
        return
      fi
      step_log_console "Partitioning PCI block device $dev"

      # Check if it is a PCI device
      local pci_disk_check=$(udevadm info -q path -n ${dev} 2>&107 \
                             | grep pci | grep -v usb)

      if [ -z "$pci_disk_check" ]; then
         echo "Not a pci/usb block device ${dev}"
         return
      fi

      #Is volume group name same as desired
      OLD_DISK1_PV=$(pvdisplay ${dev} 2>&107 | grep "VG Name" | awk '{print $3}')
      if [[ "${OLD_DISK1_PV}" == "${DISK1_PV}" ]]; then
          # If volume group name is as expected, check the number of 
          # LVs in this VG. And check if the name of the calvados
          # volume matches the expected name (calvados_1). 
          cnt=$(lvscan 2>&107 | grep ${DISK1_LV} | wc -l)
          if [[ ${cnt} == ${D1_NUM_LV} ]]; then
               #Volume count matches remove any stale xr_data_lv in pci_disk
               lvremove -f /dev/pci_disk1/xr_data_lv* >> /tmp/log 2>&1 
              # Volume count matches, check if the volume name matches 
              cnt=$(lvscan 2>&107 | grep ${D1_CVDS_LV1} | wc -l)
              if [[ ${cnt} == 1 ]]; then
                check_fs_secondary_vols "${DISK1_PV}" "${dev}"
                ret=$?

                if [ "${ret}" == 0 ]; then
                    step_log_console "Retaining Volume Group ${DISK1_PV}"
                    return
                else
                    step_log_console "Removing Volume Group ${DISK1_PV}"
                fi
              fi
          fi
          step_log_console "Removing Volume Group ${DISK1_PV}"
          vgremove -f ${DISK1_PV}  >&107 2>&1
          pvremove -ff -y ${dev} >&107 2>&1
      else
          if [ "$PLATFORM" == "scapa" -a \
                "${OLD_DISK1_PV}" == "pci_disk1" ]; then
              #Do we have same number of logical volumes
              cnt=$(lvscan 2>&107 | grep ${DISK1_LV} | wc -l)
              if [[ ${cnt} == ${D1_NUM_LV} ]]; then
                  #Rename the volumes group name ! need active here ?
                  vgrename -v /dev/pci_disk1 /dev/ecu_disk1
                  return
              fi
	      /usr/bin/logger -p 0 -t udev "ecu : mismatch in number of logical volumes: ${cnt} to ${D1_NUM_LV}"
          fi

          #Remove the physical volume on the device
          step_log_console "Removing Volume Group ${DISK1_PV} due to mis-match"
          vgremove -f ${OLD_DISK1_PV} >&107 2>&1
          pvremove -ff -y ${dev} >&107 2>&1
      fi
      get_disk_size ${dev}
      let total_disk_size=$total_disk_size+DISK_SIZE
  done

  if [ "$gotone" = "" ]
  then
    return
  fi

  if [[ "$PLATFORM" == "asr9k" ]]; then
  /bin/dd if=/dev/zero of=${dev} bs=1024 count=10000 >&107 2>&1
  else
  secondary_disks=$(echo "${secondary_disks}" | sed -e 's/^[ \t]*//')
  /bin/dd if=/dev/zero of=${secondary_disks[0]} bs=1024 count=10000 >&107 2>&1
  fi
  pvcreate -ff -y ${secondary_disks} >&107 2>&1
  vgcreate -f -y ${DISK1_PV} ${secondary_disks} >&107 2>&1

  #Logical volume for Host
  let logvol_size=$total_disk_size*${DISK_SSD_HOST_SIZE}/100
  lvcreate -L ${logvol_size} -n ${DISK1_LV}${D1_HOST_LV} ${DISK1_PV} >&107 2>&1
  check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_HOST_LV}" \
                     "${D1_HOST_LV}_${DISK1_LABEL}"

  let cal_logvol_size=$total_disk_size*${DISK_SSD_CALVADOS_SIZE}/100
  let xr_logvol_size=$total_disk_size*${DISK_SSD_XR_SIZE}/100

  if [[ $VIRT_METHOD == "lxc" ]]; then
    #Logical volume for Calvados VM1/2
    lvcreate -L ${cal_logvol_size} -n ${DISK1_LV}${D1_CVDS_LV1} ${DISK1_PV} >&107 2>&1
    check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_CVDS_LV1}" \
                       "${D1_CVDS_LABEL_LV1}_${DISK1_LABEL}"

   # lvcreate -L ${cal_logvol_size} -n ${DISK1_LV}${D1_CVDS_LV2} ${DISK1_PV} >&107 2>&1
    #check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_CVDS_LV2}" \
     #                  "${D1_CVDS_LABEL_LV2}_${DISK1_LABEL}"

    #Logical volume for XR VM1/2
    if [ ! -z "$static_part" ]; then
    lvcreate -L ${xr_logvol_size} -n ${DISK1_LV}${D1_XR_LV1} ${DISK1_PV} >&107 2>&1
    check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_XR_LV1}" \
                       "${D1_XR_LV1}_${DISK1_LABEL}"

    #lvcreate -L ${xr_logvol_size} -n ${DISK1_LV}${D1_XR_LV2} ${DISK1_PV} >&107 2>&1
    #check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_XR_LV2}" \
     #                  "${D1_XR_LV2}_${DISK1_LABEL}"
    fi
  else
    #Logical volume for Calvados VM1/2
    lvcreate -L ${cal_logvol_size} -n ${DISK1_LV}${D1_CVDS_LV1} ${DISK1_PV} >&107 2>&1

    check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_CVDS_LV1}" \
                       "${DISK1_LABEL}"

   declare -F pd_create_dummy_volumes >& /dev/null
   if [ $? -eq 0 ]; then
     #creating two dummy volumes for ncs6k and ncs4k to make vol count to 5 to support 61x to 524 downgrade 
     pd_create_dummy_volumes ${DISK1_PV}
   fi

    #lvcreate -L ${cal_logvol_size} -n ${DISK1_LV}${D1_CVDS_LV2} ${DISK1_PV} >&107 2>&1
    #check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_CVDS_LV2}" \
     #                  "${DISK1_LABEL}"

    #Logical volume for XR VM1/2
    if [ ! -z "$static_part" ]; then
    lvcreate -L ${xr_logvol_size} -n ${DISK1_LV}${D1_XR_LV1} ${DISK1_PV} >&107 2>&1

    check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_XR_LV1}" \
                       "${DISK1_LABEL}"

   # lvcreate -L ${xr_logvol_size} -n ${DISK1_LV}${D1_XR_LV2} ${DISK1_PV} >&107 2>&1
   # check_fs_partition "/dev/mapper/${DISK1_PV}-${DISK1_LV}${D1_XR_LV2}" \
    #                   "${DISK1_LABEL}"
    fi
  fi
}

# Run a soft filesystem check on each of the secondary disk volumes to check for
# filesystem corruption through bad sectors, superblocks etc.
# Failing this check, these volumes will need to be re-partitioned and re-formatted.
function check_fs_secondary_vols {
    local disk1_pv=${1}
    local dev=${2}
    local retval=0
    local is_ssd_local=0

    declare -F pd_check_fs_secondary_vols >&107 2>&1
    if [ $? -eq 0 ]; then
        # filesystem check DISK1_LV LVs
        pd_check_fs_secondary_vols ${1} ${DISK1_LV}
        return $?
    fi

    declare -F pd_check_for_secondary_vols_resize >&107 2>&1
    if [ $? -eq 0 ]; then
        # Check for DISK1_LV change in sizes
        pd_check_for_secondary_vols_resize ${dev}
        if [ $? -ne 0 ]; then
            step_log_console "Secondary volumes need to be resized"
            return 1
        fi
    fi

    # Currently this check is in place only for platforms that have their main disk
    # hosting secondary disk volumes since recovering such a partition on a live
    # system is non-trivial.
    for _pv in `pvdisplay | awk '/PV Name.*dev.sda/{print $3}'`; do
        # If there is an existing PV on disk(sda) hosting secondary disk volumes,
        local vg_name=`pvdisplay $_pv | awk '/VG Name/{print $3}' | grep $disk1_pv`
        if [ -n "${vg_name}" ]; then
           is_ssd_local=1 
           break
        fi
    done

    if [ "${is_ssd_local}" == 0 ]; then
        step_log_file "Secondary disk fs check is only for platforms that host secondary disk volumes on the main disk"
        return $retval
    fi
    
    lvchange -a y /dev/${disk1_pv} >&107 2>&1
    ssd_lvnames=`lvdisplay ${disk1_pv} | grep "LV Path" | awk '{print $3}'`
    for lv in ${ssd_lvnames[@]}; do
        check_fs_sb $lv
        retval=$?
        if [ "${retval}" != 0 ]; then
            step_log_console "Filesystem for $lv is corrupt!!"
            step_log_console "Need to re-format ${DISK1_PV} volumes"
            break
        fi
    done
    lvchange -a n /dev/${disk1_pv} >&107 2>&1 
    return $retval
}

function activate_disk_one_vg {
    modprobe dm-mod
    disk1_pv=$(pvscan | grep ${DISK1_PV} | awk '{print $4}')
    if [ "${disk1_pv}" == "${DISK1_PV}" ]; then
        lvchange -a y /dev/${DISK1_PV} >&107 2>&1
    fi
}

# Mount a filesystem by label. Before its mounting, run fsck to fix corrutpion
# if found.
function mount_fs_label {
    local label=${1}
    local dir=${2}

    echo "$(date) mount ${label} ${dir}" >&107 2>&1
    fsck -y LABEL=${label} >&107 2>&1
    mount -L ${label} ${dir} >&107 2>&1
}                                    

function mount_disk_one {
    local mount_dir=${1}
    local label=${DISK1_LABEL}
    local install=$(cat /proc/cmdline | grep install=)
   
    if [ -n "${install}" ]; then
        return
    fi

    # Activate volume group on disk1
    activate_disk_one_vg >&107 2>&1 

    local vm_type=`cat /proc/cmdline | grep vmtype=`
    if [ -z "${vm_type}" ] || [[ "${vm_type}" =~ "hostos" ]]; then
        label=${D1_HOST_LV}_${DISK1_LABEL}
    fi
    if [[ $VIRT_METHOD == "lxc" ]]; then
        if [ -z "${vm_type}" ] || [[ "${vm_type}" =~ "sysadmin-vm" ]]; then
            label=${D1_CVDS_LABEL_LV1}_${DISK1_LABEL}
        fi
        if [ -z "${vm_type}" ] || [[ "${vm_type}" =~ "xr-vm" ]]; then
            label=${D1_XR_LV1}_${DISK1_LABEL}
        fi
        # TBD: When are V2 labels to be used?
    fi

    # Loop through each of the block-device and mount the filesystem
    # that was labeled "DISK_ONE" during install.

    for device in `find /dev/ -xdev -type b`; do
        out=$(dumpe2fs -h ${device} 2>&107 | grep "Filesystem volume name:" | \
              awk '{print $4}')
        if [ "${out}" == "${label}" ]; then
            mkdir -p ${mount_dir} >&107 2>&1
            fsck -y ${device} >&107 2>&1
            /sbin/tune2fs -c 0 -i 0 ${device} >&107 2>&1
            mount -o discard ${device} ${mount_dir} >&107 2>&1
            echo "Mount ${device} at ${mount_dir}"
            return
        fi
    done
}


function remove_old_volumes {

  # function copied from http://grox.net/sysadm/unix/nuke.lvm
  # adapted for spirit
  # Remove volumes on /dev/sda and /dev/sdb with the name panini*
  # of pci*

  declare -F pd_remove_old_volumes >&107 2>&1
  if [ $? -eq 0 ]; then
    # Remove non-DISK1_LV LVs
    pd_remove_old_volumes ${DISK1_LV} ${DISK1_PV}
    return
  fi

  step_log_console "Inside Volume-Cleaning Function"
  /usr/bin/logger -p 0 -t udev "ecu : Inside Volume-Cleaning Function"
  # remove existings lvm configs for for panini_vol_grp
  for _vol in `lvdisplay | awk '/LV Name/{print $3}' | awk '/panini_vol_grp/{print $1}'`; do
    umount -f $_vol >> /tmp/log 2>&1
    lvchange -an $_vol >&107 2>&1
    yes | lvremove -f $_vol >&107 2>&1
    step_log_console "Removed LVM ${_vol} for Panini"
  done

 # remove existings lvm configs for for app_vol_grp
  for _vol in `lvdisplay | awk '/LV Name/{print $3}' | awk '/app_vol_grp/{print $1}'`; do
    umount -f $_vol >> /tmp/log 2>&1
    lvchange -an $_vol >&107 2>&1
    yes | lvremove -f $_vol >&107 2>&1
    step_log_console "Removed LVM ${_vol} for App-Host"
  done

 # removing app-vol-groups
  for _vol in `vgdisplay | awk '/VG Name/{print $3}' | awk '/app_vol_grp/{print $1}'`; do
    vgchange -an $_vol >&107 2>&1
    yes | vgremove -f $_vol >&107 2>&1
    step_log_console "Removed App-Vol Grp ${_vol}"
  done

  for _vol in `vgdisplay | awk '/VG Name/{print $3}' | awk '/panini_vol_grp/{print $1}'`; do
    vgchange -an $_vol >&107 2>&1
    yes | vgremove -f $_vol >&107 2>&1
    step_log_console "Removed Panini Vol-Grp ${_vol}"
  done

  # last step didn't get 'em all...
  for _vol in /dev/mapper/panini*; do
    if [ -b "$_vol" ]; then
      dd if=/dev/zero of=$_vol bs=512 count=12 >&107 2>&1
      step_log_console "Formatted Panini volume ${_vol}"
    fi
  done


  # Formatting App-Volume Groups
  # last step didn't get 'em all...
  for _vol in /dev/mapper/app* ; do
    if [ -b "$_vol" ]; then
        dd if=/dev/zero of=$_vol bs=512 count=12 >&107 2>&1
        step_log_console "Formatted App-Volume ${_vol}"
    fi
  done

  for _pv in `pvdisplay | awk '/PV Name.*dev.sda/{print $3}'`; do
    # If there is an existing PV on disk(sda) hosting secondary disk volumes,
    # delete ONLY non disk1 volumes under it.
    local vg_name=`pvdisplay $_pv | awk '/VG Name/{print $3}' | grep $DISK1_PV`
    if [ -z $vg_name ] || [ "${BOARDTYPE}" != "RP" ]; then
        yes | pvremove -ff -y $_pv >&107 2>&1
    else
        for _vol in `lvdisplay ${vg_name} | awk '/LV Path/{print $3}' | grep -v ${DISK1_LV}`; do
            umount -f $_vol >> /tmp/log 2>&1
            lvchange -an $_vol >&107 2>&1
            yes | lvremove -f $_vol >&107 2>&1
        done
    fi
  done

  # just in case some were missed... (some always are)
  for _pv in $disks; do
    yes | pvremove -ff -y $_pv >&107 2>&1
    dd if=/dev/zero of=$_pv bs=512 count=255 >&107 2>&1
  done

  step_log_console "Removed PV"

  # see what else the system still knows about
  # and get rid of them, too.
  # note that we ignore 'sd*' partitions and that this
  # assumes that we don't need dm-? for the system
  # that we're running on. i know, big assumption.
  #
  for _part in `awk '/dm-/{print $4}' /proc/partitions`; do
    yes | pvremove -ff -y $_part >&107 2>&1
    dd if=/dev/zero of=$_part bs=512 count=255 >&107 2>&1
  done
  step_log_console "Exiting from the Volume Cleaning Section"

}

function check_disk_one_space {
  local dev=/dev/${1}
  local dsize=0

  if [ ! -b "${dev}" ]; then
    return 0
  fi
  echo "Checking PCI block device $dev disk space"

  # Check if it is a PCI device
  local pci_disk_check=$(udevadm info -q path -n ${dev} 2>&107 \
                         | grep pci | grep -v usb)

  if [ ! -z "${pci_disk_check}" ]; then
    # find disk one volume group name
    DISK1PV=$(pvdisplay ${dev} 2>&107 | grep "VG Name" | awk '{print $3}')

    if [[ "${DISK1PV}"="ecu_disk1" || "${DISK1PV}"="pci_disk1" ]]; then
      local label=${DISK1PV}-${DISK1_LV}${D1_CVDS_LV1}
      local device=/dev/mapper/$label

      #Do we have same number of logical volumes
      cnt=$(lvscan 2>&107 | grep ${DISK1_LV} | wc -l)
      if [[ ${cnt} == "${D1_NUM_LV}" ]]; then
        # Activate volume group on disk1
        activate_disk_one_vg

        # mount calvados-1 partition to check disk space
        DISK1MNT=$(mktemp -d /tmp/disk1dev.XXXXXX)
        mount -o ro,noload ${device} ${DISK1MNT} 2>&107 || return 1

        dsize=$(df -k ${DISK1MNT} | tail -1 | awk {'print $3'})
        echo "PCI block device ${dev} free space: ${dsize}K"

        # unmount ISO, we no longer need it
        [ -d "${DISK1MNT}" ] && umount ${DISK1MNT} && rmdir ${DISK1MNT}
        if [ "${dsize}" -gt 2000000 ]; then
          return 0
        else
          return 1
        fi
      fi
    fi
  fi
  /usr/bin/logger -p 0 -t udev "ecu : disk-functions : check_disk_one_space - this disk need partition properly, continue install"
  # this disk need partition properly, continue install.
  return 0
}

function pxe_install_second_disk_pre_check {
    # check disk space, need at least 2G disk space for install image for pxe boot
    if [ ! -z ${SIMULATION} ]; then
      check_disk_one_space "${second_disk}${1}"
      if [ $? -eq 1 ]; then
        pxeflag=1
	/usr/bin/logger -p 0 -t udev "ecu : disk-functions : pxe_install_second_disk_pre_check - There is not enough disk space in /misc/disk1 to copy internal PXE boot image"
        echo "There is not enough disk space in /misc/disk1 to copy internal PXE boot image."
      fi

      while [ -n "${pxeflag}" ]; do
        echo "Choose an option :"
        echo "1). Format /misc/disk1, and continue install"
        echo "2). Abort install"
        printf "option [1/2]? "
        read answers123

        if [ "${answers123}" = "1" -o "${answers123}" = "2" ]; then
          if [ "${answers123}" = "1" ]; then
            printf "Option 1 is selected. Existing files on /misc/disk1 will be lost.  Continue? [y/n] "
          elif [ "${answers123}" = "2" ]; then
            printf "Option 2 is selected. Installation will be terminated.  Confirm? [y/n] "
          fi

          read answers

          if [ "${answers}" = "y" ]; then
            if [ "${answers123}" -eq 1 ]; then
              format_calvados_partition
              echo "format disk1 passed to sysadmin VM"
            /usr/bin/logger -p 0 -t udev "ecu : disk-functions : pxe_install_second_disk_pre_check - format disk1 passed to sysadmin VM"  
	    break
            elif [ "${answers123}" -eq 2 ]; then
              echo "Installation terminated.  Please clean up /misc/disk1 and rerun install."
	      /usr/bin/logger -p 0 -t udev "ecu : disk-functions : pxe_install_second_disk_pre_check - Installation terminated.  Please clean up /misc/disk1 and rerun install."
              call_reboot
              exit
            fi
          fi
        fi
      done
    fi
}


function reformat_partition {
    local dev_name=${1}

    # Reformat partition with an ext4 file system
    if [ "$PLATFORM" == "mystique" ]; then
        /sbin/mkfs.ext4 -b 4096 -O ^huge_file -vv ${dev_name}
        /sbin/tune2fs -c 0 -i 0 ${dev_name}
    else
        /sbin/mkfs.ext4 -b 4096 -O ^huge_file -vv ${dev_name} >&107 2>&1
        /sbin/tune2fs -c 0 -i 0 ${dev_name} >&107 2>&1
    fi
    sync
}
readonly -f reformat_partition

# Get debug partition (dp) offset and size
function get_dp_offset {
    local dev=${1}
    max=$(fdisk -l ${dev} 2>/dev/null | grep "Disk /dev"  | cut -d ',' -f2)
    max=${max%bytes}
    max=$(($max / 1000000))
    startm=$(($max - 10))
    startb=$(($startm * 1000000))
    dpstarts=$(($startb / 512))
    endb=$(($max * 1000000))
    dpends=$(($endb / 512))
    if [ $(($startm % 512)) -ne 0 ]; then
       dpstarts=$(($dpstarts + 1))
    fi
    dpdiffs=$(($dpends - $dpstarts + 1))
    dpoffset=$(($dpstarts * 512))
    dpsizeb=$(($dpdiffs * 512))
}
# Mount dp to /tmp/bakelog. If dp does not exist, create dp.
function prepare_dploop {
    local dev=${1}
    local src=${2}
    mkdir -p ${LOGFLOWDIR}.sav
    rm -rf ${LOGFLOWDIR}.sav/*
    cp -rf ${LOGFLOWDIR}/* ${LOGFLOWDIR}.sav/ >&107 2>&1
    cp -f ${LOGDIR}/${LOGFILE0} ${LOGFLOWDIR}.sav/ >&107 2>&1
    cp -f ${LOGDIR2}/${LOGFILE} ${LOGFLOWDIR}.sav/ >&107 2>&1
    rm -rf ${LOGFLOWDIR}/*
    dploop=$(losetup --find)
    losetup --offset $dpoffset --sizelimit $dpsizeb ${dploop} ${dev}
    local label=`blkid ${dploop} | grep "debug" | grep "ext4"`
    if [ -z "$label" ]; then
       if [ -z "$src" ]; then
          check_fs_partition ${dploop} "debug"
       else
          losetup -d ${dploop} >&107 2>&1
          return 1 
       fi
    fi
    mount ${dploop} ${LOGFLOWDIR} >&107 2>&1
    if [ $? -eq 0 -a -z "$src" ]; then
       avail=$(df -k | grep ${dploop} |awk '{print $4}')
       if [ "$avail" -lt 1536 ]; then
          umount ${LOGFLOWDIR} >/dev/null 2>&1
          check_fs_partition ${dploop} "debug"
          mount ${dploop} ${LOGFLOWDIR} >&107 2>&1
       fi
    fi
    if [ $? -ne 0 ]; then
       umount ${LOGFLOWDIR} >/dev/null 2>&1
       losetup -d ${dploop} >&107 2>&1
       cp -rf ${LOGFLOWDIR}.sav/* ${LOGFLOWDIR}/ >&107 2>&1 
       rm -rf ${LOGFLOWDIR}.sav 
       return 1
    fi
    if [ -z "$src" ]; then
       avail=$(df -k | grep ${dploop} |awk '{print $4}')
       if [ "$avail" -lt 1536 ]; then
          umount ${LOGFLOWDIR} >/dev/null 2>&1
          losetup -d ${dploop} >&107 2>&1
          cp -rf ${LOGFLOWDIR}.sav/* ${LOGFLOWDIR}/ >&107 2>&1
          rm -rf ${LOGFLOWDIR}.sav
          return 1
       fi
    fi

    cp -rf ${LOGFLOWDIR}.sav/* ${LOGFLOWDIR}/ >&107 2>&1 
    rm -rf ${LOGFLOWDIR}.sav 
    sync
    return 0
}

