After figuring out the SnapVault stuff, I needed to implement a whole bunch of SnapMirror relations. As I am lazy (as in click-lazy), I ended up writing a somewhat short Bash script, that’ll either establish a bunch of SnapMirror relations (for a single host) or just for a single volume.
The script expects, that SSH public key authentification has been set up, and that the source for the SnapMirror exists and is online/not-restricted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
#!/bin/bash -f # Create a SnapMirror relation between two volumes # 1) create volume on target, if it doesn't exist # 2) set snapshot reserve on target # 3) start the snapmirror relationship KEY_FILE="/root/.ssh/netapp.dsa" SSH_OPTS="/root/.ssh/netapp-ssh_config" usage() { echo "Usage: fas-snapmirror-start.sh <MODE> <VOLUME|HOSTNAME> <SM_PRIMARY> <SM_SECONDARY> [SM_RATE_LIMIT]" echo "" if [ -n "$1" ] ; then echo "$1" echo "" fi echo "Required parameters:" echo "" echo " - MODE: Either host or volume (case sensitive)." echo "" echo " - VOLUME: Volume for which to configure SnapMirror (if mode is set to volume)" echo " - HOSTNAME: Host for which to configure SnapMirror (if mode is set to host)" echo " - SM_SECONDARY: Hostname of the SnapMirror Secondary" echo " - SM_PRIMARY: Hostname of the SnapMirror Primary" echo "" echo "Optional parameters:" echo "" echo " - SM_RATE_LIMIT: Limit the SnapMirror transfer to xx kb, may help on busy systems." echo " Defaults to no limit at all, may cause harm to already busy FAS" echo " controllers." echo "" exit 1 } ssh_fas() { # $@: commands for Data ONTAP COMMANDS="$@" /usr/bin/ssh -i $KEY_FILE -l root -F $SSH_OPTS $COMMANDS } snapmirror_setup() { if [ "$#" -lt 4 ] ; then break fi # $1: sm_secondary # $2: sm_primary # $4: volume # $6: sm_rate_limit sm_secondary=$1 sm_primary=$2 volume=$3 sm_rate_limit=$4 # Check if snapmirror access is configured correctly sm_secondary_ip="$( ssh_fas $sm_secondary rdfile /etc/hosts | grep $sm_secondary-e0a | awk '{ print $1 }' )" sm_access="$( ssh_fas $sm_primary options snapmirror.access | grep $sm_secondary_ip )" if [ -z "$sm_access" ] ; then echo "Please make sure, that SnapMirror access is correctly" echo "configured on $sm_primary, so that $sm_secondary" echo "can access it using snapmirror." echo echo "Hint: options snapmirror.access should look like this:" echo " options snapmirror.access host=$sm_secondary_ip" echo exit 1 fi # Get FlexVol size from SM_PRIMARY (SnapMirror destination has the same # size as the SnapMirror source) VOL_SIZE="$( ssh_fas $sm_primary vol size $volume | awk '{ print $8 }' | sed "s,.,," )" # Check if the is a qtree on SM_PRIMARY QTREE="$( ssh_fas $sm_primary qtree status | grep $volume | cut -d -f2 | sed '/^$/d' )" if [ -z "$QTREE" ] ; then echo echo "SnapDrive only supports Qtree to Qtree relations!" echo "Please create a qtree (qtree create /vol/${volume}/sv" echo exit 1 fi # Assume to always use aggr1 on SM_SECONDARY echo "SnapMirror operations for FlexVol: $volume" echo " - Creating FlexVol" ssh_fas $sm_secondary vol create $volume -s none aggr1 $VOL_SIZE &>/dev/null echo " - Disabling Unicode/atime/automatic snapshotting" ssh_fas $sm_secondary vol options $volume fractional_reserve 100 ssh_fas $sm_secondary vol options $volume no_atime_update on ssh_fas $sm_secondary vol options $volume create_ucode off ssh_fas $sm_secondary vol options $volume nosnap on ssh_fas $sm_secondary vol options $volume convert_ucode off ssh_fas $sm_secondary vol autosize $volume off &>/dev/null ssh_fas $sm_secondary snap reserve $volume $SNAP_RESERVE &>/dev/null echo " - Restricting volume on $sm_secondary" ssh_fas $sm_secondary vol restrict $volume &>/dev/null # Now create the SnapMirror relationship between SM_SECONDARY and SM_PRIMARY if [ -n $sm_rate_limit ] ; then smi_rate_limit="-k $sm_rate_limit" smc_rate_limit="kbs=$sm_rate_limit" else smc_rate_limit="-" fi echo " - Starting SnapMirror relation between $sm_secondary and $sm_primary" ssh_fas $sm_secondary snapmirror initialize $smi_rate_limit -S $sm_primary-e0a:$volume $sm_secondary:$volume &>/dev/null echo " - Updating snapmirror.conf on $sm_secondary" smc_opts="$sm_primary-e0a:$volume $sm_secondary:$volume $smc_rate_limit * 0-23/1 * *" ssh_fas $sm_secondary wrfile -a /etc/snapmirror.conf $smc_opts echo echo "You can monitor the SnapMirror initialization on the SnapMirror Secondary ($sm_secondary)" echo "by using the following command:" echo echo " 'snapmirror status $volume'" echo } # Main script starts here. #set -x if [ "$#" -lt 4 ] ; then usage fi case $1 in host) MODE="host"; HOST=$2 ;; volume) MODE="volume"; VOLUME=$2 ;; *) usage "Invalid mode specified" esac SM_PRIMARY=$3 SM_SECONDARY=$4 SM_RATE_LIMIT=${5:-10000} if [ "$MODE" == "host" ] ; then # Get the LUN list VOLUME_LIST="$( ssh_fas $SM_PRIMARY lun show | grep -i $HOST | grep -v windows_ | awk '{ print $1 }' | cut -d/ -f3 | sort -u | tr 'n' ' ' | sort -u )" for vol in $VOLUME_LIST; do # Check if snapreserve is enabled SNAP="$( ssh_fas $SM_PRIMARY snap reserve $vol | cut -d -f7 | sed "s,%,," )" if [ $SNAP -ne "0" ] ; then snapmirror_setup $SM_SECONDARY $SM_PRIMARY $vol $SM_RATE_LIMIT else echo "No snap reserve configured for $vol" fi done elif [ "$MODE" == "volume" ] ; then SNAP="$( ssh_fas $SM_PRIMARY snap reserve $VOLUME | cut -d -f7 | sed "s,%,," )" if [ $SNAP -ne "0" ] ; then snapmirror_setup $SM_SECONDARY $SM_PRIMARY $VOLUME $SM_RATE_LIMIT else echo "No snap reserve configured for $vol" fi fi #set -x |