#!/bin/sh


############################################################################
#
#  makeraid - dpi raid setup and formatter script
#
#  created by Mike Goins
#
#  modified Aug 24, 2006
#
############################################################################

readonly DRIVE1=/dev/sda
readonly DRIVE2=/dev/sdb
readonly RAID1=/dev/md0
readonly RAID1_FORMAT=ext3
readonly MNT=/media/hd0
readonly SFDISK="/sbin/sfdisk"
readonly NEW_RAID=",,fd\n"  # sfdisk commands for creating partition
SCRIPT_NAME=`/bin/basename $0`
LOG_TAG=$'[RAIDMAN]'
MDADM_BIN=/usr/local/sbin/mdadm
# list of folders that need to be on the drive
FOLDER_LIST="media schdvc cmddvc list osd shd schmi mvl rdy schins verins"
ROOT_FOLDS="log .meta"
USER=adtec                   
GROUP=users
RAIDSTATUS=/tmp/raidstatus     # mdadm daemon status file

usage () 
{
  echo "Usage: ${SCRIPT_NAME} [OPTION]"
  echo "A utility for managing the raid drives."
  echo "Options include:"
  echo "    -i       Initialize the raid array.  DANGEROUS: Deletes data."
  echo "    -r       Initialize an already failed or replaced drive."
  echo "    -s       Get raid status."
  echo "    -h       Display this screen"
}
               
partition_devices ()
{
    logger -t $LOG_TAG "Partitioning $DRIVE1"
    echo -e ${NEW_RAID} | ${SFDISK} ${DRIVE1} 
    logger -t $LOG_TAG "Partitioning $DRIVE2"
    echo -e ${NEW_RAID} | ${SFDISK} ${DRIVE2} 
    logger -t $LOG_TAG "Partitioning complete"
}                   

make_folders () 
{
  for DIR in $FOLDER_LIST; do
    mkdir $MNT/$DIR
    chown $USER:$GROUP $MNT/$DIR
    chmod g+s $MNT/$DIR
  done
  for DIR in $ROOT_FOLDS; do
    mkdir $MNT/$DIR
  done
  logger -t $LOG_TAG "Created folders on $RAID1"
}

create_raid ()
{
    mkraid --really-force --dangerous-no-resync $RAID1
    logger -t $LOG_TAG "Created $RAID1"
}

format_drive ()
{
    #  It is very important that the chunk-size parameter in the /etc/raidtab 
    # file match the value of the block size multiplied by the stride value
    mkfs.ext3 -b 4096 -R stride=1 $RAID1
    logger -t $LOG_TAG "Formatted $RAID1"
}

start_raid ()
{
    raidstart $RAID1
    logger -t $LOG_TAG "Started $RAID1"
}

mount_raid ()
{
    mount $RAID1 $MNT -t $RAID1_FORMAT 
    logger -t $LOG_TAG "Mounted $RAID1"
    
}

prep_system ()
{
  /etc/init.d/syslog stop   # halt syslogger, maybe using drive
  /etc/init.d/mirrord stop  # ditto
  /etc/init.d/freg stop
  /etc/init.d/apache2 stop
  umount -l $RAID1
  logger -t $LOG_TAG "Umounted $RAID1"
  raidstop $RAID1
  if [ $? -ne 0 ]; then   # not able to stop raid
    logger -t $LOG_TAG "Not able to stop $RAID1"
    mount_raid
    restore_services
    exit 1
  else 
    logger -t $LOG_TAG "Stopped $RAID1"
  fi    
}

restore_services ()
{
  /etc/init.d/syslog start
  /etc/init.d/mirrord start  
  /etc/init.d/freg start
  /etc/init.d/apache2 start
}

  
initialize_drive ()
{
  echo -n "Enter Y to confirm initialiazation: "
  read -t 10 LINE #<&1  # ten second timeout
  
  if [ -z "$LINE" ]; then
    echo "Timed out, exiting."
  elif [ "$LINE" != "Y" ]; then
    echo "Not confirmed exiting."
    exit 0
  fi
 
  prep_system  
  partition_devices 
  create_raid 
  format_drive
  start_raid 
  mount_raid
  make_folders  
  restore_services
}

get_status ()
{
  if [ -e $RAIDSTATUS ] ; then
    cat $RAIDSTATUS
  else
    echo "Raid status missing."
    logger -t $LOG_TAG "Raid status missing."
 fi     
}

# Finds bad drive in array, removes it, partitions it and hot adds it.
reset_drive () 
{
  # get bad drive
  local FAIL=$(lsraid -p | grep -m 1 unbound)
  #FAIL=$($MDADM_BIN --detail ${RAID1} | grep faulty)
  if [ -z "$FAIL" ]; then # no failed drives
     exit 0     
  fi
  local DRV=$(expr "$FAIL" : ".*\(/dev/[a-z]\{,3\}\)")
  #DRV=$(echo $FAIL | cut -d" " -f7)
  #echo "$MDADM_BIN --manage $RAID1 --remove $DEV"
  $MDADM_BIN --manage $RAID1 --remove ${DRV}1         # remove the drive
  echo -e ${NEW_RAID} | ${SFDISK} --force ${DRV}   # partition it
  $SFDISK -R $DRV                                  # reload partition table
  $MDADM_BIN ${RAID1} --add ${DRV}1                   # add drive back to array
}

while getopts "idrsh" OPTION; do
  case $OPTION in
    i) initialize_drive; break;;
    d) get_bad_drive; break;;
    r) reset_drive; break;;
    s) get_status; exit $?; break;;
    h|*) usage; break;;
  esac
done 
