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

Annexe C Liste des codes du type de ressources échantillon de la BDSD

Cette annexe fournit le code complet de chaque méthode du type de ressources SUNW.xfnts. Elle comprend la liste de xfnts.c contenant le code des sous-routines appelées par les méthodes de rappel. Programmes figurant dans cette annexe :

xfnts.c

Ce fichier met en oeuvre les sous-routines appelées par les méthodes SUNW.xfnts.


Exemple C–1 xfnts.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * Utilitaires xfnts.c – commun de HA-XFS
 *
 * Cet utilitaire comprend les méthodes de validation, démarrage et arrêt du
 * service de données et du système de détection des pannes. Il contient également
 * la méthode de détection de l'état du service de données. La détection précise 
 * simplement le succès ou l'échec. L'action est entreprise en fonction de la 
 * valeur retournée dans laméthode figurant dans le fichier xfnts_probe.c
 *
 */

#pragma ident “@(#)xfnts.c 1.47 01/01/18 SMI”

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <scha.h>
#include <rgm/libdsdev.h>
#include <errno.h>
#include “xfnts.h”

/*
 * Délai d'attente initial autorisé pour que le service de données HAXFS
 * soit pleinement opérationnel. Nous attendrons pendant 3 % (SVC_WAIT_PCT)
 * du délai_démarrage avant de détecter le service.
 */
#define   SVC_WAIT_PCT      3

/*
 * Nous devons utiliser 95 % du délai_sonde pour la connexion au port, le
 * temps restant servant à la déconnexion de ce port dans la fonction svc_probe.
 */
#define   SVC_CONNECT_TIMEOUT_PCT      95

/*
 * SVC_WAIT_TIME sert uniquement lors du démarrage dans svc_wait().
 * Dans svc_wait(), nous devons nous assurer que le service est opérationnel
 * avant de revenir au mode de fonctionnement antérieur, puis nous devons appeler 
 * svc_probe() pour contrôler le service. SVC_WAIT_TIME correspond à la durée entre
 * ces détections.
 */

#define   SVC_WAIT_TIME      5

/*
 * Cette valeur sera utilisée en tant que délai de déconnexion, si le délai
 * à partir de délai_sonde est écoulé.
 */

#define   SVC_DISCONNECT_TIMEOUT_SECONDS      2


/*
 * svc_validate():
 *
 * Effectuez une validation HA-XFS spécifique de la configuration de la ressource.
 *
 * svc_validate vérifie :
 * 1. La propriété d'extension Liste_rép_conf
 * 2. Le fichier fontserver.cfg
 * 3. La valeur xfs binaire
 * 4. La propriété liste_ports
 * 5. Les ressources réseau
 * 6. Les autres propriétés d'extension
 *
 * Si l'une des validations ci-dessus échoue, Return> 0 ou
 * retournez 0 pour obtenir un succès
 */

int
svc_validate(scds_handle_t scds_handle)
{
   char   xfnts_conf[SCDS_ARRAY_SIZE];
   scha_str_array_t *confdirs;
   scds_net_resource_list_t *snrlp;
   int rc;
   struct stat statbuf;
   scds_port_list_t   *portlist;
   scha_err_t   err;

   /*
    * Obtenez le répertoire de configuration du service de données XFS à partir 
    * de la propriété d'extension/
   confdirs = scds_get_ext_confdir_list(scds_handle);

   /* Une erreur est retournée en l'absence de la propriété d'extension liste_rép_conf
*/
   if (confdirs == NULL || confdirs->array_cnt != 1) {
      scds_syslog(LOG_ERR,
          “Property Confdir_list is not set properly.”);
      return (1); /* Validation failure */
   }

   /*
    * Définissez le chemin d'accès au fichier de configuration à partir de la 
    * propriété d'extension liste_rép_conf. Comme HA-XFS possède une seule 
    * configuration, nous devons utiliser la première entrée de la propriété
    * liste_rép_conf.
    */
   (void) sprintf(xfnts_conf, “%s/fontserver.cfg”,
confdirs->str_array[0]);

   /*
    * Vérifiez que le fichier de configuration de HA-XFS figure au bon emplacement.
    * Essayez d'accéder au fichier de configuration de HA-XFS et vérifiez que les
    * permissions d'accès sont correctement définies
    */
   if (stat(xfnts_conf, &statbuf) != 0) {
      /*
       * Supprimez l'erreur lint car le prototype errno.h
       * ne possède pas d'argument nul
       */
      scds_syslog(LOG_ERR,
          “Failed to access file <%s> : <%s>”,
          xfnts_conf, strerror(errno));   /*lint !e746 */
      return (1);
   }

   /*
    * Vérifiez que la valeur xfs binaire existe et que les permissions d'accès
    * sont correctes. La valeur XFS binaire doit figurer dans le système de 
    * fichiers local et non dans le système de fichiers global
    */
   if (stat(“/usr/openwin/bin/xfs”, &statbuf)
!= 0) {
      scds_syslog(LOG_ERR,
          “Cannot access XFS binary : <%s> “,
strerror(errno));
      return (1);
   }

   /* HA-XFS possède uniquement un port */
   err = scds_get_port_list(scds_handle, &portlist);
   if (err != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          “Could not access property Port_list: %s.”,
         scds_error_string(err));
      return (1); /* Echec de validation */
   }

