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.
#!/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
|