Sun Cluster 3.1 10/03: Guía del desarrollador de los servicios de datos

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 se compone de:

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 lo ejecuta el método dns_monitor_start, invocado automáticamente por RGM una vez el servicio de datos de ejemplo se ha puesto en línea. El servicio de datos lo detiene el método dns_monitor_stop, invocado por RGM antes de que el servicio de datos de ejemplo esté fuera de línea.

Esta sección describe los principales fragmentos del método PROBE para la aplicación de ejemplo, pero no las funciones comunes a todos los métodos de rellamada, como la función parse_args() ni la obtención del recurso syslog; éstos describen en Funciones comunes para todos los métodos.

Para obtener una lista completa del método PROBE, consulte Programa PROBE.

Información general 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 éste está en ejecución, el análisis reposa durante un intervalo establecido (que establece la propiedad definida por el sistema Thorough_probe_interval) y luego realiza otra 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 necesita los valores de las propiedades siguientes:

La función scha_resource_get() obtiene los valores de estas propiedades y los guarda en variables del shell, como se indica a continuación.

PROBE_INTERVAL=`scha_resource_get -O THOROUGH_PROBE_INTERVAL \
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

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_NAMÈ

RETRY_COUNT=`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME
-G\
 $RESOURCEGROUP_NAMÈ

