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

Chapitre 8 Mise en œuvre du type de ressource BDSD modèle

Ce chapitre décrit un type de ressource modèle, SUNW.xfnts, mis en œuvre avec BDSD. Le service de données est rédigé en C. L'application sous-jacente est le serveur de polices X, un service basé sur le protocole TCP/IP.

Les informations fournies par ce chapitre sont les suivantes :

Serveur de polices X

Le serveur de polices X est un service simple, basé sur le protocole TCP/IP, servant des fichiers de police à ses clients. Les clients se connectent au serveur pour demander un jeu de polices et le serveur lit les fichiers de police à partir du disque avant de les servir aux clients. Le démon du serveur de polices X se compose d'un binaire de serveur /usr/openwin/bin/xfs. Le démon est normalement démarré à partir de inetd. Toutefois, pour le modèle présenté, supposez que l’entrée appropriée du fichier /etc/inetd.conf a été désactivée (par exemple, par la commande fsadmin -d). Le démon est donc sous le seul contrôle de Sun Cluster.

Fichier de configuration du serveur de polices X

Par défaut, le serveur de polices X lit ses informations de configuration à partir du fichier /usr/openwin/lib/X11/fontserver.cfg. L'entrée de catalogue de ce fichier contient une liste de répertoires de police disponibles pour le démon, qui fait office de serveur. L'administrateur du cluster peut localiser ces répertoires sur le système de fichiers global (afin d'optimiser l'utilisation du serveur de polices X sur Sun Cluster en gérant une seule copie de la base de données des polices sur le système). Dans ce cas, l'administrateur doit éditer fontserver.cfg afin de refléter les nouveaux chemins des répertoires contenant les polices.

Pour faciliter la configuration, l'administrateur peut également placer le fichier de configuration lui-même dans le système de fichiers global. Le démon xfs propose des arguments de ligne de commande permettant d'ignorer l'emplacement intégré par défaut de ce fichier. Le type de ressource SUNW.xfnts utilise la commande suivante pour démarrer le démon sous le contrôle de Sun Cluster :


/usr/openwin/bin/xfs -config < emplacement_du_fichier_cfg>/fontserver.cfg \ -port <numéroport>

Dans la mise en œuvre du type de ressource SUNW.xfnts, vous pouvez utiliser la propriété Confdir_list pour gérer l'emplacement du fichier de configuration fontserver.cfg.

Numéro du port TCP

Le numéro du port TCP qu'écoute le démon du serveur xfs est normalement le port “fs” (généralement défini comme 7100 dans le fichier /etc/services). Toutefois, l'option -port de la ligne de commande xfs permet à l'administrateur système d'ignorer la valeur par défaut. Vous pouvez utiliser la propriété Port_list dans le type de ressources SUNW.xfnts pour définir la valeur par défaut et pour prendre en charge l'utilisation de l'option -port dans la ligne de commande xfs. Vous définissez la valeur par défaut de cette propriété comme 7100/tcp dans le fichier RTR. Dans la méthode SUNW.xfnts Start, vous transmettez Port_list à l'option -port de la ligne de commande xfs. Par conséquent, un utilisateur de ce type de ressource n’est pas obligé de spécifier un numéro de port (le port par défaut est 7100/tcp mais, s’il le souhaite, il peut en indiquer un autre lors de la configuration du type de ressource. Pour ce faire, il lui suffit d’entrer une valeur différente pour la propriété Port_list.

Conventions de dénomination

Vous pouvez identifier les différentes parties du code modèle en gardant les conventions suivantes à l'esprit :

Fichier RTR SUNW.xfnts

Cette rubrique décrit plusieurs propriétés clés du fichier RTR SUNW.xfnts. Elle ne décrit pas l'objectif de chaque propriété du fichier. Pour une telle description, reportez-vous à la rubrique Paramétrage des propriétés de ressources et de types de ressources.

La propriété d'extension Confdir_list identifie le répertoire de configuration (ou une liste de répertoires) de la manière suivante :


{
        PROPRIÉTÉ = Confdir_list;
        EXTENSION;
        CHAÎNE;
        RÉGLABLE = À_LA_CRÉATION;
        DESCRIPTION = "Chemin(s) du répertoire de configuration";
}

La propriété Confdir_list ne spécifie pas de valeur par défaut. L'administrateur du cluster doit indiquer un répertoire au moment de la création de la ressource. Cette valeur ne peut plus être modifiée ultérieurement parce que son paramétrage est limité à AT_CREATION.

La propriété Port_list identifie le port qu'écoute le démon du serveur de la manière suivante :


