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

Apéndice B Listados del código del servicio de datos de ejemplo

Este apéndice proporciona el código completo de cada método en el servicio de datos de ejemplo. Enumera también el contenido del archivo de registro del tipo de recurso.

Este apéndice incluye los siguientes listados de código.

Listado del archivo de registro del tipo de recurso

El archivo RTR (registro de tipo de recurso) contiene las declaraciones de propiedad del recurso y del tipo de recurso que define la configuración inicial del servicio de datos en el momento en que el administrador del clúster registra el servicio de datos.


Ejemplo B–1 Archivo RTR de SUNW.Ejemplo

#
# Copyright (c) 1998-2003 de Sun Microsystems, Inc.
# Reservados todos los derechos.
#
# Información de registro para el Servicio de nombres de dominio (DNS)
#
 
 
#pragma ident   “@(#)SUNW.sample  1.1   00/05/24 SMI”
 
RESOURCE_TYPE = “sample”;
VENDOR_ID = SUNW;
RT_DESCRIPTION = “Servicio de nombres de dominio de Sun Cluster”;
 
RT_VERSION =”1.0”;
API_VERSION = 2;
FAILOVER = TRUE;
 
RT_BASEDIR=/opt/SUNWsampleo/bin;
PKGLIST = SUNWsample;
 
START             = dns_svc_start;
STOP              = dns_svc_stop;
 
VALIDATE          = dns_validate;
UPDATE            = dns_update;
 
MONITOR_START     = dns_monitor_start;
MONITOR_STOP      = dns_monitor_stop;
MONITOR_CHECK     = dns_monitor_check;
 
# Una lista de declaraciones de propiedades de recurso entre llaves
# sigue a las declaraciones del tipo de recurso. La declaración del
# nombre de la propiedad debe ser el primer atributo después de la llave
# de apertura de cada entrada.
#
 
# Las propiedades de <method>_timeout fijan el valor en segundo
# tras el cual RGM determina que la invocación del método no ha
# sido satisfactoria.
 
# El valor MIN para todos los tiempos de espera de métodos es de 60
# segundos. Así se impide que los administradores definan tiempos de
# espera menores, que no mejoran el rendimiento de las operaciones
# de conmutación/recuperación de fallos y pueden provocar acciones
# indeseadas de RGM (recuperaciones de fallos falsas, rearranques de
# nodo o desplazamiento del grupo de recursos a un estado
# ERROR_STOP_FAILED, que requiera la intervención de un operador).
# Definir tiempos de espera demasiado cortos provoca una *disminución*
# de la disponibilidad global del servicio de datos.
{
   PROPERTY = Start_timeout;
   MIN=60;
   DEFAULT=300;
}
 
{
        PROPERTY = Stop_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Validate_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Update_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Monitor_Start_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Monitor_Stop_timeout;
        MIN=60;
        DEFAULT=300;
}
{
        PROPERTY = Thorough_Probe_Interval;
        MIN=1;
        MAX=3600;
        DEFAULT=60;
        TUNABLE = ANYTIME;
}
 
# El número de reintentos que se va a realizar en un determinado
# periodo antes de determinar que la aplicación no se puede iniciar
# satisfactoriamente en este nodo.
{
        PROPERTY = Retry_Count;
        MIN=0;
        MAX=10;
        DEFAULT=2;
        TUNABLE = ANYTIME;
}

# Definir Retry_Interval como múltiplo de 60, porque se convierte de
# segundos a minutos, en un redondeo. Por ejemplo, un valor de 50
# (segundos) se convierte en 1 minuto. Utilizar esta propiedad
# para cronometrar el número de reintentos (Retry_Count).
{
        PROPERTY = Retry_Interval;
        MIN=60;
        MAX=3600;
        DEFAULT=300;
        TUNABLE = ANYTIME;
}
 
{
        PROPERTY = Network_resources_used;
        TUNABLE = AT_CREATION;
        DEFAULT = ““;
}
 
#
# Propiedades de extensión
#
 