#ifdef TEST
   if (portlist->num_ports != 1) {
      scds_syslog(LOG_ERR,
          “Property Port_list must have only one value.”);
      scds_free_port_list(portlist);
      return (1); /* Echec de validation */
   }
#endif

   /*
    * Retournez une erreur en cas d'erreur lors de la tentative d'obtention
    * de ressources d'adresses réseau disponibles pour cette ressource
    */
   if ((err = scds_get_rs_hostnames(scds_handle, &snrlp))
      != SCHA_ERR_NOERR) {
      scds_syslog(LOG_ERR,
          “No network address resource in resource group: %s.”,
         scds_error_string(err));
      return (1); /* Echec de validation */
   }

   /* Retournez une erreur en l'absence de ressources d'adresses réseau */
   if (snrlp == NULL || snrlp->num_netresources == 0) {
      scds_syslog(LOG_ERR,
          “No network address resource in resource group.”);
      rc = 1;
      goto finished;
   }

   /* Vérifiez que les autres propriétés d'extension importantes sont définies */
   if (scds_get_ext_monitor_retry_count(scds_handle) <= 0)
{
      scds_syslog(LOG_ERR,
          “Property Monitor_retry_count is not set.”);
      rc = 1; /* Échec de validation */
      goto finished;
   }
   if (scds_get_ext_monitor_retry_interval(scds_handle) <=
0) {
      scds_syslog(LOG_ERR,
          “Property Monitor_retry_interval is not set.”);
      rc = 1; /* Échec de validation */
      goto finished;
   }

   /* Tous les contrôles de validation ont réussi */
   scds_syslog(LOG_INFO, “Successful validation.”);
   rc = 0;

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

   return (rc); /* retour des résultats de la validation */
}


/*
 * svc_start():
 *
 * Démarre le serveur de polices X
 * Retourne 0 si succès,> 0 si échec.
 *
 * Le service XFS est démarré en exécutant la commande
 * /usr/openwin/bin/xfs -config <fontserver.cfg file> -port <port to listen>
 * XFS est démarré via la fonction PMF. XFS est démarré en tant que service 
 * d'instances unique. La balise PMF du service de données se présente sous 
 * la forme <resourcegroupname,resourcename,instance_number.svc>. Dans le cas
 * de XFS, comme il n'y a qu'une seule instance, instance_number, dans 
 * la balise est de 0.
 */