{
       PROPERTY = Port_list;
        DEFAULT = 7100/tcp;
        TUNABLE = AT_CREATION;
}

La propriété déclarant une valeur par défaut, l'administrateur du cluster a la possibilité de spécifier une nouvelle valeur ou d'accepter la valeur par défaut au moment de la création de la ressource. Cette valeur ne peut plus être modifiée ultérieurement parce que son paramétrage est limité à AT_CREATION.

Fonction scds_initialize()

BDSD exige que chaque méthode de rappel appelle la fonction scds_initialize(3HA) au début de la méthode. Cette fonction exécute les opérations suivantes :

La fonction scds_close() vous permet de récupérer les ressources allouées par scds_initialize().

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.


Méthode xfnts_stop

La méthode xfnts_start utilisant scds_pmf_start() pour démarrer le service sous le gestionnaire de processus, xfnts_stop emploie scds_pmf_stop() pour arrêter celui-ci.


Remarque –

le premier appel de xfnts_stop est destiné à la fonction scds_initialize() exécutant des fonctions de gestion interne nécessaires (pour de plus amples informations, reportez-vous à la rubrique Fonction scds_initialize() et à la page de manuel scds_initialize(3HA)).


La méthode xfnts_stop appelle la méthode svc_stop(), définie dans xfnts.c de la manière suivante :


scds_syslog(LOG_ERR, "Issuing a stop request.");
   err = scds_pmf_stop(scds_handle,
       SCDS_PMF_TYPE_SVC, SCDS_PMF_SINGLE_INSTANCE, SIGTERM,
       scds_get_rs_stop_timeout(scds_handle));

   if (err != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          "Failed to stop HA-XFS.");
      return (1);
   }

   scds_syslog(LOG_INFO,
       "Successfully stopped HA-XFS.");
   return (SCHA_ERR_NOERR); /* Arrêt réussi */

Tenez compte des points suivants concernant l'appel d'svc_stop() destiné à la fonction scds_pmf_stop() :


Remarque –

avant sa fermeture, la méthode d'xfnts_stop appelle scds_close() afin de récupérer les ressources réparties par scds_initialize (). Reportez-vous à la rubrique Fonction scds_initialize() et à la page de manuel scds_close(3HA) pour de plus amples informations.


Méthode xfnts_monitor_start

Le RGM appelle la méthode Monitor_start sur un nœud pour démarrer le détecteur de pannes une fois une ressource démarrée sur le nœud. La méthode xfnts_monitor_start utilise scds_pmf_start() pour démarrer le démon du détecteur sous le gestionnaire de processus.


Remarque –

le premier appel de xfnts_monitor_start est adressé à scds_initialize() qui exécute des fonctions de gestion interne nécessaires (pour de plus amples informations, reportez-vous à la rubrique Fonction scds_initialize() et à la page de manuel scds_initialize(3HA)).


La méthode xfnts_monitor_start appelle la méthode mon_start, définie dans xfnts.c de la manière suivante :


scds_syslog_debug(DBG_LEVEL_HIGH,
      "Calling Monitor_start method for resource <%s>.",
      scds_get_resource_name(scds_handle));

    /* Appel de scds_pmf_start et transmission du nom de la sonde. */
   err = scds_pmf_start(scds_handle, SCDS_PMF_TYPE_MON,
       SCDS_PMF_SINGLE_INSTANCE, "xfnts_probe", 0);

   if (err != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          "Failed to start fault monitor.");
      return (1);
   }

   scds_syslog(LOG_INFO,
       "Started the fault monitor.");

   return (SCHA_ERR_NOERR); /* Détecteur démarré avec succès */
}

Remarquez les points suivants sur l'appel de svc_mon_start() adressé à la fonction scds_pmf_start() :


Remarque –

avant sa fermeture, la méthode xfnts_monitor_start appelle scds_close() pour 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.


Méthode xfnts_monitor_stop

La méthode xfnts_monitor_start utilisant scds_pmf_start() pour démarrer le démon du détecteur sous le gestionnaire de processus, xfnts_monitor_stop utilise scds_pmf_stop() pour l'arrêter.


Remarque –

le premier appel de xfnts_monitor_stop est destiné à scds_initialize() effectuant les fonctions de gestion interne nécessaires (pour de plus amples informations, consultez la rubrique Fonction scds_initialize() et la page de manuel scds_initialize(3HA).)


La méthode xfnts_monitor_stop() appelle la méthode mon_stop, définie dans xfnts.c, de la manière suivante :