#  El administrador del clúster debe definir el valor de esta propiedad para
#  que apunte al directorio que contiene los archivos de configuración
#  que utiliza la aplicación. Para esta aplicación, DNS, la ruta del archivo
#  de configuración de DNS se especifica en PXFS (normalmente
#  named.conf).
{
   PROPERTY = Confdir;
   EXTENSION;
   STRING;
   TUNABLE = AT_CREATION;
   DESCRIPTION = “La ruta al directorio de configuración”;
}
 
# Valor de tiempo de espera en segundos antes de declarar que el
# análisis no ha sido satisfactorio.
{
        PROPERTY = Probe_timeout;
        EXTENSION;
        INT;
        DEFAULT = 30;
        TUNABLE = ANYTIME;
        DESCRIPTION = “Valor del tiempo de espera del análisis (segundos)”;
}

Método Start

RGM invoca el método Start en un nodo del clúster cuando el grupo de recursos que contiene el recurso de servicio de datos se pone en línea en ese nodo o cuando se habilita el recurso. En la aplicación de ejemplo, el método Start activa el daemon in.named (DNS) en ese nodo.


Ejemplo B–2 Método dns_svc_start

#!/bin/ksh
#
# Método Start para HA-DNS.
#
# Este método inicia el servicio de datos bajo control de PMF. Antes de
# empezar el proceso in.named para DNS, realiza ciertas verificaciones de
# estado. La etiqueta de PMF para el servicio de datos es $RESOURCE_NAME.named.
# PMF intenta iniciar el servicio un número especificado de veces (Retry_count)
# y si el número de intentos supera este valor en un intervalo especificado
# (Retry_interval) PMF informa de que se ha producido un fallo al iniciar
# el servicio. Retry_count y Retry_interval son propiedades del recurso
# establecido en el archivo RTR.


#pragma ident   “@(#)dns_svc_start   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 se configura
                        # 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

}




###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que hay que utilizar 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

# Obtener el valor de la propiedad Confdir del recurso para iniciar DNS.
# Con el nombre de recurso y el grupo de recursos introducidos, buscar
# el valor de Confdir fijado por el administrador de clúster 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” de las propiedades de
# extensión. Obtener sólo el valor de la propiedad de extensión.
CONFIG_DIR=`echo $config_info | awk `{print $2}'`

# Comprobar si $CONFIG_DIR es accesible.
if [ ! -d $CONFIG_DIR ]; then
   logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
       “${ARGV0} Directorio $CONFIG_DIR falta o no está montado”
   exit 1
fi

# Cambiar al directorio $CONFIG_DIR en caso de que haya nombres de ruta
# relativos en los archivos de datos.
cd $CONFIG_DIR

# Comprobar que el archivo named.conf esté presente en el directorio $CONFIG_DIR.
if [ ! -s named.conf ]; then
   logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
       “${ARGV0} El archivo $CONFIG_DIR/named.conf falta o está vacío”
   exit 1
fi

# Obtener el valor de Retry_count del archivo RTR.
RETRY_CNT=`scha_resource_get -O Retry_Count -R $RESOURCE_NAME
-G \ $RESOURCEGROUP_NAMÈ

# Obtener el valor de Retry_interval del archivo RTR. Convertir este valor, que
# está en segundos, a minutos para pasarlo a pmfadm. Observar que es una
# conversión con redondeo, por ejemplo, 50 segundos se redondea a un minuto.
((RETRY_INTRVAL = `scha_resource_get -O Retry_Interval
-R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ / 60))

# Iniciar el daemon in.named bajo el control del PMF. Permitir una caída y reiniciar
# hasta $RETRY_COUNT veces en un periodo de $RETRY_INTERVAL; si se cae más a menudo,
# PMF dejará de intentar reiniciarlo. Si  hay un proceso ya registrado con la etiqueta
# <$PMF_TAG>, PMF enviará un mensaje de alerta indicando que el proceso ya está en
# ejecución.
echo “Retry interval is “$RETRY_INTRVAL
pmfadm -c $PMF_TAG.named -n $RETRY_CNT -t $RETRY_INTRVAL \
    /usr/sbin/in.named -c named.conf