int
svc_start(scds_handle_t scds_handle)
{
   char    xfnts_conf[SCDS_ARRAY_SIZE];
   char   cmd[SCDS_ARRAY_SIZE];
   scha_str_array_t *confdirs;
   scds_port_list_t    *portlist;
   scha_err_t   err;

   /* Obtenez le répertoire de configuration à partir de 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]);

   /* Obtenez le port à utiliser par XFS à partir de la propriété Liste_ports */
   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);
   }

   /*
    * Créez la commande pour démarrer HA-XFS.
    * REMARQUE : le démon XFS imprime le message suivant tout en arrêtant XFS
    * “/usr/openwin/bin/xfs notice: terminating”
    * Afin de supprimer le message du démon,
    * la sortie est redirigée vers /dev/null.
    */
   (void) sprintf(cmd,
       “/usr/openwin/bin/xfs -config %s -port %d 2>/dev/null”,
       xfnts_conf, portlist->ports[0].port);

   /*
    * Démarrez HA-XFS via la fonction PMF. Notez que HA-XFS est démarré en tant que 
    * service d'instances unique. Le dernier argument de la fonction scds_pmf_start
    * indique le niveau enfant à contrôler. Si ce paramètre possède une valeur de –1,
    * tous les enfants et le processus original doivent être contrôlés.
    */
   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 “);
   }

   scds_free_port_list(portlist);
   return (err); /* retourne un état succès/échec */
}


/*
 * svc_stop():
 *
 * Arrête le serveur XFS
 * Retourne 0 si succès,> 0 si échec.
 *
 * svc_stop arrête le serveur en appelant la fonction de la boîte à outils :
 * scds_pmf_stop.
 */
int
svc_stop(scds_handle_t scds_handle)
{
   scha_err_t   err;

   /*
    * La valeur du délai d'attente de la méthode d'arrêt pour réussir est définie 
    * dans la propriété Délai_arrêt (définie par le système)
    */
   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*/
}

/*
 * svc_wait():
 *
 * Attendez que le service de données démarre complètement et vérifiez qu'il
 * fonctionne correctement
 */

int
svc_wait(scds_handle_t scds_handle)
{
   int rc, svc_start_timeout, probe_timeout;
   scds_netaddr_list_t   *netaddr;

   /* Obtenez la ressource réseau à utiliser pour la détection */
   if (scds_get_netaddr_list(scds_handle, &netaddr)) {
      scds_syslog(LOG_ERR,
          “No network address resources found in resource group.”);
      return (1);
   }

   /* Retournez 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);
   }

   /*
    * Obtenez le délai d'attente de la méthode de démarrage, le numéro de port 
    * sur lequel effectuer la détection, la valeur du délai d'attente de détection
    */
   délai_démarrage_svc = scds_get_rs_start_timeout(scds_handle);
   délai_sonde = scds_get_ext_probe_timeout(scds_handle);

   /*
    * patientez pendant le pourcentage de SVC_WAIT_PCT du délai_démarrage
    * avant de vraiment détecter le service de données. Ceci permet
    * au service de données d'être complètement opérationnel pour répondre à la
    * détection. REMARQUE : la valeur de SVC_WAIT_PCT peut être différente
    * pour différents services de données.
    * Au lieu d'appeler sleep(),
    * appelez scds_svc_wait() de sorte que si le service échoue également
    * plusieurs fois, vous pouvez abandonner et revenir rapidement.
    */
   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 {
      /*
       * Détectez le service de données sur l'adresse IP de la
       * ressource réseau et du nom de port
       */
      rc = svc_probe(scds_handle,
          netaddr->netaddrs[0].hostname,
          netaddr->netaddrs[0].port_proto.port, probe_timeout);
      if (rc == SCHA_ERR_NOERR) {
         /* Succès. Libérez les ressources et retournez */
         scds_free_netaddr_list(netaddr);
         return (0);
      }

      /*
       * Le service de données essaie toujours de s'afficher. Attendez quelques 
       * instants avant de relancer la détection. Au lieu d'appeler sleep(),
       * appelez scds_svc_wait() de sorte que si le service échoue également
       * plusieurs fois, vous pouvez abandonner et revenir rapidement.
       */
      if (scds_svc_wait(scds_handle, SVC_WAIT_TIME)
         != SCHA_ERR_NOERR) {
         scds_syslog(LOG_ERR, “Service failed to start.”);
         return (1);
      }

   /* Nous comptons sur le gestionnaire RGM pour temporiser et terminer le programme */
   } while (1);

}

