Merge commit 'rusty/script-report'
[vlendec/samba-autobuild/.git] / ctdb / config / events.d / 10.interface
index 9fa4166ac0b65a9075aadb8ebc37631007a204a2..f881808f1154257680838091962ef9e14e840e7a 100755 (executable)
@@ -6,21 +6,18 @@
 # public interface
 
 . $CTDB_BASE/functions
-loadconfig ctdb
-
-cmd="$1"
-shift
+loadconfig
 
 [ -z "$CTDB_PUBLIC_ADDRESSES" ] && {
        CTDB_PUBLIC_ADDRESSES=$CTDB_BASE/public_addresses
 }
 
 [ ! -f "$CTDB_PUBLIC_ADDRESSES" ] && {
-       echo "`date` No public addresses file found. Nothing to do for 10.interfaces"
+       echo "No public addresses file found. Nothing to do for 10.interfaces"
        exit 0
 }
 
-case $cmd in 
+case "$1" in 
      #############################
      # called when ctdbd starts up
      startup)
@@ -34,7 +31,7 @@ case $cmd in
                [ -z "$_IP_HELD" ] || {
                        _IFACE=`echo $_IP_HELD | sed -e "s/.*\s//"`
                        _NM=`echo $_IP_HELD | sed -e "s/.*$_IP\///" -e "s/\s.*//"`
-                       echo "`date` Removing public address $_IP/$_NM from device $_IFACE"
+                       echo "Removing public address $_IP/$_NM from device $_IFACE"
                        /sbin/ip addr del $_IP/$_NM dev $_IFACE
                }
        done
@@ -44,25 +41,24 @@ case $cmd in
      ################################################
      # called when ctdbd wants to claim an IP address
      takeip)