# Registrar un mensaje que indique que se ha iniciado HA-DNS.
if [ $? -eq 0 ]; then
   logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]\
           “${ARGV0} HA-DNS iniciado satisfactoriamente”
fi
exit 0
 

Método Stop

El método Stop se invoca en un nodo del clúster cuando el grupo de recursos que contiene el recurso HA-DNS se pone fuera de línea en ese nodo o se inhabilita el recurso. Este método detiene el daemon in.named (DNS) en ese nodo.


Ejemplo B–3 Método dns_svc_stop

#!/bin/ksh
#
# Método Stop para HA-DNS
#
# Detener el servicio de datos con PMF. Si el servicio no está en ejecución
# el método sale con estado 0, porque devolver otro valor pone el recurso
# en estado STOP_FAILED.


#pragma ident   “@(#)dns_svc_stop   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 el recurso
                        # está configurado.
                        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

}


###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog para utilizar mensajes de registro.
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

# Obtener el valor Stop_timeout del archivo RTR.
STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT -R $RESOURCE_NAME
-G \ $RESOURCEGROUP_NAMÈ

# Intentar detener el servicio de datos de forma ordenada con una señal SIGTERM
# mediante PMF. Esperar un 80% del valor de Stop_timeout para ver si SIGTERM
# detiene satisfactoriamente el servicio de datos. Si no es así, enviar SIGKILL
# para detener el servicio de datos. Utilizar hasta un 15% del valor de Stop_timeout
# para ver si SIGKILL tiene éxito. Si no, hay un fallo y el método sale con estado
# diferente de cero. El 5% restante del valor Stop_timeout es para otros usos.
((SMOOTH_TIMEOUT=$STOP_TIMEOUT * 80/100))

((HARD_TIMEOUT=$STOP_TIMEOUT * 15/100))

# Consultar si in.named está en ejecución; si es así, terminarlo.
if pmfadm -q $PMF_TAG.named; then
   # Enviar una señal SIGTERM al servicio de datos y esperar un 80% del
   # valor total del tiempo de espera.
   pmfadm -s $PMF_TAG.named -w $SMOOTH_TIMEOUT TERM
   if [ $? -ne 0 ]; then
      logger -p ${SYSLOG_FACILITY}.info -t [SYSLOG_TAG] \
          “${ARGV0} No se ha podido detener HA-DNS
          con SIGTERM; Reintertarlo con \
          SIGKILL”

      # Dado que el servicio de datos no se ha detenido con una señal SIGTERM,
      # usar SIGKILL ahora y esperar otro 15% del valor del tiempo de espera total.
      pmfadm -s $PMF_TAG.named -w $HARD_TIMEOUT KILL
      if [ $? -ne 0 ]; then
          logger -p ${SYSLOG_FACILITY}.err -t [SYSLOG_TAG]
\
          “${ARGV0} No se ha podido detener HA-DNS;
          Salida NO SATISFACTORIA”

          exit 1
      fi
fi
else
   # El servicio de datos no se está ejecutando actualmente. Registrar
   # un mensaje y salir con resultado satisfactorio.
   logger -p ${SYSLOG_FACILITY}.info -t [SYSLOG_TAG] \
           “HA-DNS no se ha iniciado”

   # Aunque HA-DNS no esté en ejecución, salir con resultado satisfactorio
   # para no poner el recurso del servicio de datos en estado STOP_FAILED.

   exit 0

fi

# Se ha podido detener satisfactoriamente DNS. Registrar un mensaje y salir
# con resultado satisfactorio.
logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
    “HA-DNS se ha detenido satisfactoriamente”
exit 0

Utilidad gettime

La utilidad gettime es un programa en C utilizado por el programa PROBE para realizar un seguimiento del tiempo que pasa entre los reinicios del analizador. Debe compilar este programa y colocarlo en el mismo directorio que los métodos de rellamada, es decir, el directorio al que apunta la propiedad RT_basedir.


