Sun Cluster Entwicklerhandbuch Datendienste für Solaris OS

PROBE-Programm

Das PROBE-Programm prüft die Verfügbarkeit des Datendienstes mithilfe von nslookup( 1M)-Befehlen. Die Rückmeldemethode Monitor_start startet dieses Programm, und die Rückmeldemethode Monitor_start stoppt es.


Beispiel B–5 dns_probe-Programm

#!/bin/ksh
#pragma ident   “@(#)dns_probe   1.1   00/04/19 SMI”
#
#Testsignal-Methode für HA-DNS.
#
# Dieses Programm prüft die Verfügbarkeit des Datendienstes mithilfe von
# nslookup, das den DNS-Server auffordert, selbst nach dem DNS-Server zu suchen. Wenn
# der Server nicht antwortet bzw. die Abfrage von einem anderen Server beantwortet wird,
# schließt der Test, dass ein Problem mit dem Datendienst aufgetreten ist,
# und führt ein Failover auf einen anderen Knoten im Cluster durch. Die Testsignale
# werden in bestimmten Intervallen gesendet, eingestellt durch THOROUGH_PROBE_INTERVAL
# in der RTR-Datei.
  
#pragma ident   “@(#)dns_probe   1.1   00/05/24 SMI”

###############################################################################
# Programmargumente analysieren.
function parse_args # [args ...]
{
        typeset opt

        while getopts `R:G:T:' opt
        do
                case “$opt” in
                R)
                        # Name der DNS-Ressource.
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # Name der Ressourcengruppe, in der die Ressource
                        # konfiguriert ist.
                        RESOURCEGROUP_NAME=$OPTARG
                        ;;
                T)
                        # Name des Ressourcentyps.
                        RESOURCETYPE_NAME=$OPTARG
                        ;;
                *)
                    logger -p ${SYSLOG_FACILITY}.err \
                    -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \
                    “FEHLER: Option $OPTARG unbekannt”
                     exit 1
                     ;;
                esac
        done
}

###############################################################################
# restart_service ()
#
# Diese Funktion versucht, den Datendienst durch Aufruf der Stopp-Methode,
# gefolgt von der Start-Methode des Datendienstes neu zu starten. Wenn der
# Datendienst bereits beendet wurde und keine Markierung für den Datendienst
# unter PMF registriert wurde, führt diese Funktion ein Failover für den Dienst
# auf einen anderen Knoten im Cluster aus.
#
function restart_service
{
        # Zum Neustarten des Datendienstes zunächst überprüfen,
        # ob der Datendienst selbst noch unter PMF registriert ist.
        pmfadm -q $PMF_TAG
        if [[ $? -eq 0 ]]; then
                # Da das TAG für den Datendienst noch unter PMF registriert
                # ist, zuerst den Datendienst stoppen und dann wieder neu starten..
                # Stopp-Methodenname und STOP_TIMEOUT-Wert für
                # diese Ressource abrufen.
                STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                STOP_METHOD=`scha_resource_get -O STOP \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
                        -T $RESOURCETYPE_NAME

                if [[ $? -ne 0 ]]; then
                        logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]
                                “${ARGV0} Stopp-Methode fehlgeschlagen.”
                        return 1
                fi

                # Start-Methodenname und START_TIMEOUT-Wert für
                # diese Ressource abrufen.
                START_TIMEOUT=`scha_resource_get -O START_TIMEOUT \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                START_METHOD=`scha_resource_get -O START \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
                hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD \
                        -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
                        -T $RESOURCETYPE_NAME

                if [[ $? -ne 0 ]]; then
                        logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                                “${ARGV0} Start-Methode fehlgeschlagen.”
                        return 1
                fi

        else
                # Das Fehlen des TAG für den Datendienst
                # weist darauf hin, dass der Datendienst bereits die
                # unter PMF zulässigen Wiederholungen überschritten hat.
                # Es wird also nicht versucht, den Datendienst noch einmal
                # neu zu starten, sondern ein Failover auf
                # einen anderen Knoten im Cluster auszuführen.
                scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
                        -R $RESOURCE_NAME
        fi

        return 0
}