scds_syslog_debug(DBG_LEVEL_HIGH,
      "Calling scds_pmf_stop method");

   err = scds_pmf_stop(scds_handle, SCDS_PMF_TYPE_MON,
       SCDS_PMF_SINGLE_INSTANCE, SIGKILL,
       scds_get_rs_monitor_stop_timeout(scds_handle));

   if (err != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          "Failed to stop fault monitor.");
      return (1);
   }

   scds_syslog(LOG_INFO,
       "Stopped the fault monitor.");

   return (SCHA_ERR_NOERR); /* Détecteur arrêté avec succès */
}

Tenez compte des points suivants concernant l'appel de svc_mon_stop() destiné à la fonction scds_pmf_stop() :


Remarque –

avant sa fermeture, la méthode xfnts_monitor_stop_xfnts appelle scds_close() pour 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.


Méthode xfnts_monitor_check

Le RGM appelle la méthode Monitor_check lorsque le détecteur de pannes tente de basculer le groupe contenant la ressource sur un autre nœud. La méthode xfnts_monitor_check appelle la méthode svc_validate() pour vérifier qu'une configuration est en place pour prendre en charge le démon xfs (reportez-vous à la rubrique Méthode xfnts_validate pour de plus amples informations). Le code de xfnts_monitor_check est le suivant :


   /* Traitement des arguments transmis par le RGM et initialisation de syslog */
   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, "Failed to initialize the handle.");
      return (1);
   }

   rc =  svc_validate(scds_handle);
   scds_syslog_debug(DBG_LEVEL_HIGH,
       "monitor_check method "
       "was called and returned <%d>.", rc);

   /* Libération de la mémoire allouée par scds_initialize */
   scds_close(&scds_handle);

   /* Renvoi du résultat de la méthode Validation dans le cadre du contrôle du détecteur */
   return (rc);
}

Détecteur de pannes SUNW.xfnts

Le RGM n'appelle pas directement la méthode PROBE, mais plutôt la méthode Monitor_start pour démarrer le détecteur une fois une ressource démarrée sur un nœud. La méthode xfnts_monitor_start démarre le détecteur de pannes sous le contrôle du gestionnaire de processus. La méthode xfnts_monitor_stop arrête le détecteur de pannes.

Le détecteur de pannes SUNW.xfnts effectue les opérations suivantes :

Boucle principale xfonts_probe

La méthode xfonts_probe met une boucle en œuvre. Avant cela, xfonts_probe :

La méthode xfnts_probe met la boucle en œuvre de la manière suivante :


for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
         /*
          * Obtention du nom d’hôte et du port sur lesquels
          * la santé a été surveillée.
          */
         hostname = netaddr->netaddrs[ip].hostname;
         port = netaddr->netaddrs[ip].port_proto.port;
         /*
          * HA-XFS ne prend en charge qu’un seul port
          * et obtient la valeur du port depuis la
          * première entrée du tableau des ports.
          */
         ht1 = gethrtime(); /* Blocage du délai de démarrage du sondage */
         scds_syslog(LOG_INFO, "Probing the service on port: %d.", port);

         probe_result =
         svc_probe(scds_handle, hostname, port, timeout);

         /*
          * Mise à jour de l’historique des sondages du service,
          * action si nécessaire.
          * Blocage du délai de fin du sondage.
          */
         ht2 = gethrtime();

         /* Conversion en millisecondes */
         dt = (ulong_t)((ht2 - ht1) / 1e6);

         /*
          * Calcul de l’historique des pannes
          * et action si nécessaire
          */
         (void) scds_fm_action(scds_handle,
             probe_result, (long)dt);
      }   /* Chaque ressource réseau */
   }    /* Toujours continuer le sondage */

La fonction svc_probe() met la logique de sondage en œuvre. La valeur retournée par svc_probe() est transmise à scds_fm_action(), qui détermine s’il convient de redémarrer l’application, de basculer le groupe de ressources ou de ne rien faire.

Fonction svc_probe()

La fonction svc_probe() établit une connexion de socket simple au port spécifié en appelant scds_fm_tcp_connect(). Si la connexion échoue, svc_probe() renvoie une valeur de 100 indiquant un échec total. Si la connexion s'établit, mais que la déconnexion échoue, svc_probe() renvoie une valeur de 50 indiquant un échec partiel. Si la connexion et la déconnexion réussissent, svc_probe() renvoie une valeur de 0, indiquant une réussite.

Le code de svc_probe() est le suivant :