/*
 * Cette fonction démarre le système de détection des pannes d'une ressource HA-XFS.
 * Pour ce faire, il suffit de lancer la détection via fonction PMF. La balise PMF
 * est dérivée en tant que <RG-name,RS-name,instance_number.mon>.
 * L'option de redémarrage de la fonction PMF est utilisée mais pas le 
 * “redémarrage illimité”.

 * interval/retry_time est obtenu à la place à partir du fichier RTR.
 */

int
mon_start(scds_handle_t scds_handle)
{
   scha_err_t   err;

   scds_syslog_debug(DBG_LEVEL_HIGH,
      “Calling MONITOR_START method for resource <%s>.”,
      scds_get_resource_name(scds_handle));

   /*
    * La détection xfnts_probe est supposée être disponible dans le même
    * sous-répertoire que celui dans lequel les autres méthodes de rappel du type de
    * ressources sont installées. Le dernier paramètre de scds_pmf_start indique le
    * niveau de contrôle enfant. Comme nous commençons la détection via la fonction PMF,
    * nous devons seulement contrôler le processus de détection, par conséquent nous 
    * utiliserons une valeur de 0.
    */
   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 */
}


/*
 * Cette fonction arrête le système de détection des pannes d'une ressource HA-XFS.
 * Cette action est réalisée par le biais de la fonction PMF. La balise PMF du système 
 * de détection des pannes est créée sur le modèle <RG-name_RS-name,instance_number.mon>.
 */

int
mon_stop(scds_handle_t scds_handle)
{

   scha_err_t   err;

   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 */
}

/*
 * svc_probe() : exécute la détection spécifique d'un service de données. Retourne 
 * une valeur flottantecomprise entre 0 (succès) et 100 (échec total).
 *
 * La détection se connecte simplement au serveur XFS sur le port spécifié qui est 
 * configuré en tant que propriété d'extension de la ressource (Liste_ports) et
 * pingue le service de données. Si la détection ne parvient pas à se connecter au port, 
 * nous retournons une valeur de 100 indiquant un échec total. Si la connexion
 * réussit et la déconnexion échoue, une valeur de 50 est retournée, indiquant 
 * un échec partiel.
 *
 */
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;


   /*
    * Détectez le service de données par une connexion au port
    * spécifié dans la propriété liste_ports de l'hôte qui prend en charge
    * le service de données XFS. Si le service XFS qui est configuré
    * pour écouter le port spécifié répond à la connexion, la détection
    * est réussie. Autrement, nous attendons pendant le temps spécifié dans 
    * la propriété délai_sonde avant de conclure à l'échec de la détection.
    */

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

   /*
    * La détection se connecte au nom d'hôte et au port spécifiés.
    * La connexion est temporisée sur 95 % du délai_sonde réel.
    */
   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. Ce délai doit être 
    * inférieur ou égal au délai_connexion alloué pour se connecter.
    * Si la connexion requiert l'intégralité du délai alloué,
    * la valeur restante du délai_sonde, passée à la fonction est 
    * utilisée en tant que délai de déconnexion. Sinon, le délai de 
    * connexion restant est également ajouté au délai de déconnexion.
    *
    */

   time_used = (int)(t2 - t1);

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

   time_remaining = timeout - (int)time_used;

   /*
    * Si le délai est intégralement utilisé, utilisez un délai d'attente codé
    * dans un petit programme spécifique pour tenter de nouveau une déconnexion.
    * Cette action é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;
   }

   /*
    * Retournez un échec partiel en cas d'échec de déconnexion.
    * Motif : l'appel de connexion a réussi ce qui signifie que
    * l'application fonctionne. Un échec de déconnexion peut survenir 
    * si une application est interrompue ou une charge volumineuse.
    * Dans ce dernier cas, ne déclarez pas l'application comme 
    * bloquée en retournant un échec total. Déclarez plutôt
    * un échec partiel. Si cette situation persiste, l'appel
    * de déconnexion échoue de nouveau 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;

   /*
    * En l'absence de temps restant, n'exécutez pas le test complet avec
    * fsinfo. Retournez plutôt SCDS_PROBE_COMPLETE_FAILURE/2.
    * Vous avez ainsi l'assurance que si ce délai d'attente
    * persiste, le serveur est redémarré.
    */
   if (time_remaining <= 0) {
      scds_syslog(LOG_ERR, “Probe timed out.”);
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }

   /*
    * La connexion au port et la déconnexion du port sont réussies.
    * Exécutez la commande fsinfo pour réaliser un contrôle complet
    * de l'état du serveur.
    * Redirigez stdout, sinon la sortie de fsinfo
    * se termine 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);
}

Méthode de contrôle_détecteur_xfnts

Cette méthode vérifie que la configuration de base du type de ressources est valide.


Exemple C–2 xfnts_monitor_check.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_monitor_check.c - méthode de contrôle du détecteur de HA-XFS
 */

