El programa PROBE comprueba la disponibilidad del servicio de datos con las órdenes nslookup(1M). El método de rellamada Monitor_start inicia este programa y el método de rellamada Monitor_start lo detiene.
#!/bin/ksh
#pragma ident “@(#)dns_probe 1.1 00/04/19 SMI”
#
# Método Probe de HA-DNS.
#
# Este programa comprueba la disponibilidad del servicio de datos con nslookup, que
# consulta al servidor de DNS para que busque el propio servidor DNS. Si éste no
# responde o si la consulta la responde otro servidor, el análisis concluye que hay un
# problema con el servicio de datos y realiza una operación de recuperación de
# fallos del servicio a otro nodo del clúster. El análisis se realiza en
# intervalos específicos, determinados por THOROUGH_PROBE_INTERVAL en el archivo RTR.
#pragma ident “@(#)dns_probe 1.1 00/05/24 SMI”
###############################################################################
# Analizar argumentos de programa.
function parse_args # [args ...]
{
typeset opt
while getopts `R:G:T:' opt
do
case “$opt” in
R)
# Nombre del recurso de DNS.
RESOURCE_NAME=$OPTARG
;;
G)
# Nombre del grupo de recursos en el que está
# configurado el recurso.
RESOURCEGROUP_NAME=$OPTARG
;;
T)
# Nombre del tipo de recurso.
RESOURCETYPE_NAME=$OPTARG
;;
*)
logger -p ${SYSLOG_FACILITY}.err \
-t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] \
“ERROR: Opción $OPTARG desconocida”
exit 1
;;
esac
done
}
###############################################################################
# restart_service ()
#
# Esta función intenta reiniciar el servicio de datos invocando el método Stop,
# y el método Start después, del servicio de datos. Si el servicio de datos
# ya se ha terminado y no se ha registrado ninguna etiqueta para el servicio
# de datos en PMF, esta función realiza una operación de recuperación de fallos
# del servicio a otro nodo del clúster.
#
function restart_service
{
# Para reiniciar el servicio de datos, verificar primero que éste
# siga registrado bajo PMF.
pmfadm -q $PMF_TAG
if [[ $? -eq 0 ]]; then
# Dado que TAG para el servicio de datos sigue registrado
# en PMF, detener el servicio de datos y volver a iniciarlo.
# Obtener el nombre del método Stop y el valor de STOP_TIMEOUT
# para este recurso.
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} Método de parada no satisfactorio.”
return 1
fi
# Obtener el nombre del método Start y el valor de START_TIMEOUT
# para este recurso.
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} Método de inicio no satisfactorio.”
return 1
fi
else
# La ausencia de TAG del servicio de datos
# implica que el servicio de datos ya ha superado
# el número máximo de reintentos permitidos en PMF.
# No intentar reiniciar el servicio de datos
# otra vez; intentar realizar una operación de
# recuperación de fallos a otro nodo del clúster.
scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
-R $RESOURCE_NAME
fi
return 0
}
###############################################################################
# decide_restart_or_failover ()
#
# Esta función decide la acción que hay que realizar cuando se produce el fallo
# de un analizador: reiniciar el servicio de datos localmente o realizar una
# recuperación de fallos a otro nodo del clúster.
#
function decide_restart_or_failover
{
# Comprobar si es el primer intento de reinicio.
if [ $retries -eq 0 ]; then
# Es el primer fallo. Observar la hora del
# primer intento.
start_time=`$RT_BASEDIR/gettimè
retries=`expr $retries + 1`
# Dado que es el primer fallo, intentar reiniciar
# el servicio de datos.
restart_service
if [ $? -ne 0 ]; then
logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
“${ARGV0} No se ha podido iniciar el servicio de datos.”
exit 1
fi
else
# No es el primer fallo
current_time=`$RT_BASEDIR/gettimè
time_diff=`expr $current_time - $start_timè
if [ $time_diff -ge $RETRY_INTERVAL ]; then
# Este fallo se ha producido tras la ventana
# de tiempo. Poner a cero el contador de reintentos,
# deslizar la ventana y realizar un reintento.
retries=1
start_time=$current_time
# Dado que el fallo anterior se produjo hace más de
# Retry_interval, intentar reiniciar el servicio de datos.
restart_service
if [ $? -ne 0 ]; then
logger -p ${SYSLOG_FACILITY}.err \
-t [$SYSLOG_TAG
“${ARGV0} No se ha podido reiniciar HA-DNS.”
exit 1
fi
elif [ $retries -ge $RETRY_COUNT ]; then
# Aún dentro de la ventana de tiempo,
# y el contador de reintentos vencido, así que se
# realiza una recuperación de fallos.
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} Intento de recuperación de fallos no satisfactorio.”
exit 1
fi
else
# Aún dentro de la ventana de tiempo,
# y el contador de reintentos no ha vencido,
# así que hacer otro reintento.
retries=`expr $retries + 1`
restart_service
if [ $? -ne 0 ]; then
logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
“${ARGV0} No se ha podido reiniciar HA-DNS.”
exit 1
fi
fi
fi
}
###############################################################################
# MAIN
###############################################################################
export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH
# Obtener el recurso syslog que se debe usar para registrar mensajes.
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`
# Analizar los argumentos que se han pasado a este método
parse_args “$@”
PMF_TAG=$RESOURCE_NAME.named
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME
# El intervalo en el que se debe realizar el análisis se especifica en la propiedad
# THOROUGH_PROBE_INTERVAL. Obtener el valor de esta propiedad con
# scha_resource_get
PROBE_INTERVAL=scha_resource_get -O THOROUGH_PROBE_INTERVAL \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ
# Obtener el valor de tiempo de espera permitido para el análisis, establecido en
# la propiedad de extensión PROBE_TIMEOUT en el archivo RTR. El valor de tiempo
# de espera predeterminado para nslookup es 1,5 minutos.
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}'`
# Identificar el servidor en el que DNS está sirviendo para obtener el valor de
# la propiedad NETWORK_RESOURCES_USED del recurso.
DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ
# Obtener el valor de recuento de reintentos de la propiedad definida por el
# sistema Retry_count
RETRY_COUNT =`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ
# Obtener el valor del intervalo de reintentos de la propiedad definida por el
# sistema Retry_interval
RETRY_INTERVAL=scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ
# Obtener la ruta completa para la utilidad gettime desde la propiedad RT_basedir
# del tipo de recurso.
RT_BASEDIR=scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAMÈ
# El análisis se ejecuta en un bucle infinito, probando las órdenes nslookup.
# Establecer un archivo temporal para las respuestas de nslookup.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0
while :
do
# El intervalo al que debe ejecutarse el analizador se especifica en la
# propiedad THOROUGH_PROBE_INTERVAL. Por tanto, poner el análisis
# en reposo durante el tiempo que indica <THOROUGH_PROBE_INTERVAL>
sleep $PROBE_INTERVAL
# Ejecutar el análisis, que consulta la dirección IP en
# la que sirve el DNS.
hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \
> $DNSPROBEFILE 2>&1
retcode=$?
if [ retcode -ne 0 ]; then
probefail=1
fi
# Asegurarse de que la respuesta a nslookup provenga del servidor
# de HA-DNS y no de otro servidor de nombres mencionado en el
# archivo /etc/resolv.conf.
if [ $probefail -eq 0 ]; then
# Obtener el nombre del servidor que ha respondido a la consulta 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 no se establece la variable probefail en 0, la orden nslookup ha agotado
# el tiempo de espera o la respuesta a la consulta provino de otro servidor
# (especificado en el archivo /etc/resolv.conf). En cualquier caso, el servidor
# de DNS no responde y el método invoca decide_restart_or_failover, que evalúa si
# hay que reiniciar el servicio de datos o realizar un recuperación de fallos
# a otro nodo.
if [ $probefail -ne 0 ]; then
decide_restart_or_failover
else
logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
“${ARGV0} Análisis del recurso HA-DNS satisfactorio”
fi
done
|