Guide du développeur de services de données Sun Cluster pour SE Solaris

Méthode Démarrage_xfnts

Le RGM exécute la méthode Start sur un noeud de cluster lorsque le groupe de ressources qui contient la ressource du service de données est mis en ligne sur ce noeud ou lorsque la ressource est activée. Dans l'exemple de type de ressource SUNW.xfnts, la méthode xfnts_start active le démon xfs sur ce noeud.

La méthode xfnts_start appelle la fonction scds_pmf_start() pour démarrer le démon sous le gestionnaire de processus (PMF). Le PMF envoie une notification d'échec automatique et redémarre les fonctionnalités, et il s'intègre au détecteur de pannes.


Remarque –

Le premier appel de xfnts_start est destiné à scds_initialize (), qui effectue certaines tâches de gestion interne nécessaires. Les pages de manuel Fonction scds_initialize() et scds_initialize(3HA) contiennent plus de détails.


Validation du service avant le démarrage du serveur X Font

Avant d'essayer de démarrer le serveur X Font, 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.

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

Reportez-vous à la section Méthode xfnts_validate pour plus de détails.

Démarrage du service avec svc_start()

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

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


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

La propriété d'extension Confdir_list identifie le config-directory alors que la propriété système Port_list identifie le port-number. L'administrateur du cluster fournit à ces propriétés des valeurs spécifiques lorsqu'il configure le service de données.

La méthode xfnts_start déclare ces propriétés en tant que tableaux de chaînes de caractères. Elle prend les valeurs que l'administrateur du cluster définit à l'aide des fonctions scds_get_ext_confdir_list() et scds_get_port_list(). Ces fonctions sont décrites dans la page de manuel scds_property_functions(3HA).

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

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

La méthode xfnts_start utilise la fonction sprintf() pour former la ligne de commande 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);

Notez 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.

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

Notez les points suivants en ce qui concerne l'appel destiné à scds_pmf_start() :

Avant de renvoyer un message, svc_pmf_start() libère la mémoire allouée pour la structure portlist.

scds_free_port_list(portlist);
return (err);

Retour de svc_start()

Même lorsque svc_start() renvoie un message de réussite, il se peut que l'application sous-jacente n'ait pas réussi à 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 également tenir compte du fait que l'application peut ne pas être disponible immédiatement étant donné que son démarrage prend un certain temps. La méthode svc_start() appelle la fonction svc_wait(), qui est définie dans le fichier xfnts.c, pour vérifier que l'application est en cours d'exécution.

/* 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 fonction svc_wait() appelle scds_get_netaddr_list () pour obtenir les ressources d'adresse réseau nécessaires pour sonder l'application.

/* 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 fonction svc_wait() prend les valeurs Start_timeout et Stop_timeout.

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

Pour prendre en compte le temps qu'il faut au serveur pour démarrer, svc_wait() appelle scds_svc_wait() et transmet une valeur de délai d'attente équivalente à trois pour cent de la valeur Start_timeout. La fonction svc_wait() appelle la fonction 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é. Si elle n'arrive pas à se connecter au port, elle renvoie une valeur de 100, ce qui indique un échec total. Si la connexion se fait 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 ressource, la fonction scds_svc_wait() renvoie un échec. Dans ce cas, la fonction svc_start() renvoie également un échec.

#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);

Remarque –

Avant de quitter, la méthode xfnts_start appelle scds_close() pour récupérer les ressources affectées par scds_initialize (). Les pages de manuel Fonction scds_initialize() et scds_close(3HA) contiennent plus de détails.