From 0d34462e5e0e79eee160503beccf4ac77c7f17fb Mon Sep 17 00:00:00 2001 From: yujian Date: Wed, 8 Feb 2006 10:30:46 +0000 Subject: [PATCH] A script for verifying the service IP and the real interface IP in a remote host are in the same subnet. --- lustre/utils/verify_serviceIP.sh | 228 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100755 lustre/utils/verify_serviceIP.sh diff --git a/lustre/utils/verify_serviceIP.sh b/lustre/utils/verify_serviceIP.sh new file mode 100755 index 0000000..794f153 --- /dev/null +++ b/lustre/utils/verify_serviceIP.sh @@ -0,0 +1,228 @@ +#!/bin/bash +# +# verify_serviceIP.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 + +# +# 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 host + declare line + declare intf + declare addr + declare state + + declare target=$1 + declare hostname=$2 + + { + while read host intf line + do + while read host 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 + } < <(pdsh -w $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 line + declare addr + declare target=$1 + declare hostname=$2 + + while read line + do + set - $line + + while [ $# -gt 0 ]; do + case $1 in + Mask:*) + echo ${1##*:} # return netmask addr + return 0 + ;; + esac + shift + done + done < <(pdsh -w $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 IP address from /etc/hosts table according to the hostname + real_IPaddr=`egrep "[[:space:]]$hostname([[:space:]]|$)" /etc/hosts \ + | awk '{print $1}'` + if [ -z "$real_IPaddr" ]; then + echo >&2 "`basename $0`: $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" \ + "according 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 -- 1.8.3.1