#pragma ident “@(#)xfnts_monitor_check.c 1.11 01/01/18
SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Effectuez un simple contrôle de validation du service
*/

int
main(int argc, char *argv[])
{
   scds_handle_t   scds_handle;
   int   rc;

   /* Traitez les arguments passés au gestionnaire RGM et initialisez 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érez toute la mémoire allouée par scds_initialize */
   scds_close(&scds_handle);

   /* Retournez le résultat de la méthode de validation exécutée dans le cadre /* 
   /* du contrôle du détecteurreturn (rc); /* 
}

Méthode de démarrage_détecteur_xfnts

Cette méthode exécute la méthode de sondage_ xfnts.


Exemple C–3 xfnts_monitor_start.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_monitor_start.c - Méthode de démarrage du détecteur de HA-XFS
 */

#pragma ident “@(#)xfnts_monitor_start.c 1.10 01/01/18
SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Cette méthode démarre le système de détection des pannes d'une ressource HA-XFS.
 * Cette action est réalisée en lançant la détection sous la fonction PMF. 
 * La balise PMF est dérivée en tant que RG-name,RS-name.mon. L'option de redémarrage 
 * de la fonction PMF est utilisée mais pas le “redémarrage illimité”.
 * interval/retry_time est obtenu à la place à partir du fichier RTR.
 */

int
main(int argc, char *argv[])
{
   scds_handle_t   scds_handle;
   int   rc;

   /* Traitez les arguments passés par le gestionnaire RGM et initialisez syslog */
   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }

   rc = mon_start(scds_handle);

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

   /* Retournez le résultat de la méthode de démarrage_détecteur */
   return (rc);
}

Méthode d'arrêt_détecteur_xfnts

Cette méthode arrête la méthode de sonde_xfnts.


Exemple C–4 xfnts_monitor_stop.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_monitor_stop.c - Méthode d'arrêt du détecteur de HA-XFS
 */

#pragma ident “@(#)xfnts_monitor_stop.c 1.9 01/01/18 SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Cette méthode arrête le système de détection des pannes d'une ressource HA-XFS.
 * Cette action est réalisée via la fonction PMF. La balise PMF du système de détection 
 * des pannes est créée sur le modèle RG-name_RS-name.mon.
 */

int
main(int argc, char *argv[])
{

   scds_handle_t   scds_handle;
   int    rc;

   /* Traitez les arguments passés par le gestionnaire RGM et initialisez syslog */
   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }
   rc = mon_stop(scds_handle);

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

   /* Retournez le résultat de la méthode d'arrêt du détecteur */
   return (rc);
}

Méthode de sonde_xfnts

La méthode de sonde_xfnts contrôle la disponibilité de l'application et choisit de basculer ou de redémarrer le service de données. La méthode de rappel de démarrage_détecteur_xfnts lance ce programme tandis que la méthode de rappel d'arrêt_détecteur_xfnts l'arrête.


Exemple C–5 xfnts_probe.c+

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_probe.c - Probe for HA-XFS
 */

#pragma ident “@(#)xfnts_probe.c 1.26 01/01/18 SMI”

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <strings.h>
#include <rgm/libdsdev.h>
#include “xfnts.h”


/*
 * main():
 * Boucle illimitée qui attend (sleep()s) pendant un laps de temps que le script
 * d'action de la fonction PMF interrompe sleep(). Une fois qu'il est interrompu
 * elle appelle la méthode de démarrage de HA-XFS pour le redémarrer.
 *
 */

