make /etc/ctdb/functions executable and add a hashbang to it so
[sahlberg/ctdb.git] / config / functions
index f557d62910719bba52741be0848d9c2691f5d498..3c47e4a16a2dd0fc2bfee655ca6177007010cee7 100644 (file)
@@ -1,3 +1,4 @@
+#!/bin/sh
 # utility functions for ctdb event scripts
 
 #######################################
@@ -8,6 +9,8 @@ loadconfig() {
        . /etc/sysconfig/$name
     elif [ -f /etc/default/$name ]; then
        . /etc/default/$name
+    elif [ -f $CTDB_BASE/sysconfig/$name ]; then
+       . $CTDB_BASE/sysconfig/$name
     fi
 }
 
@@ -22,13 +25,49 @@ service() {
   elif [ -x /etc/init.d/$service_name ]; then
       /etc/init.d/$service_name "$op"
   elif [ -x /etc/rc.d/init.d/$service_name ]; then
-      /etc/init.d/$service_name "$op"
+      /etc/rc.d/init.d/$service_name "$op"
+  fi
+}
+
+######################################################
+# simulate /sbin/service (niced) on platforms that don't have it
+nice_service() { 
+  service_name="$1"
+  op="$2"
+  if [ -x /sbin/service ]; then
+      nice /sbin/service "$service_name" "$op"
+  elif [ -x /etc/init.d/$service_name ]; then
+      nice /etc/init.d/$service_name "$op"
+  elif [ -x /etc/rc.d/init.d/$service_name ]; then
+      nice /etc/rc.d/init.d/$service_name "$op"
   fi
 }
 
+######################################################
+# wait for a command to return a zero exit status
+# usage: ctdb_wait_command SERVICE_NAME <command>
+######################################################
+ctdb_wait_command() {
+  service_name="$1"
+  wait_cmd="$2"
+  [ -z "$wait_cmd" ] && return;
+  all_ok=0
+  echo "Waiting for service $service_name to start"
+  while [ $all_ok -eq 0 ]; do
+         $wait_cmd > /dev/null 2>&1 && all_ok=1
+         ctdb status > /dev/null 2>&1 || {
+               echo "ctdb daemon has died. Exiting wait for $service_name"
+               exit 1
+         }
+         [ $all_ok -eq 1 ] || sleep 1
+  done
+  echo "Local service $service_name is up"
+}
+
+
 ######################################################
 # wait for a set of tcp ports