Ejemplo B–4 Programa de utilidad gettime.c

#
# Este programa, utilizado por el método de análisis del servicio de datos,
# realiza un seguimiento del tiempo transcurrido, en segundos, desde un
# punto de referencia conocido (hito). Debe compilarse y situarse en el mismo
# directorio que los métodos de rellamada de servicios de datos (RT_basedir).


#pragma ident   “@(#)gettime.c   1.1   00/05/24 SMI”


#include <stdio.h>
#include <sys/types.h>
#include <time.h>

main()
{
    printf(“%d\n”, time(0));
    exit(0);
}

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 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 al 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 los comandos 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, el comando nslookup
   # ha agotado el tiempo de espera o la respuesta a la consulta provino de otro
   # (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

Método Monitor_start

Este método inicia el programa PROBE del servicio de datos.


Ejemplo B–6 Método dns_monitor_start

#!/bin/ksh
#
# Método Monitor start para HA-DNS.
#
# Este método inicia el supervisor (analizador) del servicio de datos
# controlado por PMF. El supervisor es un proceso que analiza el servicio de
# datos a intervalos periódicos y, si hay un problema, lo reinicia en el mismo
# nodo o realiza una operación de recuperación de fallos a otro nodo del clúster.
# La etiqueta de PMF para el supervisor es $RESOURCE_NAME.monitor.


#pragma ident   “@(#)dns_monitor_start   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 DNS.
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # Nombre del grupo de recursos en el que el
                        # recurso se ha configurado.
                        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

}



###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que hay que 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# Buscar dónde reside el método 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 $PMF_TAG.monitor -n -1 -t -1 \
    $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME
\
    -T $RESOURCETYPE_NAME

# Registrar un mensaje que indique que el supervisor de HA-DNS se ha iniciado.
if [ $? -eq 0 ]; then
   logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
           “${ARGV0} Se ha iniciado el supervisor para HA-DNS”
fi
exit 0

Método Monitor_stop

Este método detiene el programa PROBE del servicio de datos.


Ejemplo B–7 Método dns_monitor_stop

#!/bin/ksh
#
# Método Monitor stop para HA-DNS
#
# Detiene el supervisor que se está ejecutando con PMF.


#pragma ident   “@(#)dns_monitor_stop   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 el
                        # recurso se ha configurado.
                        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

}


###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que hay que utilizar 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# Consultar si el supervisor está en ejecución. Si es así, terminarlo.
if pmfadm -q $PMF_TAG.monitor; then
   pmfadm -s $PMF_TAG.monitor 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}.info -t [$SYSLOG_TAG]\
          “${ARGV0} Supervisor del recurso “ $RESOURCE_NAME
\
          “ detenido satisfactoriamente”
   fi
fi

exit 0

Método Monitor_check

Este método verifica la existencia del directorio al que señala la propiedad Confdir. RGM invoca Monitor_check cuando el método PROBE realiza una operación de recuperación de fallos del servicio de datos a un nodo nuevo y para comprobar los nodos que son maestros potenciales.


Ejemplo B–8 Método dns_monitor_check

#!/bin/ksh
#
# Método Monitor check para DNS.
#
# RGM invoca este método cuando el supervisor de fallos realice una recuperación
# de fallos del servicio de datos a un nodo nuevo. Monitor_check invoca el método
# Validate para comprobar si el directorio y los archivos de configuración están
# disponibles en el nuevo nodo.


#pragma ident   “@(#)dns_monitor_check 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 DNS.
      RESOURCE_NAME=$OPTARG
      ;;

      G)
      # Nombre del grupo de recursos en el que se ha 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

}

###############################################################################
# MAIN
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que hay que utilizar 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

# 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. Usar 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

# Registrar un mensaje que indique que la comprobación del supervisor
# ha sido satisfactoria.
if [ $? -eq 0 ]; then
   logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
      “${ARGV0} Comprobación del supervisor para DNS satisfactoria.”
   exit 0
else
   logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] \
      “${ARGV0} Comprobación del supervisor para DNS no satisfactoria.”
   exit 1
