#!/bin/ksh
#
# Program: fbr
# Current Revision: 1.12
# Last Modification Date: 04/03/15
# Last Modified by: %N%
#
# Copyright 2002,2003 Sun Microsystems, Inc.  All Rights Reserved
# Use is subject to license terms.
#
# FBR Script
#
# This script provides the ability to archive (backup) or
# recover (restore) critical personality files for the
# Storage Service Processor from the flash USB disk device
# attached to the Service Processor Core USB port.
# 
# ASSUMPTIONS:
#   There is a personality file in cache that was initially
#   installed from the flash disk.
#
# The user interface requires a single argument describing
# the action to be performed, backup or restore.  Verbose mode
# is activated with the -v option.
#
# fbr -b [-v]
# fbr -r [-v]
#
# This script locates the list of files, using a list that
# resides in the file backup_files.  This file resides in the
# file directory of the SUNWsefbru package.
#

PKGNAME=SUNWsefbru
PKGBASE=$INSTALL_BASE/opt
PGMNAME=`basename $0`
LOGGER=$INSTALL_BASE/opt/se6x20/bin/log

FBR_FILE_LIST=$PKGBASE/$PKGNAME/files/backup_list
HP_FILE_LIST=$PKGBASE/$PKGNAME/files/hi_pri_list
CACHE_DIR=$PKGBASE/$PKGNAME/files
WORK_DIR=/tmp
TARGET_FILENAME=SP_Personality
HP_FILENAME=hi_pri_list

OP=
let VERBOSE=0
let DO_BACKUP=0

FLASH_DIR=/flash
FLASHDRIVE_FOUND=FALSE

USAGE="\n USAGE: $PGMNAME -[b | r] [-v] \n\n
 OPTIONS\n\n
       -b Backs up the Personality to the flash disk \n
       -r Restores the Personality from the flash disk \n
       -v Verbose mode \n"
#
#
#  Function Definitions
#
#  Determine the USB Flash disk device entry
#
GetUSBDevice() {
  for i in `ls /dev/rdsk`; do
    DEV=`print $i`
    if [ "$DEV" != "" ]; then
      if [ `print $i | grep -c "s2"` -gt 0 ]; then
        RDEV=/dev/rdsk/${i}  # Raw Drive for Inquiry
        FDEV=/dev/dsk/${i}   # Formatted Drive for mount
        PHYS_PATH_LINK=`ls -l $RDEV | grep usb` 
        if [ "$PHYS_PATH_LINK" !=  "" ]; then
          FLASHDRIVE_FOUND=TRUE
          break
        fi
      fi
    fi
  done
  if [ "$FLASHDRIVE_FOUND" = "FALSE" ]; then
    if (( VERBOSE )); then
      print "No device entry found for the USB flash disk"
    fi
    $LOGGER PERSISTENCE_IO_ERROR_ON_STORAGE
    return 7
  fi
}
#
# Mount an identified USB flash disk device on /flash
#
MountFlashDisk() {
  STAT=`fsck -m $RDEV >/dev/null 2>&1; print $?`
  case $STAT in
    0|33)  ;;
    32)
      fsck -F ufs -y $FDEV ;;
    *)   
      if [ $OP = "backup" ]; then
        STAT=`mkfs -F ufs $RDEV 30720 32 64 8192 1024 16 10 3 2048 t 0 -1 8 16 >/dev/null 2>&1; print $?`
        if [ $STAT -ne 0 ]; then
          if (( VERBOSE )); then
            print "USB device not mountable"
          fi
          $LOGGER PERSISTENCE_IO_ERROR
          return 6
        fi
      fi;;
  esac

  if [ ! -d $FLASH_DIR ]; then
    mkdir $FLASH_DIR
    chmod 0755 $FLASH_DIR
  fi

  STAT=`mount $FDEV $FLASH_DIR >/dev/null 2>&1; print $?`
  if [ $STAT -ne 0 ]; then 
    if (( VERBOSE )); then
      print "Mount of USB device failed"
    fi
    $LOGGER PERSISTENCE_IO_ERROR
    return 8
  fi
}
#
# main()
#
# Verify that an argument list has been specified
#
if [ $# -eq 0 ]; then
  DATE=`date '+%m/%d/%y %H:%M:%S'`
  print "$DATE: $PGMNAME: OPER_ERROR: Missing/Invalid Argument[s]"
  print $USAGE
  exit 1
fi
#
# Parse arg list and validate request
#
while getopts ":brv" opt; do
  case $opt in
     b)  if [ -z $OP ]; then
           OP=backup
         else
           print $USAGE
           exit 2
         fi;;
     r)  if [ -z $OP ]; then
           OP=restore
         else
           print $USAGE
           exit 2
         fi;;
     v)  let VERBOSE=1;;
    \?)  print $USAGE
         exit 2;;
  esac
done
if [ -z $OP ]; then
  print $USAGE
  exit 2
#
# Do a backup
#
elif [ $OP = "backup" ]; then
#
# Tar up the high priority files 
#
  flist=`cat $HP_FILE_LIST`
  tar -cpf $WORK_DIR/$HP_FILENAME.tar $flist >/dev/null 2>&1
#
# Check to see if any of the high priority files have changed since the
# last backup.  If they have, then trigger the backup to happen.
#
  if (( VERBOSE )); then
    print "Checking for personality changes"
  fi
  if [[ -a $CACHE_DIR/$HP_FILENAME.tar ]]; then
    CMPSTAT=`cmp $WORK_DIR/$HP_FILENAME.tar $CACHE_DIR/$HP_FILENAME.tar >/dev/null 2>&1; print $?`
    if [[ $CMPSTAT -ne 0 ]]; then
      cp $WORK_DIR/$HP_FILENAME.tar $CACHE_DIR/$HP_FILENAME.tar
      let DO_BACKUP=1
    else
