From: yujian Date: Fri, 2 Jun 2006 10:21:21 +0000 (+0000) Subject: b=9853 X-Git-Tag: v1_7_100~1^90~8^2~162 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=37fb799d1c022d79f2997f5d2535023ced4689f9;p=fs%2Flustre-release.git b=9853 Script to verify the service IP and the real interface IP in a remote host are in the same subnet. --- diff --git a/lustre/scripts/lc_servip.sh b/lustre/scripts/lc_servip.sh new file mode 100755 index 0000000..779aa34 --- /dev/null +++ b/lustre/scripts/lc_servip.sh @@ -0,0 +1,250 @@ +#!/bin/bash +# +# lc_servip.sh - script for verifying the service IP and the real +# interface IP in a remote host are in the same subnet +# +############################################################################### + +# Usage +usage() { + cat >&2 < + + service IPaddr the IP address to failover + hostname the hostname of the remote node + +EOF + exit 1 +} + +# Check arguments +if [ $# -lt 2 ]; then + usage +fi + +# Remote command +REMOTE=${REMOTE:-"ssh -x -q"} + +# Check whether the reomte command is pdsh +is_pdsh() { + if [ "${REMOTE}" = "${REMOTE#*pdsh}" ]; then + return 1 + fi + + return 0 +} + +# +# inSameIPsubnet serviceIPaddr interfaceIPaddr mask +# +# Given two IP addresses and a subnet mask determine if these IP +# addresses are in the same subnet. If they are, return 0, else return 1. +# +inSameIPsubnet() { + declare -i n + declare -ia mask + declare -ia ip1 ip2 # IP addresses given + declare -i quad1 quad2 # calculated quad words + + # + # Remove '.' characters from dotted decimal notation and save + # in arrays. i.e. + # + # 192.168.1.163 -> array[0] = 192 + # array[1] = 168 + # array[2] = 1 + # array[3] = 163 + # + let n=0 + for quad in $(echo $1 | awk -F. '{print $1 " " $2 " " $3 " " $4}') + do + ip1[n]=$quad + let n=n+1 + done + + let n=0 + for quad in $(echo $2 | awk -F. '{print $1 " " $2 " " $3 " " $4}') + do + ip2[n]=$quad + let n=n+1 + done + + let n=0 + for quad in $(echo $3 | awk -F. '{print $1 " " $2 " " $3 " " $4}') + do + mask[n]=$quad + let n=n+1 + done + + # + # For each quad word, logically AND the IP address with the subnet + # mask to get the network/subnet quad word. If the resulting + # quad words for both IP addresses are the same they are in the + # same IP subnet. + # + for n in 0 1 2 3 + do + let $((quad1=${ip1[n]} & ${mask[n]})) + let $((quad2=${ip2[n]} & ${mask[n]})) + + if [ $quad1 != $quad2 ]; then + echo >&2 $"`basename $0`: Service IP address $1 and"\ + "real interface IP address $2 are in"\ + "different subnets!" + return 1 # in different subnets + fi + done + + return 0 # in the same subnet, all quad words matched +} + +# +# findInterface IPaddr hostname +# +# Given a target IP address and a hostname, find the interface in which +# this address is configured. If found return 0, if not return 1. The +# interface name is returned to stdout. +# +findInterface() { + declare ret_line + declare line + declare intf + declare addr + declare state + + declare target=$1 + declare hostname=$2 + + while read ret_line + do + set -- ${ret_line} + is_pdsh && shift + intf="$1" + shift + line="$*" + + while read line + do + if [ "$line" = "" ]; then # go to next interface + continue 2 + fi + + set - $line + addr= + while [ $# -gt 0 ]; do + case $1 in + addr:*) + addr=${1##addr:} + if [ -n "$addr" -a "$addr" = "$target" ] + then + echo $intf + return 0 + fi + ;; + esac + shift + done + done + done < <(${REMOTE} $hostname /sbin/ifconfig) + + echo >&2 "`basename $0`: Cannot find the interface in which" \ + "$target is configured in the host $hostname!" + return 1 +} + +# +# findNetmask interface hostname +# +# Given an interface find the netmask addresses associated with it. +# Return 0 when found, else return 1. The netmask is returned to stdout. +# +findNetmask() { + declare ret_line + declare line + declare addr + declare target=$1 + declare hostname=$2 + + while read ret_line + do + set -- ${ret_line} + is_pdsh && shift + line="$*" + + set - $line + + while [ $# -gt 0 ]; do + case $1 in + Mask:*) + echo ${1##*:} # return netmask addr + return 0 + ;; + esac + shift + done + done < <(${REMOTE} $hostname /sbin/ifconfig $target) + + echo >&2 "`basename $0`: Cannot find the netmask associated with" \ + "the interface $target in the host $hostname!" + return 1 +} + +# +# check_srvIPaddr serviceIPaddr hostname +# +# Given a service IP address and hostname, check whether the service IP address +# and the real interface IP address of hostname are in the same subnet. +# If they are, return 0, else return 1. +# +check_srvIPaddr() { + declare real_IPaddr + declare real_intf + declare netmask + declare srv_IPaddr=$1 + declare hostname=$2 + + # Get the corresponding IP address of the hostname from /etc/hosts table + real_IPaddr=`egrep "[[:space:]]$hostname([[:space:]]|$)" /etc/hosts \ + | awk '{print $1}'` + if [ -z "$real_IPaddr" ]; then + echo >&2 "`basename $0`: Hostname $hostname does not exist in" \ + "the local /etc/hosts table!" + return 1 + fi + + if [ ${#real_IPaddr} -gt 15 ]; then + echo >&2 "`basename $0`: More than one IP address line" \ + "corresponding to $hostname in the local" \ + "/etc/hosts table!" + return 1 + fi + + # Get the interface in which the real IP address is configured + real_intf=$(findInterface $real_IPaddr $hostname) + if [ $? -ne 0 ]; then + return 1 + fi + real_intf=${real_intf%%:*} + + # Get the netmask address associated with the real interface + netmask=$(findNetmask $real_intf $hostname) + if [ $? -ne 0 ]; then + return 1 + fi + + # Determine if the service IP address and the real IP address + # are in the same subnet + inSameIPsubnet $srv_IPaddr $real_IPaddr $netmask + if [ $? -ne 0 ]; then + return 1 + fi + + return 0 +} + +# Check service IP address +if ! check_srvIPaddr $1 $2; then + exit 1 +fi +exit 0