int
main(int argc, char *argv[])
{
   int         timeout;
   int         port, ip, probe_result;
   scds_handle_t      scds_handle;

   hrtime_t      ht1, ht2;
   unsigned long      dt;

   scds_netaddr_list_t *netaddr;
   char   *hostname;

   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }


   /* Obtenez les adresses IP disponibles pour cette ressource */
   if (scds_get_netaddr_list(scds_handle, &netaddr)) {
      scds_syslog(LOG_ERR,
          “No network address resource in resource group.”);
      scds_close(&scds_handle);
      return (1);
   }

   /* Retournez 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);
   }


   /*
    * Définissez le délai d'attente des propriétés X. Cela signifie que chaque 
    * itération de détection obtient un délai d'attente complet sur chaque ressource
    * réseau sans supprimer le délai d'attente entre toutes les ressources réseau
    * configurées pour cette ressource.
    */
   timeout = scds_get_ext_probe_timeout(scds_handle);

   for (;;) {

      /*
       * Attendez que s'écoule l'intervalle_sonde_complet entre les
       *  tentatives réussies.
       */
      (void) scds_fm_sleep(scds_handle,
          scds_get_rs_thorough_probe_interval(scds_handle));

      /*
       * À présent, détectez toutes les adresses IP utilisées. Itérez
       * 1. Toutes les ressources réseau utilisées.
       * 2. Toutes les adresses IP d'une ressource donnée.
       * Chaque adresse IP testée,
       * Calculez l'historique d'échec.
       */
      probe_result = 0;
      /*
       * Itérez toutes les ressources pour obtenir chaque
       * adresse IP à utiliser pour appeler svc_probe()
       */
      for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
         /*
          * Saisissez le nom d'hôte et le port
          * dont l'état doit être contrôlé.
          */
         nom_hôte = netaddr->netaddrs[ip].hostname;
         port = netaddr->netaddrs[ip].port_proto.port;
         /*
          * HA-XFS ne prend en charge qu'un port, par conséquent
          * obtenez la valeur du port à partir de la
          * première entrée dans l'ensemble des ports.
          */
         ht1 = gethrtime(); /* Latch probe start time */
         scds_syslog(LOG_INFO, “Probing the service on “
             “port: %d.”, port);

         résultat_sonde =
         svc_probe(scds_handle, hostname, port, timeout);

         /*
          * Mettez à jour l'historique de détection du service,
          * effectuez les actions requises si nécessaire.
          * Verrouillez le délai de fin de détection.
          */
         ht2 = gethrtime();

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

         /*
          * Calculez l'historique d'échec et effectuez les actions
          * requises le cas échéant
          */
         (void) scds_fm_action(scds_handle,
             probe_result, (long)dt);
      }   /* Chaque ressource réseau */
   }    /* Conserver la détection */
}

Méthode de démarrage_xfnts

Le gestionnaire RGM appelle la méthode de Démarrage sur un noeud du cluster lorsque le groupe de ressources contenant la ressource du service de données est connecté à ce noeud ou lorsque la ressource est activée. La méthode dedémarrage_xfnts active le démon xfs sur ce noeud.


Exemple C–6 xfnts_start.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_svc_start.c - Méthode de démarrage de HA-XFS
 */

#pragma ident “@(#)xfnts_svc_start.c 1.13 01/01/18 SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Méthode de démarrage de HA-XFS. Effectue quelques contrôles sanitaires sur
 * les paramètres de ressource, puis démarre HA-XFS via la fonction PMF avec un
 * script d'action.
 */

int
main(int argc, char *argv[])
{
   scds_handle_t   scds_handle;
   int rc;

   /*
    * Traitez tous les arguments qui nous ont été passés à partir du gestionnaire
    * RG et effectuez des actions d'initialisation pour syslog
    */

   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }

   /* Validez l'initialisation et retournez en arrière en cas d'erreur */
   rc = svc_validate(scds_handle);
   if (rc != 0) {
      scds_syslog(LOG_ERR,
          “Failed to validate configuration.”);
      return (rc);
   }

   /* Démarrez le service de données et retournez une erreur en cas d'erreur */
   rc = svc_start(scds_handle);
   if (rc != 0) {
      goto finished;
   }

   /* Attendez que le service démarre complètement */
   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.”);
   }


