Current File : //proc/self/root/usr/local/jetapps/usr/share/rear/layout/prepare/default/200_recreate_hpraid.sh |
#
# Ask to recreate HP's Smart Array line of hardware RAID controllers
# and actually recreate that before the actual restoration takes place.
#
# This script is only about HP Smart Array hardware RAID controllers
# that are supported by the 'cciss' kernel module.
# Newer HP Smart Array hardware RAID controllers that need
# the 'hpsa' kernel module are not supported by this script.
# Cf.
# http://cciss.sourceforge.net/
# which reads (excerpt):
# The cciss driver has been removed from RHEL7 and SLES12.
# If you really want cciss on RHEL7 checkout the elrepo directory.
# A new Smart Array driver called "hpsa" has been accepted into
# the main line linux kernel as of Dec 18, 2009, in linux-2.6.33-rc1.
# This new driver will support new Smart Array products going
# forward, and the cciss driver will eventually be deprecated.
#
# Skip that unless the cciss kernel module
# (for HP Smart Array hardware RAID controllers)
# is loaded:
grep -q '^cciss ' /proc/modules || return 0
# The code below calls layout-functions like create_device()
# that append code to a file referenced by the global LAYOUT_CODE variable
# so that we must also use that global variable name in this script
# but with a special value only for this script here:
orig_LAYOUT_CODE="$LAYOUT_CODE"
LAYOUT_CODE=$VAR_DIR/layout/hpraid.sh
# Initialize our special LAYOUT_CODE:
cat <<EOF >$LAYOUT_CODE
# Recreate HP Smart Array hardware RAID
LogPrint "Recreating HP Smart Array hardware RAID"
set -e
# Unload CCISS kernel module to make sure nothing is using it:
rmmod cciss || Error "Failed to unload 'cciss' kernel module, something is using it"
modprobe cciss
sleep 2
EOF
# First recreate HP Smart Array controllers or skip some via user dialog:
controllers_to_be_recreated=()
echo "# First recreate HP Smart Array controllers" >>$LAYOUT_CODE
while read type name junk ; do
prompt="Recreate HP Smart Array controller '$name' (yes/no)?"
input_value=""
wilful_input=""
# Generate a runtime-specific user_input_ID so that for each HP Smart Array controller
# a different user_input_ID is used for the UserInput call so that the user can specify
# for each HP Smart Array controller a different predefined user input.
# Only uppercase letters and digits are used to ensure the user_input_ID is a valid bash variable name
# (otherwise the UserInput call could become invalid which aborts 'rear recover' with a BugError) and
# hopefully only uppercase letters and digits are sufficient to distinguish different controllers:
controller_basename_alnum_uppercase="$( basename "$name" | tr -d -c '[:alnum:]' | tr '[:lower:]' '[:upper:]' )"
test "$controller_basename_alnum_uppercase" || controller_basename_alnum_uppercase="CONTROLLER"
local user_input_ID="HP_SMART_ARRAY_$controller_basename_alnum_uppercase"
input_value="$( UserInput -I "$user_input_ID" -p "$prompt" -D 'YES' )" && wilful_input="yes" || wilful_input="no"
if is_true "$input_value" ; then
is_true "$wilful_input" && LogPrint "User confirmed recreating HP Smart Array controller '$name'" || LogPrint "Recreating HP Smart Array controller '$name' by default"
echo "# Recreate HP Smart Array controller '$name'" >>$LAYOUT_CODE
create_device "$name" 'smartarray'
controllers_to_be_recreated+=( $name )
fi
done < <( grep '^smartarray ' $LAYOUT_FILE )
# Then recreate all logical drives for those controllers that will be recreated:
echo "# Then recreate all logical drives for those controllers that were recreated" >>$LAYOUT_CODE
while read type name remainder junk ; do
ctrl=$( echo "$remainder" | cut -d " " -f1 | cut -d "|" -f1 )
if IsInArray "$ctrl" "${controllers_to_be_recreated[@]}" ; then
echo "# Recreate logical drive '$name'" >>$LAYOUT_CODE
create_device "$name" 'logicaldrive'
fi
done < <( grep '^logicaldrive ' $LAYOUT_FILE )
# Finally engage SCSI for the hosts in /proc/driver/cciss/cciss?
cat <<'EOF' >>$LAYOUT_CODE
# Finally engage SCSI for the hosts in /proc/driver/cciss/cciss?
# engage scsi can fail in certain cases
set +e
# make the CCISS tape device visible
for host in /proc/driver/cciss/cciss? ; do
Log "Engage SCSI on host $host"
echo engage scsi >$host
done
sleep 2
EOF
# Run the HP Smart Array recreation script only if at least one HP Smart Array controller will be recreated:
if test ${#controllers_to_be_recreated} -gt 0 ; then
# Call function to find proper Smart Storage Administrator CLI command
# (it defines the HPSSACLI variable):
define_HPSSACLI
# Run our special LAYOUT_CODE
# i.e. actually recreate the HP Smart Array stuff here
# cf. the code in layout/recreate/default/200_run_layout_code.sh
rear_workflow="rear $WORKFLOW"
rear_shell_history="$( echo -e "$HPSSACLI ctrl all show detail\n$HPSSACLI ctrl all show config detail\n$HPSSACLI ctrl all show config" )"
unset choices
choices[0]="Rerun HP Smart Array recreation script ($LAYOUT_CODE)"
choices[1]="View '$rear_workflow' log file ($RUNTIME_LOGFILE)"
choices[2]="Edit HP Smart Array recreation script ($LAYOUT_CODE)"
choices[3]="Use Relax-and-Recover shell and return back to here"
choices[4]="Abort '$rear_workflow'"
prompt="The HP Smart Array recreation script failed"
choice=""
wilful_input=""
# When USER_INPUT_HP_SMART_ARRAY_CODE_RUN has any 'true' value be liberal in what you accept and
# assume choices[0] 'Run disk recreation script again' was actually meant:
is_true "$USER_INPUT_HP_SMART_ARRAY_CODE_RUN" && USER_INPUT_HP_SMART_ARRAY_CODE_RUN="${choices[0]}"
# Run the disk layout recreation code (diskrestore.sh)
# again and again until it succeeds or the user aborts:
while true ; do
# Run LAYOUT_CODE in a sub-shell because it sets 'set -e'
# so that it exits the running shell in case of an error
# but that exit must not exit this running bash here:
( source $LAYOUT_CODE )
# Since bash 4.x one must explicitly test whether or not $? is zero in a separated bash command
# otherwise the 'set -e' inside the sourced script would be noneffective
# cf. layout/recreate/default/200_run_layout_code.sh
# and https://github.com/rear/rear/pull/1573#issuecomment-344303590
# Break the outer while loop when LAYOUT_CODE succeeded:
(( $? == 0 )) && break
# Run an inner while loop with a user dialog so that the user can fix things when LAYOUT_CODE failed:
while true ; do
choice="$( UserInput -I LAYOUT_CODE_RUN -p "$prompt" -D "${choices[0]}" "${choices[@]}" )" && wilful_input="yes" || wilful_input="no"
case "$choice" in
(${choices[0]})
# Rerun disk recreation script:
is_true "$wilful_input" && LogPrint "User reruns HP Smart Array recreation script" || LogPrint "Rerunning HP Smart Array recreation script by default"
# Only break the inner while loop (i.e. the user dialog loop):
break
;;
(${choices[1]})
# Run 'less' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user:
less $RUNTIME_LOGFILE 0<&6 1>&7 2>&8
;;
(${choices[2]})
# Run 'vi' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user:
vi $LAYOUT_CODE 0<&6 1>&7 2>&8
;;
(${choices[3]})
# rear_shell runs 'bash' with the original STDIN STDOUT and STDERR when 'rear' was launched by the user:
rear_shell "" "$rear_shell_history"
;;
(${choices[4]})
abort_recreate
Error "User chose to abort '$rear_workflow' in ${BASH_SOURCE[0]}"
;;
esac
done
done
fi
# It is crucial for the subsequent scripts
# that the normal LAYOUT_CODE value is restored:
LAYOUT_CODE="$orig_LAYOUT_CODE"