Este capítulo explica el uso habitual de la Biblioteca de desarrollo del servicio de datos (DSDL) al diseñar e implementar tipos de recursos. Se presta especial atención al diseño de los tipos de recursos para validar la configuración del recurso, así como iniciar, detener y supervisar éste. Además, se describe cómo utilizar DSDL para implementar los métodos de rellamada del tipo de recurso.
Para obtener más información, consulte la página de comando man rt_callbacks(1HA).
Para realizar estas tareas deberá acceder a la configuración de la propiedad del recurso. La utilidad de DSDL scds_initialize() proporciona un método uniforme para acceder a las propiedades de recursos. Esta función esta diseñada para invocarse al principio de los métodos de rellamada; Esta función de la utilidad recupera las propiedades de un recurso de la estructura del clúster y las pone a disposición de la familia de funciones scds_getname().
En este capítulo se tratan los temas siguientes:
El archivo de Registro del tipo de recurso (Resource Type Registration, RTR) especifica información acerca del tipo de recurso en el software de Sun Cluster. Esta información incluye:
Las propiedades necesarias para la implementación
Los tipos de datos y los valores predeterminados de esas propiedades
La ruta del sistema de archivo para los métodos de rellamada de la implementación del tipo de recurso
Diversos valores de configuración para las propiedades definidas por el sistema
El archivo RTR de ejemplo incluido en DSDL es suficiente para la mayoría de las implementaciones de tipos de recursos. Sólo deberá editar algunos elementos básicos como, por ejemplo, el nombre del tipo de recurso y el nombre de ruta de los métodos de rellamada. Si es necesaria una nueva propiedad para implementar el tipo de recurso, puede declararla como propiedad de extensión en el archivo RTR de la implementación del tipo de recurso y acceder a ella mediante la utilidad scds_get_ext_property() de DSDL.
La finalidad del método de rellamada Validate de un tipo de recurso es comprobar que la configuración de recursos propuesta (especificada por la configuración de propiedades propuesta en el recuso) es válida para ese tipo de recurso.
El Gestor de grupos de recursos (RGM) llama al método Validate de una implementación de tipo de recurso si se produce una de las dos situaciones siguientes:
Se está creando un nuevo recurso del tipo de recurso
Se está actualizando una propiedad del recurso o del grupo de recursos
Estas dos situaciones pueden distinguirse por la presencia de la opción de línea de comandos -c (crear) o -u (actualizar), que se pasa al método Validate del recurso.
El método Validate se invoca en cada nodo del conjunto de nodos definido por el valor de la propiedad de tipo de recurso Init_nodes. Si Init_nodes se establece en RG_PRIMARIES , se llama al método Validate en cada nodo que pueda albergar el grupo de recursos (o ser el nodo principal del grupo) que contenga a su vez el recurso. Si Init_nodes se establece en RT_INSTALLED_NODES, se llama al método Validate en cada nodo en el que esté instalado el software del tipo de recurso, normalmente, todos los nodos del clúster.
El valor predeterminado de Init_nodes es RG_PRIMARIES (consulte la página de comando man rt_reg(4)). Al llamar al método Validate, RGM aún no ha creado el recurso (en caso de una rellamada de creación) o no ha aplicado aún los valores actualizados de las propiedades (en caso de una rellamada de actualización)
Si utiliza sistemas de archivos locales administrados por el tipo de recurso HAStoragePlus, puede utilizar la función scds_hasp_check() para comprobar el estado del tipo de recurso. Esta información se obtiene del estado (en línea o no) de todos los recursos de SUNW.HAStoragePlus de los que depende el recurso usando las propiedades de sistema Resource_dependencies o Resource_dependencies_weak definidas para el recurso. Consulte la página de comando man scds_hasp_check(3HA) para obtener una lista completa de los códigos de estado devueltos por la función scds_hasp_check ().
La función DSDL scds_initialize() administra estas situaciones de la siguiente forma:
Si se está creando el recurso, scds_initialize() analiza las propiedades de recursos propuestas a medida que se pasan en la línea de comandos. Por lo tanto, los valores propuestos de las propiedades de recursos están disponibles, aunque el recurso ya se haya creado en el sistema.
Si se está actualizando el recurso o el grupo de recursos, los valores propuestos de las propiedades que el administrador del clúster está actualizando se leen desde la línea de comandos. Las propiedades restantes (cuyos valores no se están actualizando) se leen desde Sun Cluster mediante la API de administración de recursos. SI utiliza DSDL, no es necesario que realice estas tareas. Puede actualizar un recurso como si todas las propiedades del mismo estuvieran disponibles.
Suponga que la función que implementa la validación de las propiedades del recurso se denomina svc_validate() y que utiliza la familia de funciones scds_get_name() para consultar la propiedad que se va a validar. Suponiendo que el código de devolución 0 representa una configuración válida del recurso desde esta función, el siguiente código puede representar, por lo tanto, el método Validate del tipo de recurso:
int main(int argc, char *argv[]) { scds_handle_t handle; int rc; if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR) { return (1); /* Initialization Error */ } rc = svc_validate(handle); scds_close(&handle); return (rc); }
La función de validación debería registrar el motivo por el que ha fallado la validación del recurso. Sin embargo, si descartamos ese detalle (el Capítulo 8, Ejemplo de implementación del tipo de recurso con DSDL describe de forma más realista la función de validación), puede implementar una función svc_validate() de ejemplo más sencilla de la siguiente forma:
int svc_validate(scds_handle_t handle) { scha_str_array_t *confdirs; struct stat statbuf; confdirs = scds_get_confdir_list(handle); if (stat(confdirs->str_array[0], &statbuf) == -1) { return (1); /* Invalid resource property setting */ } return (0); /* Acceptable setting */ }
Por consiguiente, debe centrarse únicamente en la implementación de la función svc_validate().
RGM invoca el método de rellamada Start de una implementación de tipo de recursos en un nodo del clúster seleccionado para iniciar el recurso. En la línea de comandos se pasan los nombres del grupo de recurso, del recurso y del tipo de recurso. El método Start realiza las acciones necesarias para iniciar un recurso del servicio de datos en el nodo del clúster. Normalmente, este proceso requiere la recuperación de las propiedades de recursos, la búsqueda del archivo ejecutable o los archivos de configuración específicos de la aplicación, o ambos, así como el inicio de la aplicación con los argumentos de línea de comandos correctos.
Con DSDL, la configuración del recurso se recupera con la utilidad scds_initialize(). La acción de inicio de la aplicación se puede contener en una función svc_start(). Se puede llamar a otra función, svc_wait(), para verificar que la aplicación se inicie realmente. El código simplificado del método Start es el siguiente:
int main(int argc, char *argv[]) { scds_handle_t handle; if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR) { return (1); /* Initialization Error */ } if (svc_validate(handle) != 0) { return (1); /* Invalid settings */ } if (svc_start(handle) != 0) { return (1); /* Start failed */ } return (svc_wait(handle)); }
Esta implementación de método de inicio llama a svc_validate() para validar la configuración del recurso. Si falla, es posible que no coincidan la configuración del recurso y la de la aplicación o que haya actualmente un problema en este nodo del clúster en relación con el sistema. Por ejemplo, es posible que no esté disponible actualmente el sistema de archivos del clúster necesario para el recurso en este nodo de clúster. En ese caso, es inútil intentar iniciar el recurso en este nodo del clúster; es mejor que RGM intente iniciar el recurso en otro nodo.
No obstante, tenga en cuenta que la afirmación anterior presupone que svc_validate () presenta un comportamiento lo suficientemente moderado, comprobando únicamente los recursos del nodo del clúster que son absolutamente necesarios para la aplicación. De lo contrario, es posible que el recurso no puede iniciarse en todos los nodos del clúster y, por consiguiente, presente el estado START_FAILED. Consulte la página de comando man scswitch(1M) y Sun Cluster Data Services Planning and Administration Guide for Solaris OS para obtener más información sobre este estado.
La función svc_start() debe devolver 0 para que el inicio del recurso en el nodo sea satisfactorio. Si la función de inicio encuentra un problema, debe devolver un valor distinto a 0. Si esta función falla, RGM intenta iniciar el recurso en otro nodo del clúster.
Para sacar el mayor provecho posible de DSDL, la función svc_start() puede llamar a la utilidad scds_pmf_start() para iniciar la aplicación bajo el control de la Utilidad de supervisor de procesos (PMF). Esta utilidad emplea también la acción de función de rellamada de PMF para detectar fallos en los procesos. Consulte la descripción del argumento de acción - a en la página de comando man pmfadm(1M) para obtener más información.
RGM invoca el método de rellamada Stop de una implementación del tipo de recurso en un nodo del clúster para detener la aplicación. La semántica de rellamada del método Stop requiere los siguientes factores:
El método Stop ha de ser idempotent, ya que RGM lo puede invocar aun cuando el método Start no se haya completado satisfactoriamente en el nodo. De esta manera, el método Stop debe completarse con éxito (resultado cero), aunque la aplicación no se esté ejecutando actualmente en el nodo del clúster y no haya ningún acción que realizar.
Si el método Stop del tipo de recurso falla (resultado distinto a cero) en un nodo del clúster, el recurso que se va a detener presentará el estado STOP_FAILED. En función de la configuración de Failover_mode en el recurso, es posible que esta condición provoque que RGM realice un reinicio completo del nodo del clúster.
Por lo tanto, debe diseñar el método Stop para que detenga la aplicación por completo. Es posible que deba utilizar SIGKILL para desactivar la aplicación abruptamente en caso de que no se pueda finalizar.
Debe también asegurarse de que este método detenga la aplicación de forma oportuna, ya que la estructura considera el tiempo de caducidad indicado en la propiedad Stop_timeout como un error del proceso de parada y, por lo tanto, establece el recurso en el estado STOP_FAILED.
La utilidad scds_pmf_stop() de DSDL debería bastar para la mayoría de las aplicaciones, ya que, en primer lugar, intenta detener con cautela la aplicación mediante SIGTERM . Esta función envía a continuación SIGKILL al proceso. Esta función supone que la aplicación se ha iniciado bajo el control de PMF con scds_pmf_start(). Consulte Funciones de PMF para obtener información sobre esta utilidad.
Suponiendo que la función que detiene la aplicación se denomina svc_stop(), implemente el método Stop de la siguiente forma:
if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR) { return (1); /* Initialization Error */ } return (svc_stop(handle));
No es relevante que la implementación de la funicón svc_stop() anterior incluya o no la función scds_pmf_stop(). La inclusión (o no) de la función scds_pmf_stop() depende de si la aplicación se ha iniciado bajo el control de PMF mediante el método Start.
El métodosvc_validate() no se utiliza en la implementación del método Stop porque, aunque el sistema esté experimentando actualmente problemas, este último método debería intentar detener la aplicación en este nodo.
RGM llama al método Monitor_start para iniciar el supervisor de fallos del recurso. El supervisor de fallos supervisa el estado de la aplicación administrada por el recurso. Las implementaciones de tipos de recursos utilizan normalmente el supervisor de fallos como daemon independiente que se ejecuta en segundo plano. El método de rellamada Monitor_start se utiliza para iniciar este daemon con los argumentos correctos.
Como el daemon del supervisor es propenso a presentar fallos (por ejemplo, podría desactivarse y dejar a la aplicación sin supervisión), debería utilizar PMF para iniciarlo. La utilidad scds_pmf_start() de DSDL disponde de compatibilidad integrada para iniciar los supervisores de fallos. Esta utilidad emplea el nombre de ruta relativo a RT_basedir para conocer la ubicación de las implementaciones de métodos de rellamada del tipo de recurso del programa del supervisor. También utiliza las propiedades de extensión Monitor_retry_interval y Monitor_retry_count administradas por DSDL para impedir que se realice un número ilimitado de reinicios del daemon.
Esta utilidad impone también la misma sintaxis de línea de comandos que se ha definido para todos los métodos de rellamada (es decir, -R resource -G resource-group -T resource-type) en el daemon del supervisor, aunque RGM nunca haya llamado al daemon directamente. Por último, esta utilidad permite también que la propia implementación del daemon del supervisor habilite la utilidad scds_initialize() para configurar su propio entorno. El esfuerzo principal se destina a diseñar el propio daemon del supervisor.
RGM llama al método Monitor_stop para detener el daemon del supervisor de fallos iniciado con el método Monitor_start. Un fallo de este método de rellamada se trata exactamente igual que un fallo del método Stop; por tanto, el método Monitor_stop debe ser idempotente y robusto, como el método Stop.
Si emplea scds_pmf_start() para iniciar el daemon del supervisor de fallos, utilice scds_pmf_stop() para detenerlo.
RGM ejecuta el método de rellamada Monitor_check en un recurso de un nodo para averiguar si el nodo del clúster es capaz de controlar el recurso. En otras palabras, RGM ejecuta este método para determinar si la aplicación administrada por el recurso puede ejecutarse satisfactoriamente en el nodo.
Normalmente, en esta situación, es necesario asegurarse de que los recursos del sistema necesarios para la aplicación estén realmente disponibles en el nodo del clúster. Como se indica en Método Validate, la función svc_validate() implementada está diseñada para comprobar como mínimo esta situación.
En función de la aplicación específica que esté siendo administrada por la implementación del tipo de recurso, puede escribirse el método Monitor_check para que realice tareas adicionales. 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. Si utiliza DSDL, el método Monitor_check debería llamar a la función svc_validate(), que implementa la validación de las propiedades de recursos específica de la aplicación.
RGM llama al método Update de una implementación del tipo de recurso para aplicar cualquier cambio realizado por el administrador del clúster en la configuración del recurso activo. El método Update sólo se invoca en los nodos en los que el recurso está en línea en este momento (si los hubiera).
Para que los cambios que acaban de realizarse en la configuración del recurso se consideren aceptables para la implementación del tipo de recurso, el método Validate debe ejecutarse antes que el método Update . Se llama al método Validate antes de que se modifiquen las propiedades del grupo de recursos; este método pueda vetar los cambios propuestos. El método Update se invoca después de que los cambios se hayan aplicado para darle al recurso activo (en línea) la oportunidad de notar los nuevos valores.
Debe determinar atentamente las propiedades que desea que se actualicen dinámicamente y marcarlas con el valor TUNABLE = ANYTIME en el archivo RTR. Puede especificar normalmente que desea poder actualizar dinámicamente las propiedades de la implementación del tipo de recurso que utiliza el daemon del supervisor de fallos. Sin embargo, la implementación del método Update debe reiniciar como mínimo el daemon del supervisor.
Entre las propiedades que puede utilizar, se incluyen:
Thorough_probe_interval
Retry_count
Retry_interval
Monitor_retry_count
Monitor_retry_interval
Probe_timeout
Estas propiedades afectan al modo en que el daemon del supervisor de fallos comprueba el estado del servicio, la frecuencia con la que el daemon realiza estas comprobaciones, al intervalo del historial utilizado por el daemon para realizar un seguimiento de los errores y a los umbrales de reinicio establecidos por PMF. Para implementar las actualizaciones de estas propiedades se incluye la utilidad scds_pmf_restart() en DSDL.
SI necesita poder actualizar dinámicamente una propiedad de recurso, pero es posible que la modificación de esa propiedad afecte a la aplicación que se está ejecutando, debe implementar las acciones correctas. Debe asegurarse de que las actualizaciones de esa propiedad se hayan aplicado correctamente a todas las instancias de la aplicación que se están ejecutando. Actualmente, no puede utilizar DSDL para actualizar dinámicamente una propiedad de recurso de esta forma. No se pueden pasar las propiedades modificadas a Update en la línea de comandos (como se hace con Validate).
Son métodos de acción única, como se indica en las especificaciones de la API de administración de recursos. La implementación de ejemplo que se incluye con DSDL no ilustra la utilización de estos métodos. Sin embargo, todas las utilidades de DSDL están disponibles también para estos métodos en caso de necesitarlos. Generalmente, los métodos Init y Boot serán exactamente iguales que los de una implementación del tipo de recurso para implementar una acción única. El método Fini realizará normalmente una acción que deshaga la acción de los métodos Init o Boot.
Las implementaciones de tipos de recursos que utilizan DSDL disponen generalmente de un daemon del supervisor de fallos que lleva a cabo las siguientes acciones:
Supervisa periódicamente el estado de la aplicación que se está administrando. La responsabilidad específica de un daemon del supervisor depende en gran medida de la aplicación y puede variar sustancialmente de un tipo de recurso a otro. DSDL contiene algunas funciones de utilidad integradas que realizan comprobaciones de estado de los servicios basados en TCP. Puede emplear estas utilidades para implementar aplicaciones que utilicen protocolos basados en ASCII como, por ejemplo, HTTP, NNTP, IMAP y POP3.
Realiza un seguimiento de los problemas detectados por la aplicación mediante el uso de las propiedades de recursos Retry_interval y Retry_count . Si falla por completo la aplicación, el supervisor de fallos debe determinar si la secuencia de acción de PMF debe reiniciar el servicio o si los fallos de la aplicación se han acumulado de forma tan rápida que es necesario realizar una recuperación ante fallos. Las utilidades scds_fm_action() y scds_fm_sleep() de DSDL están diseñadas para ayudarle en la implementación de este mecanismo.
Lleva a cabo acciones, normalmente el reinicio de una aplicación o una recuperación ante fallos del grupo de recursos. La utilidad scds_fm_action () de DSDL implementa este algoritmo. Esta utilidad calcula la acumulación actual de fallos de análisis durante los segundos indicados en Retry_interval para este fin.
Actualiza el estado del recurso con el fin de que el estado de la aplicación esté disponible para el comando scstat, así como para la GUI de administración del clúster.
Las utilidades de DSDL están diseñadas para que el seudocódigo incluido al final de esta sección pueda representar al bucle principal del daemon del supervisor de fallos.
Tenga en cuenta los siguientes factores al implementar un supervisor de fallos con DSDL:
scds_fm_sleep() detecta rápidamente la inactividad de un proceso de la aplicación porque la notificación sobre esta condición que se realiza mediante PMF es asíncrona. Por lo tanto, se reduce de forma significativa el tiempo de detección de fallos, aumentando de esta forma la disponibilidad del servicio. También es posible que se active un supervisor de fallos con la suficiente frecuencia como para comprobar el estado de un servicio y descubir que el proceso se encuentra inactivo.
Si RGM rechaza el intento de realizar una recuperación ante fallos del servicio con la API de scha_control, scds_fm_action() restablecerá, o simplemente olvidará, el historial de fallos actual. Esta función restablece el historial de fallos actual porque éste supera el valor de Retry_count. Si, en la ocasión siguiente, el daemon del supervisor se activa y es incapaz de completar satisfactoriamente la comprobación de estado, intentará de nuevo llamar a la función scha_control(). Es muy probable que esta llamada sea rechazada una vez más, ya que la situación que provocaba el rechazo en la ocasión anterior aún está vigente. Al restablecer el historial, se garantiza que el supervisor de fallos intentará al menos corregir la situación de forma local (por ejemplo, mediante el restablecimiento de la aplicación) la próxima vez.
scds_fm_action() no restablece el historial de fallos de la aplicación en caso de producirse fallos de reinicio, ya que, por lo general, es recomendable emitir rápidamente la función scha_control() si la situación no se soluciona automáticamente.
La utilidad scds_fm_action() actualiza el estado del recurso a SCHA_RSSTATUS_OK, SCHA_RSSTATUS_DEGRADED o SCHA_RSSTATUS_FAULTED en función del historial de fallos. Por lo tanto, este estado está disponible para la administración del sistema de clúster.
En la mayoría de los casos, se puede implementar una comprobación de estado de la aplicación en una utilidad independiente (por ejemplo, svc_probe()). Puede integrarla en el siguiente bucle principal genérico.
for (;;) { /* sleep for a duration of thorough_probe_interval between * successive probes. */ (void) scds_fm_sleep(scds_handle, scds_get_rs_thorough_probe_interval(scds_handle)); /* Now probe all ipaddress we use. Loop over * 1. All net resources we use. * 2. All ipaddresses in a given resource. * For each of the ipaddress that is probed, * compute the failure history. */ probe_result = 0; /* Iterate through the all resources to get each * IP address to use for calling svc_probe() */ for (ip = 0; ip < netaddr->num_netaddrs; ip++) { /* Grab the hostname and port on which the * health has to be monitored. */ hostname = netaddr->netaddrs[ip].hostname; port = netaddr->netaddrs[ip].port_proto.port; /* * HA-XFS supports only one port and * hence obtaint the port value from the * first entry in the array of ports. */ ht1 = gethrtime(); /* Latch probe start time */ probe_result = svc_probe(scds_handle, hostname, port, timeout); /* * Update service probe history, * take action if necessary. * Latch probe end time. */ ht2 = gethrtime(); /* Convert to milliseconds */ dt = (ulong_t)((ht2 - ht1) / 1e6); /* * Compute failure history and take * action if needed */ (void) scds_fm_action(scds_handle, probe_result, (long)dt); } /* Each net resource */ } /* Keep probing forever */