Guide des développeurs pour les services de données Sun Cluster pour SE Solaris

Programme PROBE

Le programme PROBE vérifie la disponibilité du services de données à l'aide des commandes nslookup( 1M). La méthode de rappel Monitor_start lance ce programme et la méthode de rappel Monitor_stop l'arrête.


Exemple B–5 Programme dns_probe

#!/bin/ksh
#pragma ident   “@(#)dns_probe   1.1   00/04/19 SMI”
#
# Méthode de détection (Probe) de HA-DNS.
#
# Ce programme vérifie la disponibilité du service de données à l'aide de nslookup, qui 
# demande au serveur DNS de rechercher lui-même le serveur DNS. Si le serveur ne répond pas
# ou si un autre serveur répond à la requête, la méthode de détection conclut qu'il y a 
# un problème au niveau du service de données et bascule ce service sur un autre nœud du
# cluster. La détection est réalisée suivant un intervalle spécifique défini par 
# THOROUGH_PROBE_INTERVAL dans le fichier RTR. 
  
#pragma ident   “@(#)dns_probe   1.1   00/05/24 SMI”

###############################################################################
# Analysez les arguments du programme.
function parse_args # [args ...]
{
        typeset opt

        while getopts `R:G:T:' opt
        do
                case “$opt” in
                R)
                        # Nom de la ressource DNS.
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # Nom du groupe de ressources dans lequel la ressource
                        # est configurée.
                        RESOURCEGROUP_NAME=$OPTARG
                        ;;
                T)
                        # Nom du type de ressources.
                        RESOURCETYPE_NAME=$OPTARG
                        ;;
                *)
                    logger -p ${SYSLOG_FACILITY}.err \
                    -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \
                    “ERROR: Option $OPTARG unknown”
                     exit 1
                     ;;
                esac
        done
}

###############################################################################
# restart_service ()
#
# Cette fonction tente de redémarrer le service de données en appelant sa méthode 
# Stop, puis sa méthode Start. Si le service de données a déjà été 
# arrêté et qu'aucune balise n'est enregistrée pour ce service sous la fonction PMF,
# cette fonction bascule le service vers un autre nœud du cluster.
#
function restart_service
{
        # Pour redémarrer le service de données, commencez par vérifier qu'il 
        # est toujours enregistré sous la fonction PMF.
        pmfadm -q $PMF_TAG
        if [[ $? -eq 0 ]]; then
                # Comme la balise TAG du service de données est toujours enregistrée
                # sous la fonction PMF, commencez par arrêter le service de données, puis redémarrez-le.
                # Obtenez le nom de la méthode Stop et la valeur STOP_TIMEOUT
                # de cette ressource.
                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} Stop method failed.”
                        return 1
                fi

                # Obtenez le nom de la méthode Start et la valeur START_TIMEOUT
                # de cette ressource.
                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 method failed.”
                        return 1
                fi

        else
                # L'absence de la balise TAG du service de données 
                # implique que ce service a déjà dépassé le nombre 
                # maximum de tentatives permises sous la fonction PMF. 
                # Par conséquent, ne retentez pas de redémarrer
                # le service de données. Essayez de le basculer 
                # sur un autre nœud du cluster.
                scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
                        -R $RESOURCE_NAME
        fi

        return 0
}

###############################################################################
# decide_restart_or_failover ()
#
# Cette fonction décide de l'action à entreprendre suite à l'échec d'une détection : 
# redémarrez le service de données localement ou basculez-le sur un autre nœud du cluster.
#
function decide_restart_or_failover
{
   
   # Vérifiez s'il s'agit de la première tentative de redémarrage.
   if [ $retries -eq 0 ]; then
         # Il s'agit de la première tentative de redémarrage. Notez la durée 
         # de cette première tentative. 
         start_time=`$RT_BASEDIR/gettimè
         retries=`expr $retries + 1`
         # Comme il s'agit de la première tentative, tentez de redémarrer
         # le service de données.
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                “${ARGV0} Failed to restart data service.”
            exit 1
         fi
   else
      # Ce n'est pas la première tentative
      current_time=`$RT_BASEDIR/gettimè
      time_diff=`expr $current_time - $start_timè
      if [ $time_diff -ge $RETRY_INTERVAL ]; then
         # Cet échec survient une fois la fenêtre de temps
         # écoulée. Réinitialisez le compteur de tentatives,
         # faites glisser la fenêtre et recommencez.
         retries=1
         start_time=$current_time
         # Comme l'échec précédent est survenu il y a plus de 
         # Retry_interval, tentez de redémarrer le service de données.
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err \
                -t [$SYSLOG_TAG
                “${ARGV0} Failed to restart HA-DNS.”
            exit 1
         fi
      elif [ $retries -ge $RETRY_COUNT ]; then
         # Toujours dans la fenêtre de temps,
         # le compteur de tentative a expiré. Basculez.
         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 attempt failed.”
            exit 1
         fi
      else
         # Toujours dans la fenêtre de temps,
         # le compteur de temps n'a pas expiré,
         # faites une autre tentative.
         retries=`expr $retries + 1`
         restart_service
         if [ $? -ne 0 ]; then
            logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
                “${ARGV0} Failed to restart HA-DNS.”
            exit 1
         fi
      fi
fi
}

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

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

# Obtenez la fonction syslog à utiliser pour consigner les messages.
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`

# Analysez les arguments qui ont été transmis à cette méthode
parse_args “$@”

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

# L'intervalle suivant lequel la détection doit être effectuée est paramétré dans
# la propriété définie par le système THOROUGH_PROBE_INTERVAL.  
# Obtenez la valeur de cete propriété avec scha_resource_get 
PROBE_INTERVAL=scha_resource_get -O THOROUGH_PROBE_INTERVAL \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

# Obtenez la valeur du délai d'attente autorisé pour la détection qui est définie 
# dans la propriété d'extension PROBE_TIMEOUT dans le fichier RTR. Le délai d'attente 
# par défaut de nslookup est de 1,5 minutes.
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}'`

# Identifiez le serveur sur lequel le service de noms de domaine fonctionne en obtenant
# la valeur de la propriété NETWORK_RESOURCES_USED de la ressource.
DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ

# Obtenez la valeur du compteur de tentative à partir de la propriété Retry_count définie par le système
RETRY_COUNT =`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ

# Obtenez la valeur de l'intervalle entre les tentatives à partir de la propriété Retry_interval définie par le système
RETRY_INTERVAL=scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ

# Obtenez le chemin complet de l'utilitaire gettime à partir de la propriété  
# RT_basedir du type de ressources.
RT_BASEDIR=scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ

# La détection est exécutée dans une boucle sans fin, essayant les commandes nslookup. 
# Définissez un fichier temporaire pour les réponses de nslookup.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

while :
do
   # L'intervalle suivant lequel la détection doit être exécutée est spécifié dans la 
   # propriété THOROUGH_PROBE_INTERVAL. Cependant, définissez la durée 
   # <THOROUGH_PROBE_INTERVAL> pendant laquelle la détection est en sommeil.
   sleep $PROBE_INTERVAL

   # Exécutez la détection qui demande l'adresse IP sur laquelle
   # le service de noms de domaine fonctionne.
   hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \
           > $DNSPROBEFILE 2>&1
   
   retcode=$?
        if [ retcode -ne 0 ]; then
                probefail=1
        fi

   # Vérifiez que la réponse à la commande nslookup est émise par le serveur HA-DNS
   # et non par un autre serveur répertorié dans le fichier  
   # /etc/resolv.conf.
   if [ $probefail -eq 0 ]; then
      # Obtenez le nom du serveur qui a répondu à la requête de nslookup.
                   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

   # Si la variable probefail n'est pas définie sur 0, cela signifie que le délai de la commande nslookup
   # est dépassé ou que la réponse à la requête a été émise par un autre serveur
   # (spécifié dans le fichier /etc/resolv.conf). Dans les deux cas, le serveur DNS
   # ne répond pas et la méthode appelle decide_restart_or_failover,
   # qui détermine si le service de données doit être redémarré ou basculé
   # sur un autre nœud.

   if [ $probefail -ne 0 ]; then
         decide_restart_or_failover
   else
         logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
         “${ARGV0} Probe for resource HA-DNS successful”
   fi
done