int svc_probe(scds_handle_t scds_handle, 
char *hostname, int port, int timeout)
{
   int  rc;
   hrtime_t   t1, t2;
   int    sock;
   char   testcmd[2048];
   int    time_used, time_remaining;
   time_t      connect_timeout;


   /*
    * Sondage du service de données par le biais d’une connexion de socket au port */
* spécifié dans la propriété liste_port de l’hôte alimentant le service
* de données XFS. Si le service XFS configuré pour écouter le port
* spécifié répond à la connexion, le sondage est réussi.
* Dans le cas contraire, nous attendons pendant une période définie
* dans la propriété délai_sonde avant de conclure à l’échec du sondage.
    */

   /*
    * Utilisez le pourcentage SVC_CONNECT_TIMEOUT_PCT du délai imparti
* pour vous connecter au port
    */
   connect_timeout = (SVC_CONNECT_TIMEOUT_PCT * timeout)/100;
   t1 = (hrtime_t)(gethrtime()/1E9);

   /*
    * la sonde établit une connexion au nom d’hôte et au port spécifiés.
    * La connexion reçoit 95% du délai_sonde effectif.
    */
   rc = scds_fm_tcp_connect(scds_handle, &sock, hostname, port,
       connect_timeout);
   if (rc) {
      scds_syslog(LOG_ERR,
          "Failed to connect to port <%d> of resource <%s>.",
          port, scds_get_resource_name(scds_handle));
      /* il s’agit d’un échec total */
      return (SCDS_PROBE_COMPLETE_FAILURE);
   }

   t2 = (hrtime_t)(gethrtime()/1E9);

   /*
    * Calculez le temps réel requis pour la connexion. Il doit être inférieur
* ou égal à délai_connexion, le temps alloué à la connexion.
* Si la connexion utilise tout le délai qui lui est imparti,
* la valeur restante de délai_sonde transmise à cette fonction
* est utilisée comme délai imparti à la déconnexion. Sinon, le
* temps restant de l’appel de connexion est ajouté au délai
* de déconnexion.
    *
    */

   time_used = (int)(t2 - t1);

   /*
    * Utilisez le temps restant (timeout - time_took_to_connect) pour la déconnexion
    */

   time_remaining = timeout - (int)time_used;

   /*
    * Si tout le délai est écoulé, utilisez un délai imparti court à code permanent
* pour essayer une nouvelle fois de provoquer la déconnexion. Ceci évite la fuite fd.
    */
   if (time_remaining <= 0) {
      scds_syslog_debug(DBG_LEVEL_LOW,
          "svc_probe used entire timeout of "
          "%d seconds during connect operation and exceeded the "
          "timeout by %d seconds. Attempting disconnect with timeout"
          " %d ",
          connect_timeout,
          abs(time_used),
          SVC_DISCONNECT_TIMEOUT_SECONDS);

      time_remaining = SVC_DISCONNECT_TIMEOUT_SECONDS;
   }

   /*
    * Renvoi d’un échec partiel en cas d’échec à la déconnexion.
* Motif : l’appel de connexion réussit, ce qui signifie que
* l’application vit. Un échec à la déconnexion peut* être dû à une application bloquée ou à une lourde charge.
* Dans ce dernier cas, ne déclarez pas que l’application
* est morte en renvoyant un échec total. Au lieu de cela, déclarez
* qu’il s’agit d’un échec partiel. Si cette situation perdure, l’appel
* de déconnexion échoue une nouvelle fois et l’application est
* redémarrée.
    */
   rc = scds_fm_tcp_disconnect(scds_handle, sock, time_remaining);
   if (rc != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          "Failed to disconnect to port %d of resource %s.",
          port, scds_get_resource_name(scds_handle));
      /* il s’agit d’un échec partiel */
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }

   t2 = (hrtime_t)(gethrtime()/1E9);
   time_used = (int)(t2 - t1);
   time_remaining = timeout - time_used;

   /*
    * S’il ne reste pas de temps, n’effectuez pas le test complet avec
* fsinfo. Au lieu de cela, renvoyez SCDS_PROBE_COMPLETE_FAILURE/2
* Cette opération garantit que si le dépassement du délai
* imparti persiste, le serveur sera redémarré.
    */
   if (time_remaining <= 0) {
      scds_syslog(LOG_ERR, "Probe timed out.");
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }

   /*
    * La connexion et la déconnexion au port ont réussi.
* Exécutez la commande fsinfo pour effectuer un contrôle total de
* la santé du serveur.
* Redirigez stdout, sans quoi la sortie de fsinfo
* se retrouve sur la console.
    */
   (void) sprintf(testcmd,
       "/usr/openwin/bin/fsinfo -server %s:%d > /dev/null",
       hostname, port);
   scds_syslog_debug(DBG_LEVEL_HIGH,
       "Checking the server status with %s.", testcmd);
   if (scds_timerun(scds_handle, testcmd, time_remaining,
      SIGKILL, &rc) != SCHA_ERR_NOERR || rc != 0) {

      scds_syslog(LOG_ERR,
         "Failed to check server status with command <%s>",
         testcmd);
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }
   return (0);
}