#
# It is possible a configuration to change while the USB device
# is disconnected.  This causes the hi_pri_list archive to be
# newer than the cached personality.  This could cause customer
# to lose information.
#
      FINDSTAT=`find $CACHE_DIR -newer $CACHE_DIR/$TARGET_FILENAME.tar.Z | grep $HP_FILENAME.tar > /dev/null 2>&1; print $?`
      if [ $FINDSTAT -eq 0 ]; then
#
# Sync up the files
#
        cp $WORK_DIR/$HP_FILENAME.tar $CACHE_DIR/$HP_FILENAME.tar
        let DO_BACKUP=1
      fi
    fi
  else
#
# The high priority files were not already cached, so cache them
#
    cp $WORK_DIR/$HP_FILENAME.tar $CACHE_DIR/$HP_FILENAME.tar
    let DO_BACKUP=1
  fi
#
# Check to see if the personality has not been backed up for 24 hours.
# The requirement is to backup every 24 hours if nothing has changed.
# If it hasn't, then trigger the backup to happen.
#
  FINDSTAT=`find $CACHE_DIR -type f -mtime -1 | grep $TARGET_FILENAME > /dev/null 2>&1; print $?`
  if [ $FINDSTAT -ne 0 ]; then 
    let DO_BACKUP=1
  fi
  if (( DO_BACKUP )); then
    if (( VERBOSE )); then
      print "Generating list of files that define the system's personality"
    fi
#
# Temporary performance fix:  The Download directory in /var/opt/SUWNstade/DATA
# is a repository for Explorer or Solution Extractor output and is not 
# necessary to keep as persistent information.  The files are too large anyway.
# Remove the directory from the list of StorADE DATA files.
#
    SAfiles=$WORK_DIR/SAfiles$$
    ls -l1 /var/opt/SUNWstade/DATA | grep -v Download \
                                   | awk '{print $9}' > $SAfiles
    SAlist=$WORK_DIR/SAlist$$
    touch $SAlist
    for f in `cat $SAfiles`; do
      print "/var/opt/SUNWstade/DATA/$f" >> $SAlist
    done
    LIST=`cat $FBR_FILE_LIST | grep -v "/var/opt/SUNWstade/DATA"; \
          cat $HP_FILE_LIST; cat $SAlist`
#
#  Create Personality TAR file of backup file list contents
#
    if (( VERBOSE )); then
      print "Creating personality tar file"
    fi
    tar -cpf $WORK_DIR/$TARGET_FILENAME.tar $LIST >/dev/null 2>&1
#
#  Compress Personality file to reduce storage space
#
    if (( VERBOSE )); then
      print "Compressing personality tar file"
    fi
    compress -f $WORK_DIR/$TARGET_FILENAME.tar
    if (( VERBOSE )); then
      print "Finding device entry for USB device"
    fi
    GetUSBDevice
    ret=$?
    if [ $ret -eq 0 ]; then
      if (( VERBOSE )); then
        print "Mounting USB drive"
      fi
      MountFlashDisk
      ret=$?
      if [ $ret -eq 0 ]; then
        if (( VERBOSE )); then
          print "Personality changed, updating cache"
        fi
        cp $WORK_DIR/$TARGET_FILENAME.tar.Z $CACHE_DIR/$TARGET_FILENAME.tar.Z
        cp $WORK_DIR/$TARGET_FILENAME.tar.Z $FLASH_DIR/$TARGET_FILENAME.tar.Z
        umount $FLASH_DIR
      else
        print "Backup Command Failed ($ret)"
        exit $ret
      fi
    else
      print "Backup Command Failed ($ret)"
      exit $ret
    fi
#
#  Cleanup work area
#
    rm $WORK_DIR/$TARGET_FILENAME.tar.Z
    rm $SAlist
    rm $SAfiles
  fi
  rm $WORK_DIR/$HP_FILENAME.tar
  print "Backup Command Successful"
#
# Do a restore
#
elif [ "$OP" = "restore" ]; then
  if (( VERBOSE )); then
    print "Restoring personality from flash disk"
  fi
  if (( VERBOSE )); then
      print "Finding device entry for flash disk"
  fi
  GetUSBDevice
  ret=$?
  if [ $ret -eq 0 ]; then
    if (( VERBOSE )); then
      print "Mounting USB drive"
    fi
    MountFlashDisk
    ret=$?
    if [ $ret -eq 0 ]; then
#
#  Copy Personality file from flash disk to cache area
#
      if (( VERBOSE )); then
        print "Copying personality from flash disk and restoring"
      fi
      if [ -f $FLASH_DIR/$TARGET_FILENAME.tar.Z ]; then
        cp $FLASH_DIR/$TARGET_FILENAME.tar.Z $CACHE_DIR/$TARGET_FILENAME.tar.Z
#
#  Restore Personality files to Service Processor
#
        zcat $CACHE_DIR/$TARGET_FILENAME.tar.Z | tar -xpf - >/dev/null 2>&1
      else
        if (( VERBOSE )); then
          print "No personality file on flash disk"
        fi
        $LOGGER PERSISTENCE_IO_ERROR_ON_FILE $FLASH_DIR/$TARGET_FILENAME.tar.Z
        print "Restore Command Failed (3)"
        umount $FLASH_DIR
        exit 3
      fi
#
#  Unmounting flash disk device
#
      umount $FLASH_DIR
    else
      print "Restore Command Failed ($ret)"
      exit $ret
    fi
  else
    print "Restore Command Failed ($ret)"
    exit $ret
  fi
  print "Restore Command Successful"
fi
exit 0
