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 las órdenes 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 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