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

Definición de un supervisor de fallos

La aplicación de ejemplo implementa un supervisor básico de fallos para supervisar la fiabilidad del recurso de DNS (in.named). El supervisor de fallos está compuesto por los siguientes elementos:

Funcionamiento del programa de análisis

El programa dns_probe implementa un proceso en ejecución permanente que comprueba que el recurso de DNS controlado por el servicio de datos de ejemplo esté en ejecución. dns_probe se inicia mediante el método dns_monitor_start, ejecutado automáticamente por RGM una vez establecido en línea el servicio de datos de ejemplo. El método dns_monitor_stop, que se ejecuta antes de que RGM ponga fuera de línea el servicio de datos de ejemplo, detiene este servicio.

Esta sección describe los principales fragmentos del método PROBE para la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.

Para conocer la lista completa del método PROBE, consulte Listado de código del programa PROBE .

Comportamiento del programa de análisis

El análisis se ejecuta en un bucle infinito. Utiliza nslookup para comprobar que se está ejecutando el recurso de DNS correcto. Si no se está ejecutando, el análisis permanece inactivo durante un intervalo preestablecido (mediante la propiedad definida por el sistema Thorough_probe_interval) y realiza de nuevo la comprobación. Si DNS no está en ejecución, este programa intenta reiniciarlo localmente o, dependiendo del número de intentos de reinicio, solicita que RGM reubique el servicio de datos en otro nodo.

Obtención de los valores de propiedad

Este programa requiere los valores de las siguientes propiedades:

La función scha_resource_get() obtiene los valores de estas propiedades y los almacena en variables de shell, como se muestra a continuación:

PROBE_INTERVAL=`scha_resource_get -O Thorough_probe_interval \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAME`

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}'`

DNS_HOST=`scha_resource_get -O Network_resources_used -R $RESOURCE_NAME \
-G $RESOURCEGROUP_NAME`

