/usr/sbin/lc_servip is in lustre-utils 1.8.5+dfsg-3ubuntu1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | #!/bin/bash
#
# lc_servip - script for verifying the service IP and the real
# interface IP in a remote host are in the same subnet
#
###############################################################################
# Usage
usage() {
cat >&2 <<EOF
Usage: `basename $0` <service IPaddr> <hostname>
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
|