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

Método xfnts_start

RGM ejecuta el método Start en un nodo del clúster cuando el grupo de recursos que contiene el recurso del servicio de datos se establece en línea en ese nodo o cuando se inhabilita el recurso. En el tipo de recurso de ejemplo SUNW.xfnts, el método xfnts_start activa el daemon de xfs en ese nodo.

El método xfnts_start llama a scds_pmf_start() para iniciar el daemon bajo el control de PMF. Esta utilidad proporciona funciones de notificación de fallos automática y de reinicio, así como integración con el supervisor de fallos.


Nota –

La primera llamada de xfnts_start va dirigida a scds_initialize (), que realiza algunas funciones de mantenimiento necesarias. Para obtener más información, consulte Función scds_initialize() y la página de comando man scds_initialize(3HA).


Validación del servicio antes de iniciar el servidor de fuentes X

Antes de que el método xfnts_start intente iniciar el servidor de fuentes X, llama a svc_validate() para comprobar que se ha establecido la configuración correcta para admitir el daemon de xfs.

rc = svc_validate(scds_handle);
   if (rc != 0) {
      scds_syslog(LOG_ERR,
          "No se ha podido validar la configuración.");
      return (rc);
   }

Consulte Método xfnts_validate para obtener información.

Inicio del servicio con svc_start()

El método xfnts_start llama al método svc_start(), definido en el archivo xfnts.c, para iniciar el daemon de xfs. Esta sección describe svc_start().

A continuación se muestra el comando que permite iniciar el daemon de xfs:


# xfs -config config-directory/fontserver.cfg -port port-number

La propiedad de extensión Confdir_list identifica el directorio de configuración, config-directory, mientras que la propiedad del sistema Port_list identifica el número de puerto, port-number. El administrador del clúster proporciona valores específicos para estas propiedades al configurar el servicio de datos.

El método xfnts_start declara estas propiedades en forma de matriz de cadenas. El método xfnts_start obtiene los valores establecidos por el administrador del clúster mediante el uso de las funciones scds_get_ext_confdir_list() y scds_get_port_list(). Estas funciones se describen en la página de comando man scds_property_functions(3HA).

scha_str_array_t *confdirs;
scds_port_list_t    *portlist;
scha_err_t   err;

   /* get the configuration directory from the confdir_list property */
   confdirs = scds_get_ext_confdir_list(scds_handle);

   (void) sprintf(xfnts_conf, "%s/fontserver.cfg", confdirs->str_array[0]);

   /* obtain the port to be used by XFS from the Port_list property */
   err = scds_get_port_list(scds_handle, &portlist);
   if (err != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          "Could not access property Port_list.");
      return (1);
   }

Observe que la variable confdirs señala al primer elemento (0) de la matriz.

El método xfnts_start utiliza sprintf() para formar la línea de comandos de xfs.

/* Construct the command to start the xfs daemon. */
   (void) sprintf(cmd,
       "/usr/openwin/bin/xfs -config %s -port %d 2>/dev/null",
       xfnts_conf, portlist->ports[0].port);

Tenga en cuenta que el resultado se redirige a /dev/null para suprimir los mensajes generados por el daemon.

El método xfnts_start pasa la línea de comandos de xfs a scds_pmf_start() para iniciar el servicio de datos bajo el control de PMF.

scds_syslog(LOG_INFO, "Issuing a start request.");
   err = scds_pmf_start(scds_handle, SCDS_PMF_TYPE_SVC,
      SCDS_PMF_SINGLE_INSTANCE, cmd, -1);

   if (err == SCHA_ERR_NOERR) {
      scds_syslog(LOG_INFO,
          "Start command completed successfully.");
   } else {
      scds_syslog(LOG_ERR,
          "Failed to start HA-XFS ");
   }

Tenga en cuenta los siguientes puntos acerca de la llamada a scds_pmf_start():

Antes de volver, svc_pmf_start() libera la memoria asignada para la estructura portlist.

scds_free_port_list(portlist);
return (err);

Devolución de svc_start()

