#!/bin/sh ################################################################################ # # SCRIPT: vgrecover # VERSION: 1.0 # AUTHOR: Dave Thompson, NSS, ISD, Lee County Clerk of Courts # RELEASE DATE: 07/22/2005 # # DESCRIPTION: vgrecover allows user to preview or execute vgimports. It is # designed to work in conjunction with vgsnapshot and load_balance. # ################################################################################ # Variables. IFS=" " export PATH="/usr/sbin:/usr/bin:/sbin:" SCRIPT="vgrecover" USER=`who am i | awk '{print $1}'` WORKING_DIR="/tmp/sysadmin/vg" MAP_DIR="${WORKING_DIR}/maps" GROUP_DIR="${WORKING_DIR}/groups" LOG="${WORKING_DIR}/vg.log" umask 022 # Function to log messages to syslog. log_it() { logger -p user.info -t ${SCRIPT} "NOTICE (from ${USER}): ${1}" } # Function to determine current date and time. dateit() { DATE=`date +%Y-%m-%d_%H:%M:%S` } # Function to send stdout and stderr to stdout and to the log. tee_it() { ${1} 2>&1 | tee -a ${LOG} } # Function to write output to the user's screen and to the log, including # the current date and time, each time it is invoked. screen_log() { dateit tee_it "echo ${DATE}: ${1}" } # Set trap to send e-mail if this script is killed. kill_do() { MSG="${SCRIPT} abruptly killed" log_it "${MSG}" screen_log "${MSG}" exit 1 } trap kill_do 1 2 3 15 30 # Function for help output. help() { echo " Usage: ${SCRIPT} -[h|p|x] h help (this output) p preview mode only x execute vgimport A single argument is required. Multiple arguments are prohibited. ${SCRIPT} cycles through all volume groups and allows you to either preview or execute vgimports. It is designed to work in conjunction with vgsnapshot, which executes vgexports for volume groups; and load_balance, which balances the load across controllers after volume groups have been re-imported. If you only want to view the contents of any files created by ${SCRIPT}, simply view them in ${MAP_DIR}. " } # Insert line for dilineation purposes in both the log and to stdout. tee_it "echo ================================================================================ " screen_log "echo Executing ${SCRIPT}..." blank_line # Validate only one argument is given. if [ ! -n "${1}" ]; then screen_log "ERROR: No argument specified.\n" help exit 1 elif [ -n "${2}" ]; then screen_log "ERROR: Multiple arguments specified.\n" help exit 1 fi # Function to insert a blank line into stdout and log. blank_line() { tee_it "echo " } # Function to re-create device directory and node for group file. gen_group() { screen_log "Re-creating ${VG_LONG}..." if [ ! -d "${VG_LONG}" ]; then mkdir ${VG_LONG} screen_log "Done." else screen_log "${VG_LONG} already existed." fi screen_log "Re-creating group file in ${VG_LONG}..." GROUP_FILE="${VG_LONG}/group" if [ ! -c "${GROUP_FILE}" ]; then mknod ${GROUP_FILE} c `cat ${GROUP_DIR}/${VG} | awk '{print $5, $6}'` ll ${GROUP_FILE} screen_log "Done." else screen_log "${GROUP_FILE} already existed." fi } # Ensure variables that may be pre-set in the user's shell are not passed to # this script. PREVIEW="NULL" EXECUTE="NULL" # Configure variables based upon argument selected by user. Exit if no # argument specified. if [ "${1}" = "-h" ]; then help exit 0 elif [ "${1}" = "-p" ]; then PREVIEW="${1}" elif [ "${1}" = "-x" ]; then EXECUTE="${1}" else screen_log "ERROR: Improper argument specified.\n" help exit 1 fi # Create syslog entry that script is beginning. log_it "${SCRIPT} started" # Preview or import map files. for VG in `ls ${MAP_DIR} | cut -c21- | cut -d'.' -f 1 | sort -n | uniq`; do VG_LONG="/dev/${VG}" blank_line screen_log "Select a map file to import or preview for ${VG}:\n" tee_it "ll ${MAP_DIR}/*${VG}.map" blank_line screen_log "Typically, the latest map file should be selected. The last one is:\n" LATEST_MAP=`ls -ltr ${MAP_DIR}/*${VG}.map | awk '{print $9}' | grep -v "^$" | tail -1` screen_log "${LATEST_MAP}" blank_line screen_log "Select latest (l), enter the absolute path of a map file, or to skip: \c" read MAP2IMPORT blank_line [ "${MAP2IMPORT}" = "l" ] && MAP2IMPORT="${LATEST_MAP}" [ "${MAP2IMPORT}" = "" ] && screen_log "No selection made. Skipping..." [ ! -f "${MAP2IMPORT}" -a "${MAP2IMPORT}" != "" ] && screen_log "Invalid selection. Skipping..." if [ "${PREVIEW}" = "-p" -a -f "${MAP2IMPORT}" ]; then gen_group screen_log "Previewing map file ${MAP2IMPORT}..." tee_it "vgimport -m ${MAP2IMPORT} -s -v -p ${VG}" screen_log "To perform actual imports, execute \"${SCRIPT} -x\"." elif [ "${EXECUTE}" = "-x" -a -f "${MAP2IMPORT}" ]; then screen_log "WARNING: You are about to perform imports on ${VG}. Do you wish to continue [y/n]? \c" read ANSWER if [ "${ANSWER}" = "y" ]; then gen_group screen_log "Importing file ${MAP2IMPORT} for ${VG}..." tee_it "vgimport -m ${MAP2IMPORT} -s -v ${VG}" log_it "Vgimported ${VG}" screen_log "Done." screen_log "Activating ${VG}..." vgchange -a y ${VG} if [ "${?}" = "0" ]; then log_it "Activated ${VG}" screen_log "Done." screen_log "Mounting filesystems onto ${VG}..." for FS in `grep ${VG} /etc/fstab | awk '{print $2}'`; do screen_log "Mounting ${FS}..." mount ${FS} #tee_it "mount | grep ${FS}" tee_it "bdf ${FS}" #tee_it "bdf | egrep "Filesystem|${FS}" log_it "Mounted ${FS}" screen_log "Done." done screen_log "Finished mounting filesystems." fi else screen_log "You chose not to import ${VG}. Skipping..." fi fi screen_log "Done." done screen_log "The log is ${LOG}." screen_log "If all VG's were imported successfully, consider executing \`load_balance\` to re-balance the load across the controllers." # Exit. log_it "${SCRIPT} finished" exit 0