Guide des développeurs pour les services de données Sun Cluster pour SE Solaris

Méthode xfnts_start

Le RGM appelle la méthode Start sur un nœud du cluster lorsque le groupe contenant la ressource du service de données est mis en ligne sur ce nœud ou lorsque la ressource est activée. Dans le type de ressource modèle SUNW.xfnts, la méthode xfnts_start active le démon xfs sur ce nœud.

La méthode xfnts_start appelle scds_pmf_start () pour démarrer le démon sous le gestionnaire de processus. Celui-ci propose une notification automatique des pannes ainsi que des fonctions de redémarrage, de même qu'une intégration avec le détecteur de pannes.


Remarque –

le premier appel dans xfnts_start est destiné à scds_initialize() qui effectue certaines fonctions de gestion interne nécessaires (les pages Fonction scds_initialize() et scds_initialize(3HA) du manuel contiennent plus de détails).


Validation du service avant démarrage

Avant de tenter de démarrer le serveur de polices X, la méthode xfnts_start appelle svc_validate() pour vérifier si une configuration correcte est en place pour prendre en charge le démon xfs (reportez-vous à la rubrique Méthode xfnts_validate pour de plus amples informations), de la manière suivante :


rc = svc_validate(scds_handle);
   if (rc != 0) {
      scds_syslog(LOG_ERR,
          "Failed to validate configuration.");
      return (rc);
   }

Démarrage du service

La méthode xfnts_start appelle la méthode svc_start(), définie dans xfnts.c pour démarrer le démon xfs. Cette rubrique décrit svc_start().

La commande permettant de lancer le démon xfs est la suivante :


xfs -config répertoire_config/fontserver.cfg -port  numéro_port

La propriété d'extension Confdir_list identifie le répertoire_config alors que la propriété système Port_list identifie le numéro_port. Lorsque l'administrateur du cluster configure le service de données, il fournit des valeurs spécifiques pour ces propriétés.

La méthode xfnts_start déclare ces propriétés comme tableaux de chaînes et obtient les valeurs définies par l'administrateur à l'aide des fonctions scds_get_ext_confdir_list() et scds_get_port_list() (décrites dans scds_property_functions(3HA)), de la manière suivante :


scha_str_array_t *confdirs;
scds_port_list_t    *portlist;
scha_err_t   err;

   /* obtention du répertoire de configuration depuis la propriété Confdir_list */
   confdirs = scds_get_ext_confdir_list(scds_handle);

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

   /* obtention du port à utiliser par XFS depuis la propriété Liste_port */
   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);
   }

Remarquez que la variable confdirs pointe vers le premier élément (0) du tableau.

La méthode xfnts_start utilise sprintf pour former la ligne de commande pour xfs de la manière suivante :


/* Construction de la commande pour démarrer le démon xfs. */ 
(void) sprintf(cmd, 
"/usr/openwin/bin/xfs -config %s -port %d 2>/dev/null", xfnts_conf, portlist->ports[0].port);

Remarquez que la sortie est redirigée vers dev/null pour supprimer les messages générés par le démon.

La méthode xfnts_start transmet la ligne de commande xfs à scds_pmf_start() pour démarrer le service de données sous le contrôle du gestionnaire de processus, de la manière suivante :


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 ");
   }

Tenez compte des points suivants concernant l'appel vers scds_pmf_start () :

Avant son retour, svc_pmf_start() libère la mémoire allouée à la structure portlist, de la manière suivante :


scds_free_port_list(portlist); return (err);

Retour de svc_start()

Même lorsque svc_start() renvoie une réussite, il est possible que l'application sous-jacente n'arrive pas à démarrer. svc_start() doit donc sonder l'application afin de vérifier qu'elle fonctionne avant de renvoyer un message de réussite. La sonde doit tenir compte du fait que l'application peut ne pas être immédiatement disponible parce que son démarrage prend un certain temps. La méthode svc_start() appelle svc_wait(), définie dans xfnts.c, pour vérifier si l'application tourne, de la manière suivante :


/* Attendre que le service ait complètement démarré */ 
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 fonction svc_wait() appelle scds_get_netaddr_list(3HA) pour obtenir les ressources d'adresses réseau nécessaires pour sonder l'application, de la manière suivante :


/* Obtention de la ressource réseau à utiliser pour le sondage */
   if (scds_get_netaddr_list(scds_handle, &netaddr)) {
      scds_syslog(LOG_ERR,
          "No network address resources found in resource group.");
      return (1);
   }

   /* Renvoi d'une erreur en l'absence de ressources réseau */
   if (netaddr == NULL || netaddr->num_netaddrs == 0) {
      scds_syslog(LOG_ERR,
          "No network address resource in resource group.");
      return (1);
   }

Ensuite, svc_wait() obtient les valeurs de start_timeout et de stop_timeout de la manière suivante :


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

Pour tenir compte du délai nécessaire au serveur pour démarrer, svc_wait() appelle scds_svc_wait() et transmet une valeur de délai imparti équivalant à trois pourcent de la valeur de start_timeout. Ensuite, svc_wait() appelle svc_probe() pour vérifier que l'application a démarré. La méthode svc_probe() établit une connexion de socket simple au serveur sur le port spécifié. En cas d'échec de la connexion au port, svc_probe() renvoie une valeur de 100, indiquant un échec total. Si la connexion s'établit mais que la déconnexion du port échoue, svc_probe() renvoie une valeur de 50.

En cas d'échec total ou partiel de svc_probe(), svc_wait() appelle scds_svc_wait() avec un délai imparti de 5. La méthode scds_svc_wait() limite la fréquence des sondages à un intervalle de 5 secondes. Cette méthode comptabilise également le nombre de tentatives de démarrage du service. Si le nombre de tentatives dépasse la valeur de la propriété Retry_count de la ressource dans la période spécifiée par la propriété Retry_interval de la ressources, la fonction scds_svc_wait() renvoie un échec. Dans ce cas, la fonction svc_start() renvoie également un échec.


#définir    SVC_CONNECT_TIMEOUT_PCT    95
#définir    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 {
      /*
       * sondage du service de données sur l'adresse IP
       * de la ressource réseau et du nom du port
       */
      rc = svc_probe(scds_handle,
          netaddr->netaddrs[0].hostname,
          netaddr->netaddrs[0].port_proto.port, probe_timeout);
      if (rc == SCHA_ERR_NOERR) {
         /* Réussite. Libération des ressources et retour */
         scds_free_netaddr_list(netaddr);
         return (0);
      }

       /* Appel de scds_svc_wait() au cas où le service échoue également
         if (scds_svc_wait(scds_handle, SVC_WAIT_TIME)
         != SCHA_ERR_NOERR) {
         scds_syslog(LOG_ERR, "Service failed to start.");
         return (1);
      }

   /* Appui sur le RGM pour arrêter le programme en cas de dépassement du délai imparti */
   } while (1);


Remarque –

avant sa fermeture, la fonction xfnts_start appelle scds_close() de manière à récupérer les ressources allouées par scds_initialize (). Reportez-vous à la rubrique Fonction scds_initialize() et à la page de manuel scds_close(3HA) pour de plus amples informations.