Après avoir terminé, svc_probe() renvoie une valeur indiquant une réussite (0), un échec partiel (50) ou un échec total (100). La méthode xfnts_probe transmet cette valeur à scds_fm_action().

Détermination de l'action du détecteur de pannes

La méthode xfnts_probe appelle scds_fm_action() pour déterminer la mesure à prendre. La logique scds_fm_action() est la suivante :

Par exemple, supposons que la sonde établisse une connexion au serveur xfs, mais ne puisse pas se déconnecter. Ceci indique que le serveur tourne mais qu'il peut être bloqué ou être provisoirement soumis à une forte charge. Un échec de la déconnexion renvoie une erreur partielle (50) à scds_fm_action(). Cette valeur se situe sous le seuil de redémarrage du service de données, mais la valeur est gérée dans l'historique des pannes.

Si, pendant le sondage suivant, le serveur n’arrive à nouveau pas à se déconnecter, une valeur 50 est ajoutée à l’historique des pannes géré par scds_fm_action(). La valeur cumulée des pannes est à présent de 100. Par conséquent, scds_fm_action() redémarre le service de données.

Méthode xfnts_validate

Le RGM appelle la méthode Validate quand une ressource est créée et quand une opération de l'administrateur met à jour les propriétés de la ressource ou du groupe la contenant. Le RGM appelle Validate avant la création ou la mise à jour, et un code de sortie avec échec issu de la méthode sur un nœud entraîne l'annulation de la création ou de la mise à jour.

Il n'appelle Validate que lorsque les propriétés de la ressource ou du groupe sont modifiées par une opération de l'administrateur, et non lorsque le RGM définit des propriétés, ou lorsqu'un détecteur définit les propriétés Status et Status_msg de la ressource.


Remarque –

la méthode Monitor_check appelle aussi explicitement la méthode Validate lorsque la méthode PROBE tente de basculer le service de données sur un autre nœud.


Le RGM appelle Validate avec des arguments différents de ceux transmis aux autres méthodes, y compris les propriétés et valeurs mises à jour. L'appel destiné à scds_initialize() au début de xfnts_validate analyse tous les arguments que le RGM transmet à xfnts_validate et enregistre les informations dans le paramètre scds_handle. Les sous-routines appelées par xfnts_validate utilisent ces informations.

La méthode xfnts_validate appelle svc_validate() qui vérifie les éléments suivants :

Avant son renvoi, svc_validate() libère toutes les ressources allouées.


finished:
   scds_free_net_list(snrlp);
   scds_free_port_list(portlist);

   return (rc); /* renvoi du résultat de la validation */


Remarque –

avant sa fermeture, la méthode xfnts_validate appelle scds_close() pour 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.


Méthode xfnts_update

Le RGM appelle la méthode Update pour notifier à la ressource en cours d'exécution que ses propriétés ont changé. Les seules propriétés pouvant être modifiées par le service de données xfnts concernent le détecteur de pannes. C'est la raison pour laquelle, lorsqu'une propriété est mise à jour, la méthode xfnts_update appelle scds_pmf_restart_fm () pour redémarrer le détecteur de pannes.


* vérifier si le détecteur de pannes tourne déjà et, dans ce cas, l’arrêter
* et le redémarrer. Le second paramètre pour scds_pmf_restart_fm()
* identifie de manière unique l’instance du détecteur de pannes
* à redémarrer.
*/
scds_syslog(LOG_INFO, "Restarting the fault monitor.");
result = scds_pmf_restart_fm(scds_handle, 0);
if (result != SCHA_ERR_NOERR) {
scds_syslog(LOG_ERR,
"Failed to restart fault monitor.");
/* Libère toute la mémoire allouée par scds_initialize */
      scds_close(&scds_handle);
      return (1);
   }

   scds_syslog(LOG_INFO,
   "Completed successfully.");


Remarque –

le second paramètre destiné à scds_pmf_restart_fm() identifie de manière unique l'instance du détecteur de pannes à redémarrer s'il en existe plusieurs. La valeur 0 de l'exemple indique qu'il n'existe qu'une seule instance du détecteur de pannes.