RETRY_COUNT=`scha_resource_get -O Retry_count -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

RETRY_INTERVAL=`scha_resource_get -O Retry_interval -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \
 $RESOURCEGROUP_NAME`

Nota –

Para las propiedades definidas por el sistema, como Thorough_probe_interval , la función scha_resource_get() devuelve sólo el valor. Para las propiedades de extensión, como Probe_timeout, la función scha_resource_get() devuelve el valor y el tipo. Utilice el comando awk para obtener únicamente el valor.


Comprobación de la fiabilidad del servicio

El análisis es en sí mismo un bucle while de los comandos nslookup. Antes del bucle while, se configura un archivo temporal para contener las respuestas de nslookup. Las variables probefail y retries se inicializan en 0.

# Set up a temporary file for the nslookup replies.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

El bucle while realiza las siguientes tareas:

Éste es el código bucle while.

while :
do
   # The interval at which the probe needs to run is specified in the
   # property THOROUGH_PROBE_INTERVAL. Therefore, set the probe to sleep
   # for a duration of THOROUGH_PROBE_INTERVAL.
   sleep $PROBE_INTERVAL

   # Run an nslookup command of the IP address on which DNS is serving.
   hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \
   > $DNSPROBEFILE 2>&1

      retcode=$?
      if [ $retcode -ne 0 ]; then
            probefail=1
      fi

   # Make sure that the reply to nslookup comes from the HA-DNS
   # server and not from another nameserver mentioned in the 
   # /etc/resolv.conf file.
   if [ $probefail -eq 0 ]; then
# Get the name of the server that replied to the nslookup query.
   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

Comparación del reinicio y la recuperación ante fallos

Si la variable probefail tiene un valor diferente a 0 (éxito), se agota el tiempo de espera del comando nslookup o la respuesta proviene de un servidor diferente al servidor de DNS del servicio de ejemplo. En ambos casos, el servidor de DNS no funciona como debería y el supervisor de fallos invoca la función decide_restart_or_failover() para determinar si se debe reiniciar el servicio de datos localmente o solicitar que RGM reubique el servicio de datos en otro nodo. Si la variable probefail es 0, se genera un mensaje en el que se indica que el análisis se ha realizado satisfactoriamente.

   if [ $probefail -ne 0 ]; then
         decide_restart_or_failover
   else
         logger -p ${SYSLOG_FACILITY}.err\
         -t [$SYSLOG_TAG]\
         "${ARGV0} Probe for resource HA-DNS successful"
   fi

La función decide_restart_or_failover() utiliza un intervalo de tiempo (Retry_interval) y un recuento de fallos (Retry_count) para determinar si se debe reiniciar localmente DNS o solicitar que RGM reubique el servicio de datos en un nodo diferente. Esta función implementa la siguiente lógica condicional. El código se incluye en el listado de decide_restart_or_failover() en Listado de código del programa PROBE .

Si el número de reinicios alcanza el límite durante el intervalo de tiempo, la función solicita que RGM reubique el servicio de datos en otro nodo. Si el número de reinicios está dentro del límite o se ha superado el intervalo, por lo que el recuento vuelve a empezar, la función intenta reiniciar DNS en el mismo nodo. Sobre esta función debe tener en cuenta lo siguiente:

Reinicio del servicio de datos

decide_restart_or_failover() llama a la función restart_service() para intentar reiniciar el servicio de datos en el mismo nodo. Esta función ejecuta la siguiente lógica:

function restart_service
{

        # To restart the data service, first verify that the 
        # data service itself is still registered under PMF.
        pmfadm -q $PMF_TAG
        if [[ $? -eq 0 ]]; then
                # Since the TAG for the data service is still registered under
                # PMF, first stop the data service and start it back up again.

                # Obtain the Stop method name and the STOP_TIMEOUT value for
                # this resource.
                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} Stop method failed.”
                        return 1
                fi

                # Obtain the START method name and the START_TIMEOUT value for
                # this resource.
                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} Start method failed.”
                        return 1
                fi


        else
                # The absence of the TAG for the dataservice 
                # implies that the data service has already
                # exceeded the maximum retries allowed under PMF.
                # Therefore, do not attempt to restart the
                # data service again, but try to failover
                # to another node in the cluster.
                scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME \
                        -R $RESOURCE_NAME
        fi

        return 0
}

Estado de salida del análisis

El programa PROBE del servicio de datos sale con errores si fallan los intentos de reinicio local y de recuperación ante fallos en un nodo diferente. Este programa registra un mensaje sobre el fallo del intento de recuperación: Failover attempt failed.

Funcionamiento del método Monitor_start

RGM invoca el método Monitor_start para iniciar el método dns_probe después de que el servicio de datos de ejemplo se ponga en línea.

En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.

Para obtener un listado completo del método Monitor_start, consulte Listado de código del método Monitor_start .

Comportamiento del método Monitor_start

Este método utiliza PMF (pmfadm) para iniciar el análisis.

Inicio del análisis

El método Monitor_start obtiene el valor de la propiedad RT_basedir para construir el nombre completo de la ruta del programa PROBE. Este método inicia el análisis mediante la opción de pmfadm (-n -1, -t -1), que implica que si el análisis no puede iniciarse, PMF intenta iniciarlo un número infinito de veces durante un periodo ilimitado de tiempo.

# Find where the probe program resides by obtaining the value of the
# RT_basedir property of the resource.
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAME`

# Start the probe for the data service under PMF. Use the infinite retries
# option to start the probe. Pass the resource name, type, and group to the
# probe program. 
pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \
   $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME

Funcionamiento del método Monitor_stop

RGM llama al método Monitor_stop para detener la ejecución de dns_probe cuando el servicio de datos de ejemplo se pone fuera de línea.

En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.

Para obtener un listado completo del método Monitor_stop, consulte Listado de código del método Monitor_stop.

Comportamiento del método Monitor_stop