Aunque svc_start() devuelva un mensaje satisfactorio, es posible que la aplicación subyacente no haya podido ejecutarse. Por tanto, svc_start() debe analizar la aplicación para verificar si se está ejecutando antes de devolver un mensaje satisfactorio. El análisis debe tener en cuenta también que la aplicación puede no estar disponible inmediatamente, ya que el proceso de inicio tarda algún tiempo. El método svc_start() llama a svc_wait(), que se define en archivo xfnts.c, para verificar que la aplicación se esté ejecutando.

/* Wait for the service to start up fully */
   scds_syslog_debug(DBG_LEVEL_HIGH,
       "Calling svc_wait to verify that service has started.");

   rc = svc_wait(scds_handle);

   scds_syslog_debug(DBG_LEVEL_HIGH,
       "Returned from svc_wait");

   if (rc == 0) {
      scds_syslog(LOG_INFO, "Successfully started the service.");
   } else {
      scds_syslog(LOG_ERR, "Failed to start the service.");
   }

La función svc_wait() llama a scds_get_netaddr_list () para obtener el recurso de dirección de red necesario para analizar la aplicación.

/* obtain the network resource to use for probing */
   if (scds_get_netaddr_list(scds_handle, &netaddr)) {
      scds_syslog(LOG_ERR,
          "No network address resources found in resource group.");
      return (1);
   }

   /* Return an error if there are no network resources */
   if (netaddr == NULL || netaddr->num_netaddrs == 0) {
      scds_syslog(LOG_ERR,
          "No network address resource in resource group.");
      return (1);
   }

La función svc_wait() obtiene los valores de Start_timeout y Stop_timeout.

svc_start_timeout = scds_get_rs_start_timeout(scds_handle)
   probe_timeout = scds_get_ext_probe_timeout(scds_handle)

Para contabilizar el tiempo que necesita el servidor para iniciarse, svc_wait() llama a scds_svc_wait() y pasa un valor de tiempo de espera equivalente al tres por ciento del valor de Start_timeout. La función svc_wait() llama a svc_probe() para comprobar que la aplicación se ha iniciado. El método svc_probe() realiza una conexión de socket sencilla con el servidor en el puerto especificado. Si no se puede conectar al puerto, svc_probe() devuelve el valor 100, que indica un fallo completo. Si se establece la conexión, pero falla la desconexión del puerto, svc_probe() devuelve el valor 50.

Cuando se produce un fallo parcial o total de svc_probe(), svc_wait() invoca scds_svc_wait() con un valor de tiempo de espera de 5. El método scds_svc_wait() limita la frecuencia de los análisis a cada 5 segundos. Este método cuenta también el número de intentos hechos para iniciar el servicio. Si el número de intentos supera el valor de la propiedad Retry_count del recurso en el periodo especificado en la propiedad Retry_interval , la función scds_svc_wait() devuelve un fallo. En ese caso, la función svc_start() también devuelve un fallo.

#define    SVC_CONNECT_TIMEOUT_PCT    95
#define    SVC_WAIT_PCT       3
   if (scds_svc_wait(scds_handle, (svc_start_timeout * SVC_WAIT_PCT)/100)
      != SCHA_ERR_NOERR) {

      scds_syslog(LOG_ERR, "Service failed to start.");
      return (1);
   }

   do {
      /*
       * probe the data service on the IP address of the
       * network resource and the portname
       */
      rc = svc_probe(scds_handle,
          netaddr->netaddrs[0].hostname,
          netaddr->netaddrs[0].port_proto.port, probe_timeout);
      if (rc == SCHA_ERR_NOERR) {
         /* Success. Free up resources and return */
         scds_free_netaddr_list(netaddr);
         return (0);
      }

       /* Call scds_svc_wait() so that if service fails too
      if (scds_svc_wait(scds_handle, SVC_WAIT_TIME)
         != SCHA_ERR_NOERR) {
         scds_syslog(LOG_ERR, "Service failed to start.");
         return (1);
      }

   /* Rely on RGM to timeout and terminate the program */
   } while (1);

Nota –

Antes de salir, el método xfnts_start llama a scds_close() para reclamar los recursos asignados por scds_initialize (). Para obtener más información, consulte Función scds_initialize() y la página de comando man scds_close(3HA).