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 |