Guide des développeurs pour les services de données Sun Cluster 3.1 10/03

Méthode de démarrage_xfnts

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

La méthode de démarrage_xfnts 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 démarrage_xfnts 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 X Font, la méthode de démarrage_xfnts 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 de validation_xfnts pour de plus amples détails), 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 de démarrage_xfnts appelle la méthode de démarrage_svc(), définie dans xfnts.c pour démarrer le démon xfs. Cette rubrique décrit démarrage_svc().

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 Liste_rép_conf identifie le répertoire_config alors que la propriété système Liste_port 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 de démarrage_xfnts 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é liste_rép_conf  */
   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 Rép_conf pointe vers le premier élément (0) du tableau.

La méthode de démarrage_xfnts 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 de démarrage_xfnts 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 ");
   }

Remarquez les points suivants relatifs à l'appel vers scds_pmf_start () :

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


scds_free_port_list(portlist);
return (err);

Retour de démarrage_svc()

Même lorsque démarrage_svc() renvoie une réussite, il est possible que l'application sous-jacente n'arrive pas à démarrer. démarrage_svc() 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 démarrage_svc() 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 délai_démarrage et de délai_arrêt 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 délai_démarrage. 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é Nombre_nouvelles_tentatives de la ressource dans la période spécifiée par la propriété Intervalle_nouvelles_tentatives de la ressource, la fonction scds_svc_wait() renvoie un échec. Dans ce cas, la fonction démarrage_svc() 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) {
         /* Success. Free up resources and return */
         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 démarrage_xfnts 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 scds_close (3HA) du manuel pour plus de détails.