Le programme de SONDE vérifie la disponibilité du services de données à l'aide des commandes nslookup( 1M). La méthode de rappel de démarrage_détecteur lance ce programme et la méthode de rappel de démarrage_détecteur l'arrête.
#!/bin/ksh
#pragma ident “@(#)dns_probe 1.1 00/04/19 SMI”
#
# Méthode de détection 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 a
# un problème au niveau du service de données et bascule ce service sur un autre noeud du
# cluster. La détection est réalisée suivant un intervalle spécifique défini par
# INTERVALLE_SONDE_COMPLET 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
# d'Arrêt, puis sa méthode de Démarrage. 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 noeud 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 d'Arrêt et la valeur DÉLAI_ARRÊT de
# cette ressource.
DÉLAI_ARRÊT=`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 de Démarrage et la valeur DÉLAI_DÉMARRAGE
# de cette ressource.
DÉLAI_DÉMARRAGE=`scha_resource_get -O START_TIMEOUT
\
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
MÉTHODE_DÉMARRAGE=`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 noeud 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 noeud 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
# Intervalle_nouvelles_tentatives, tentez de redémarrer le service de données.
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 tentative 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 INTERVALLE_SONDE_COMPLET.
# Obtenez la valeur de cette propriété avec scha_resource_get
INTERVALLE_SONDE=`scha_resource_get -O INTERVALLE_SONDE_COMPLET
-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 DÉLAI_SONDE 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`
DÉLAI_SONDE=`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é RESSOURCES_RÉSEAU_UTILISÉES de la ressource.
HÔTE_DNS=`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é
# Nombre_nouvelles_tentatives définie par le système
NOMBRE_NOUVELLES_TENTATIVES=`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é
# Intervalle_nouvelles_tentatives définie par le système
INTERVALLE_NOUVELLES_TENTATIVES=`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é
# Rép_base_TR du type de ressources.
RÉP_BASE_TR=`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é INTERVALLE_SONDE_COMPLETS. Cependant, définissez la durée
# <INTERVALLE_SONDE_COMPLET> 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 noeud.
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
|