3445 lines
124 KiB
Bash
3445 lines
124 KiB
Bash
#!/bin/bash
|
|
# rescuebru.sh
|
|
# Rescue CD Backup & Restore Utility client script
|
|
# version 7.2.5
|
|
# Rod Wright 1/19/2024
|
|
# Refer to CHANGELOG file for details.
|
|
# -----------------------------------------------------------------------------
|
|
|
|
PROG_NAME="rescuebru.sh"
|
|
PROG_VERSION=7.2.5
|
|
|
|
# Paths
|
|
RBRU_INSTALL_PATH="/root/rescuebru"
|
|
MEDIA_MNT_DIR="/mnt/rescuebru"
|
|
BACKUP_DIR="rescuebru-backups"
|
|
IMAGE_PATH="$MEDIA_MNT_DIR/$BACKUP_DIR"
|
|
HELP_PATH="$RBRU_INSTALL_PATH/rescuebru-help"
|
|
NFS_REMOTE_DIR_DEF="/mnt/rescuebru"
|
|
LOCAL_DIR="/mnt/rescuebru/rescuebru-backups"
|
|
LOG_PATH="/root/rescuebru_logs"
|
|
|
|
# Arguments for external programs
|
|
PI_BACKUP_ARGS="-cod --debug=1 -M -B\"a=b\" save"
|
|
PI_RESTORE_ARGS="-B\"a=b\" --debug=1 restore"
|
|
FA_BACKUP_ARGS="savefs -s 2000 -v -d -j4"
|
|
FA_RESTORE_ARGS="restfs -v -d -j4"
|
|
SFD_RESTORE_ARGS="-q --force --no-reread"
|
|
for subnet in `seq 10`; do wlist="$wlist -W 10.111.$subnet.1";done
|
|
DHCPCD_RBRUSERVER_ARGS="-d -L -t120 -h rescuebru `echo $wlist`"
|
|
DHCPCD_GLOBAL_ARGS="-d -L -t120 -h rescuebru"
|
|
MAX_CARRIER_ATTEMPTS=10
|
|
|
|
# Defaults
|
|
MEDIA_TYPE_DEF="NFS"
|
|
BU_METHOD_DEF="auto"
|
|
NFS_SUBNET_DEF="10.111.1"
|
|
NFS_REMOTE_ADDR_DEF="$NFS_SUBNET_DEF.1"
|
|
NFS_LOCAL_DEF="99"
|
|
NFS_CLIENT_START_DEF="20"
|
|
NETSETUP_TYPE="auto"
|
|
BACKUP_SERVER_TYPE="RescueBRU Server"
|
|
POSTACTION_DEF="Return to menu"
|
|
BU_COMP_DEF="normal"
|
|
|
|
# Initial status
|
|
CLIENT_NET_STATUS=0
|
|
LOCAL_STATUS=0
|
|
|
|
# Values
|
|
ROUTE_TIMEOUT=30
|
|
MIN_MEDIA_FREE=2048
|
|
NOTES_TEMPLATE="$MEDIA_MNT_DIR/notes_template.txt"
|
|
|
|
TEMP_NOTES="/root/${operation}_`date +%Y-%m-%d_%H%M%S`.notes"
|
|
|
|
# Logging
|
|
LOGGING_ENABLED=1
|
|
SESSION_LOG="$LOG_PATH/session_`date +%Y-%m-%d_%H%M%S`.log"
|
|
OPERATION_LOG="/dev/null" # There is no operation yet, but the text
|
|
# needs to have somewhere to go. This
|
|
# will get redefined as a real file at the
|
|
# beginning of a real operation. Set it back
|
|
# to /dev/null at the end of a real
|
|
# operation so it won't continue to
|
|
# accumulate data from subsequent operations.
|
|
|
|
# Import functions
|
|
source $RBRU_INSTALL_PATH/functions.sh
|
|
|
|
# Declare global associative arrays
|
|
declare -A blockdevs
|
|
declare -A seldevs
|
|
declare -A devbm
|
|
declare -A images
|
|
declare -A selimages
|
|
declare -A imgid
|
|
|
|
# ----------- BACKUP/RESTORE FUNCTIONS -------------
|
|
function do_backup() {
|
|
# Handles backup process
|
|
operation="backup"
|
|
operation_log "on"
|
|
unset imagename srcimagename destimagename iname_confirmed iname_invalid
|
|
unset FAIL prabrt
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
for key in ${!devbm[@]}; do unset devbm[$key]; done
|
|
|
|
progreport ""
|
|
log "Starting $operation process."
|
|
|
|
# Attempt to mount media
|
|
media_reqd=1
|
|
if ! media "mount" ; then
|
|
pause "Unable to mount backup media."
|
|
log "Unable to mount backup media."
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 1
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing a backup.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
|
|
# Check that media is set up
|
|
if [ ! -d $IMAGE_PATH ]; then
|
|
inform "Backup media is not set up."
|
|
if ! mediasetup ; then
|
|
pause "Backup media could not be set up. Aborting."
|
|
log "Backup media could not be set up. Aborting."
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 1
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing a backup.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
fi
|
|
|
|
# Get image name
|
|
if ! getimagename "backup" ; then
|
|
pause "User aborted while getting image name."
|
|
log "User aborted while getting image name."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 0
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing a backup of $imagename.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
|
|
# Get info on all disks
|
|
log "Getting disk information..."
|
|
inform "Getting disk information..." "2"
|
|
if getblkdevs ; then
|
|
log "Got disk information."
|
|
else
|
|
pause "Couldn't get disk information."
|
|
log "Couldn't get disk information."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 1
|
|
fi
|
|
|
|
# Select devices to be backed up
|
|
log "Selecting device(s) to back up..."
|
|
inform "Selecting device(s) to back up..." "2"
|
|
if deviceselect "multiple" "Select devices to back up"; then
|
|
log "Selected device(s) to back up."
|
|
else
|
|
pause "Couldn't select device(s) to back up."
|
|
log "Couldn't select device(s) to back up."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 0
|
|
fi
|
|
|
|
# Analyze and determine backup method if set to auto
|
|
if [[ $bu_method = "auto" ]]; then
|
|
inform "Determining backup method."
|
|
log "Determining backup method."
|
|
method_analyze
|
|
fi
|
|
|
|
# Get notes for backup
|
|
log "Getting notes for $operation."
|
|
if [ -e $NOTES_TEMPLATE ]; then
|
|
cat $NOTES_TEMPLATE>$TEMP_NOTES
|
|
else
|
|
touch $TEMP_NOTES
|
|
fi
|
|
get_notes "$operation of $imagename"
|
|
|
|
# Get backup version
|
|
log "Getting backup version..."
|
|
get_version "$operation of $imagename"
|
|
log "Backup version is $bu_version"
|
|
|
|
# Set compression level arguments
|
|
setcomplevel
|
|
|
|
# Confirm actions
|
|
log "Confirming actions..."
|
|
if confirm_actions ; then
|
|
inform "Backup actions confirmed." "2"
|
|
log "Backup actions confirmed."
|
|
|
|
# Write the status file
|
|
|
|
|
|
# Create the directory
|
|
if createdir ; then
|
|
log "Backup directory created."
|
|
else
|
|
pause "Backup directory could not be created."
|
|
log "Backup directory could not be created."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 1
|
|
fi
|
|
|
|
# Write version number file
|
|
if echo "$bu_version">$IMAGE_PATH/$imagename/version.txt ; then
|
|
inform "Wrote version number file." "2"
|
|
log "Wrote version number file."
|
|
else
|
|
inform "WARNING: Couldn't write version number file."
|
|
log "WARNING: Couldn't write version number file."
|
|
fi
|
|
|
|
# Write backup date file
|
|
if date +%Y-%m-%d >$IMAGE_PATH/$imagename/latest_backup_date.txt ; then
|
|
inform "Wrote backup date file." "2"
|
|
log "Wrote backup date file."
|
|
else
|
|
inform "WARNING: Couldn't write backup date file."
|
|
log "WARNING: Couldn't write backup date file."
|
|
fi
|
|
|
|
# Run backups of selected devices
|
|
for budev in `echo ${!seldevs[@]}|tr " " "\n"|sort|tr "\n" " "` ; do
|
|
# Determine device type
|
|
if echo $budev|egrep -q -o -e "sd[a-z]$|c[0-9]d[0-9]$|hd[a-z]$|nvme[0-9]n[0-9]$" ; then
|
|
# device is a drive
|
|
backup="drivebackup"
|
|
elif echo $budev|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
# device is a partition
|
|
backup="partbackup"
|
|
else
|
|
pause "$FUNCNAME : $LINENO :Internal program error! Unable to determine devtype!"
|
|
FAIL=1
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 1
|
|
fi
|
|
id="${seldevs[$budev]}"
|
|
log "Starting backup of $budev."
|
|
inform "Starting backup of $budev." "2"
|
|
if $backup $budev "$id"; then
|
|
log "Backup of $budev succeeded."
|
|
inform "Backup of $budev succeeded." "2"
|
|
else
|
|
inform "Errors were encountered while backing up $budev."
|
|
log "Errors were encountered while backing up $budev."
|
|
FAIL=1
|
|
break
|
|
fi
|
|
done
|
|
else
|
|
pause "$operation aborted by user."
|
|
log "$operation aborted."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
if [ $media_reqd ]; then media "unmount"; fi
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 0
|
|
fi
|
|
if [ ! "$FAIL" ]; then
|
|
inform "Backup finished."
|
|
log "Backup finished."
|
|
if [ $media_reqd ]; then
|
|
if [ $imgovr ]; then
|
|
log "Replacing $finalimgname with $imagename."
|
|
inform "Replacing $finalimgname with $imagename. Please wait..."
|
|
rm -rf $IMAGE_PATH/$finalimgname
|
|
mv $IMAGE_PATH/$imagename $IMAGE_PATH/$finalimgname
|
|
inform "Replacing $finalimgname with $imagename. Please wait... Done"
|
|
else
|
|
finalimgname=$imagename
|
|
fi
|
|
fi
|
|
if [ "$postaction" = "Reboot" ]; then
|
|
log "Backup finished. Starting automatic reboot..."
|
|
inform "Backup finished. Starting automatic reboot..."
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$finalimgname/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$finalimgname/backup_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
if ! shutdown_proc "reboot" ; then
|
|
if [ $media_reqd ]; then media "mount"; fi
|
|
pause "Reboot aborted."
|
|
log "Reboot aborted."
|
|
let prabrt=1
|
|
fi
|
|
fi
|
|
if [ "$postaction" = "Shut Down" ]; then
|
|
log "Backup finished. Starting automatic shutdown..."
|
|
inform "Backup finished. Starting automatic shutdown..."
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$finalimgname/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$finalimgname/backup_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
if ! shutdown_proc "shutdown" ; then
|
|
if [ $media_reqd ]; then media "mount";fi
|
|
pause "Powerdown aborted."
|
|
log "Powerdown aborted."
|
|
let prabrt=1
|
|
fi
|
|
fi
|
|
dialog --textbox $OPERATION_LOG 24 80
|
|
if [ ! $prabrt ]; then
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$finalimgname/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$finalimgname/backup_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
fi
|
|
else
|
|
inform "Backup FAILED!"
|
|
log "Backup FAILED!"
|
|
if [ $imgovr ]; then
|
|
inform "NOT replacing original backup."
|
|
log "NOT replacing original backup."
|
|
fi
|
|
if [ -s "$OPERATION_LOG" ]; then dialog --title "Backup Log" --textbox $OPERATION_LOG 24 80 ;fi
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$imagename/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$imagename/`date +%Y-%m-%d_%H%M%S`backup.notes
|
|
if approved "Would you like to keep the failed backup?" "y"; then
|
|
inform "Saving failed backup as $imagename.fail. Please wait..."
|
|
mv $IMAGE_PATH/$imagename $IMAGE_PATH/$imagename.fail
|
|
inform "Saving failed backup as $imagename.fail. Please wait... done."
|
|
else
|
|
inform "Removing $imagename. Please wait..."
|
|
rm -rf $IMAGE_PATH/$imagename
|
|
inform "Removing $imagename. Please wait... done."
|
|
fi
|
|
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
fi
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/backup*.log
|
|
return 0
|
|
}
|
|
|
|
function do_restore() {
|
|
# Handles restoration process
|
|
operation="restore"
|
|
operation_log "on"
|
|
unset imagename srcimagename destimagename iname_confirmed iname_invalid
|
|
unset FAIL prabrt
|
|
for key in ${!images[@]}; do unset images[$key]; done
|
|
for key in ${!selimages[@]}; do unset selimages[$key]; done
|
|
for key in ${!imgid[@]}; do unset imgid[$key]; done
|
|
|
|
log "Starting $operation process."
|
|
|
|
# Attempt to mount media
|
|
media_reqd=1
|
|
if ! media "mount" ; then
|
|
pause "Unable to mount backup media."
|
|
log "Unable to mount backup media."
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing a restore.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
|
|
# Get image name
|
|
if ! getimagename "restore" ; then
|
|
pause "User aborted while getting image name."
|
|
log "User aborted while getting image name."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing a restore of $imagename.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
|
|
# Get info on all disks
|
|
log "Getting disk information..."
|
|
inform "Getting disk information..." "2"
|
|
if getblkdevs ; then
|
|
log "Got disk information on block devices"
|
|
else
|
|
pause "Couldn't get disk information."
|
|
log "Couldn't get disk information."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
|
|
# Build an array of images
|
|
log "Getting saved images..."
|
|
if getimages ; then
|
|
log "Got saved images."
|
|
else
|
|
pause "Couldn't get saved images."
|
|
log "Couldn't get saved images."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
|
|
# Select images to be restored
|
|
log "Selecting image(s) to be restored..."
|
|
sleep 2
|
|
if imageselect ; then
|
|
sleep 3
|
|
log "Selected image(s) to restore."
|
|
else
|
|
pause "Couldn't select image(s) to restore."
|
|
log "Couldn't select image(s) to restore."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
|
|
# Analyze and warn about images too big for drive
|
|
for aimg in ${!selimages[@]} ; do
|
|
# get the size of the device that was backed up
|
|
if busize=$(cat $IMAGE_PATH/$imagename/`echo "$aimg"|rev|cut -d"/" -f1|rev`.sz) ; then
|
|
# if the backup is a partition, get drive name
|
|
if echo "$aimg"|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
if echo "$aimg"|egrep -q -o -e "c[0-9]+d[0-9]+p[0-9]+|nvme[0-9]+n[0-9]+p[0-9]+" ; then
|
|
local drive=`echo $aimg|rev|cut -c3-|rev`
|
|
else
|
|
local drive=`echo $aimg|rev|cut -c2-|rev`
|
|
fi
|
|
else
|
|
local drive="$aimg"
|
|
fi
|
|
if contains "$drive" ${!blockdevs[@]} ; then
|
|
devsize=`blockdev --getsize64 $drive 2>/dev/null`
|
|
if [ $busize -gt $devsize ]; then
|
|
if ! approved "The device this image was made for was larger than the
|
|
current disk. It probably will fail to restore correctly. Proceed anyway?" "n"; then
|
|
inform "Restore aborted."
|
|
log "Restore aborted."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
fi
|
|
else
|
|
pause "The disk this backup was created from no longer exists. Restore aborted."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
else
|
|
log "Unable to determine size of the original drive."
|
|
inform "Unable to determine size of the original drive."
|
|
fi
|
|
done
|
|
|
|
# Get notes for restore
|
|
log "Getting notes for $operation."
|
|
get_notes "$operation of $imagename"
|
|
|
|
# Confirm actions
|
|
log "Confirming actions..."
|
|
if confirm_actions ; then
|
|
inform "Restore actions confirmed." "2"
|
|
log "Restore actions confirmed."
|
|
log "Backup method was $bu_method"
|
|
|
|
# Restore selected images
|
|
for devimg in `echo ${!selimages[@]}|tr " " "\n"|sort|tr "\n" " "` ; do
|
|
# Determine device type
|
|
if echo $devimg|egrep -q -o -e "sd[a-z]$|c[0-9]d[0-9]$|hd[a-z]$|nvme[0-9]n[0-9]$" ; then
|
|
# device is a drive
|
|
restore="driverestore"
|
|
elif echo $devimg|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
# device is a partition
|
|
restore="partrestore"
|
|
else
|
|
pause "$FUNCNAME : $LINENO :Internal program error! Unable to determine devtype!"
|
|
FAIL=1
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 1
|
|
fi
|
|
method="${selimages[$devimg]}"
|
|
log "Starting restore of $devimg ."
|
|
inform "Starting restore of $devimg." "2"
|
|
if $restore $devimg $method; then
|
|
inform "Restore of $devimg succeeded." "2"
|
|
log "Restore of $devimg succeeded."
|
|
else
|
|
inform "Errors were encountered while restoring $devimg ."
|
|
log "Errors were encountered while restoring $devimg."
|
|
FAIL=1
|
|
break
|
|
fi
|
|
done
|
|
else
|
|
pause "$operation aborted by user."
|
|
log "$operation aborted."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
if [ $media_reqd ]; then media "unmount"; fi
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 0
|
|
fi
|
|
if [ ! "$FAIL" ]; then
|
|
if [ "$postaction" = "Reboot" ]; then
|
|
log "Restore finished. Starting automatic reboot..."
|
|
inform "Restore finished. Starting automatic reboot..."
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$imagename/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$imagename/restore_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
if ! shutdown_proc "reboot" ; then
|
|
if [ $media_reqd ]; then media "mount"; fi
|
|
pause "Reboot aborted."
|
|
log "Reboot aborted."
|
|
let prabrt=1
|
|
fi
|
|
fi
|
|
if [ "$postaction" = "Shut Down" ]; then
|
|
log "Restore finished. Starting automatic shutdown..."
|
|
inform "Restore finished. Starting automatic shutdown..."
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$imagename/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$imagename/restore_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
if ! shutdown_proc "shutdown" ; then
|
|
if [ $media_reqd ]; then media "mount";fi
|
|
pause "Powerdown aborted."
|
|
log "Powerdown aborted."
|
|
let prabrt=1
|
|
fi
|
|
fi
|
|
if [ -s "$OPERATION_LOG" ]; then dialog --title "Restore Log" --textbox $OPERATION_LOG 24 80 ;fi
|
|
if [ ! $prabrt ]; then
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$imagename/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$imagename/restore_`date +%Y-%m-%d_%H%M%S`.notes
|
|
rm -f $TEMP_NOTES
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
fi
|
|
else
|
|
inform "Restore FAILED!"
|
|
log "Restore FAILED!"
|
|
if [ -s "$OPERATION_LOG" ]; then dialog --title "Restore Log" --textbox $OPERATION_LOG 24 80 ;fi
|
|
if [ $media_reqd ]; then
|
|
cp $LOG_PATH/*.log $IMAGE_PATH/$imagename/
|
|
cp $TEMP_NOTES $IMAGE_PATH/$imagename/restore_`date +%Y-%m-%d_%H%M%S`.notes
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
fi
|
|
fi
|
|
operation_log "off"
|
|
rm -f $LOG_PATH/restore*.log
|
|
return 0
|
|
}
|
|
|
|
function do_image_mod() {
|
|
# Sets up for image management processes
|
|
unset imagename srcimagename destimagename iname_confirmed iname_invalid
|
|
# Attempt to mount media
|
|
media_reqd=1
|
|
if ! media "mount" ; then
|
|
pause "Unable to mount backup media."
|
|
log "Unable to mount backup media."
|
|
return 1
|
|
fi
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is modifying images.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
image_mod
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
return 0
|
|
}
|
|
|
|
function get_notes() {
|
|
# Prompt user to enter notes to be saved with a backup or restore.
|
|
# Takes one argument, the title text of the dialog box
|
|
notetexttmp=`mktemp -q`
|
|
if [ $imgovr ]; then
|
|
if lastbkupnotes=`ls $IMAGE_PATH/$imagename/backup*notes|sort|tail -1 2>/dev/null` ; then
|
|
inform "Importing previous backup notes"
|
|
cp -f $lastbkupnotes $TEMP_NOTES
|
|
fi
|
|
fi
|
|
touch $TEMP_NOTES
|
|
if dialog --title "$1" \
|
|
--backtitle "Enter notes or leave blank then Tab to <Submit> or <No notes> and press enter." \
|
|
--ok-label "Submit" --cancel-label "No notes" \
|
|
--editbox $TEMP_NOTES 20 80 2>$notetexttmp ; then
|
|
cp -f $notetexttmp $TEMP_NOTES
|
|
else
|
|
rm -f $TEMP_NOTES
|
|
fi
|
|
rm -f $notetexttmp
|
|
}
|
|
|
|
function get_version() {
|
|
# Prompt user to enter version number to be saved with a backup.
|
|
# Takes one argument, the title text of the dialog box.
|
|
# Creates a string variable, bu_version, containing version text
|
|
local verstext_invalid=1
|
|
while [ $verstext_invalid ]; do
|
|
verstmp=`mktemp -q`
|
|
if dialog --title "$1" \
|
|
--backtitle "Enter a version string for this backup or leave blank and press enter." \
|
|
--ok-label "Submit" --no-cancel \
|
|
--inputbox "Backup Version:" 0 0 2>$verstmp ; then
|
|
bu_version=`cat $verstmp|sed 's/ /_/g'`
|
|
if ! validate_text name $bu_version; then
|
|
pause "Version string contains invalid characters. Valid characters are upper and lowercase letters, numbers, underscores, dashes, and periods. Try again." 0 0
|
|
else
|
|
unset verstext_invalid
|
|
rm -f $verstmp
|
|
fi
|
|
fi
|
|
rm -f $verstmp
|
|
done
|
|
}
|
|
|
|
function drivebackup() {
|
|
# Back up a partition table or a drive
|
|
# Takes two arguments. First is the full path device name. Second
|
|
# is the id (value in seldevs)
|
|
local retval=0
|
|
local devname=$1
|
|
local id=$2
|
|
|
|
# Determine effective backup method
|
|
if [[ $bu_method = "auto" ]]; then
|
|
eff_bu_method="${devbm[$devname]}"
|
|
else
|
|
eff_bu_method="$bu_method"
|
|
fi
|
|
|
|
# Determine filename
|
|
local basefn=`echo $devname|rev|cut -d/ -f1|rev`
|
|
|
|
# Save S.M.A.R.T. info for device
|
|
if smartctl -a $devname >/dev/null 2>&1 ; then
|
|
smartctl -a $devname > $IMAGE_PATH/$imagename/$basefn.sm
|
|
inform "S.M.A.R.T. info for $devname saved." "2"
|
|
log "S.M.A.R.T. info for $devname saved."
|
|
log "`cat $IMAGE_PATH/$imagename/$basefn.sm|egrep -A3 -e \"Device:|Device Model:\"`"
|
|
else
|
|
inform "S.M.A.R.T. info not available for $devname." "2"
|
|
log "S.M.A.R.T. info not available for $devname."
|
|
fi
|
|
|
|
# Save drive size info
|
|
drivesize=`blockdev --getsize64 $devname`
|
|
if echo $drivesize > $IMAGE_PATH/$imagename/$basefn.sz ; then
|
|
inform "drive size info for $devname saved." "2"
|
|
log "drive size info for $devname saved."
|
|
else
|
|
inform "ERROR: drive size info for $devname could not be saved."
|
|
log "ERROR: drive size info for $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
# Save id of device
|
|
if echo $id > $IMAGE_PATH/$imagename/$basefn.id ; then
|
|
inform "disk ID of $devname saved." "2"
|
|
log "disk ID of $devname saved."
|
|
else
|
|
inform "ERROR: disk ID of $devname could not be saved."
|
|
log "ERROR: disk ID of $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
if [[ $eff_bu_method = "dd" ]]; then
|
|
# If this is a dd backup, dd the drive
|
|
inform "$eff_bu_method backup of $devname started..." "2"
|
|
if monitor "dd if=$devname conv=sync,noerror|pv -s $drivesize|$ddb_comp|split --bytes=2000m --suffix-length=3 --numeric-suffixes - $IMAGE_PATH/$imagename/$basefn.dd." "pausable" ; then
|
|
inform "$eff_bu_method backup of $devname succeeded." "2"
|
|
log "$eff_bu_method backup of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method $operation of $devname failed."
|
|
log "ERROR: $eff_bu_method $operation of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
elif [[ $eff_bu_method = "partimage" || $eff_bu_method = "fsarchiver" ]]; then
|
|
# Determine if we have an MBR or GPT partition scheme
|
|
local ptable_type=`fdisk -l $devname|grep "Disklabel type:"|cut -d: -f2|tr -d ' '`
|
|
if [[ $ptable_type = "dos" ]]; then
|
|
# Save fdisk output for device
|
|
if fdisk -l $devname > $IMAGE_PATH/$imagename/$basefn.fd ; then
|
|
inform "fdisk info for $devname saved." "2"
|
|
log "fdisk info for $devname saved."
|
|
else
|
|
inform "ERROR: fdisk info for $devname could not be saved."
|
|
log "ERROR: fdisk info for $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
# Save MBR
|
|
if dd if=$devname of=$IMAGE_PATH/$imagename/$basefn.mbr bs=512 count=1 ; then
|
|
inform "MBR of $devname saved." "2"
|
|
log "MBR of $devname saved."
|
|
else
|
|
inform "ERROR: MBR of $devname could not be saved."
|
|
log "ERROR: MBR of $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
# Save extended partition info
|
|
if sfdisk -d $devname > $IMAGE_PATH/$imagename/$basefn.sf ; then
|
|
inform "extended partition info of $devname saved." "2"
|
|
log "extended partition info of $devname saved."
|
|
else
|
|
inform "ERROR: extended partition info of $devname could not be saved."
|
|
log "ERROR: extended partition info of $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
elif [[ $ptable_type = "gpt" ]]; then
|
|
# Save gpt data for device
|
|
if sgdisk -b $IMAGE_PATH/$imagename/$basefn.gpt $devname ; then
|
|
inform "GPT partition info of $devname saved." "2"
|
|
log "GPT partition info of $devname saved."
|
|
else
|
|
inform "ERROR: GPT partition info of $devname could not be saved."
|
|
log "ERROR: GPT partition info of $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
else
|
|
inform "ERROR: Could not determine partition table type of $devname."
|
|
log "ERROR: Could not determine partition table type of $devname."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
fi
|
|
sync
|
|
return $retval
|
|
}
|
|
|
|
function driverestore() {
|
|
# Restores MBRs and extended partition info or dd images to a drive
|
|
# Takes two arguments. First is the full path image name.
|
|
# Second is the backup method used
|
|
local retval=0
|
|
local devname=$1
|
|
local eff_bu_method=$2
|
|
local basefn=`echo $devname|rev|cut -d/ -f1|rev`
|
|
|
|
# Display S.M.A.R.T. info of original device
|
|
log "Original drive was: `cat $IMAGE_PATH/$imagename/$basefn.sm|head -8|tail -4`"
|
|
inform "Original drive was: `cat $IMAGE_PATH/$imagename/$basefn.sm|head -8|tail -4`" "4"
|
|
|
|
# Display S.M.A.R.T. info of current device
|
|
if smartctl -a $devname >/dev/null 2>&1 ; then
|
|
log "Current drive is: `smartctl -a $devname|head -8|tail -4`"
|
|
inform "Current drive is: `smartctl -a $devname|head -8|tail -4`" "4"
|
|
else
|
|
log "S.M.A.R.T. info not available for $devname."
|
|
inform "S.M.A.R.T. info not available for $devname." "4"
|
|
fi
|
|
|
|
if [ "$eff_bu_method" = "dd" ]; then
|
|
# If this was a dd backup, determine the compression level used
|
|
if file $IMAGE_PATH/$imagename/$basefn.dd.000|grep -q bzip2; then
|
|
bu_comp="high"
|
|
elif file $IMAGE_PATH/$imagename/$basefn.dd.000|grep -q gzip; then
|
|
bu_comp="normal"
|
|
else
|
|
bu_comp="low"
|
|
fi
|
|
setcomplevel
|
|
# dd the image
|
|
inform "$eff_bu_method restore of $devname started..." "2"
|
|
if imgsize=`cat $IMAGE_PATH/$imagename/$basefn.sz` ; then
|
|
progress_cmd="pv -s $imgsize"
|
|
else
|
|
progress_cmd="pv -prb"
|
|
fi
|
|
if monitor "cat $IMAGE_PATH/$imagename/$basefn.dd.*|$ddr_comp|$progress_cmd|dd of=$devname" "nopause" ; then
|
|
inform "$eff_bu_method restore of $devname succeeded." "2"
|
|
log "$eff_bu_method restore of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method $operation of $devname failed."
|
|
log "ERROR: $eff_bu_method $operation of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
inform "Re-reading partition table of $devname." "2"
|
|
log "Re-reading partition table of $devname."
|
|
partprobe $devname
|
|
elif [[ $eff_bu_method = "partimage" || $eff_bu_method = "fsarchiver" ]]; then
|
|
# Determine the partition table type of the backup
|
|
if [ -e $IMAGE_PATH/$imagename/$basefn.mbr ]; then
|
|
# Restore MBR and extended partition info
|
|
dd if=$IMAGE_PATH/$imagename/$basefn.mbr of=$devname >/dev/null 2>&1
|
|
if sfdisk $SFD_RESTORE_ARGS $devname < $IMAGE_PATH/$imagename/$basefn.sf >/dev/null 2>&1; then
|
|
inform "$operation of MBR and extended partition info of $devname successful." "2"
|
|
log "$operation of MBR and extended partition info of $devname successful."
|
|
else
|
|
partprobe $devname
|
|
if ! sfdisk $SFD_RESTORE_ARGS $devname < $IMAGE_PATH/$imagename/$basefn.sf >/dev/null 2>&1; then
|
|
inform "ERROR: $operation of MBR and extended partition info of $devname failed."
|
|
log "ERROR: $operation of MBR and extended partition info of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
else
|
|
inform "$operation of MBR and extended partition info of $devname successful." "2"
|
|
log "$operation of MBR and extended partition info of $devname successful."
|
|
fi
|
|
fi
|
|
inform "Re-reading partition table of $devname." "2"
|
|
log "Re-reading partition table of $devname."
|
|
partprobe $devname
|
|
elif [ -e $IMAGE_PATH/$imagename/$basefn.gpt ]; then
|
|
if sgdisk -Z $devname >/dev/null 2>&1 ; then
|
|
inform "Partition table of $devname cleared." "2"
|
|
log "Partition table of $devname cleared."
|
|
else
|
|
inform "ERROR: Partition table of $devname could not be cleared."
|
|
log "ERROR: Partition table of $devname could not be cleared."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
if sgdisk -gl $IMAGE_PATH/$imagename/$basefn.gpt $devname ; then
|
|
inform "$operation of GPT partition table of $devname successful." "2"
|
|
log "$operation of GPT partition table of $devname successful."
|
|
else
|
|
partprobe $devname
|
|
if ! sgdisk -gl $IMAGE_PATH/$imagename/$basefn.gpt $devname ; then
|
|
inform "ERROR: $operation of GPT partition table of $devname failed."
|
|
log "ERROR: $operation of GPT partition table of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
else
|
|
inform "$operation of GPT partition table of $devname successful." "2"
|
|
log "$operation of GPT partition table of $devname successful."
|
|
fi
|
|
fi
|
|
inform "Re-reading partition table of $devname." "2"
|
|
log "Re-reading partition table of $devname."
|
|
partprobe $devname
|
|
else
|
|
inform "ERROR: Could not determine partition table type of the backup."
|
|
log "ERROR: Could not determine partition table type of the backup."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
fi
|
|
sync
|
|
return $retval
|
|
}
|
|
|
|
function partbackup() {
|
|
# Back up a partition
|
|
# Takes two arguments. First is the full path device name. Second
|
|
# is the id (value in seldevs)
|
|
local retval=0
|
|
local devname=$1
|
|
local id=$2
|
|
|
|
# Determine effective backup method
|
|
if [[ $bu_method = "auto" ]]; then
|
|
eff_bu_method="${devbm[$devname]}"
|
|
else
|
|
eff_bu_method="$bu_method"
|
|
fi
|
|
|
|
# Determine filename
|
|
local basefn=`echo $devname|rev|cut -d/ -f1|rev`
|
|
|
|
# Save partition size info
|
|
partsize=`blockdev --getsize64 $devname`
|
|
if echo $partsize > $IMAGE_PATH/$imagename/$basefn.sz ; then
|
|
inform "partition size info for $devname saved." "2"
|
|
log "partition size info for $devname saved."
|
|
else
|
|
inform "ERROR: partition size info for $devname could not be saved." "2"
|
|
log "ERROR: partition size info for $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
# Save id of device
|
|
if echo $id > $IMAGE_PATH/$imagename/$basefn.id ; then
|
|
inform "filesystem/partition type of $devname saved." "2"
|
|
log "filesystem/partition type of $devname saved."
|
|
else
|
|
inform "ERROR: filesystem/partition type of $devname could not be saved."
|
|
log "ERROR: filesystem/partition type of $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
|
|
if [[ $eff_bu_method = "dd" ]]; then
|
|
# If this is a dd backup, dd the drive
|
|
inform "$eff_bu_method backup of $devname started..." "2"
|
|
if monitor "dd if=$devname conv=sync,noerror|pv -s $partsize|$ddb_comp|split --bytes=2000m --suffix-length=3 --numeric-suffixes - $IMAGE_PATH/$imagename/$basefn.dd." "pausable" ; then
|
|
inform "$eff_bu_method backup of $devname succeeded." "2"
|
|
log "$eff_bu_method backup of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method backup of $devname failed."
|
|
log "ERROR: $eff_bu_method backup of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
elif [[ $eff_bu_method = "partimage" || $eff_bu_method = "fsarchiver" ]]; then
|
|
if echo "$devname"|grep -q -o -e "c[0-9]+d[0-9]+p[0-9]+|nvme[0-9]+n[0-9]+p[0-9]+" ; then
|
|
local drive=`echo $devname|rev|cut -c3-|rev`
|
|
else
|
|
local drive=`echo $devname|rev|cut -c2-|rev`
|
|
fi
|
|
if fdisk -l $drive|grep $devname|grep -q "Linux swap"; then
|
|
# partition is a swap partition
|
|
if `file -s $devname |grep -q swap` ; then
|
|
inform "Recognized $devname as Linux swap partition."
|
|
log "Recognized $devname as Linux swap partition."
|
|
swptxt=`blkid $devname`
|
|
else
|
|
inform "Warning: $devname has a partition type of Linux swap, but is not"
|
|
inform "formatted as swap."
|
|
log "Warning: $devname has a partition type of Linux swap, but is not"
|
|
log "formatted as swap."
|
|
swptxt="swap"
|
|
fi
|
|
if [[ $eff_bu_method = "partimage" ]]; then suffix="img.000";fi
|
|
if [[ $eff_bu_method = "fsarchiver" ]]; then suffix="fsa";fi
|
|
if echo $swptxt >$IMAGE_PATH/$imagename/$basefn.$suffix ; then
|
|
if echo $swptxt|grep -q UUID ; then
|
|
inform "swap partition UUID for $devname saved." "2"
|
|
log "swap partition UUID for $devname saved."
|
|
else
|
|
inform "unformatted swap partition $devname saved." "2"
|
|
log "unformatted swap partition $devname saved."
|
|
fi
|
|
else
|
|
inform "ERROR: swap partition $devname could not be saved."
|
|
log "ERROR: swap partition $devname could not be saved."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
else
|
|
if [[ $eff_bu_method = "partimage" ]]; then
|
|
inform "$eff_bu_method backup of $devname started..." "2"
|
|
if monitor "partimage $pi_comp $PI_BACKUP_ARGS $devname $IMAGE_PATH/$imagename/$basefn.img" "pausable" ; then
|
|
inform "$eff_bu_method backup of $devname succeeded." "2"
|
|
log "$eff_bu_method backup of $devname succeeded."
|
|
else
|
|
inform "ERROR: partimage backup of $devname failed."
|
|
log "ERROR: partimage backup of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
fi
|
|
if [[ $eff_bu_method = "fsarchiver" ]]; then
|
|
inform "$eff_bu_method backup of $devname started..." "2"
|
|
if monitor "fsarchiver $FA_BACKUP_ARGS $fa_comp $IMAGE_PATH/$imagename/$basefn.fsa $devname" "pausable" ; then
|
|
inform "$eff_bu_method backup of $devname succeeded." "2"
|
|
log "$eff_bu_method backup of $devname succeeded."
|
|
else
|
|
inform "ERROR: fsarchiver backup of $devname failed."
|
|
log "ERROR: fsarchiver backup of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
sync
|
|
return $retval
|
|
}
|
|
|
|
function partrestore() {
|
|
# Restore a partition
|
|
# Takes two arguments. First is the full path image name.
|
|
# Second is the backup method used
|
|
local retval=0
|
|
local devname=$1
|
|
local eff_bu_method=$2
|
|
local basefn=`echo $devname|rev|cut -d/ -f1|rev`
|
|
if [[ $eff_bu_method = "dd" ]]; then
|
|
# If this was a dd backup, determine the compression level used
|
|
if file $IMAGE_PATH/$imagename/$basefn.dd.000|grep -q bzip2; then
|
|
bu_comp="high"
|
|
elif file $IMAGE_PATH/$imagename/$basefn.dd.000|grep -q gzip; then
|
|
bu_comp="normal"
|
|
else
|
|
bu_comp="low"
|
|
fi
|
|
setcomplevel
|
|
# dd the image
|
|
log "$eff_bu_method restore of $devname started..."
|
|
inform "$eff_bu_method restore of $devname started..." "2"
|
|
if imgsize=`cat $IMAGE_PATH/$imagename/$basefn.sz` ; then
|
|
progress_cmd="pv -s $imgsize"
|
|
else
|
|
progress_cmd="pv -prb"
|
|
fi
|
|
if monitor "cat $IMAGE_PATH/$imagename/$basefn.dd.*|$ddr_comp|$progress_cmd|dd of=$devname" "nopause" ; then
|
|
inform "$eff_bu_method restore of $devname succeeded." "2"
|
|
log "$eff_bu_method restore of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method $operation of $devname failed."
|
|
log "ERROR: $eff_bu_method $operation of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
elif [[ $eff_bu_method = "partimage" || $eff_bu_method = "fsarchiver" ]]; then
|
|
log "$eff_bu_method restore of $devname started..."
|
|
inform "$eff_bu_method restore of $devname started..." "2"
|
|
if [[ $eff_bu_method = "partimage" ]]; then
|
|
suffix="img.000"
|
|
fi
|
|
if [[ $eff_bu_method = "fsarchiver" ]]; then
|
|
suffix="fsa"
|
|
fi
|
|
|
|
# Detect swap partition and create appropriately
|
|
if file $IMAGE_PATH/$imagename/$basefn.$suffix|grep -q "ASCII text"&&grep -q swap $IMAGE_PATH/$imagename/$basefn.$suffix; then
|
|
if grep -q UUID $IMAGE_PATH/$imagename/$basefn.$suffix; then
|
|
log "$devname is a Linux swap partition with saved UUID. Running mkswap and setting UUID."
|
|
inform "$devname is a Linux swap partition with saved UUID. Running mkswap and setting UUID." "2"
|
|
if mkswap -U "$(cat $IMAGE_PATH/$imagename/$basefn.$suffix|grep -o -E ' UUID="[^ ]+"'|cut -d'"' -f2)" $devname ; then
|
|
log "Created Linux swap partition with saved UUID on $devname"
|
|
inform "Created Linux swap partition with saved UUID on $devname" "2"
|
|
else
|
|
log "ERROR: Could not create Linux swap partition with saved UUID on $devname"
|
|
inform "ERROR: Could not create Linux swap partition with saved UUID on $devname"
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
else
|
|
log "$devname is a Linux swap partition without saved UUID. Running mkswap."
|
|
inform "$devname is a Linux swap partition without saved UUID. Running mkswap." "2"
|
|
if mkswap $devname ; then
|
|
log "Created Linux swap partition with new UUID on $devname"
|
|
inform "Created Linux swap partition with new UUID on $devname" "2"
|
|
else
|
|
log "ERROR: Could not create Linux swap partition on $devname"
|
|
inform "ERROR: Could not create Linux swap partition on $devname"
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
fi
|
|
else
|
|
# For non-swap partitions, run the appropriate restore command
|
|
case "$eff_bu_method" in
|
|
"partimage" )
|
|
if monitor "partimage $PI_RESTORE_ARGS $devname $IMAGE_PATH/$imagename/$basefn.img.000" "nopause" ; then
|
|
inform "$eff_bu_method restore of $devname succeeded." "2"
|
|
log "$eff_bu_method restore of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method $operation of $devname failed."
|
|
log "ERROR: $eff_bu_method $operation of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
;;
|
|
"fsarchiver" )
|
|
if monitor "fsarchiver $FA_RESTORE_ARGS $IMAGE_PATH/$imagename/$basefn.fsa id=0,dest=$devname" "nopause" ; then
|
|
inform "$eff_bu_method restore of $devname succeeded." "2"
|
|
log "$eff_bu_method restore of $devname succeeded."
|
|
else
|
|
inform "ERROR: $eff_bu_method $operation of $devname failed."
|
|
log "ERROR: $eff_bu_method $operation of $devname failed."
|
|
FAIL=1
|
|
local retval=1
|
|
fi
|
|
;;
|
|
esac
|
|
fi
|
|
fi
|
|
sync
|
|
return $retval
|
|
}
|
|
|
|
function method_analyze() {
|
|
# Analyzes devices in seldevs array to determine best backup method
|
|
# Populates the devbm associative array. Keys are device pathnames.
|
|
# Values are the backup methods.
|
|
# Examine selected devices
|
|
for adev in ${!seldevs[@]} ; do
|
|
if echo $adev|egrep -q -o -e "/dev/sd[a-z]$|/dev/cciss/c[0-9]d[0-9]$|/dev/i2o/hd[a-z]$|/dev/nvme[0-9]n[0-9]$" ; then
|
|
# device is a drive
|
|
if fdisk -l $adev |grep -q "Disklabel type:" ; then
|
|
# not really partimage, but will get the MBR or the GPT info, which will work.
|
|
devbm[$adev]="partimage"
|
|
else
|
|
# no partition table that we can see. Have to dd it.
|
|
devbm[$adev]="dd"
|
|
fi
|
|
fi
|
|
if echo $adev|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]" ; then
|
|
# device is a partition
|
|
case ${seldevs[$adev]} in
|
|
"ext4 filesystem" | \
|
|
"reiser4 filesystem" | \
|
|
"btrfs filesystem" \
|
|
)
|
|
devbm[$adev]="fsarchiver"
|
|
;;
|
|
|
|
"vfat filesystem" | \
|
|
"hpfs filesystem" | \
|
|
"ufs filesystem" | \
|
|
"hfs filesystem" \
|
|
)
|
|
devbm[$adev]="partimage"
|
|
;;
|
|
|
|
"ext2 filesystem" | \
|
|
"ext3 filesystem" | \
|
|
"reiserfs filesystem" | \
|
|
"jfs filesystem" | \
|
|
"xfs filesystem" | \
|
|
"swap partition" | \
|
|
"ntfs filesystem" \
|
|
)
|
|
devbm[$adev]="partimage"
|
|
;;
|
|
|
|
* )
|
|
devbm[$adev]="dd"
|
|
;;
|
|
esac
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
# -------------- DISK UTILITY FUNCTIONS ---------------
|
|
function diskutil() {
|
|
dutemp=`mktemp -q`
|
|
while true; do
|
|
flush_input
|
|
dialog --no-cancel \
|
|
--title "DISK UTILITIES" \
|
|
--menu "Please enter choice:" 13 50 6 \
|
|
"1" "Clone disk" \
|
|
"2" "Blank disk" \
|
|
"3" "Test disk for bad blocks" \
|
|
"4" "Set up backup media" \
|
|
"?" "Disk utility help" \
|
|
"M" "Return to main menu" 2> $dutemp
|
|
utilchoice=`cat $dutemp`
|
|
rm -f $dutemp
|
|
case $utilchoice in
|
|
"M" )
|
|
return 0
|
|
;;
|
|
|
|
"?" )
|
|
if [ -r "$HELP_PATH/diskutil.txt" ]; then
|
|
dialog --title "RescueBRU Help - Disk utilities" --no-shadow --textbox $HELP_PATH/diskutil.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/diskutil.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
4 )
|
|
media_reqd=1
|
|
if media "mount" ; then
|
|
mediasetup
|
|
media "unmount"
|
|
else
|
|
pause "Could not mount backup media. Unable to perform media setup."
|
|
fi
|
|
;;
|
|
|
|
3 )
|
|
unset media_reqd
|
|
do_badblocks
|
|
;;
|
|
|
|
2 )
|
|
unset media_reqd
|
|
do_blank
|
|
;;
|
|
|
|
1 )
|
|
unset media_reqd
|
|
do_clone
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function do_clone() {
|
|
operation="clone"
|
|
operation_log "on"
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
|
|
# Select source/destination drives
|
|
if ! clone_select ; then
|
|
pause "Unable to select source and destination drives for clone."
|
|
log "Unable to select source and destination drives for clone."
|
|
operation_log "off"
|
|
return 1
|
|
fi
|
|
# Warn if target is smaller than source
|
|
if [ $(blockdev --getsize64 $targetdev) -lt $(blockdev --getsize64 $sourcedev) ]; then
|
|
if ! approved "The target device is smaller than the source device. All data will not fit. Continue?" "n" ; then
|
|
return 1
|
|
fi
|
|
fi
|
|
if confirm_actions ; then
|
|
# Clone the drive
|
|
if ! clone.sh $sourcedev $targetdev ; then
|
|
pause "Clone failed."
|
|
log "Clone failed."
|
|
operation_log "off"
|
|
return 1
|
|
else
|
|
inform "clone completed." "2"
|
|
log "clone completed."
|
|
# reread target device partition table
|
|
if echo "$targetdev"|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
if echo "$targetdev"|grep -q -o -e "c[0-9]+d[0-9]+p[0-9]+|nvme[0-9]+n[0-9]+p[0-9]+" ; then
|
|
local drive=`echo $targetdev|rev|cut -c3-|rev`
|
|
else
|
|
local drive=`echo $targetdev|rev|cut -c2-|rev`
|
|
fi
|
|
else
|
|
local drive="$targetdev"
|
|
fi
|
|
inform "Re-reading partition table of $drive..."
|
|
log "Re-reading partition table of $drive"
|
|
partprobe $drivebackup
|
|
inform "Re-reading partition table of $drive...done."
|
|
case $postaction in
|
|
"Return to menu" )
|
|
operation_log "off"
|
|
return 0
|
|
;;
|
|
|
|
"Reboot" )
|
|
log "Clone completed. Starting automatic reboot..."
|
|
if ! shutdown_proc "reboot" ; then
|
|
inform "Reboot aborted." "2"
|
|
log "Reboot aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
|
|
"Shut down" )
|
|
log "Clone completed. Starting automatic shutdown..."
|
|
if ! shutdown_proc "shutdown" ; then
|
|
inform "Shutdown aborted." "2"
|
|
log "Shutdown aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
fi
|
|
else
|
|
inform "Operation aborted." "2"
|
|
log "Operation aborted."
|
|
operation_log "off"
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function do_blank() {
|
|
operation="blank"
|
|
operation_log "on"
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
|
|
# Select target drive
|
|
if ! blank_select ; then
|
|
inform "Unable to select target drive for blanking." "2"
|
|
log "Unable to select target drive for blanking."
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
operation_log "off"
|
|
return 1
|
|
fi
|
|
|
|
if confirm_actions ; then
|
|
# Blank the drive
|
|
blank.sh $targetdev
|
|
inform "blanking completed."
|
|
log "blanking completed."
|
|
# reread target device partition table
|
|
if echo "$targetdev"|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
if echo "$targetdev"|grep -q -o -e "c[0-9]+d[0-9]+p[0-9]+|nvme[0-9]+n[0-9]+p[0-9]+" ; then
|
|
local drive=`echo $targetdev|rev|cut -c3-|rev`
|
|
else
|
|
local drive=`echo $targetdev|rev|cut -c2-|rev`
|
|
fi
|
|
else
|
|
local drive="$targetdev"
|
|
fi
|
|
inform "Re-reading partition table of $drive..."
|
|
log "Re-reading partition table of $drive"
|
|
partprobe $drivebackup
|
|
inform "Re-reading partition table of $drive...done."
|
|
case $postaction in
|
|
"Return to menu" )
|
|
operation_log "off"
|
|
return 0
|
|
;;
|
|
|
|
"Reboot" )
|
|
log "Blanking completed. Starting automatic reboot..."
|
|
if ! shutdown_proc "reboot" ; then
|
|
inform "Reboot aborted."
|
|
log "Reboot aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
|
|
"Shut down" )
|
|
log "Blanking completed. Starting automatic shutdown..."
|
|
if ! shutdown_proc "shutdown" ; then
|
|
inform "Shutdown aborted."
|
|
log "Shutdown aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
else
|
|
inform "Operation aborted."
|
|
log "Operation aborted."
|
|
operation_log "off"
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function do_badblocks() {
|
|
operation="badblocks test"
|
|
operation_log "on"
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
|
|
# Select target drive
|
|
if ! badblocks_select ; then
|
|
inform "Unable to select target drive for badblocks testing." "2"
|
|
log "Unable to select target drive for badblocks testing."
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
operation_log "off"
|
|
return 1
|
|
fi
|
|
|
|
# Select read-write option
|
|
if ! rwoptselect ; then
|
|
inform "Unable to select read-write option for badblocks testing." "2"
|
|
log "Unable to select read-write option for badblocks testing."
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
operation_log "off"
|
|
return 1
|
|
fi
|
|
|
|
if confirm_actions ; then
|
|
# test the drive
|
|
if ! monitor "badblocks $badblocks_args $targetdev" "pausable" ; then
|
|
pause "badblocks test failed."
|
|
log "badblocks test failed."
|
|
operation_log "off"
|
|
return 1
|
|
else
|
|
inform "badblocks test passed."
|
|
log "badblocks test passed."
|
|
case $postaction in
|
|
"Return to menu" )
|
|
operation_log "off"
|
|
return 0
|
|
;;
|
|
|
|
"Reboot" )
|
|
log "Badblocks test finished. Starting automatic reboot..."
|
|
if ! shutdown_proc "reboot" ; then
|
|
inform "Reboot aborted."
|
|
log "Reboot aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
|
|
"Shut down" )
|
|
log "Badblocks test finished. Starting automatic shutdown..."
|
|
if ! shutdown_proc "shutdown" ; then
|
|
inform "Shutdown aborted."
|
|
log "Shutdown aborted."
|
|
operation_log "off"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
fi
|
|
else
|
|
inform "Operation aborted."
|
|
log "Operation aborted."
|
|
operation_log "off"
|
|
flush_input
|
|
pause "Press any key to return to the disk utilities menu."
|
|
return 0
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function clone_select() {
|
|
# Select source and destination devices for clone
|
|
unset sourcedev
|
|
unset targetdev
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
|
|
if ! getblkdevs ; then
|
|
pause "Couldn't get disk information."
|
|
log "Couldn't get disk information."
|
|
return 1
|
|
fi
|
|
|
|
# Display a menu of devices for source
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
if deviceselect "single" "Select SOURCE device for clone" ; then
|
|
sourcedev="${!seldevs[@]}"
|
|
else
|
|
pause "Couldn't determine source device."
|
|
log "Couldn't determine source device."
|
|
return 1
|
|
fi
|
|
|
|
# Exclude the source device from the target device list
|
|
if ! exclude_dev "$sourcedev" ; then
|
|
pause "Unable to exclude source device from target device list."
|
|
return 1
|
|
fi
|
|
|
|
# Display menu of devices for target
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
if deviceselect "single" "Select TARGET device for clone" ; then
|
|
targetdev="${!seldevs[@]}"
|
|
else
|
|
pause "Couldn't determine target device."
|
|
log "Couldn't determine target device."
|
|
return 1
|
|
fi
|
|
|
|
# Warn if target drive is smaller than source device
|
|
# if the target is a partition, get drive name
|
|
if echo "$targetdev"|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]$" ; then
|
|
if echo "$targetdev"|grep -q -o -e "c[0-9]+d[0-9]+p[0-9]+|nvme[0-9]+n[0-9]+p[0-9]+" ; then
|
|
local targetdrive=`echo $targetdev|rev|cut -c3-|rev`
|
|
else
|
|
local targetdrive=`echo $targetdev|rev|cut -c2-|rev`
|
|
fi
|
|
else
|
|
local targetdrive="$targetdev"
|
|
fi
|
|
sourcesize=`blockdev --getsize64 $sourcedev 2>/dev/null`
|
|
targetsize=`blockdev --getsize64 $targetdrive 2>/dev/null`
|
|
if [ $targetsize -lt $sourcesize ]; then
|
|
if ! approved "The source device appears to be larger than the target drive.
|
|
The data will probably not fit and the clone process will report failure.
|
|
Proceed anyway?" "n"; then
|
|
inform "Clone device selection aborted."
|
|
log "Clone device selection aborted."
|
|
unset sourcedev
|
|
unset targetdev
|
|
rm -f $LOG_PATH/clone*.log
|
|
return 1
|
|
fi
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function blank_select() {
|
|
# Select target device for blanking
|
|
unset targetdev
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
|
|
if ! getblkdevs ; then
|
|
pause "Couldn't get disk information."
|
|
log "Couldn't get disk information."
|
|
return 1
|
|
fi
|
|
|
|
# Display menu of devices for target
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
if deviceselect "single" "Select device to blank" ; then
|
|
targetdev="${!seldevs[@]}"
|
|
else
|
|
pause "Couldn't determine target device."
|
|
log "Couldn't determine target device."
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function badblocks_select() {
|
|
# Select target drive for testing
|
|
unset targetdev
|
|
for key in ${!blockdevs[@]}; do unset blockdevs[$key]; done
|
|
if ! getblkdevs ; then
|
|
pause "Couldn't get disk information."
|
|
log "Couldn't get disk information."
|
|
return 1
|
|
fi
|
|
|
|
# Display menu of devices for target
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
if deviceselect "single" "Select device to test" ; then
|
|
targetdev="${!seldevs[@]}"
|
|
else
|
|
pause "Couldn't determine target device."
|
|
log "Couldn't determine target device."
|
|
return 1
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function rwoptselect() {
|
|
# For badblocks test, select a read-only or write test
|
|
rwtmp=`mktemp -q`
|
|
if dialog --no-items --radiolist "Select type of badblocks test" 12 40 12 \
|
|
"read-only" "on" "write" "off" 2>$rwtmp ; then
|
|
rwopt=`cat $rwtmp`
|
|
case $rwopt in
|
|
"read-only" ) badblocks_args="-vs" ;;
|
|
"write" ) badblocks_args="-vws" ;;
|
|
esac
|
|
else
|
|
pause "badblocks test type selection cancelled."
|
|
log "badblocks test type selection cancelled."
|
|
rm -f $rwtmp
|
|
return 1
|
|
fi
|
|
rm -f $rwtmp
|
|
return 0
|
|
}
|
|
|
|
|
|
# ------------ DEVICE FUNCTIONS ------------------
|
|
|
|
function getblkdevs() {
|
|
# Populate associative array, blockdevs, of block devices.
|
|
# Array keys will be absolute paths of devices.
|
|
# Array values will be smartctl reported Device model or "disk"
|
|
# for drive, "extpart" for an extended partition,
|
|
# "<fstype> filesystem" for a primary or logical partition
|
|
# containing a filesystem, "swap partition"
|
|
# for swap, or "unknown partition" if it couldn't be determined.
|
|
for blkdev in `ls /dev/sd* /dev/cciss/c*d* /dev/i2o/hd* /dev/nvme*n* 2>/dev/null` ; do
|
|
if echo $blkdev|egrep -q -o -e "/dev/sd[a-z]$|/dev/cciss/c[0-9]d[0-9]$|/dev/i2o/hd[a-z]$|/dev/nvme[0-9]n[0-9]$" ; then
|
|
# it's a drive
|
|
id=`smartctl -i $blkdev|egrep -e "Device:|Device Model:"|head -1|cut -d: -f2|xargs`
|
|
if [[ $id = "" ]]; then id="disk"; fi
|
|
blockdevs[$blkdev]="$id"
|
|
else
|
|
# it's a partition. determine its filesystem
|
|
pdrive=`echo $blkdev|egrep -o -e "/dev/sd[a-z]|/dev/cciss/c[0-9]d[0-9]|/dev/i2o/hd[a-z]|/dev/nvme[0-9]n[0-9]"`
|
|
if fdisk -l $pdrive|grep $blkdev|egrep -q -e "Extended|W95 Ext|Linux extended" ; then
|
|
blockdevs[$blkdev]="extpart"
|
|
else
|
|
local fstype=`blkid $blkdev |egrep -o -e ' TYPE="[a-zA-Z0-9]*"'|cut -d"\"" -f2`
|
|
if [[ $fstype = "swap" ]]; then
|
|
blockdevs[$blkdev]="swap partition"
|
|
elif [[ $fstype = "" ]]; then
|
|
blockdevs[$blkdev]="unknown partition"
|
|
else
|
|
blockdevs[$blkdev]="$fstype filesystem"
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
if [ $(echo ${#blockdevs[@]}) -eq 0 ]; then
|
|
pause "No block devices found!"
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function deviceselect() {
|
|
# Prompt for block devices on which to perform an operation
|
|
# Parses the blockdevs array, removes excluded devices,
|
|
# presents a checklist of drives on which to operate.
|
|
# Takes two arguments. First, the string "single" or "multiple" that
|
|
# controls whether a radiolist or checklist is displayed. Second,
|
|
# the prompt string to be displayed.
|
|
# Populates an associative array, seldevs. The keys are the absolute
|
|
# paths of block devices, and the values are the partition types taken
|
|
# from the blockdevs array
|
|
|
|
for key in ${!seldevs[@]}; do unset seldevs[$key]; done
|
|
for key in ${!devbm[@]}; do unset devbm[$key]; done
|
|
if [ $# -ne 2 ]; then
|
|
pause "$FUNCNAME : $LINENO :Not enough arguments."
|
|
return 1
|
|
fi
|
|
if [ "$1" = "single" ]; then
|
|
listtype="--radiolist"
|
|
elif [ "$1" = "multiple" ]; then
|
|
listtype="--checklist"
|
|
else
|
|
pause "$FUNCNAME : $LINENO :Must specify \"single\" or \"multiple\"."
|
|
return 1
|
|
fi
|
|
prompttext=$2
|
|
# Generate a list of devices for the list dialog
|
|
local listitems=( )
|
|
tagtmp=`mktemp -q`
|
|
for dev in `echo ${!blockdevs[@]}|tr " " "\n"|sort|tr "\n" " "` ; do
|
|
if [[ ${blockdevs[$dev]} = "extpart" ]]; then
|
|
exclude_dev $dev;log "excluded $dev (extended partition)"
|
|
fi
|
|
if not_excluded $dev ; then listitems+=( "$dev" "${blockdevs[$dev]}" "off" ) ; fi
|
|
done
|
|
# Select devices
|
|
flush_input
|
|
while [ ! $finished ] ; do
|
|
if ! dialog $listtype "$prompttext" 20 60 20 "${listitems[@]}" 2>$tagtmp ; then
|
|
dialog --sleep 3 --aspect 80 --infobox "Device selection canceled." 0 0
|
|
rm -f $tagtmp
|
|
return 1
|
|
fi
|
|
for devname in `cat $tagtmp` ; do
|
|
seldevs[$devname]="${blockdevs[$devname]}"
|
|
done
|
|
local finished=1
|
|
if [ ${#seldevs[@]} -eq 0 ]; then
|
|
pause "You didn't select any devices. If this was your intent, press enter to return to the selection list and select Cancel."
|
|
unset finished
|
|
fi
|
|
done
|
|
rm -f $tagtmp
|
|
return 0
|
|
}
|
|
|
|
function getimages() {
|
|
# Populate an associative array, images, with backup images.
|
|
# Array keys will be absolute path block device names.
|
|
# Values will be backup method.
|
|
# Populate an associative array, imgid, with with
|
|
# disk id/filesystem type.
|
|
# Array keys will be absolute path block device names.
|
|
# Values will be disk id/filesystem type.
|
|
# standard /dev/sdx images
|
|
for img in `ls $IMAGE_PATH/$imagename/sd* 2>/dev/null` ; do
|
|
if `echo $img|egrep -q -o -e "sd[a-z].mbr|sd[a-z].gpt"` ; then
|
|
# MBR or GPT treated as partimage
|
|
baseimgname=`echo $img|egrep -o -e 'sd[a-z].mbr|sd[a-z].gpt'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e $IMAGE_PATH/$imagename/$baseimgname.id ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="MBR"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "sd[a-z][0-9]+.img.000"` ; then
|
|
# partimage partition
|
|
baseimgname=`echo $img|egrep -o -e 'sd[a-z][0-9]+.img.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "sd[a-z][0-9]+.fsa"` ; then
|
|
# fsarchiver partition
|
|
baseimgname=`echo $img|egrep -o -e 'sd[a-z][0-9]+.fsa'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="fsarchiver"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "sd[a-z][0-9]+.dd.000"` ; then
|
|
# dd partition
|
|
baseimgname=`echo $img|egrep -o -e 'sd[a-z][0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition image"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "sd[a-z].dd.000"` ; then
|
|
# dd disk
|
|
baseimgname=`echo $img|egrep -o -e 'sd[a-z].dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="disk image"
|
|
fi
|
|
fi
|
|
done
|
|
# HP CISS images
|
|
for img in `ls $IMAGE_PATH/$imagename/c*d* 2>/dev/null` ; do
|
|
if `echo $img|egrep -q -o -e "c[0-9]+d[0-9]+.mbr"` ; then
|
|
# MBR treated as partimage
|
|
baseimgname=`echo $img|egrep -o -e 'c[0-9]+d[0-9]+.mbr'|cut -d "." -f1`
|
|
imgkey="/dev/cciss/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="MBR"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "c[0-9]+d[0-9]+p[0-9]+.img.000"` ; then
|
|
# partimage partition
|
|
baseimgname=`echo $img|egrep -o -e 'c[0-9]+d[0-9]+p[0-9]+.img.000'|cut -d "." -f1`
|
|
imgkey="/dev/cciss/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "c[0-9]+d[0-9]+p[0-9]+.fsa"` ; then
|
|
# fsarchiver partition
|
|
baseimgname=`echo $img|egrep -o -e 'c[0-9]+d[0-9]+p[0-9]+.fsa'|cut -d "." -f1`
|
|
imgkey="/dev/cciss/$baseimgname"
|
|
images[$imgkey]="fsarchiver"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "c[0-9]+d[0-9]+p[0-9]+.dd.000"` ; then
|
|
# dd partition
|
|
baseimgname=`echo $img|egrep -o -e 'c[0-9]+d[0-9]+p[0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/cciss/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition image"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "c[0-9]+d[0-9]+.dd.000"` ; then
|
|
# dd disk
|
|
baseimgname=`echo $img|egrep -o -e 'c[0-9]+d[0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/cciss/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="disk image"
|
|
fi
|
|
fi
|
|
done
|
|
# Adaptec i2o images
|
|
for img in `ls $IMAGE_PATH/$imagename/hd* 2>/dev/null` ; do
|
|
if `echo $img|egrep -q -o -e "hd[a-z].mbr"` ; then
|
|
# MBR treated as partimage
|
|
baseimgname=`echo $img|egrep -o -e 'hd[a-z].mbr'|cut -d "." -f1`
|
|
imgkey="/dev/i2o/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="MBR"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "hd[a-z][0-9]+.img.000"` ; then
|
|
# partimage partition
|
|
baseimgname=`echo $img|egrep -o -e 'hd[a-z][0-9]+.img.000'|cut -d "." -f1`
|
|
imgkey="/dev/i2o/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "hd[a-z][0-9]+.fsa"` ; then
|
|
# fsarchiver partition
|
|
baseimgname=`echo $img|egrep -o -e 'hd[a-z][0-9]+.fsa'|cut -d "." -f1`
|
|
imgkey="/dev/i2o/$baseimgname"
|
|
images[$imgkey]="fsarchiver"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "hd[a-z][0-9]+.dd.000"` ; then
|
|
# dd partition
|
|
baseimgname=`echo $img|egrep -o -e 'hd[a-z][0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/i2o/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition image"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "hd[a-z].dd.000"` ; then
|
|
# dd disk
|
|
baseimgname=`echo $img|egrep -o -e 'hd[a-z].dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/i2o/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="disk image"
|
|
fi
|
|
fi
|
|
done
|
|
# NVMe images
|
|
for img in `ls $IMAGE_PATH/$imagename/nvme*n* 2>/dev/null` ; do
|
|
if `echo $img|egrep -q -o -e "nvme[0-9]+n[0-9]+.mbr|nvme[0-9]+n[0-9]+.gpt"` ; then
|
|
# MBR or GPT treated as partimage
|
|
baseimgname=`echo $img|egrep -o -e 'nvme[0-9]+n[0-9]+.mbr|nvme[0-9]+n[0-9]+.gpt'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="MBR"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "nvme[0-9]+n[0-9]+p[0-9]+.img.000"` ; then
|
|
# partimage partition
|
|
baseimgname=`echo $img|egrep -o -e 'nvme[0-9]+n[0-9]+p[0-9]+.img.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="partimage"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "nvme[0-9]+n[0-9]+p[0-9]+.fsa"` ; then
|
|
# fsarchiver partition
|
|
baseimgname=`echo $img|egrep -o -e 'nvme[0-9]+n[0-9]+p[0-9]+.fsa'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="fsarchiver"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "nvme[0-9]+n[0-9]+p[0-9]+.dd.000"` ; then
|
|
# dd partition
|
|
baseimgname=`echo $img|egrep -o -e 'nvme[0-9]+n[0-9]+p[0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="partition image"
|
|
fi
|
|
elif `echo $img|egrep -q -o -e "nvme[0-9]+n[0-9]+.dd.000"` ; then
|
|
# dd disk
|
|
baseimgname=`echo $img|egrep -o -e 'nvme[0-9]+n[0-9]+.dd.000'|cut -d "." -f1`
|
|
imgkey="/dev/$baseimgname"
|
|
images[$imgkey]="dd"
|
|
if [ -e "$IMAGE_PATH/$imagename/$baseimgname.id" ]; then
|
|
imgid[$imgkey]=`cat $IMAGE_PATH/$imagename/$baseimgname.id`
|
|
else
|
|
imgid[$imgkey]="disk image"
|
|
fi
|
|
fi
|
|
done
|
|
if [[ ${#images[@]} -eq 0 ]]; then
|
|
return 1
|
|
else
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function imageselect() {
|
|
# Select device images to be restored
|
|
# Parses the images array, presents a checklist of
|
|
# images to restore. Returns an associative array, selimages.
|
|
# Array keys are absolute path device names to restore.
|
|
# Values are the backup methods used
|
|
|
|
for key in ${!selimages[@]}; do unset selimages[$key]; done
|
|
for key in ${!imgid[@]}; do unset imgid[$key]; done
|
|
# Generate a list of images for the checklist dialog
|
|
local listitems=( )
|
|
tagtmp=`mktemp -q`
|
|
for img in `echo ${!images[@]}|tr " " "\n"|sort|tr "\n" " "` ; do
|
|
listitems+=( "$img" "${imgid[$img]}" "off" )
|
|
done
|
|
# Select images
|
|
flush_input
|
|
while [ ! $finished ] ; do
|
|
if ! dialog --checklist "Select images to restore" 20 60 20 "${listitems[@]}" 2>$tagtmp ; then
|
|
dialog --sleep 3 --aspect 80 --infobox "Image selection canceled." 0 0
|
|
rm -f $tagtmp
|
|
return 1
|
|
fi
|
|
for imgname in `cat $tagtmp` ; do
|
|
selimages[$imgname]="${images[$imgname]}"
|
|
done
|
|
local finished=1
|
|
if [ ${#selimages[@]} -eq 0 ]; then
|
|
pause "You didn't select any images. If this was your intent, press enter to return to the selection list and select Cancel."
|
|
unset finished
|
|
fi
|
|
done
|
|
rm -f $tagtmp
|
|
return 0
|
|
}
|
|
|
|
function exclude_dev() {
|
|
# add a device to the exclude array
|
|
# takes 1 parameter, a device pathname
|
|
exclude_list=( ${exclude_list[@]} $1 )
|
|
return 0
|
|
}
|
|
|
|
function not_excluded() {
|
|
# Tests to see if a device is in the device exclude list.
|
|
# Takes one parameter, a device path
|
|
# Returns 0 if device is not in list or 1 if it is.
|
|
pathnm=$1
|
|
for lst_mem in ${exclude_list[@]}; do
|
|
if [ "$pathnm" = "$lst_mem" ]; then
|
|
return 1
|
|
fi
|
|
done
|
|
return 0
|
|
}
|
|
|
|
|
|
# ------------- PROGRAM SETTING FUNCTIONS ------------
|
|
function defaultsettings() {
|
|
|
|
# Restore program settings to defaults
|
|
media_type=$MEDIA_TYPE_DEF
|
|
bu_method=$BU_METHOD_DEF
|
|
postaction=$POSTACTION_DEF
|
|
netsetup_type=$NETSETUP_TYPE
|
|
backup_server_type=$BACKUP_SERVER_TYPE
|
|
bu_comp=$BU_COMP_DEF
|
|
remote_dir=$NFS_REMOTE_DIR_DEF
|
|
|
|
}
|
|
|
|
function settings() {
|
|
|
|
smtemp=`mktemp -q`
|
|
while true; do
|
|
flush_input
|
|
dialog --no-cancel \
|
|
--title "RescueBRU Settings" \
|
|
--menu "" 14 79 9 \
|
|
"1" "Select backup media type (currently $media_type)" \
|
|
"2" "Select backup method (currently $bu_method)" \
|
|
"3" "Select backup compression level (currently $bu_comp)" \
|
|
"4" "Set action after successful operation (currently $postaction)" \
|
|
"5" "Select backup server type (currently $backup_server_type)" \
|
|
"6" "Select network setup type (currently $netsetup_type)" \
|
|
"7" "Set remote NFS share (currently $remote_dir)" \
|
|
"R" "Reset all to defaults" \
|
|
"M" "Return to main menu" 2> $smtemp
|
|
setch=`cat $smtemp`
|
|
rm -f $smtemp
|
|
case $setch in
|
|
"M" )
|
|
|
|
return 0
|
|
;;
|
|
|
|
"R" )
|
|
defaultsettings
|
|
;;
|
|
|
|
7 )
|
|
setremotedir
|
|
;;
|
|
|
|
6 )
|
|
netsetupselect
|
|
;;
|
|
|
|
5 )
|
|
servertypeselect
|
|
;;
|
|
|
|
4 )
|
|
setpostaction
|
|
;;
|
|
|
|
3 )
|
|
complvlselect
|
|
;;
|
|
|
|
2 )
|
|
methodselect
|
|
;;
|
|
|
|
1 )
|
|
mediaselect
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function setremotedir() {
|
|
orig_remote_dir=$remote_dir
|
|
local rdir_invalid=1
|
|
while [ $rdir_invalid ]; do
|
|
# Prompt for new remote directory name
|
|
rdnametmp=`mktemp -q`
|
|
if dialog --inputbox "Please enter remote NFS share name" \
|
|
8 50 "$remote_dir" 2>$rdnametmp ; then
|
|
remote_dir=`cat $rdnametmp`
|
|
if ! validate_text path $remote_dir; then
|
|
pause "Share name contains invalid characters. Valid characters are forward slash, upper and lowercase letters, numbers, underscore, and dash. Try again." 0 0
|
|
elif [ "$remote_dir" = "" ]; then
|
|
pause "Share name cannot be blank. \nTry again."
|
|
elif [ "$imagename" = "lost+found" ]; then
|
|
pause "\"lost+found\" is not a valid share name. \nChoose another."
|
|
else
|
|
unset rdir_invalid
|
|
rm -f $rdnametmp
|
|
fi
|
|
else
|
|
inform "Share name entry aborted."
|
|
rm -f $rdnametmp
|
|
remote_dir=$orig_remote_dir
|
|
return 1
|
|
fi
|
|
done
|
|
log "New NFS share name is $remote_dir"
|
|
}
|
|
|
|
function complvlselect() {
|
|
# Set compression level for backups
|
|
clstemp=`mktemp -q`
|
|
while true ; do
|
|
if ! dialog --default-item "$bu_comp" --menu "Select compression level for backups (currently $bu_comp)" 12 40 8 \
|
|
"L" "low" \
|
|
"N" "normal" \
|
|
"H" "high" \
|
|
"?" "Compression level help" 2> $clstemp ; then
|
|
rm -f $clstemp
|
|
return 0
|
|
else
|
|
buc=`cat $clstemp`
|
|
rm -f $clstemp
|
|
fi
|
|
case $buc in
|
|
"L" )
|
|
bu_comp="low"
|
|
log "Backup compression level set to $bu_comp."
|
|
setcomplevel
|
|
return 0
|
|
;;
|
|
|
|
"N" )
|
|
bu_comp="normal"
|
|
log "Backup compression level set to $bu_comp."
|
|
setcomplevel
|
|
return 0
|
|
;;
|
|
|
|
"H" )
|
|
bu_comp="high"
|
|
log "Backup compression level set to $bu_comp."
|
|
setcomplevel
|
|
return 0
|
|
;;
|
|
|
|
"?" )
|
|
if [ -r "$HELP_PATH/bucomp.txt" ]; then
|
|
dialog --title "RescueBRU Help - Backup Compression" \
|
|
--no-shadow --textbox $HELP_PATH/bucomp.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/bucomp.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function setcomplevel() {
|
|
# Sets the compression level arguments appropriately for the
|
|
# different backup methods
|
|
case $bu_comp in
|
|
"low" )
|
|
ddb_comp="cat"
|
|
ddr_comp="cat"
|
|
pi_comp="-z0"
|
|
fa_comp="-z1"
|
|
return 0
|
|
;;
|
|
|
|
"normal" )
|
|
ddb_comp="gzip -cq"
|
|
ddr_comp="gzip -dq"
|
|
pi_comp="-z1"
|
|
fa_comp="-z3"
|
|
return 0
|
|
;;
|
|
|
|
"high" )
|
|
ddb_comp="bzip2 -cq"
|
|
ddr_comp="bzip2 -dq"
|
|
pi_comp="-z2"
|
|
fa_comp="-z7"
|
|
return 0
|
|
;;
|
|
|
|
* )
|
|
ddb_comp="gzip -cq"
|
|
ddr_comp="gzip -dq"
|
|
pi_comp="-z1"
|
|
fa_comp="-z3"
|
|
return 0
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function netsetupselect() {
|
|
# Select the type of network setup
|
|
nsstemp=`mktemp -q`
|
|
if ! dialog --menu "Select network setup type (currently $netsetup_type)" 10 50 8 \
|
|
"A" "auto" \
|
|
"M" "manual" 2> $nsstemp ; then
|
|
rm -f $nsstemp
|
|
return 0
|
|
else
|
|
nst=`cat $nsstemp`
|
|
rm -f $nsstemp
|
|
fi
|
|
case $nst in
|
|
"M" ) netsetup_type="manual" ;;
|
|
"A" ) netsetup_type="auto" ;;
|
|
esac
|
|
log "Net setup type set to $netsetup_type."
|
|
}
|
|
|
|
function servertypeselect() {
|
|
# Select the type of backup server
|
|
bsttemp=`mktemp -q`
|
|
if ! dialog --menu "Select backup server type (currently $backup_server_type)" 10 50 8 \
|
|
"R" "RescueBRU Server" \
|
|
"A" "any DHCP server" 2> $bsttemp ; then
|
|
rm -f $bsttemp
|
|
return 0
|
|
else
|
|
bst=`cat $bsttemp`
|
|
rm -f $bsttemp
|
|
fi
|
|
case $bst in
|
|
"R" ) backup_server_type="RescueBRU Server" ;;
|
|
"A" ) backup_server_type="any DHCP server" ;;
|
|
esac
|
|
log "Backup server type set to $backup_server_type."
|
|
}
|
|
|
|
function setpostaction() {
|
|
# Set the action taken after successful operation
|
|
patemp=`mktemp -q`
|
|
if ! dialog --menu "Select action after successful operation (currently $postaction)" 11 73 8 \
|
|
"M" "Return to menu" \
|
|
"R" "Reboot" \
|
|
"S" "Shutdown" 2> $patemp ; then
|
|
rm -f $patemp
|
|
return 0
|
|
else
|
|
pa=`cat $patemp`
|
|
rm -f $patemp
|
|
fi
|
|
case $pa in
|
|
"M" ) postaction="Return to menu" ;;
|
|
"R" ) postaction="Reboot" ;;
|
|
"S" ) postaction="Shut Down" ;;
|
|
esac
|
|
log "Action after successful operation set to $postaction."
|
|
}
|
|
|
|
function methodselect() {
|
|
# Prompt user to select backup method type
|
|
bmtemp=`mktemp -q`
|
|
while true ; do
|
|
if ! dialog --default-item "$bu_method" --menu "Select backup method (currently $bu_method)" 13 50 8 \
|
|
"A" "auto" \
|
|
"P" "partimage" \
|
|
"F" "fsarchiver" \
|
|
"D" "dd" \
|
|
"?" "Backup method help" 2> $bmtemp ; then
|
|
rm -f $bmtemp
|
|
return 0
|
|
else
|
|
bm=`cat $bmtemp`
|
|
rm -f $bmtemp
|
|
fi
|
|
case $bm in
|
|
"A" )
|
|
bu_method="auto"
|
|
log "Backup method set to $bu_method."
|
|
return 0
|
|
;;
|
|
|
|
"P" )
|
|
bu_method="partimage"
|
|
log "Backup method set to $bu_method."
|
|
return 0
|
|
;;
|
|
|
|
"F" )
|
|
bu_method="fsarchiver"
|
|
log "Backup method set to $bu_method."
|
|
return 0
|
|
;;
|
|
|
|
"D" )
|
|
bu_method="dd"
|
|
log "Backup method set to $bu_method."
|
|
return 0
|
|
;;
|
|
|
|
"?" )
|
|
if [ -r "$HELP_PATH/method.txt" ]; then
|
|
dialog --title "RescueBRU Help - Backup method" \
|
|
--no-shadow --textbox $HELP_PATH/method.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/method.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
function mediaselect() {
|
|
# Prompt user to select media type.
|
|
mttemp=`mktemp -q`
|
|
while true ; do
|
|
if ! dialog --default-item "$media_type" --menu "Select media type (currently $media_type)" 12 40 8 \
|
|
"N" "NFS" \
|
|
"U" "USB" \
|
|
"L" "Local" \
|
|
"?" "Media type help" 2> $mttemp ; then
|
|
rm -f $mttemp
|
|
return 0
|
|
else
|
|
mt=`cat $mttemp`
|
|
rm -f $mttemp
|
|
fi
|
|
case $mt in
|
|
"N" )
|
|
media_type="NFS"
|
|
log "Media type set to $media_type."
|
|
return 0
|
|
;;
|
|
|
|
"U" )
|
|
media_type="USB"
|
|
log "Media type set to $media_type."
|
|
return 0
|
|
;;
|
|
|
|
"L" )
|
|
media_type="Local"
|
|
log "Media type set to $media_type."
|
|
return 0
|
|
;;
|
|
|
|
"?" )
|
|
if [ -r "$HELP_PATH/mediatype.txt" ]; then
|
|
dialog --title "RescueBRU Help - Media type" \
|
|
--no-shadow --textbox $HELP_PATH/mediatype.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/mediatype.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
|
|
# ------------------ MENUS --------------------------
|
|
function mainmenu() {
|
|
mmtemp=`mktemp -q`
|
|
if [ $LOCAL_SERVER_RUNNING ]; then
|
|
flush_input
|
|
dialog --clear --no-cancel \
|
|
--title "RescueBRU Main Menu"\
|
|
--menu "Welcome to Rescue CD Backup & Restore Utility
|
|
__ Version $PROG_VERSION __
|
|
|
|
Please enter choice:" 22 50 22 \
|
|
"1" "Settings Menu" \
|
|
"2" "Do a backup" \
|
|
"3" "Do a restore" \
|
|
"4" "Disk utilities" \
|
|
"5" "Image management" \
|
|
"6" "View logs or notes" \
|
|
"7" "Show backups available on media" \
|
|
"?" "Help" \
|
|
"S" "Exit and return to rbruserver" 2> $mmtemp
|
|
else
|
|
flush_input
|
|
dialog --clear --no-cancel \
|
|
--title "RescueBRU Main Menu"\
|
|
--menu "Welcome to Rescue CD Backup & Restore Utility
|
|
__ Version $PROG_VERSION __
|
|
|
|
Please enter choice:" 22 50 22 \
|
|
"1" "Settings Menu" \
|
|
"2" "Do a backup" \
|
|
"3" "Do a restore" \
|
|
"4" "Disk utilities" \
|
|
"5" "Image management" \
|
|
"6" "View logs or notes" \
|
|
"7" "Show backups available on media" \
|
|
"?" "Help" \
|
|
"S" "Exit to shell" \
|
|
"R" "Exit and reboot" \
|
|
"P" "Exit and power down" 2> $mmtemp
|
|
fi
|
|
mmchoice=`cat $mmtemp`
|
|
log "Option $mmchoice chosen from main menu."
|
|
rm -f $mmtemp
|
|
return 0
|
|
}
|
|
|
|
function showhelp() {
|
|
hmtemp=`mktemp -q`
|
|
while true; do
|
|
flush_input
|
|
dialog --clear --no-cancel \
|
|
--title "HELP MENU"\
|
|
--menu "Please enter choice:" 15 40 8 \
|
|
"1" "General" \
|
|
"2" "Doing a backup" \
|
|
"3" "Restoring from a backup" \
|
|
"4" "Backup media" \
|
|
"5" "Backup method" \
|
|
"6" "Media type" \
|
|
"7" "Disk utilities" \
|
|
"M" "Exit help menu" 2> $hmtemp
|
|
hmchoice=`cat $hmtemp`
|
|
rm -f $hmtemp
|
|
case $hmchoice in
|
|
"M" )
|
|
return 0
|
|
;;
|
|
|
|
7 )
|
|
if [ -r "$HELP_PATH/diskutil.txt" ]; then
|
|
dialog --title "RescueBRU Help - Disk utilities" \
|
|
--no-shadow --textbox $HELP_PATH/diskutil.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/diskutil.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
6 )
|
|
echo
|
|
if [ -r "$HELP_PATH/mediatype.txt" ]; then
|
|
dialog --title "RescueBRU Help - Media type" \
|
|
--no-shadow --textbox $HELP_PATH/mediatype.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/mediatype.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
5 )
|
|
echo
|
|
if [ -r "$HELP_PATH/method.txt" ]; then
|
|
dialog --title "RescueBRU Help - Backup method" \
|
|
--no-shadow --textbox $HELP_PATH/method.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/method.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
4 )
|
|
echo
|
|
if [ -r "$HELP_PATH/media.txt" ]; then
|
|
dialog --title "RescueBRU Help - Backup media" \
|
|
--no-shadow --textbox $HELP_PATH/media.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/media.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
3 )
|
|
echo
|
|
if [ -r "$HELP_PATH/restore.txt" ]; then
|
|
dialog --title "RescueBRU Help - Restoring from a backup" \
|
|
--no-shadow --textbox $HELP_PATH/restore.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/restore.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
2 )
|
|
echo
|
|
if [ -r "$HELP_PATH/backup.txt" ]; then
|
|
dialog --title "RescueBRU Help - Doing a backup" \
|
|
--no-shadow --textbox $HELP_PATH/backup.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/backup.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
|
|
1 )
|
|
echo
|
|
if [ -r "$HELP_PATH/general.txt" ]; then
|
|
dialog --title "RescueBRU Help - General" \
|
|
--no-shadow --textbox $HELP_PATH/general.txt 25 80
|
|
else
|
|
pause "Help file $HELP_PATH/general.txt could not be found. Check your installation."
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
return 0
|
|
}
|
|
|
|
|
|
# ------------------ PROCESS FUNCTIONS ---------------
|
|
|
|
function cleanup() {
|
|
# Perform cleanup functions prior to exit
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
mount $remote_addr:$remote_dir $MEDIA_MNT_DIR
|
|
rm -f $MEDIA_MNT_DIR/$wkg_addr
|
|
umount $MEDIA_MNT_DIR
|
|
/etc/init.d/nfsmount stop >/dev/null 2>&1
|
|
ifconfig $interface 0.0.0.0 down
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function confirm_actions() {
|
|
# Display and confirm actions before an operation
|
|
unset devarray
|
|
declare -A devarray
|
|
while true ; do
|
|
local opsumtmp=`mktemp -q`
|
|
local conflisttmp=`mktemp -q`
|
|
local chgtmp=`mktemp -q`
|
|
local devtmp=`mktemp -q`
|
|
local notestmp=`mktemp -q`
|
|
|
|
# Indexes for options:
|
|
# 0 - Operation
|
|
# 1 - Media type
|
|
# 2 - Backup method
|
|
# 3 - Compression level
|
|
# 4 - Image name
|
|
# 5 - Version
|
|
# 6 - Devices
|
|
# 7 - Source device
|
|
# 8 - Target device
|
|
# 9 - Type of test
|
|
# 10 - Action on success
|
|
# 11 - Notes
|
|
|
|
# Define operation settings array
|
|
opsettings=( "Operation" "Media type" "Backup method" "Compression level" "Image name" "Version" "Devices" "Source device" "Target device" "Type of test" "Action on success" "Notes")
|
|
# Generate displayable list of devices from seldevs array
|
|
for key in ${!devarray[@]}; do unset devarray[$key]; done
|
|
echo "">$devtmp
|
|
if [ "$operation" = "backup" ]; then
|
|
for dev in ${!seldevs[@]} ; do
|
|
devarray[$dev]="${seldevs[$dev]}"
|
|
done
|
|
elif [ "$operation" = "restore" ]; then
|
|
for img in ${!selimages[@]} ; do
|
|
devarray[$img]="${imgid[$img]}"
|
|
done
|
|
fi
|
|
for dev in ${!devarray[@]} ; do
|
|
if echo $dev|egrep -q -o -e "/dev/sd[a-z]$|/dev/cciss/c[0-9]d[0-9]$|/dev/i2o/hd[a-z]$|nvme[0-9]n[0-9]$"; then
|
|
# it's a drive
|
|
echo " $dev ${devarray[$dev]}">>$devtmp
|
|
elif echo $dev|egrep -q -o -e "sd[a-z][1-9]$|c[0-9]d[0-9]p[0-9]$|hd[a-z][1-9]$|nvme[0-9]n[0-9]p[0-9]" ; then
|
|
# it's a partition
|
|
echo " $dev ${devarray[$dev]}">>$devtmp
|
|
fi
|
|
sort -k 1,1 $devtmp -o $devtmp
|
|
dispdevs=`cat $devtmp`
|
|
done
|
|
# Generate displayable notes from $TEMP_NOTES
|
|
if [ -s $TEMP_NOTES ]; then
|
|
echo "">$notestmp
|
|
cat $TEMP_NOTES>>$notestmp
|
|
opnotes=`cat $notestmp 2>/dev/null`
|
|
rm -f $notestmp
|
|
else
|
|
unset opnotes
|
|
fi
|
|
# Define variables that correspond to operation settings
|
|
opvars=( "$operation" "$media_type" "$bu_method" "$bu_comp" "$imagename" "$bu_version" "$dispdevs" "$sourcedev" "$targetdev" "$rwopt" "$postaction" "$opnotes")
|
|
# Define the appropriate settings for the operation
|
|
case $operation in
|
|
"backup" ) osindexes=( 0 1 2 3 4 5 6 10 11 );;
|
|
"restore" ) osindexes=( 0 1 4 6 10 11 );;
|
|
"blank" ) osindexes=( 0 8 10 );;
|
|
"clone" ) osindexes=( 0 7 8 10 );;
|
|
"badblocks test" ) osindexes=( 0 8 9 10 );;
|
|
esac
|
|
# Generate text for settings display and confirmation widgets
|
|
for index in ${osindexes[@]} ; do
|
|
log "${opsettings[$index]} : ${opvars[$index]}"
|
|
echo "${opsettings[$index]} : ${opvars[$index]}">>$opsumtmp
|
|
echo -n "\"$index\" \"${opsettings[$index]}\" \"off\" ">>$conflisttmp
|
|
done
|
|
# Only show the first 21 lines of the operations summary
|
|
sed -i -e '22,$d' $opsumtmp
|
|
# Display the widgets
|
|
local dialog_script=`mktemp -q`
|
|
echo "dialog --begin 0 0 --title \"Summary of Operations\" --no-collapse --no-ok --tailboxbg $opsumtmp 25 49 --and-widget --begin 0 50 --title \"Confirm Operations\" --no-collapse --defaultno --no-tags --checklist \"To proceed as shown, select OK.\nTo abort the operation, select CANCEL.\nTo make changes, check item(s) to change and select OK.\" 25 30 25 `cat $conflisttmp` 2>$chgtmp">$dialog_script
|
|
if ! bash $dialog_script ; then
|
|
# User selected CANCEL
|
|
if approved "Are you sure you want to cancel the $operation?" "n"; then
|
|
rm -f $opsumtmp $conflisttmp $chgtmp $devtmp $dialog_script $notestmp
|
|
return 1
|
|
fi
|
|
elif [ ! -s $chgtmp ]; then
|
|
# User selected OK without requesting change
|
|
rm -f $opsumtmp $conflisttmp $chgtmp $devtmp $dialog_script $notestmp
|
|
return 0
|
|
else
|
|
# User checked something to change and selected OK.
|
|
# Re-run the appropriate function(s) and reconfirm.
|
|
for index in `cat $chgtmp` ; do
|
|
case ${opsettings[$index]} in
|
|
"Operation" )
|
|
if dialog --defaultno --yesno "Changing the operation will return you to the main menu. Proceed?" 6 50 ; then
|
|
return 1
|
|
fi
|
|
;;
|
|
"Media type" )
|
|
media "unmount"
|
|
mediaselect
|
|
media "mount"
|
|
unset iname_confirmed
|
|
getimagename $operation
|
|
;;
|
|
"Backup method" )
|
|
methodselect
|
|
if [[ $bu_method = "auto" ]]; then
|
|
log "Determining backup method."
|
|
method_analyze
|
|
fi
|
|
;;
|
|
"Compression level" )
|
|
complvlselect
|
|
;;
|
|
"Image name" )
|
|
unset iname_confirmed
|
|
getimagename $operation
|
|
;;
|
|
"Version" )
|
|
get_version
|
|
;;
|
|
"Devices" )
|
|
case $operation in
|
|
"backup" ) deviceselect "multiple" "Select devices to back up" ;;
|
|
"restore" ) imageselect ;;
|
|
esac
|
|
if [[ $bu_method = "auto" ]]; then
|
|
log "Determining backup method."
|
|
method_analyze
|
|
fi
|
|
;;
|
|
"Source device" )
|
|
clone_select
|
|
;;
|
|
"Target device" )
|
|
case $operation in
|
|
"clone" ) clone_select ;;
|
|
"blank" ) blank_select ;;
|
|
"badblocks test" ) badblocks_select ;;
|
|
esac
|
|
;;
|
|
"Type of test" )
|
|
rwoptselect
|
|
;;
|
|
"Action on success" )
|
|
setpostaction
|
|
;;
|
|
"Notes" )
|
|
get_notes
|
|
;;
|
|
esac
|
|
done
|
|
rm -f $opsumtmp $conflisttmp $chgtmp $devtmp $dialog_script $notestmp
|
|
fi
|
|
done
|
|
}
|
|
|
|
|
|
# ------------------ NETWORK FUNCTIONS ----------------
|
|
function check_route() {
|
|
# Wait until a route is established.
|
|
# Takes two arguments, the remote ip address, and the number of attempts
|
|
iptocheck=$1
|
|
rc_timeout=$2
|
|
no_route=1
|
|
unset rc_timesup
|
|
rc_tries=0
|
|
while [ $no_route -a ! $rc_timesup ]; do
|
|
sleep 1
|
|
if ping -q -c1 $iptocheck >/dev/null 2>&1 ; then
|
|
unset no_route
|
|
else
|
|
let "rc_tries +=1"
|
|
fi
|
|
if [ "$rc_tries" -eq "$rc_timeout" ]; then
|
|
rc_timesup=1
|
|
fi
|
|
done
|
|
if [ $no_route ]; then return 1 ;else return 0 ; fi
|
|
}
|
|
|
|
function ip_test() {
|
|
# tests a string to see if it's in a valid IP address format
|
|
# Argument is an IP address string. Returns 0 if valid, 1 if not
|
|
ip_regex="[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
|
|
if echo $1|grep -q -e $ip_regex ; then return 0; else return 1; fi
|
|
}
|
|
|
|
function auto_net_setup() {
|
|
# Use DHCP to get an IP address
|
|
local dhcpcdtmp=`mktemp -q`
|
|
|
|
# Check for and unmount any stale mounts
|
|
if mount|grep -q $MEDIA_MNT_DIR ; then
|
|
umount -f $MEDIA_MNT_DIR
|
|
fi
|
|
|
|
# Build array of interfaces
|
|
ethifs=( )
|
|
for nif in `cat /proc/net/dev|grep eth|cut -d : -f1`; do
|
|
ethifs=( ${ethifs[@]} $nif )
|
|
done
|
|
if [ ${#ethifs[@]} -eq 0 ]; then
|
|
pause "Couldn't find any usable interfaces. You may need to use USB media."
|
|
return 1
|
|
fi
|
|
|
|
# Check to see if the network is already up (maybe from a previous run
|
|
# that terminated abnormally) and bring it down.
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
for ethif in ${ethifs[@]} ; do
|
|
ifconfig $ethif 0.0.0.0 down >/dev/null 2>&1
|
|
done
|
|
|
|
progreport "Setting up the network."
|
|
log "Setting up the network."
|
|
# create a /var/lib/nfs/state file if it doesn't exist
|
|
echo "0000" > /var/lib/nfs/state
|
|
# kill netplugd to keep it from interfering
|
|
killall netplugd >/dev/null 2>&1
|
|
# Since sysresccd-1.0.4, we have to manually start nfs
|
|
/etc/init.d/nfsmount start >/dev/null 2>&1
|
|
# Since sysresccd-1.5.8, we have to manually start rpc.statd
|
|
/etc/init.d/rpc.statd start >/dev/null 2>&1
|
|
|
|
# Get a DHCP address
|
|
|
|
case $backup_server_type in
|
|
"RescueBRU Server" )
|
|
dhcpcd_args=$DHCPCD_RBRUSERVER_ARGS
|
|
;;
|
|
|
|
"any DHCP server" )
|
|
dhcpcd_args=$DHCPCD_GLOBAL_ARGS
|
|
;;
|
|
|
|
* )
|
|
pause "There was a problem determining the backup server type. Aborting."
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
unset carrier_present
|
|
carrier_attempts=0
|
|
while [ ! $carrier_present ] && [ $carrier_attempts -lt $MAX_CARRIER_ATTEMPTS ]; do
|
|
progreport "Requesting an IP address from $backup_server_type ..."
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
echo ""> $dhcpcdtmp
|
|
dhcpcd $dhcpcd_args 2>$dhcpcdtmp
|
|
if cat $dhcpcdtmp|grep -q "no interfaces have a carrier" ; then
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
sleep 3
|
|
else
|
|
carrier_present=1
|
|
fi
|
|
let "carrier_attempts +=1"
|
|
done
|
|
if [ ! $carrier_present ]; then
|
|
pause "No ethernet interfaces have a carrier. This probably means the cables are disconnected. Aborting."
|
|
rm -f $dhcpcdtmp
|
|
return 1
|
|
fi
|
|
if ! cat $dhcpcdtmp|grep -q acknowledged ; then
|
|
inform "Couldn't get a DHCP offer from $backup_server_type" "5"
|
|
log "Couldn't get a DHCP offer from $backup_server_type"
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
rm -f $dhcpcdtmp
|
|
return 1
|
|
fi
|
|
|
|
progreport "...ok."
|
|
remote_addr=`cat $dhcpcdtmp|grep acknowledged|tail -1|rev|cut -d " " -f1|rev`
|
|
wkg_addr=`cat $dhcpcdtmp|grep acknowledged|tail -1|rev|cut -d " " -f3|rev`
|
|
interface=`cat $dhcpcdtmp|grep acknowledged|tail -1|rev|cut -d " " -f5|cut -c2-|rev`
|
|
progreport "Got the address $wkg_addr from the server at $remote_addr"
|
|
sleep 3
|
|
log "Got the address $wkg_addr from the server at $remote_addr"
|
|
if ! mount $remote_addr:$remote_dir $MEDIA_MNT_DIR >/dev/null 2>&1 ; then
|
|
pause "Couldn't mount $remote_addr:$remote_dir. Aborting."
|
|
log "Couldn't mount $remote_addr:$remote_dir. Aborting."
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
ifconfig $interface 0.0.0.0 down
|
|
rm -f $formtmp $dhcpcdtmp
|
|
return 1
|
|
fi
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
umount $MEDIA_MNT_DIR >/dev/null 2>&1
|
|
CLIENT_NET_STATUS=1
|
|
rm -f $formtmp $dhcpcdtmp
|
|
return 0
|
|
}
|
|
|
|
function manual_net_setup() {
|
|
# Set up network manually
|
|
formtmp=`mktemp -q`
|
|
progreport ""
|
|
# Check for and unmount any stale mounts
|
|
if mount|grep -q $MEDIA_MNT_DIR ; then
|
|
umount -f $MEDIA_MNT_DIR
|
|
fi
|
|
|
|
# Build array of interfaces
|
|
ethifs=( )
|
|
for nif in `cat /proc/net/dev|grep eth|cut -d : -f1`; do
|
|
ethifs=( ${ethifs[@]} $nif )
|
|
done
|
|
if [ ${#ethifs[@]} -eq 0 ]; then
|
|
pause "Couldn't find any usable interfaces. You may need to USB media."
|
|
rm -f $formtmp
|
|
return 1
|
|
fi
|
|
|
|
# Check to see if the network is already up (maybe from a previous run
|
|
# that terminated abnormally) and bring it down.
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
for ethif in ${ethifs[@]} ; do
|
|
ifconfig $ethif down >/dev/null 2>&1
|
|
done
|
|
|
|
progreport "Setting up the network."
|
|
log "Setting up the network."
|
|
# create a /var/lib/nfs/state file if it doesn't exist
|
|
echo "0000" > /var/lib/nfs/state
|
|
# kill netplugd to keep it from interfering
|
|
killall netplugd >/dev/null 2>&1
|
|
# Since sysresccd-1.0.4, we have to manually start nfs
|
|
/etc/init.d/nfsmount start >/dev/null 2>&1
|
|
# Since sysresccd-1.5.8, we have to manually start rpc.statd
|
|
/etc/init.d/rpc.statd start >/dev/null 2>&1
|
|
|
|
# prompt for IP info
|
|
addr_invalid=1
|
|
remote_dir_invalid=1
|
|
while [ "$addr_invalid" -o "$remote_dir_invalid" ]; do
|
|
dialog --form "Backup Server Network Parameters:" 10 77 4 \
|
|
"Backup server IP address:" 1 1 "$NFS_REMOTE_ADDR_DEF" 1 32 32 15 \
|
|
"Client initial IP address:" 2 1 "$NFS_SUBNET_DEF.$NFS_LOCAL_DEF" 2 32 32 15 \
|
|
"Start of client address block:" 3 1 "$NFS_SUBNET_DEF.$NFS_CLIENT_START_DEF" 3 32 32 15 \
|
|
"Remote directory:" 4 1 "$NFS_REMOTE_DIR_DEF" 4 32 32 255 \
|
|
2>$formtmp
|
|
formdata=( `cat $formtmp` )
|
|
if [ ${#formdata[@]} -eq 0 ]; then
|
|
pause "Manual net setup cancelled."
|
|
log "Manual net setup cancelled."
|
|
rm -f $formtmp
|
|
return 1
|
|
fi
|
|
remote_addr=${formdata[0]}
|
|
initial_addr=${formdata[1]}
|
|
local_blk_start=${formdata[2]}
|
|
remote_dir=${formdata[3]}
|
|
if ip_test "$remote_addr" ; then
|
|
unset addr_invalid
|
|
else
|
|
pause "Backup server IP address is not a valid IP address. Try again."
|
|
fi
|
|
if ip_test "$initial_addr" ; then
|
|
unset addr_invalid
|
|
else
|
|
pause "Client initial IP address is not a valid IP address. Try again."
|
|
fi
|
|
if ip_test "$local_blk_start" ; then
|
|
nset addr_invalid
|
|
else
|
|
pause "Start of client address block is not a valid IP address. Try again."
|
|
fi
|
|
if [ "$remote_dir" != "" ]; then
|
|
unset remote_dir_invalid
|
|
else
|
|
pause "Remote directory cannot be blank. Try again."
|
|
fi
|
|
done
|
|
|
|
# Scan interfaces for server
|
|
interface="unknown"
|
|
progreport "Scanning network interfaces for connection to backup server..."
|
|
qs_text="Performing quick scan..."
|
|
ns_text="Performing normal scan..."
|
|
ls_text="Performing long scan..."
|
|
xs_text="Performing extra-long scan..."
|
|
scanpass=0
|
|
while [ "$interface" = "unknown" -a "$scanpass" -lt 4 ]; do
|
|
let "scanpass +=1"
|
|
case $scanpass in
|
|
1 )
|
|
scanpings=1
|
|
scan_info_text="$scan_info_text \n $qs_text"
|
|
;;
|
|
2 )
|
|
scanpings=5
|
|
scan_info_text="$scan_info_text \n $ns_text"
|
|
;;
|
|
3 )
|
|
if ! dialog --no-label "Abort" --no-ok --defaultno \
|
|
--pause "No server found yet. Will keep trying. Press enter to abort." 0 0 10 ; then
|
|
scanpass=9
|
|
break
|
|
else
|
|
scanpings=10
|
|
scan_info_text="$scan_info_text \n $ls_text"
|
|
fi
|
|
;;
|
|
4 )
|
|
scanpings=20
|
|
scan_info_text="$scan_info_text \n $xs_text"
|
|
;;
|
|
esac
|
|
for ifname in ${ethifs[@]} ; do
|
|
progreport "$scan_info_text $ifname ..."
|
|
ifconfig $ifname $initial_addr netmask 255.255.255.0
|
|
sleep $scanpings
|
|
if ping -q -c $scanpings -I $ifname $remote_addr >/dev/null 2>&1 ; then
|
|
interface=$ifname
|
|
break
|
|
ifconfig $ifname down
|
|
sleep 1
|
|
fi
|
|
done
|
|
done
|
|
|
|
if [ "$interface" = "unknown" ]; then
|
|
pause "Couldn't find a server on any interface. Make sure server is running and all cables are connected."
|
|
log "Couldn't find a server on any interface."
|
|
rm -f $formtmp
|
|
ifconfig $ifname down
|
|
return 1
|
|
else
|
|
inform "Found a server on the $interface interface."
|
|
log "Found a server on the $interface interface."
|
|
fi
|
|
|
|
# Determine what my real address will be
|
|
case $scanpings in
|
|
1 )
|
|
inform "Using quick setup based on interface speed."
|
|
;;
|
|
5 )
|
|
inform "Using normal setup based on interface speed."
|
|
;;
|
|
10 )
|
|
inform "Using slow setup based on interface speed."
|
|
;;
|
|
20 )
|
|
inform "Using extra-slow setup based on interface speed."
|
|
;;
|
|
esac
|
|
initial_ha=`echo $initial_addr|cut -d "." -f4`
|
|
backup_subnet=`echo $remote_addr|cut -d "." -f1-3`
|
|
ha=`echo $local_blk_start|cut -d "." -f4`
|
|
while ping -q -c $scanpings -I $interface $backup_subnet.$ha >/dev/null 2>&1 && [ $ha -lt $initial_ha ]; do
|
|
let "ha += 1"
|
|
progreport "Trying $backup_subnet.$ha..."
|
|
done
|
|
if [ $ha -eq $initial_ha ]; then
|
|
pause "Unable to get a working IP address. Too many clients may be connected."
|
|
log "Unable to get a working IP address."
|
|
rm -f $formtmp
|
|
ifconfig $ifname down
|
|
return 1
|
|
else
|
|
inform "$backup_subnet.$ha is available."
|
|
wkg_addr=$backup_subnet.$ha
|
|
fi
|
|
ifconfig $interface down
|
|
sleep 1
|
|
ifconfig $interface $wkg_addr netmask 255.255.255.0
|
|
sleep $scanpings
|
|
if ! check_route "$remote_addr" $ROUTE_TIMEOUT; then
|
|
pause "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts. Aborting."
|
|
log "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts. Aborting."
|
|
ifconfig $interface down
|
|
rm -f $formtmp
|
|
return 1
|
|
fi
|
|
if ! mount $remote_addr:$remote_dir $MEDIA_MNT_DIR >/dev/null 2>&1 ; then
|
|
pause "Couldn't mount $remote_addr:$remote_dir. Aborting."
|
|
log "Couldn't mount $remote_addr:$remote_dir. Aborting."
|
|
ifconfig $interface down
|
|
rm -f $formtmp
|
|
return 1
|
|
fi
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
umount $MEDIA_MNT_DIR >/dev/null 2>&1
|
|
CLIENT_NET_STATUS=1
|
|
log "Backup server IP address is $remote_addr"
|
|
log "Local IP address is $wkg_addr"
|
|
log "Remote directory is $remote_dir"
|
|
rm -f $formtmp
|
|
progreport ""
|
|
return 0
|
|
}
|
|
|
|
|
|
# ------------------ MEDIA FUNCTIONS ------------------
|
|
function media() {
|
|
# Dispatcher for media mounting/unmounting. Chooses correct media type function
|
|
# parameter is "mount" or "unmount"
|
|
if [ ! -d $MEDIA_MNT_DIR ]; then
|
|
mkdir $MEDIA_MNT_DIR
|
|
fi
|
|
case $media_type in
|
|
"NFS" ) NFS "$1" ; return $? ;;
|
|
"USB" ) USB "$1" ; return $? ;;
|
|
"Local" ) Local "$1" ; return $? ;;
|
|
* )
|
|
pause "Must specify mount or unmount."
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
function NFS() {
|
|
# Mount or unmount NFS.
|
|
# parameter is "mount" or "unmount"
|
|
if [ "$CLIENT_NET_STATUS" -eq 0 ]; then
|
|
if [ "$netsetup_type" = "auto" ]; then
|
|
if ! auto_net_setup; then return 1;fi
|
|
elif [ "$netsetup_type" = "manual" ]; then
|
|
if ! manual_net_setup; then return 1;fi
|
|
fi
|
|
fi
|
|
if [ "$1" = "mount" ]; then
|
|
progreport "Please wait while route is established..."
|
|
if check_route $remote_addr $ROUTE_TIMEOUT ; then
|
|
progreport "...ok"
|
|
log "established route to $remote_addr"
|
|
else
|
|
flush_input
|
|
pause "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts."
|
|
log "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts. Aborting."
|
|
return 1
|
|
fi
|
|
if grep -q $MEDIA_MNT_DIR /etc/mtab ; then
|
|
progreport "Remote directory appears to be already mounted. Continuing."
|
|
log "Remote directory appears to be already mounted. Continuing."
|
|
else
|
|
progreport "Mounting remote directory..."
|
|
if mount $remote_addr:$remote_dir $MEDIA_MNT_DIR -onolock ; then
|
|
progreport "...ok"
|
|
log "Remote directory mounted."
|
|
else
|
|
progreport "... FAILED"
|
|
sleep 4
|
|
flush_input
|
|
pause "Couldn't mount remote NFS directory. Ensure NFS server is running on $remote_addr."
|
|
return 1
|
|
fi
|
|
fi
|
|
nfs_media_free_txt=`df -h $MEDIA_MNT_DIR|grep "$MEDIA_MNT_DIR"|awk '{print $4}'`
|
|
nfs_media_free=`df -B 1024k $MEDIA_MNT_DIR|grep "$MEDIA_MNT_DIR"|awk '{print $4}'`
|
|
if [ $nfs_media_free -lt $MIN_MEDIA_FREE ]; then
|
|
if ! approved "There is less than 2G available on the backup media. If you are running a backup, you may run out of space. If you know what you're doing, you can continue anyway, or abort the operation. Continue?" "n"; then
|
|
inform "Aborting. Unmounting remote directory..."
|
|
log "Aborting. Unmounting remote directory."
|
|
sync
|
|
umount $MEDIA_MNT_DIR
|
|
sync
|
|
return 1
|
|
fi
|
|
fi
|
|
progreport "Remote directory $remote_dir/$BACKUP_DIR mounted with $nfs_media_free_txt free space."
|
|
sleep 3
|
|
log "Remote directory $remote_dir/$BACKUP_DIR mounted with $nfs_media_free_txt free space."
|
|
return 0
|
|
elif [ "$1" = "unmount" ]; then
|
|
progreport "Unmounting remote directory..."
|
|
log "Unmounting remote directory."
|
|
sync
|
|
umount $MEDIA_MNT_DIR
|
|
sync
|
|
progreport "... done"
|
|
return 0
|
|
else
|
|
pause "Must specify mount or unmount."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function USB() {
|
|
# Prompt user to plug in USB drive and mount it
|
|
# parameter is "mount" or "unmount"
|
|
trying=1
|
|
local infotext="Searching for USB drive"
|
|
flush_input
|
|
if [ "$1" = "mount" ]; then
|
|
while [ $trying ]; do
|
|
infotext="$infotext ."
|
|
dialog --begin 3 5 --infobox "Plug in USB drive now or press any key to abort. If drive is already plugged in, and is not detected, unplug it, wait a few seconds, and plug it in again." 0 0 \
|
|
--and-widget \
|
|
--begin 10 5 --sleep 1 --infobox "$infotext" 14 70
|
|
if read -s -n1 -t1 kp <&1 ; then
|
|
pause "USB media mounting aborted."
|
|
log "USB media mounting aborted."
|
|
return 1
|
|
fi
|
|
if tail -2 /var/log/messages|grep -q SCSI ; then
|
|
unset trying
|
|
fi
|
|
done
|
|
usbdvc=`tail -2 /var/log/messages|grep SCSI|grep -o -e "sd[a-z]"`
|
|
usbparts=`ls /dev/$usbdvc?`
|
|
# Add USB device to the exclude list
|
|
exclude_dev "/dev/$usbdvc"
|
|
# add USB partitions to exclude list
|
|
for uprt in $usbparts; do exclude_dev $uprt; done
|
|
inform "Found USB drive as /dev/$usbdvc"
|
|
log "Found USB drive as /dev/$usbdvc"
|
|
mount /dev/$usbdvc"1" $MEDIA_MNT_DIR
|
|
usb_media_free=`df -B 1024k $MEDIA_MNT_DIR|grep "$MEDIA_MNT_DIR"|awk '{print $4}'`
|
|
if [ $usb_media_free -lt $MIN_MEDIA_FREE ]; then
|
|
if ! approved "There is less than 2G available on the backup media. If you are running a backup, you may run out of space. If you know what you're doing, you can continue anyway, or abort the operation. Continue?" "n"; then
|
|
inform "Aborting. Unmounting USB media..."
|
|
log "Aborting. Unmounting USB media."
|
|
sync
|
|
umount $MEDIA_MNT_DIR
|
|
sync
|
|
inform "Aborting. Unmounting remote directory... done"
|
|
inform "It is now safe to unplug the USB drive."
|
|
return 1
|
|
fi
|
|
fi
|
|
log "USB mounted with $usb_media_free M free space."
|
|
return 0
|
|
elif [ "$1" = "unmount" ]; then
|
|
inform "Unmounting USB drive..."
|
|
sync
|
|
umount $MEDIA_MNT_DIR
|
|
sync
|
|
inform "Unmounting USB drive...done." "1"
|
|
inform "It is now safe to unplug the USB drive."
|
|
return 0
|
|
else
|
|
pause "Must specify mount or unmount."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function Local() {
|
|
# Prompt user for local pathname
|
|
# parameter is "mount" or "unmount"
|
|
if [ "$LOCAL_STATUS" -eq 0 ]; then
|
|
if ! localdir_setup ; then return 1;fi
|
|
fi
|
|
if [ "$1" = "mount" ]; then
|
|
IMAGE_PATH=$local_dir
|
|
return 0
|
|
elif [ "$1" = "unmount" ]; then
|
|
sync
|
|
return 0
|
|
else
|
|
pause "Must specify mount or unmount."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
function localdir_setup() {
|
|
# Determine correct local directory
|
|
localdirtmp=`mktemp -q`
|
|
path_invalid=true
|
|
while [ $path_invalid ]; do
|
|
flush_input
|
|
if dialog --inputbox "Enter full path of backup directory" 8 78 "$LOCAL_DIR" 2>$localdirtmp ; then
|
|
local_dir=`cat $localdirtmp`
|
|
if [ "$local_dir" = "" ]; then
|
|
local_dir=$LOCAL_DIR
|
|
fi
|
|
if [ -d "$local_dir" ]; then
|
|
unset path_invalid
|
|
else
|
|
pause "Specified directory does not exist. Perhaps you made a typo.\nTry again."
|
|
fi
|
|
else
|
|
pause "Local directory setup cancelled."
|
|
log "Local directory setup cancelled."
|
|
rm -f $localdirtemp
|
|
return 1
|
|
fi
|
|
done
|
|
LOCAL_STATUS=1
|
|
log "Local backup directory is $local_dir"
|
|
rm -f $localdirtemp
|
|
return 0
|
|
}
|
|
|
|
function createdir() {
|
|
# Create backup directory while avoiding accidental overwrites
|
|
unset finalimgname
|
|
if [ ! -d "$IMAGE_PATH" ]; then
|
|
mediasetup
|
|
fi
|
|
if [ $imgovr -eq 1 ]; then
|
|
finalimgname=$imagename
|
|
if [ -d "$IMAGE_PATH/$imagename.new" ]; then
|
|
rm -rf $IMAGE_PATH/$imagename.new
|
|
fi
|
|
imagename="$imagename.new"
|
|
fi
|
|
inform "Creating backup directory $IMAGE_PATH/$imagename..." "2"
|
|
if ! mkdir $IMAGE_PATH/$imagename ; then
|
|
pause "An error was encountered while creating backup directory. Aborting."
|
|
log "An error was encountered while creating backup directory. Aborting."
|
|
return 1
|
|
else
|
|
inform "Creating backup directory $IMAGE_PATH/$imagename... done."
|
|
log "Backup directory is $IMAGE_PATH/$imagename."
|
|
# Copy any previous log/note files to new backup
|
|
log "Copying previous log/note files to new backup."
|
|
if ls $IMAGE_PATH/$finalimgname/*.log >/dev/null 2>&1 ; then
|
|
cp -f $IMAGE_PATH/$finalimgname/*.log $IMAGE_PATH/$imagename/
|
|
fi
|
|
if ls $IMAGE_PATH/$finalimgname/*.notes >/dev/null 2>&1 ; then
|
|
cp -f $IMAGE_PATH/$finalimgname/*.notes $IMAGE_PATH/$imagename/
|
|
fi
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
function mediasetup() {
|
|
# Set up backup media
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is performing media setup.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
if [ -d $IMAGE_PATH ]; then
|
|
pause "Backup media appears to be already set up."
|
|
flush_input
|
|
if dialog --aspect 80 --defaultno \
|
|
--yesno "CONTINUING WITH MEDIA SETUP WILL DELETE ANY BACKUPS STORED ON MEDIA! Select Yes to continue, or No to abort :" 0 0 ; then
|
|
inform "Removing old image path..."
|
|
rm -rf $IMAGE_PATH
|
|
sleep 3
|
|
inform "Removing old image path...done."
|
|
sleep 1
|
|
inform "Syncing drive..."
|
|
sync
|
|
sleep 3
|
|
inform "Syncing drive...done."
|
|
sleep 1
|
|
inform "Creating new image path..."
|
|
mkdir $IMAGE_PATH
|
|
sleep 3
|
|
inform "Creating new image path...done."
|
|
sleep 1
|
|
inform "Syncing drive..."
|
|
sync
|
|
sleep 3
|
|
inform "Syncing drive...done."
|
|
inform "Media setup complete."
|
|
else
|
|
pause "Media setup aborted!"
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
return 1
|
|
fi
|
|
fi
|
|
inform "Creating new image path..."
|
|
mkdir $IMAGE_PATH
|
|
sleep 3
|
|
inform "Creating new image path...done."
|
|
sleep 1
|
|
inform "Syncing drive..."
|
|
sync
|
|
sleep 3
|
|
inform "Syncing drive...done."
|
|
inform "Media setup complete."
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
function main() {
|
|
# Main program function
|
|
# Fix the font so dialog boxes aren't corrupt
|
|
/usr/bin/setfont
|
|
|
|
# Initialize variables to defaults
|
|
defaultsettings
|
|
|
|
# Check to see if we were called by a rbruserver
|
|
# first parameter must be -localserver
|
|
# second parameter is the name of the local directory
|
|
# third and subsequent parameters are devices to exclude while doing a backup
|
|
if [ "$1" = "-localserver" ]; then
|
|
num_of_args=$#
|
|
LOCAL_SERVER_RUNNING=1
|
|
shift
|
|
let "num_of_args -= 1"
|
|
LOCAL_DIR=$1
|
|
LOCAL_STATUS=1
|
|
local_dir=$LOCAL_DIR
|
|
media_type="Local"
|
|
shift
|
|
let "num_of_args -= 1"
|
|
while [ $num_of_args -gt 0 ]; do
|
|
exclude_dev $1
|
|
shift
|
|
let "num_of_args -= 1"
|
|
done
|
|
fi
|
|
|
|
# Create a tempfile for global progress reports
|
|
progfile=`mktemp -q`
|
|
# Remove any existing temporary log file and start a new one
|
|
rm -f $LOG_PATH/*
|
|
log "RescueBRU $PROG_VERSION"
|
|
log "Run started `date`"
|
|
|
|
while true; do
|
|
mainmenu
|
|
case $mmchoice in
|
|
"p" | "P" )
|
|
log "\"Exit and power down\" chosen from main menu."
|
|
shutdown_proc "shutdown"
|
|
reset
|
|
;;
|
|
|
|
"r" | "R" )
|
|
log "\"Exit and reboot\" chosen from main menu."
|
|
shutdown_proc "reboot"
|
|
reset
|
|
;;
|
|
|
|
"s" | "S" )
|
|
log "\"Exit to shell\" chosen from main menu."
|
|
log "Run finished."
|
|
if [ $LOCAL_SERVER_RUNNING ]; then
|
|
rm -f $progfile
|
|
dialog --sleep 3 --infobox "Returning to RescueBRU Server" 3 40
|
|
exit 0
|
|
fi
|
|
rm -f $progfile
|
|
inform "Exiting to shell" "2"
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
if ! check_route $remote_addr $ROUTE_TIMEOUT ; then
|
|
inform "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts. Aborting"
|
|
log "Couldn't establish a route to $remote_addr after $ROUTE_TIMEOUT attempts. Aborting."
|
|
umount -f $MEDIA_MNT_DIR
|
|
/etc/init.d/nfsmount stop >/dev/null 2>&1
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
ifconfig $interface 0.0.0.0 down
|
|
return 1
|
|
fi
|
|
mount $remote_addr:$remote_dir $MEDIA_MNT_DIR
|
|
rm -f $MEDIA_MNT_DIR/$wkg_addr
|
|
umount $MEDIA_MNT_DIR
|
|
/etc/init.d/nfsmount stop >/dev/null 2>&1
|
|
dhcpcd -q -k >/dev/null 2>&1
|
|
ifconfig $interface 0.0.0.0 down
|
|
fi
|
|
reset
|
|
exit 0
|
|
;;
|
|
|
|
"?" )
|
|
log "\"Help\" chosen from main menu."
|
|
showhelp
|
|
;;
|
|
|
|
7 )
|
|
log "\"Show backups available on media\" chosen from main menu."
|
|
if media "mount" ; then
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and is viewing images.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
showimages
|
|
if [ "$CLIENT_NET_STATUS" -eq 1 ]; then
|
|
echo "is allocated and idle.">$MEDIA_MNT_DIR/$wkg_addr
|
|
fi
|
|
media "unmount"
|
|
else
|
|
pause "Could not mount backup media. Unable to show backup images."
|
|
fi
|
|
;;
|
|
|
|
6 )
|
|
log "\"View logs or notes\" chosen from main menu."
|
|
if media "mount" ; then
|
|
lognoteview
|
|
media "unmount"
|
|
else
|
|
pause "Could not mount backup media. Unable to view logs."
|
|
fi
|
|
;;
|
|
|
|
5 )
|
|
log "\"Image management\" chosen from main menu"
|
|
log "Media type is $media_type"
|
|
do_image_mod
|
|
;;
|
|
|
|
4 )
|
|
log "\"Disk Utilities\" chosen from main menu"
|
|
log "Media type is $media_type"
|
|
if ! diskutil ; then
|
|
pause "A disk utility failed."
|
|
fi
|
|
;;
|
|
|
|
3 )
|
|
log "\"Do a restore\" chosen from main menu."
|
|
log "Media type is $media_type"
|
|
if ! do_restore ; then
|
|
pause "Restore failed."
|
|
fi
|
|
;;
|
|
|
|
2 )
|
|
log "\"Do a backup\" chosen from main menu."
|
|
log "Media type is $media_type"
|
|
log "Backup method is $bu_method"
|
|
if ! do_backup ; then
|
|
pause "Backup failed."
|
|
fi
|
|
;;
|
|
|
|
1 )
|
|
log "\"Settings\" chosen from main menu."
|
|
settings
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
main "$@"
|
|
exit $?
|