#!/bin/bash SNAPSHOTFROMROOT=/etc/sysconfig/snapshot SYSCONFIG="$( dirname $0 )/../../$SNAPSHOTFROMROOT" SNAPSHOT=/opt/snapshot/snapshot export PERLLIB=/opt/snapshot # alternate way to write to standard error. exec 3>&2 function printHelp { ( echo "$*" echo "" echo "Usage: $0 " echo " Backup support script using LVM snapshots. " echo " Configuration is in '$SNAPSHOTFROMROOT'" echo "" ddecho " is one of" echo " login: Login to iscsi target" echo " activate: Import and activate backup logical volumes" echo " remove: Remove backup logical volumes" echo " backup: Execute backup" echo " deactivate: Deactivate and export backup logical volumes" echo " logout: Logout from iscsi target" echo " all: All of the previous targets in order" echo "" ) 1>&2 exit 1 } if [[ ! -r "$SYSCONFIG" ]] then printHelp "Config file '$SYSCONFIG' does not exist" fi . "$SYSCONFIG" if [[ $# -eq 0 ]] then printHelp fi commands="" while [[ $# -gt 0 ]] do command="$1" case "$command" in login|activate|remove|backup|deactivate|logout) commands="$commands $1" ;; all) commands="$commands login activate remove backup deactivate logout" ;; *) printHelp "Unknown command '$1'" ;; esac shift done # paths to LVM commands VGS=$( which vgs ) VGCHANGE=$( which vgchange ) VGEXPORT=$( which vgexport ) VGIMPORT=$( which vgimport ) DMSETUP=$( which dmsetup ) LVREMOVE=$( which lvremove ) function execute { echo "exec: $*" if [[ -z "$DRYRUN" ]] then $* 2>&1 if [[ $? -ne 0 ]] then exit 1 fi fi } function show { echo "" echo "========================================================================" echo "= $*" echo "========================================================================" echo "" } function login { show "login" for target in $ISCSI_TARGETS do iqn="$( echo $target | sed 's@/.*$@@g' )" portal="$( echo $target | sed 's@^.*/@@g' )" ip="$( echo $portal | sed 's@:.*$@@'g )" execute iscsiadm -m discovery -t st -p $ip execute iscsiadm -m node --targetname $iqn --portal $portal --login done execute vgscan > /dev/null 2>&1 } function mustSucceed { msg="$1" shift $* if [[ $? -ne 0 ]] then echo "=== $msg" 1>&3 exit 1 fi } function lvmFilter { grep -v "File descriptor.*leaked" } function vgs { $VGS $* 2>&1 | lvmFilter } function vgimport { $VGIMPORT $* 2>&1 | lvmFilter } function vgchange { $VGCHANGE $* 2>&1 | lvmFilter } function expandDashes { echo $* | sed 's/-/@@/g' | sed 's/@@/--/g' } function lvremove { if [[ -b "$1" ]] then vglv=$( echo "$*" | sed 's@^/dev/@@g' ) vg=$( echo $vglv | sed 's@/.*$@@g' ) lv=$( echo $vglv | sed 's@^.*/@@g' ) vg=$( expandDashes $vg ) lv=$( expandDashes $lv ) $DMSETUP -v remove $vg-$lv $LVREMOVE -f $* 2>&1 | lvmFilter else echo "Volume $* already removed" fi } function vgexport { $VGEXPORT $* 2>&1 | lvmFilter } function checkVg { vg="$1" mustSucceed "Error getting volume group info for '$vg'" vgs "$vg" > /dev/null 2>&1 } function backupVgs { ( override="" for backup in $BACKUP_VOLUMES do vg=$( echo $backup | sed 's@/.*$@@g' ) checkVg $vg echo $vg override="yes" done if [[ -z "$override" ]] then for source in $SOURCES do source="bak-$( echo $source | sed 's@/.*$@@g' )" checkVg $source echo $source done fi ) | sort | uniq } function backupLvs { ( override="" for backup in $BACKUP_VOLUMES do echo $backup override="yes" done if [[ -z "$override" ]] then for source in $SOURCES do source="bak-$( echo $source | sed 's@:.*$@@g' )" echo $source done fi ) | sort | uniq } function activate { show "activate" for vg in $( backupVgs ) do execute vgimport $vg execute vgchange -ay $vg done return 0 } function remove { show "remove" for lv in $( backupLvs ) do execute lvremove /dev/$lv done return 0 } function backup { show "backup" sources="" empty="yes" for source in $SOURCES do sources="$sources /dev/$source" empty="no" done if [[ "$empty" = "yes" ]] then echo "No source volumes specified: edit $SNAPSHOTFROMROOT to specify volumes" 1>&2 exit 1 fi addopts="" if [[ -n "$VG_PATTERN" ]] then addopts="$addopts -b $VG_PATTERN" fi if [[ -n "$LV_PATTERN" ]] then addopts="$addopts -l $LV_PATTERN" fi ( cd $( dirname $SNAPSHOT ) exec 3>&- execute ./$( basename $SNAPSHOT ) $addopts -f "$BANDWIDTH" -s "$SNAPSHOTSIZE" $sources ) return $? } function deactivate { show "deactivate" for vg in $( backupVgs ) do execute vgchange -an $vg execute vgexport $vg done return 0 } function logout { show "logout" for target in $ISCSI_TARGETS do iqn="$( echo $target | sed 's@/.*$@@g' )" execute iscsiadm -m node --targetname $iqn --logout done execute vgscan 1>/dev/null 2>&1 return 0 } for command in $commands do $command if [[ $? -ne 0 ]] then ( echo "Error executing $command" ) 1>&2 exit 1 fi echo "" done show "done"