fi

Método Validate

Este método verifica la existencia del directorio al que señala la propiedad Confdir. RGM invoca este método cuando se crea el servicio de datos y cuando el administrador del clúster actualiza las propiedades del servicio de datos. El método Monitor_check invoca este método cuando el supervisor de fallos realiza una recuperación de fallos del servicio de datos a otro nodo.


Ejemplo B–9 Método dns_validate

#!/bin/ksh
#
# Método Validate para HA-DNS.
# Este método valida la propiedad Confdir del recurso. El método Validate
# se invoca en dos situaciones: cuando el recurso se está creando y cuando
# se está actualizando una propiedad de recurso. Cuando el recurso se está
# creando, este método se invoca con el indicador -c y todas las propiedades
# definidas por el sistema y de extensión se pasan como argumentos de línea
# de comandos. Cuando se está actualizando una propiedad de recurso, el método
# Validate se invoca con el indicador -u, y sólo el par propiedad-valor de la
# propiedad que se está actualizando se pasa como argumento de línea de comandos.
#
# ej.: cuando el recurso se está creando, los argumentos de comandos serán
#
# dns_validate -c -R <..> -G <...> -T <..> -r <prop-def-sis=valor>...
# -x <prop-extensión=valor>.... -g <prop-grupo-recurso=valor>....
#
# cuando la propiedad de recurso se está actualizando
#
# dns_validate -u -R <..> -G <...> -T <..> -r <prop-sis_actualizando=valor>
#   O
# dns_validate -u -R <..> -G <...> -T <..> -x <prop-exten_actualizando=valor>
#


#pragma ident   “@(#)dns_validate   1.1   00/05/24 SMI”

###############################################################################
# Analizar argumentos de programa.
#
function parse_args # [args ...]
{
   typeset opt

   while getopts `cur:x:g:R:T:G:' opt
   do
                case “$opt” in
                R)
                        # Nombre del recurso de DNS.
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # Nombre del grupo de recursos en el que se ha
                        # configurado el recurso.
                        RESOURCEGROUP_NAME=$OPTARG
                        ;;
                T)
                        # Nombre del tipo de recurso.
                        RESOURCETYPE_NAME=$OPTARG
                        ;;

                r)
                        # El método no está accediendo a ninguna propiedad
                        # definida por el sistema, por lo que no tiene ninguna
                        # operación.
                        ;;

                g)
                        # El método no está accediendo a ninguna propiedad de
                        # grupo de recursos, por lo que no tiene operación.
                        ;;

                c)
                        # Indica que se está invocando el método Validate mientras
                        # se crea el recurso, por lo que el indicador
                        # no tiene ninguna operación.
                        ;;

                u)
                        # Indica la actualización de una propiedad cuando el recurso
                        # ya existe. Si la actualización es de la propiedad Confdir,
                        # Confdir debería aparecer en los argumentos de línea de
                        # comandos. En caso contrario, el método debe buscarlo
                        # específicamente con scha_resource_get.
                        UPDATE_PROPERTY=1
                        ;;

                x)
                        # Lista de propiedades de extensión. Separar los pares de
                        # propiedad valor con “=” como separador.
                        PROPERTY=`echo $OPTARG | awk -F= `{print $1}'`
                        VAL=`echo $OPTARG | awk -F= `{print $2}'`

                        # Si la propiedad de extensión Confdir se encuentra en la
                        # línea de comandos, anotar su valor.
                        if [ $PROPERTY == “Confdir” ];
                        then
                        CONFDIR=$VAL
                        CONFDIR_FOUND=1
                        fi
                        ;;

                *)
                        logger -p ${SYSLOG_FACILITY}.err \
                        -t [$SYSLOG_TAG] \
                        “ERROR: Opción $OPTARG desconocida”
                        exit 1
                        ;;
                esac
   done
}

