Sun Cluster: Guía del desarrollador de los servicios de datos del sistema operativo Solaris

Programa PROBE

El programa PROBE comprueba la disponibilidad del servicio de datos con los comandos nslookup( 1M) . El método de rellamada Monitor_start inicia este programa y el método de rellamada Monitor_start lo detiene.


Ejemplo B–5 Programa dns_probe

#!/bin/ksh
#pragma ident   “@(#)dns_probe   1.1   00/04/19 SMI”
#
# Método Probe para 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