finished:
   /* Libérez les ressources Environnement qui ont été allouées */
   scds_close(&scds_handle);

   return (rc);
}

Méthode d'arrêt_xfnts

Le gestionnaire RGM appelle la méthode d'Arrêt sur un noeud du cluster lorsque le groupe de ressources contenant la ressource HA-XFS est déconnecté de ce noeud ou lorsque la ressource est désactivée. Cette méthode arrête le démon xfs sur ce noeud.


Exemple C–7 xfnts_stop.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_svc_stop.c - Méthode d'arrêt de HA-XFS
 */

#pragma ident “@(#)xfnts_svc_stop.c 1.10 01/01/18 SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Arrête le processus HA-XFS via la fonction PMF
 */

int
main(int argc, char *argv[])
{

   scds_handle_t   scds_handle;
   int      rc;

   /* Traitez les arguments passés par le gestionnaire RGM et initialisez syslog */
   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }

   rc = svc_stop(scds_handle);

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

   /* Retournez le résultat de la méthode arrêt_svc */
   return (rc);
}

Méthode de mise_à_jour_xfnts

Le gestionnaire RGM appelle la méthode de Mise_à_jour pour notifier à une ressource en cours d'exécution que ses propriétés ont été modifiées. Il appelle Mise_à_jour après l'exécution réussie d'une action administrative de paramétrage des propriétés d'une ressource ou de son groupe.


Exemple C–8 xfnts_update.c

#pragma ident “@(#)xfnts_update.c  1.10     01/01/18 SMI”

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droits réservés.
 *
 * xfnts_update.c - Update method for HA-XFS
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <rgm/libdsdev.h>

/*
 * Certaines des propriétés de ressource peuvent avoir été mises à jour. Toutes
 * ces propriétés qu'il est possible de mettre à jour sont liées au système de 
 * détection des pannes. Par conséquent, il suffit normalement de redémarrer 
 * le détecteur.
 */

int
main(int argc, char *argv[])
{
   scds_handle_t   scds_handle;
   scha_err_t   result;

   /* Traitez les arguments passés par le gestionnaire RGM et initialisez syslog */
   if (scds_initialize(&scds_handle, argc, argv) != SCHA_ERR_NOERR)
{
      scds_syslog(LOG_ERR, “Failed to initialize the handle.”);
      return (1);
   }

   /*
    * Vérifiez si le système de détection des pannes fonctionne déjà et arrêtez-le 
    * le cas échéant, puis redémarrez-le. Le second paramètre de scds_pmf_restart_fm() 
    * identifie uniquement l'instance du système de détection des pannes qui doit être
    * redémarré.
    */

   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érez toute la mémoire allouée par scds_initialize */
      scds_close(&scds_handle);
      return (1);
   }

   scds_syslog(LOG_INFO,
       “Completed successfully.”);

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

   return (0);
}

Liste des codes de la méthode de validation_xfnts

Cette méthode vérifie l'existence du répertoire spécifié par la propriété Liste_rép_conf. Le gestionnaire RGM appelle cette méthode lorsque l'administrateur du cluster crée le service de données et met à jour ses propriétés. La méthode de Contrôle_détecteur appelle cette méthode chaque fois que le système de détection des pannes bascule le service de données vers un nouveau noeud.


Exemple C–9 xfnts_validate.c

/*
 * Copyright (c) 1998-2003 par Sun Microsystems, Inc.
 * Tous droit réservés.
 *
 * xfnts_validate.c - Méthode de validation de HA-XFS
 */

#pragma ident “@(#)xfnts_validate.c 1.9 01/01/18 SMI”

#include <rgm/libdsdev.h>
#include “xfnts.h”

/*
 * Vérifiez que toutes les propriétés ont été correctement définies.
 */

int
main(int argc, char *argv[])
{
   scds_handle_t   scds_handle;
   int   rc;

   /* Traitez les arguments passés par le gestionnaire RGM et initialisez 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);

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

   /* Retournez le résultat de la méthode de validation */
   return (rc);

}