3 #################################
4 # interface event script for ctdb
5 # this adds/removes IPs from your
14 [ -z "$CTDB_PUBLIC_ADDRESSES" ] && {
15 CTDB_PUBLIC_ADDRESSES=/etc/ctdb/public_addresses
18 [ ! -f "$CTDB_PUBLIC_ADDRESSES" ] && {
19 echo "`date` No public addresses file found. Nothing to do for 10.interfaces"
23 ################################################
24 # kill off any TCP connections with the given IP
25 kill_tcp_connections() {
29 netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' |
30 while read dest src; do
31 srcip=`echo $src | cut -d: -f1`
32 srcport=`echo $src | cut -d: -f2`
33 destip=`echo $dest | cut -d: -f1`
34 destport=`echo $dest | cut -d: -f2`
35 ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
36 _killcount=`expr $_killcount + 1`
39 echo "`date` Failed to send killtcp control"
43 while netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" > /dev/null; do
45 _count=`expr $_count + 1`
46 [ $_count -gt 3 ] && {
47 echo "`date` Timed out killing tcp connections for IP $_IP"
51 echo "`date` killed $_killcount TCP connections to released IP $_IP"
55 #############################
56 # called when ctdbd starts up
58 # make sure that we only respond to ARP messages from the NIC where
59 # a particular ip address is associated.
60 [ -f /proc/sys/net/ipv4/conf/all/arp_filter ] && {
61 echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
66 ################################################
67 # called when ctdbd wants to claim an IP address
70 echo "`date` must supply interface, IP and maskbits"
77 # we make sure the interface is up first
78 /sbin/ip link set $iface up || {
79 echo "`/bin/date` Failed to bringup interface $iface"
82 /sbin/ip addr add $ip/$maskbits dev $iface || {
83 echo "`/bin/date` Failed to add $ip/$maskbits on dev $iface"
86 # cope with the script being killed while we have the interface blocked
87 /sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
89 # flush our route cache
90 echo 1 > /proc/sys/net/ipv4/route/flush
94 ##################################################
95 # called when ctdbd wants to release an IP address
98 echo "`/bin/date` must supply interface, IP and maskbits"
102 # releasing an IP is a bit more complex than it seems. Once the IP
103 # is released, any open tcp connections to that IP on this host will end
104 # up being stuck. Some of them (such as NFS connections) will be unkillable
105 # so we need to use the killtcp ctdb function to kill them off. We also
106 # need to make sure that no new connections get established while we are
107 # doing this! So what we do is this:
108 # 1) firewall this IP, so no new external packets arrive for it
109 # 2) use netstat -tn to find existing connections, and kill them
110 # 3) remove the IP from the interface
111 # 4) remove the firewall rule
117 # we do an extra delete to cope with the script being killed
118 /sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
119 /sbin/iptables -I INPUT -i $iface -d $ip -j DROP
120 kill_tcp_connections $ip
121 /sbin/ip addr del $ip/$maskbits dev $iface || failed=1
122 /sbin/iptables -D INPUT -i $iface -d $ip -j DROP
124 echo "`/bin/date` Failed to del $ip on dev $iface"
128 # flush our route cache
129 echo 1 > /proc/sys/net/ipv4/route/flush
133 ###########################################
134 # called when ctdbd has finished a recovery
138 ####################################
139 # called when ctdbd is shutting down
144 [ -x /usr/sbin/ethtool ] && {
145 [ -z "$CTDB_PUBLIC_INTERFACE" ] || {
146 /usr/sbin/ethtool $CTDB_PUBLIC_INTERFACE | grep 'Link detected: yes' > /dev/null || {
147 echo "`date` ERROR: No link on the public network interface $CTDB_PUBLIC_INTERFACE"
151 cat $CTDB_PUBLIC_ADDRESSES | sed -e "s/^[^\t ]*[\t ]*//" -e "s/[\t ]*$//" |
152 sort | uniq | while read IFACE; do
154 /usr/sbin/ethtool $IFACE | grep 'Link detected: yes' > /dev/null || {
155 echo "`date` ERROR: No link on the public network interface $IFACE"