-       if [ $# != 3 ]; then
-          echo "`date` must supply interface, IP and maskbits"
+       if [ $# != 4 ]; then
+          echo "must supply interface, IP and maskbits"
           exit 1
        fi
-       iface=$1
-       ip=$2
-       maskbits=$3
+       iface=$2
+       ip=$3
+       maskbits=$4
 
        # we make sure the interface is up first
        /sbin/ip link set $iface up || {
-                echo "`/bin/date` Failed to bringup interface $iface"
+                echo "Failed to bringup interface $iface"
                 exit 1
        }
-       /sbin/ip addr add $ip/$maskbits dev $iface || {
-                echo "`/bin/date` Failed to add $ip/$maskbits on dev $iface"
-                exit 1
+       /sbin/ip addr add $ip/$maskbits brd + dev $iface || {
+                echo "Failed to add $ip/$maskbits on dev $iface"
        }
        # cope with the script being killed while we have the interface blocked
-       /sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+       iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
 
        # flush our route cache
        echo 1 > /proc/sys/net/ipv4/route/flush
@@ -72,8 +68,8 @@ case $cmd in
      ##################################################
      # called when ctdbd wants to release an IP address
      releaseip)
-       if [ $# != 3 ]; then
-          echo "`/bin/date` must supply interface, IP and maskbits"
+       if [ $# != 4 ]; then
+          echo "must supply interface, IP and maskbits"
           exit 1
        fi
 
@@ -87,37 +83,37 @@ case $cmd in
        # 2) use netstat -tn to find existing connections, and kill them 
        # 3) remove the IP from the interface
        # 4) remove the firewall rule
-       iface=$1
-       ip=$2
-       maskbits=$3
+       iface=$2
+       ip=$3
+       maskbits=$4
 
        failed=0
        # we do an extra delete to cope with the script being killed
-       /sbin/iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
-       /sbin/iptables -I INPUT -i $iface -d $ip -j DROP
+       iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
+       iptables -I INPUT -i $iface -d $ip -j DROP
        kill_tcp_connections $ip
 
        # the ip tool will delete all secondary IPs if this is the primary. To work around
        # this _very_ annoying behaviour we have to keep a record of the secondaries and re-add
        # them afterwards. yuck
        secondaries=""
-       if /sbin/ip addr list dev $iface primary | grep "inet $ip/$maskbits " > /dev/null; then
+       if /sbin/ip addr list dev $iface primary | grep -q "inet $ip/$maskbits " ; then
            secondaries=`/sbin/ip addr list dev $iface secondary | grep " inet " | awk '{print $2}'`
        fi
        /sbin/ip addr del $ip/$maskbits dev $iface || failed=1
        [ -z "$secondaries" ] || {
            for i in $secondaries; do
-               if /sbin/ip addr list dev $iface | grep "inet $i" > /dev/null; then
-                   echo "`date` kept secondary $i on dev $iface"
+               if /sbin/ip addr list dev $iface | grep -q "inet $i" ; then
+                   echo "kept secondary $i on dev $iface"
                else 
-                   echo "`date` re-adding secondary address $i to dev $iface"
+                   echo "re-adding secondary address $i to dev $iface"
                    /sbin/ip addr add $i dev $iface || failed=1         
                fi
            done
        }
-       /sbin/iptables -D INPUT -i $iface -d $ip -j DROP
+       iptables -D INPUT -i $iface -d $ip -j DROP 2> /dev/null
        [ $failed = 0 ] || {
-                echo "`/bin/date` Failed to del $ip on dev $iface"
+                echo "Failed to del $ip on dev $iface"
                 exit 1
        }
 
@@ -137,28 +133,57 @@ case $cmd in
        ;;
 
      monitor)
-       [ -x /usr/sbin/ethtool ] && {
-           [ -z "$CTDB_PUBLIC_INTERFACE" ] || {
-               /usr/sbin/ethtool $CTDB_PUBLIC_INTERFACE | grep 'Link detected: yes' > /dev/null || {
-                   echo "`date` ERROR: No link on the public network interface $CTDB_PUBLIC_INTERFACE"
-                   exit 1
-               }
+       INTERFACES=`cat $CTDB_PUBLIC_ADDRESSES | 
+               sed -e "s/^[^\t ]*[\t ]*//" -e "s/[\t ]*$//"`
+
+       [ "$CTDB_PUBLIC_INTERFACE" ] && INTERFACES="$CTDB_PUBLIC_INTERFACE $INTERFACES"
+       [ "$CTDB_NATGW_PUBLIC_IFACE" ] && INTERFACES="$CTDB_NATGW_PUBLIC_IFACE $INTERFACES"
+
+       INTERFACES=`for IFACE in $INTERFACES ; do echo $IFACE ; done | sort | uniq`
+
+       for IFACE in $INTERFACES ; do
+           # These interfaces are sometimes bond devices
+           # When we use VLANs for bond interfaces, there will only
+           # be an entry in /proc for the underlying real interface
+           REALIFACE=`echo $IFACE |sed -e 's/\..*$//'`
+           [ -f /proc/net/bonding/$REALIFACE ] && {
+               grep -q 'Currently Active Slave: None' /proc/net/bonding/$REALIFACE && {
+                       echo "ERROR: No active slaves for bond device $REALIFACE"
+                       exit 1
+               }
+               grep -q '^MII Status: up' /proc/net/bonding/$REALIFACE || {
+                       echo "ERROR: public network interface $REALIFACE is down"
+                       exit 1
+               }
+               exit 0;
            }
-           cat $CTDB_PUBLIC_ADDRESSES | sed -e "s/^[^\t ]*[\t ]*//" -e "s/[\t ]*$//" | 
-           sort | uniq | while read IFACE; do
+
+           case $IFACE in 
+           ib*)
+               # we dont know how to test ib links
+               ;;
+           *)
                [ -z "$IFACE" ] || {
-                   /usr/sbin/ethtool $IFACE | grep 'Link detected: yes' > /dev/null || {
-                       echo "`date` ERROR: No link on the public network interface $IFACE"
-                       exit 1
+                   /usr/sbin/ethtool $IFACE | grep -q 'Link detected: yes' || {
+                       # On some systems, this is not successful when a
+                       # cable is plugged but the interface has not been
+                       # brought up previously. Bring the interface up and
+                       # try again...
+                       /sbin/ip link set $IFACE up
+                       /usr/sbin/ethtool $IFACE | grep -q 'Link detected: yes' || {
+                           echo "ERROR: No link on the public network interface $IFACE"
+                           exit 1
+                       }
                    }
                }
-           done
-       }
+               ;;
+           esac
+       done
+       ;;
+    *)
+       ctdb_standard_event_handler "$@"
        ;;
-
 esac
 
 exit 0
 
-
-