-# usage: ctdb_wait_tcp_ports SERICE_NAME <ports...>
+# usage: ctdb_wait_tcp_ports SERVICE_NAME <ports...>
 ######################################################
 ctdb_wait_tcp_ports() {
   service_name="$1"
@@ -36,32 +75,37 @@ ctdb_wait_tcp_ports() {
   wait_ports="$*"
   [ -z "$wait_ports" ] && return;
   all_ok=0
-  echo "`/bin/date` Waiting for tcp service $service_name to start"
+  echo "Waiting for tcp service $service_name to start"
   while [ $all_ok -eq 0 ]; do
          all_ok=1
          for p in $wait_ports; do
              if [ -x /usr/bin/netcat ]; then
-                 /usr/bin/netcat -z 127.0.0.1 $p || all_ok=0
+                 /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
              elif [ -x /usr/bin/nc ]; then
-                 /usr/bin/nc -z 127.0.0.1 $p || all_ok=0
+                 /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
+             elif [ -x /usr/bin/netstat ]; then
+                 (netstat -a -n | egrep "0.0.0.0:$p\s*LISTEN" > /dev/null) || all_ok=0
+             elif [ -x /bin/netstat ]; then
+                 (netstat -a -n | egrep "0.0.0.0:$p\s*LISTEN" > /dev/null) || all_ok=0
              else 
-                 echo "`date` netcat not found - cannot check tcp ports"
+                 echo "No tool to check tcp ports availabe. can not check in ctdb_wait_tcp_ports"
                  return
              fi
          done
          [ $all_ok -eq 1 ] || sleep 1
-         /usr/bin/ctdb status > /dev/null 2>&1 || {
+         ctdb status > /dev/null 2>&1 || {
                echo "ctdb daemon has died. Exiting tcp wait $service_name"
                exit 1
          }
   done
-  echo "`/bin/date` Local tcp services for $service_name are up"
+  echo "Local tcp services for $service_name are up"
 }
 
 
+
 ######################################################
 # wait for a set of directories
-# usage: ctdb_wait_directories SERICE_NAME <directories...>
+# usage: ctdb_wait_directories SERVICE_NAME <directories...>
 ######################################################
 ctdb_wait_directories() {
   service_name="$1"
@@ -69,18 +113,222 @@ ctdb_wait_directories() {
   wait_dirs="$*"
   [ -z "$wait_dirs" ] && return;
   all_ok=0
-  echo "`/bin/date` Waiting for local directories for $service_name"
+  echo "Waiting for local directories for $service_name"
   while [ $all_ok -eq 0 ]; do
          all_ok=1
          for d in $wait_dirs; do
              [ -d $d ] || all_ok=0
          done
          [ $all_ok -eq 1 ] || sleep 1
-         /usr/bin/ctdb status > /dev/null 2>&1 || {
+         ctdb status > /dev/null 2>&1 || {
                echo "ctdb daemon has died. Exiting directory wait for $service_name"
                exit 1
          }
   done
-  echo "`/bin/date` Local directories for $service_name are available"
+  echo "Local directories for $service_name are available"
+}
+
+
+######################################################
+# check that a rpc server is registered with portmap
+# and responding to requests
+# usage: ctdb_check_rpc SERVICE_NAME PROGNUM VERSION
+######################################################
+ctdb_check_rpc() {
+    service_name="$1"
+    prognum="$2"
+    version="$3"
+    rpcinfo -u localhost $prognum $version > /dev/null || {
+           echo "ERROR: $service_name not responding to rpc requests"
+           exit 1
+    }
+}
+
+######################################################
+# check a set of directories is available
+# usage: ctdb_check_directories SERVICE_NAME <directories...>
+######################################################
+ctdb_check_directories() {
+  service_name="$1"
+  shift
+  wait_dirs="$*"
+  [ -z "$wait_dirs" ] && return;
+  for d in $wait_dirs; do
+      [ -d $d ] || {
+         echo "ERROR: $service_name directory $d not available"
+         exit 1
+      }
+  done
+}
+
+######################################################
+# check a set of tcp ports
+# usage: ctdb_check_tcp_ports SERVICE_NAME <ports...>
+######################################################
+ctdb_check_tcp_ports() {
+  service_name="$1"
+  shift
+  wait_ports="$*"
+  [ -z "$wait_ports" ] && return;
+  for p in $wait_ports; do
+      all_ok=1
+      if [ -x /usr/bin/netcat ]; then
+          /usr/bin/netcat -z 127.0.0.1 $p > /dev/null || all_ok=0
+      elif [ -x /usr/bin/nc ]; then
+          /usr/bin/nc -z 127.0.0.1 $p > /dev/null || all_ok=0
+      elif [ -x /usr/bin/netstat ]; then
+          (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
+      elif [ -x /bin/netstat ]; then
+          (netstat -a -n | egrep "0.0.0.0:$p .*LISTEN" > /dev/null ) || all_ok=0
+      fi
+      [ $all_ok -eq 1 ] || {
+         echo "ERROR: $service_name tcp port $p is not responding"
+         exit 1
+      }
+  done
+}
+
+######################################################
+# check a command returns zero status
+# usage: ctdb_check_command SERVICE_NAME <command>
+######################################################
+ctdb_check_command() {
+  service_name="$1"
+  wait_cmd="$2"
+  [ -z "$wait_cmd" ] && return;
+  $wait_cmd > /dev/null 2>&1 || {
+      echo "ERROR: $service_name - $wait_cmd returned error"
+      exit 1
+  }
+}
+
+################################################
+# kill off any TCP connections with the given IP
+################################################
+kill_tcp_connections() {
+    _IP="$1"    
+    _failed=0
+
+    _killcount=0
+    connfile="$CTDB_BASE/state/connections.$_IP"
+    netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" | awk '{print $4" "$5}' > $connfile
+    while read dest src; do
+       srcip=`echo $src | cut -d: -f1`
+       srcport=`echo $src | cut -d: -f2`
+       destip=`echo $dest | cut -d: -f1`
+       destport=`echo $dest | cut -d: -f2`
+       ctdb killtcp $srcip:$srcport $destip:$destport >/dev/null 2>&1 || _failed=1
+       echo "Killing TCP connection $srcip:$srcport $destip:$destport"
+       _killcount=`expr $_killcount + 1`
+    done < $connfile
+    /bin/rm -f $connfile
+    [ $_failed = 0 ] || {
+       echo "Failed to send killtcp control"
+       return;
+    }
+    [ $_killcount -gt 0 ] || {
+       return;
+    }
+    _count=0
+    while netstat -tn |egrep "^tcp.*\s+$_IP:.*ESTABLISHED" > /dev/null; do
+       sleep 1
+       _count=`expr $_count + 1`
+       [ $_count -gt 3 ] && {
+           echo "Timed out killing tcp connections for IP $_IP"
+           return;
+       }
+    done
+    echo "killed $_killcount TCP connections to released IP $_IP"
+}
+
+########################################################
+# start/stop the nfs service on different platforms
+########################################################
+startstop_nfs() {
+       PLATFORM="unknown"
+       [ -x /etc/init.d/nfsserver ] && {
+               PLATFORM="sles"
+       }
+       [ -x /etc/init.d/nfslock ] && {
+               PLATFORM="rhel"
+       }
+
+       case $PLATFORM in
+       sles)
+               case $1 in
+               start)
+                       service nfsserver start
+                       ;;
+               stop)
+                       service nfsserver stop > /dev/null 2>&1
+                       ;;
+               esac
+               ;;
+       rhel)
+               case $1 in
+               start)
+                       service nfslock start
+                       service nfs start
+                       ;;
+               stop)
+                       service nfs stop > /dev/null 2>&1
+                       service nfslock stop > /dev/null 2>&1
+                       ;;
+               esac
+               ;;
+       *)
+               echo "Unknown platform. NFS is not supported with ctdb"
+               exit 1
+               ;;
+       esac
+}
+
+########################################################
+# start/stop the nfs lockmanager service on different platforms
+########################################################
+startstop_nfslock() {
+       PLATFORM="unknown"
+       [ -x /etc/init.d/nfsserver ] && {
+               PLATFORM="sles"
+       }
+       [ -x /etc/init.d/nfslock ] && {
+               PLATFORM="rhel"
+       }
+
+       case $PLATFORM in
+       sles)
+               # for sles there is no service for lockmanager
+               # so we instead just shutdown/restart nfs
+               case $1 in
+               start)
+                       service nfsserver start
+                       ;;
+               stop)
+                       service nfsserver stop > /dev/null 2>&1
+                       ;;
+               esac
+               ;;
+       rhel)
+               case $1 in
+               start)
+                       service nfslock start
+                       ;;
+               stop)
+                       service nfslock stop > /dev/null 2>&1
+                       ;;
+               esac
+               ;;
+       *)
+               echo "Unknown platform. NFS locking is not supported with ctdb"
+               exit 1
+               ;;
+       esac
 }
 
+########################################################
+# load a site local config file
+########################################################
+
+[ -x $CTDB_BASE/rc.local ] && {
+       . $CTDB_BASE/rc.local
+}