###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que hay que usar para registrar mensajes.
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY`

# Establecer el valor de CONFDIR en null. Más tarde, este método recupera el
# valor de la propiedad Confdir de la línea de comandos o con scha_resource_get.
CONFDIR=””
UPDATE_PROPERTY=0
CONFDIR_FOUND=0

# Analizar los argumentos que se han pasado a este método.
parse_args “$@”

# Si el método Validate se invoca por una actualización de propiedades
# intentar recuperar el valor de la propiedad de extensión Confdir de línea de
# comandos. Si no, obtener el valor de Confdir con scha_resource_get.
if ( (( $UPDATE_PROPERTY == 1 )) &&  (( CONFDIR_FOUND
== 0 )) ); then
   config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME
\
       -G $RESOURCEGROUP_NAME Confdir`
   CONFDIR=`echo $config_info | awk `{print $2}'`
fi

# Verificar que la propiedad Confdir tiene un valor. En caso contrario,
# hay un fallo y sale con estado 1.
if [[ -z $CONFDIR ]]; then
   logger -p ${SYSLOG_FACILITY}.err \
       “${ARGV0} Método de validar el recurso
       “$RESOURCE_NAME “ no satisfactorio”
   exit 1
fi

# Validar ahora el valor real de la propiedad Confdir.

# Comprobar si $CONFDIR es accesible.
if [ ! -d $CONFDIR ]; then
        logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]\
            “${ARGV0} Directorio $CONFDIR falta o no está montado”
        exit 1
fi

# Comprobar que el archivo named.conf esté presente en el directorio Confdir.
if [ ! -s $CONFDIR/named.conf ]; then
        logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]
\
            “${ARGV0} El archivo $CONFDIR/named.conf falta o está vacío”
        exit 1
fi

# Registrar un mensaje que indique que el método Validate ha sido satisfactorio.
logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG] \
   “${ARGV0} Método de validar para el recurso
   “$RESOURCE_NAME \ se ha completado
   “satisfactoriamente”

exit 0

Método Update

RGM invoca el método Update para notificar a un recurso en ejecución que se han modificado sus propiedades.


Ejemplo B–10 Método dns_update

#!/bin/ksh
#
# Método Update para HA-DNS.
#
# Las actualizaciones reales a las propiedades las realiza RGM. Las
# actualizaciones sólo afectan al supervisor de fallos, por lo que este método
# debe reiniciar el supervisor de fallos.


#pragma ident   “@(#)dns_update   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 DNS.
                        RESOURCE_NAME=$OPTARG
                        ;;
                G)
                        # Nombre del grupo de recursos en el que el
                        # recurso se ha configurado.
                        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

}




###############################################################################
# MAIN
#
##############################################################################

export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH

# Obtener el recurso syslog que se debe utilizar 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.monitor
SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME

# Descubrir dónde reside el método 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È

# Cuando se invoca el método Update, RGM actualiza el valor de la propiedad que
# se está actualizando. Este método debe comprobar si el supervisor de fallos
# (analizador) está en ejecución y, si fuera así, terminarlo y reiniciarlo.
if pmfadm -q $PMF_TAG.monitor; then

   # Terminar el supervisor que se está ejecutando
        pmfadm -s $PMF_TAG.monitor TERM
        if [ $? -ne 0 ]; then
                logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]
\
                    “${ARGV0} No se se puede detener el supervisor”
                exit 1
        else
                # Se ha podido detener satisfactoriamente el DNS.
                # Registrar un mensaje.
                logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]
\
                    “Supervisor para HA-DNS detenido satisfactoriamente”
        fi

   # Reiniciar el supervisor.
   pmfadm -c $PMF_TAG.monitor -n -1 -t -1 $RT_BASEDIR/dns_probe \
      -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME -T $RESOURCETYPE_NAME
   if [ $? -ne 0 ]; then
          logger -p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG]\
                  “${ARGV0} No se ha podido reiniciar el supervisor para HA-DNS “
      exit 1
   else
      logger -p ${SYSLOG_FACILITY}.info -t [$SYSLOG_TAG]\
                    “El supervisor para HA-DNS se ha reiniciado satisfactoriamente”

   fi
fi
exit 0