###############################################################################
# decide_restart_or_failover ()
#
# Diese Funktion legt fest, welche Aktion bei Fehlschlagen eines Testsignals
# auszuführen ist: lokaler Neustart des Datendienstes oder Failover auf einen
# anderen Knoten im Cluster.
#
function decide_restart_or_failover
{

   # Prüfen, ob dies der erste Neustartversuch ist.
   if [ $retries -eq 0 ]; then
         # Dies ist der erste Fehlschlag. Zeit für diesen
         # ersten Versuch festhalten.
         start_time=`$RT_BASEDIR/gettimè
         retries=`expr $retries + 1`
         # Da es sich um den ersten Fehlschlag handelt, versuchen,
         # den Datendienst neu zu starten.
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                “${ARGV0} Datendienst konnte nicht neu gestartet werden.”
            exit 1
         fi
   else
      # Dies ist nicht der erste Fehlschlag
      current_time=`$RT_BASEDIR/gettimè
      time_diff=`expr $current_time - $start_timè
      if [ $time_diff -ge $RETRY_INTERVAL ]; then
         # Dieser Fehlschlag ist aufgetreten, nachdem das Zeitfenster
         # verstrichen war. Daher den Wiederholungszähler zurücksetzen,
         # das Intervall verschieben und eine Wiederholung ausführen.
         retries=1
         start_time=$current_time
         # Da der letzte Fehlschlag vor mehr als Retry_interval
         # auftrat, versuchen, den Datendienst neu zu starten.
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err \
                -t [$SYSLOG_TAG
                “${ARGV0} HA-DNS konnte nicht neu gestartet werden.”
            exit 1
         fi
      elif [ $retries -ge $RETRY_COUNT ]; then
         # Noch innerhalb des Zeitintervalls, und der
         # Wiederholungszähler ist abgelaufen, also Failover.
         retries=0
         scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
             -R $RESOURCE_NAME
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                “${ARGV0} Failover-Versuch fehlgeschlagen.”
            exit 1
         fi
      else
         # Noch innerhalb des Zeitintervalls, und der
         # Wiederholungszähler ist nicht abgelaufen.
         # Also wird eine weitere Wiederholung ausgeführt.
         retries=`expr $retries + 1`
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                “${ARGV0} HA-DNS konnte nicht neu gestartet werden.”
            exit 1
         fi
      fi
fi
}

###############################################################################
# MAIN
###############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# syslog-Funktion abrufen, mit der Meldungen protokolliert werden.
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`

# Argumente analysieren, die an diese Methode übergeben wurden
parse_args “$@”

PMF_TAG=$RESOURCE_NAME.named
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# Das Intervall, in dem die Testsignale gesendet werden, ist in der systemdefinierten
# Eigenschaft THOROUGH_PROBE_INTERVAL eingestellt. Den Wert dieser Eigenschaft mit
# scha_resource_get abrufen
PROBE_INTERVAL=`scha_resource_get -O THOROUGH_PROBE_INTERVAL \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

# Zeitüberschreitungswert abrufen, der für das Testsignal zulässig ist.
# Dieser ist in der Erweiterungseigenschaft PROBE_TIMEOUT in der RTR-Datei eingestellt.
# Die Standard-Zeitüberschreitung für nslookup ist 1,5 Minuten.
probe_timeout_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAME Probe_timeout`
PROBE_TIMEOUT=`echo $probe_timeout_info | awk `{print $2}'`

# Den Server, auf dem DNS läuft, durch Abrufen des Werts der
# Ressourceneigenschaft NETWORK_RESOURCES_USED identifizieren.
DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME \
 -G $RESOURCEGROUP_NAMÈ

# Wiederholungszählerwert aus der systemdefinierten Eigenschaft Retry_count abrufen
RETRY_COUNT=`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME \
-G  $RESOURCEGROUP_NAMÈ

# Wiederholungsintervallwert aus der systemdefinierten Eigenschaft
# Retry_interval abrufen
RETRY_INTERVAL=`scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ

# Vollständigen Pfad für das Gettime-Dienstprogramm aus der
# RT_basedir-Eigenschaft des Ressourcentyps abrufen.
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \
-G \$RESOURCEGROUP_NAMÈ

# Der Test läuft in einer Endlosschleife und versucht nslookup-Befehle.
# Eine temporäre Datei für die nslookup-Antworten konfigurieren.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

while :
do
   # Das Intervall, in dem das Testsignal ausgeführt muss, ist in der
   # Eigenschaft THOROUGH_PROBE_INTERVAL angegeben. Daher das Testsignal für
   # eine Dauer von <THOROUGH_PROBE_INTERVAL> ruhen lassen
   sleep $PROBE_INTERVAL

   # Test ausführen, womit die IP-Adresse abgefragt wird, auf der
   # DNS läuft.
   hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST
\
> $DNSPROBEFILE 2>&1

   retcode=$?
        if [ retcode -ne 0 ]; then
                probefail=1
        fi

   # Sicherstellen, dass die Antwort auf den nslookup-Befehl vom HA-DNS
   # -Server und nicht von einem anderen in der /etc/resolv.conf-Datei aufgelisteten
   # Server kommt.
   if [ $probefail -eq 0 ]; then
      # Namen des Servers abrufen, der auf die nslookup-Abfrage antwortet.
                   SERVER=` awk ` $1==”Server:” {
print $2 }' \
                   $DNSPROBEFILE | awk -F. ` { print $1 } ` `
                if [ -z “$SERVER” ];
then
                        probefail=1
                else
                        if [ $SERVER != $DNS_HOST ]; then
                                probefail=1
                        fi
                fi
        fi

   # Wenn die probefail-Variable nicht auf 0 eingestellt ist, ist entweder die
   # Zeit für den nslookup-Befehl abgelaufen, oder die Antwort auf die Abfrage
   # kam von einem anderen Server (angegeben in der /etc/resolv.conf-Datei). In beiden
   # Fällen antwortet der DNS-Server nicht, und die Methode ruft
   # decide_restart_or_failover auf, wodurch ausgewertet wird, ob der Datendienst neu
   # gestartet oder ein Failover auf einen anderen Knoten ausgeführt wird.

   if [ $probefail -ne 0 ]; then
         decide_restart_or_failover
   else
         logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]\
         “${ARGV0} Testsignal für HA-DNS-Ressource erfolgreich”
   fi
done