RETRY_INTERVAL=`scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME
-G\
 $RESOURCEGROUP_NAMÈ

RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G\
 $RESOURCEGROUP_NAMÈ


Nota –

En el caso de propiedades definidas por el sistema, como Thorough_probe_interval, scha_resource_get() sólo devuelve el valor. En el caso de propiedades de extensión, como Probe_timeout, scha_resource_get() devuelve tanto el tipo como el valor. Utilice el comando awk para obtener sólo el valor.


Comprobación de la fiabilidad del servicio

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


# Configurar un archivo temporal para las respuestas de nslookup.
DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe
probefail=0
retries=0

El propio bucle while:

Éste es el código bucle while.


while :
do
   # El intervalo al que se debe ejecutar el análisis se especifica en la
   # propiedad THOROUGH_PROBE_INTERVAL. Por tanto, establecer el análisis en
   # reposo durante el tiempo que indica THOROUGH_PROBE_INTERVAL.
   sleep $PROBE_INTERVAL

   # Ejecutar un comando nslookup de la dirección IP en la que sirve 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

Evaluación de reinicio frente a recuperación de fallos

Si la variable probefail es distinta de 0 (satisfactorio), significa que el comando nslookup agotó el tiempo de espera o que la respuesta ha provenido de un servidor diferente 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 que indica que el análisis ha sido satisfactorio.


   if [ $probefail -ne 0 ]; then
         decide_restart_or_failover
   else
         logger -p ${SYSLOG_FACILITY}.err\
         -t [$SYSLOG_TAG]\
         "${ARGV0} Análisis del recurso HA-DNS satisfactorio"
   fi

La función decide_restart_or_failover() utiliza una ventana de tiempo (Retry_interval) y un recuento de fallos (Retry_count) para determinar si debe reiniciar el DNS localmente o solicitar que RGM reubique el servicio de datos en otro nodo. Implementa el siguiente código condicional (consulte la lista de códigos para decide_restart_or_failover() en 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

La función restart_service() la invoca decide_restart_or_failover() para intentar reiniciar el servicio de datos en el mismo nodo. Esta función realiza lo siguiente:


function restart_service
{

        # Para reiniciar el servicio de datos, comprobar primero que
        # éste siga registrado en 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 para el 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
}

Consultar el estado de salida

El programa PROBE del servicio de datos de ejemplo sale con un fallo si los intentos de reinicio local han fallado y el intento de realizar una recuperación de fallos a otro nodo también. Registra el mensaje “Intento de recuperación de fallos no satisfactorio”.

Método Monitor_start

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

Esta sección describe los principales fragmentos del método Monitor_start para la aplicación de ejemplo, pero no las funciones comunes a todos los métodos de rellamada, como la función parse_args() ni la obtención del recurso syslog; éstos describen en Funciones comunes para todos los métodos.

Para una lista completa del método Monitor_start, consulte Método Monitor_start.

Información general de Monitor_start

Este método utiliza el recurso del supervisor de procesos (pmfadm) para ejecutar 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 ejecuta el análisis con la opción de reintentos infinitos de pmfadm (-n -1, -t -1), lo que significa que si el análisis no se inicia, PMF intenta iniciarlo un número infinito de veces durante un periodo de tiempo infinito.


# Buscar dónde reside el programa de análisis mediante la obtención
# del valor de la propiedad RT_BASEDIR del recurso.
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G \
$RESOURCEGROUP_NAMÈ

# Iniciar el análisis del servicio de datos en PMF. Utilizar la opción de reintentos
# infinitos para iniciar el análisis. Pasar el nombre de recurso, tipo y grupo al
# programa de análisis.
pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 \
   $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME

Método Monitor_stop

RGM invoca el 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.

Esta sección describe los principales fragmentos del método Monitor_stop para la aplicación de ejemplo, pero no las funciones comunes a todos los métodos de rellamada, como la función parse_args() ni la obtención del recurso syslog; éstos describen en Funciones comunes para todos los métodos.

Para una lista completa del método Monitor_stop, consulte Método Monitor_stop.

Información general de Monitor_stop

Este método utiliza el recurso del supervisor de procesos (pmfadm) para ver si el análisis está en ejecución y, en caso de que lo esté, 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.


# Consultar si el supervisor está en ejecución. Si es así, terminarlo.
if pmfadm -q $PMF_TAG; then
   pmfadm -s $PMF_TAG KILL
   if [ $? -ne 0 ]; then
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} No se puede detener el supervisor del recurso " \
            $RESOURCE_NAME
           exit 1
   else
         # se ha detenido satisfactoriamente el supervisor. Registrar un mensaje.
         logger -p ${SYSLOG_FACILITY}.err \
            -t [$SYSLOG_TAG] \
            "${ARGV0} Supervisor del recurso " $RESOURCE_NAME \
            " detenido satisfactoriamente"
   fi
fi
exit 0


Precaución – Precaución –

Asegúrese de usar la señal de KILL con pmfadm para detener el análisis y no una señal enmascarable, como TERM. En caso contrario, el método Monitor_stop puede quedar indefinidamente bloqueado hasta agotar el tiempo de espera. El motivo de este problema es que el método PROBE invoca scha_control() cuando hay que reiniciar o realizar una operación de recuperación de fallos del servicio de datos. Cuando scha_control() invoca Monitor_stop dentro del proceso de poner el servicio de datos fuera de línea, si Monitor_stop utiliza una señal enmascarable, se queda bloqueado esperando que scha_control() finalice y scha_control() se bloquea, esperando que Monitor_stop termine.


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 pone el servicio de datos de ejemplo en el estado MONITOR_FAILED en el nodo primario, lo que puede enviar un aviso grave al nodo.

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

Método Monitor_check

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

Esta sección describe los fragmentos principales del método Monitor_check para la aplicación de ejemplo, pero no las funciones comunes a todos los métodos de rellamada, como la función parse_args() ni la obtención del recurso syslog; éstos describen en Funciones comunes para todos los métodos.

Para una lista completa del método Monitor_check, consulte Método Monitor_check.

El método Monitor_check se debe implementar de forma que no entre en conflicto con la ejecución simultánea de otro método.

El método Monitor_check invoca el 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 apunta al directorio de configuración de DNS. Por tanto, Monitor_check obtiene la ruta y el nombre del método Validate y el valor de Confdir. Pasa este valor a Validate, como muestra la lista siguiente.


# Obtener la ruta completa del método Validate desde
# la propiedad RT_BASEDIR del tipo de recurso.
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME \
   -G $RESOURCEGROUP_NAMÈ

# Obtener el nombre del método Validate para este recurso.
VALIDATE_METHOD=`scha_resource_get -O VALIDATE \
   -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ

# Obtener el valor de la propiedad Confdir para iniciar el
# servicio de datos. Utilizar el nombre de recurso y grupo de recursos introducidos
# para obtener el valor Confdir establecido al agregar el recurso.
config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \
 -G $RESOURCEGROUP_NAME Confdir`

# scha_resource_get devuelve el tipo y el valor para las propiedades de
# extensión. Utilizar awk para obtener sólo el valor de la propiedad de extensión.
CONFIG_DIR=`echo $config_info | awk `{print $2}'`

# Invocar el método validate para que el servicio de datos se pueda
# recuperar de un fallo a otro nodo satisfactoriamente.
$RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME \
   -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR

Consulte Método Validate para ver cómo verifica la aplicación de ejemplo la adecuación de un nodo para alojar el servicio de datos.