Este método utiliza PMF (pmfadm) para comprobar si el análisis se está ejecutando y, si es así, detenerlo.

Parada del supervisor

El método Monitor_stop utiliza pmfadm -q para ver si el análisis está en ejecución y, si así fuera, utiliza pmfadm -s para detenerlo. Si el análisis ya está detenido, el método sigue saliendo de forma satisfactoria, lo que garantiza la idempotencia del método.


Precaución – Precaución –

Asegúrese de utilizar la señal KILL con pmfadm para detener el análisis y no una señal que pueda ocultarse, como TERM. De lo contrario, el método Monitor_stop puede bloquearse indefinidamente y, al final, se puede agotar el tiempo de espera. El motivo es que el método PROBE llama a scha_control() cuando es necesario reiniciar el servicio de datos o realizar una recuperación ante fallos. Cuando scha_control() llama a Monitor_stop como parte del proceso de establecimiento en línea del servicio de datos, si Monitor_stop utiliza una señal que pueda ocultarse, este método Monitor_stop se bloquea mientras espera que se complete scha_control() y scha_control() se bloquea también a la espera de que se complete Monitor_stop.


# See if the monitor is running, and if so, kill it.
if pmfadm -q $PMF_TAG; then
   pmfadm -s $PMF_TAG KILL
   if [ $? -ne 0 ]; then
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} Could not stop monitor for resource " \
            $RESOURCE_NAME
           exit 1
   else
         # could successfully stop the monitor. Log a message.
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} Monitor for resource " $RESOURCE_NAME \
            " successfully stopped"
   fi
fi
exit 0

Estado de salida de Monitor_stop

El método Monitor_stop registra un mensaje de error si no puede detener el método PROBE. RGM cambia el estado del servicio de datos a MONITOR_FAILED en el nodo principal, lo que puede provocar una situación de emergencia en el nodo.

Monitor_stop no debería salir antes de que se haya detenido el análisis.

Funcionamiento del método Monitor_check

RGM llama al método Monitor_check cuando el método PROBE intenta realizar una recuperación ante fallos del grupo de recursos que contiene el servicio de datos en otro nodo.

En esta sección, se describen las partes más importantes del método Monitor_start de la aplicación de ejemplo, aunque no se describen las funciones comunes a todos los métodos de rellamada como, por ejemplo, la función parse_args(). Esta sección tampoco describe el uso de la función syslog(). Las funciones comunes se describen en Funciones comunes para todos los métodos.

Para obtener un listado completo del método Monitor_check, consulte Listado de código del método Monitor_check .

Debe implementarse el método Monitor_check de tal forma que no entre en conflicto con otros métodos que se estén ejecutando simultáneamente.

El método Monitor_check llama al método Validate para verificar que el directorio de configuración de DNS esté disponible en el nuevo nodo. La propiedad de extensión Confdir señala al directorio de configuración de DNS. Por lo tanto, Monitor_check obtiene el nombre y la ruta del método Validate y el valor de Confdir. Pasa este valor a Validate, como muestra la lista siguiente.

# Obtain the full path for the Validate method from
# the RT_basedir property of the resource type.
RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME \
   -G $RESOURCEGROUP_NAMÈ

# Obtain the name of the Validate method for this resource.
VALIDATE_METHOD=`scha_resource_get -O Validate \
   -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

# Obtain the value of the Confdir property in order to start the
# data service. Use the resource name and the resource group entered to
# obtain the Confdir value set at the time of adding the resource.
config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \
 -G $RESOURCEGROUP_NAME Confdir`

# scha_resource_get returns the type as well as the value for extension
# properties. Use awk to get only the value of the extension property.
CONFIG_DIR=`echo $config_info | awk `{print $2}'`

# Call the validate method so that the dataservice can be failed over
# successfully to the new node.
$RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR

Consulte Funcionamiento del método Validate para comprobar cómo la aplicación de ejemplo comprueba si un nodo es apto para alojar el servicio de datos.