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

Chapitre 8 Mise en oeuvre du type de ressource DSDL modèle

Ce chapitre décrit un exemple de type de ressource, SUNW.xfnts, qui est mis en oeuvre à l'aide de la DSDL (Bibliothèque de développement de services de données). Ce service de données est rédigé en C. L'application sous-jacente est le serveur X Font, un service basé sur le protocole TCP/IP. Vous trouverez le code complet de chaque méthode du type de ressource SUNW.xfnts à l'Annexe C, Liste des codes de l'exemple de type de ressource de la bibliothèque DSDL .

Ce chapitre contient les rubriques suivantes :

Serveur X Font

Le serveur X Font est un service basé sur le protocole TCP/IP qui fournit 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 X Font se compose d'un binaire de serveur dans le fichier /usr/openwin/bin/xfs. Il est normalement démarré à partir de inetd. Toutefois, dans l'exemple actuel, considérez que l'entrée appropriée du fichier /etc/inetd.conf a été désactivée (par exemple, à l'aide de la commande fsadmin -d) et que le démon est donc sous le seul contrôle du logiciel Sun Cluster.

Fichier de configuration du serveur X Font

Par défaut, le serveur X Font 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 des répertoires de polices que peut fournir le démon. L'administrateur du cluster peut placer les répertoires de police sur le système de fichiers du cluster. Cet emplacement optimise l'utilisation du serveur X Font sur Sun Cluster, car une seule copie de la base de données des polices est gérée sur le système. Si l'administrateur du cluster souhaite modifier l'emplacement, il doit modifier fontserver.cfg en indiquant les nouveaux chemins d'accès aux répertoires de police.

Pour faciliter la configuration, il peut également placer le fichier de configuration dans le système de fichiers du cluster. Le démon xfs propose des arguments de ligne de commande qui remplacent 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 du logiciel Sun Cluster.

/usr/openwin/bin/xfs -config location-of-configuration-file/fontserver.cfg \
-port port-number

Lors de la mise en oeuvre 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 sur lequel é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 ajoutée à la commande xfs par l'administrateur du cluster permet à ce dernier d'ignorer la valeur par défaut.

Vous pouvez utiliser la propriété Port_list du type de ressource SUNW.xfnts pour définir la valeur par défaut et permettre à l'administrateur du cluster d'utiliser l'option -port avec la 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). L'administrateur du cluster peut spécifier une valeur différente pour la propriété Port_list lorsqu'il configure le type de ressource.

Fichier RTR SUNW.xfnts

Cette section 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. En revanche, vous trouverez cette description à la section 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é Liste_rép_conf ne spécifie pas de valeur par défaut. L'administrateur du cluster doit spécifier un nom de répertoire au moment de la création de la ressource. Cette valeur ne pourra pas être modifiée ultérieurement car son paramétrage est limité à AT_CREATION .

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

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

Étant donné que la propriété déclare une valeur par défaut, l'administrateur du cluster peut spécifier une nouvelle valeur ou accepter la valeur par défaut au moment de la création de la ressource. Cette valeur ne pourra pas être modifiée ultérieurement car son paramétrage est limité à AT_CREATION .

Conventions d'attribution de noms pour les fonctions et les méthodes de rappel

Vous pouvez identifier les différentes parties de l'exemple de code grâce aux conventions suivantes :

Fonction scds_initialize()

La DSDL requiert que chaque méthode de rappel appelle la fonction scds_initialize () au début de la méthode. Cette fonction exécute les opérations suivantes :

Utilisez la fonction scds_close() pour récupérer les ressources affectées par scds_initialize().

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.


Méthode Arrêt_xfnts

La méthode xfnts_start utilisant la fonction scds_pmf_start() pour démarrer le service sous le gestionnaire de processus, xfnts_stop utilise la fonction scds_pmf_stop() pour l'arrêter.


Remarque –

Le premier appel d'xfnts_stop est destiné à la fonction 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.


La méthode xfnts_stop appelle la méthode svc_stop(), qui est définie dans le fichier 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); /* Successfully stopped */

Notez les points suivants concernant l'appel de svc_stop() à la fonction scds_pmf_stop() :


Remarque –

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


Méthode de démarrage_détecteur_xfnts

Le RGM appelle la méthode Monitor_start sur un noeud pour démarrer le détecteur de pannes après le démarrage d'une ressource sur ce noeud. 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 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.


La méthode xfnts_monitor_start appelle la méthode mon_start , qui est définie dans le fichier 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));

    /* Call scds_pmf_start and pass the name of the probe. */
   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); /* Successfully started Monitor */
}

Notez les points suivants concernant l'appel de svc_mon_start() destiné à la fonction scds_pmf_start() :


Remarque –

Avant de quitter, la méthode xfnts_monitor_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.


Méthode Arrêt_détecteur_xfnts

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 arrêter le démon du détecteur.


Remarque –

Le premier appel de xfnts_monitor_stop 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.


La méthode xfnts_monitor_stop() appelle la méthode mon_stop , qui est définie dans le fichier 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); /* Successfully stopped monitor */
}

Notez les points suivants concernant l'appel de svc_mon_stop() destiné à la fonction scds_pmf_stop() :


Remarque –

Avant de quitter, la méthode xfnts_monitor_stop 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.


Méthode xfnts_monitor_check

Le RGM appelle la méthode Monitor_check à chaque tentative du détecteur de pannes de basculer le groupe contenant la ressource sur un autre noeud. La méthode xfnts_monitor_check appelle la méthode svc_validate() pour vérifier qu'une configuration correcte est en place pour prendre en charge le démon xfs. Reportez-vous à la section Méthode xfnts_validate pour en savoir plus. Le code de xfnts_monitor_check est le suivant :

/* Process the arguments passed by RGM and initialize 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);

   /* Free up all the memory allocated by scds_initialize */
   scds_close(&scds_handle);

   /* Return the result of validate method run as part of monitor check */
   return (rc);
}

Détecteur de pannes SUNW.xfnts

Le RGM n'appelle pas directement la méthode PROBE : il appelle d'abord la méthode Monitor_start pour démarrer le détecteur après le démarrage d'une ressource sur un noeud. 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 en oeuvre une boucle. Mais avant cela, xfonts_probe effectue les opérations suivantes :

La méthode xfnts_probe met en oeuvre la boucle suivante :

for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
         /*
          * Grab the hostname and port on which the
          * health has to be monitored.
          */
         hostname = netaddr->netaddrs[ip].hostname;
         port = netaddr->netaddrs[ip].port_proto.port;
         /*
          * HA-XFS supports only one port and
          * hence obtain the port value from the
          * first entry in the array of ports.
          */
         ht1 = gethrtime(); /* Latch probe start time */
         scds_syslog(LOG_INFO, "Probing the service on port: %d.", port);

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

         /*
          * Update service probe history,
          * take action if necessary.
          * Latch probe end time.
          */
         ht2 = gethrtime();

         /* Convert to milliseconds */
         dt = (ulong_t)((ht2 - ht1) / 1e6);

         /*
          * Compute failure history and take
          * action if needed
          */
         (void) scds_fm_action(scds_handle,
             probe_result, (long)dt);
      }   /* Each net resource */
   }    /* Keep probing forever */

La fonction svc_probe() met la logique de sondage en oeuvre. La valeur de retour de svc_probe() est transmise à scds_fm_action (), qui détermine s'il faut redémarrer l'application, basculer le groupe de ressources, ou ne rien faire du tout.

Fonction svc_probe()

La fonction svc_probe () établit une connexion de prise simple au port spécifié en appelant scds_fm_tcp_connect(). Si la connexion échoue, svc_probe() renvoie une valeur de 100, ce qui indique un échec total. Si la connexion est établie mais que la déconnexion échoue, svc_probe() renvoie une valeur de 50, ce qui indique un échec partiel. Si la connexion et la déconnexion fonctionnent, svc_probe() renvoie une valeur de 0, ce qui indique 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;


   /*
    * probe the data service by doing a socket connection to the port
    * specified in the port_list property to the host that is
    * serving the XFS data service. If the XFS service which is configured
    * to listen on the specified port, replies to the connection, then
    * the probe is successful. Else we will wait for a time period set
    * in probe_timeout property before concluding that the probe failed.
    */

   /*
    * Use the SVC_CONNECT_TIMEOUT_PCT percentage of timeout
    * to connect to the port
    */
   connect_timeout = (SVC_CONNECT_TIMEOUT_PCT * timeout)/100;
   t1 = (hrtime_t)(gethrtime()/1E9);

   /*
    * the probe makes a connection to the specified hostname and port.
    * The connection is timed for 95% of the actual probe_timeout.
    */
   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));
      /* this is a complete failure */
      return (SCDS_PROBE_COMPLETE_FAILURE);
   }

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

   /*
    * Compute the actual time it took to connect. This should be less than
    * or equal to connect_timeout, the time allocated to connect.
    * If the connect uses all the time that is allocated for it,
    * then the remaining value from the probe_timeout that is passed to
    * this function will be used as disconnect timeout. Otherwise, the
    * the remaining time from the connect call will also be added to
    * the disconnect timeout.
    *
    */

   time_used = (int)(t2 - t1);

   /*
    * Use the remaining time(timeout - time_took_to_connect) to disconnect
    */

   time_remaining = timeout - (int)time_used;

   /*
    * If all the time is used up, use a small hardcoded timeout
    * to still try to disconnect. This will avoid the fd leak.
    */
   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;
   }

   /*
    * Return partial failure in case of disconnection failure.
    * Reason: The connect call is successful, which means
    * the application is alive. A disconnection failure
    * could happen due to a hung application or heavy load.
    * If it is the later case, don't declare the application
    * as dead by returning complete failure. Instead, declare
    * it as partial failure. If this situation persists, the
    * disconnect call will fail again and the application will be
    * restarted.
    */
   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));
      /* this is a partial failure */
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }

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

   /*
    * If there is no time left, don't do the full test with
    * fsinfo. Return SCDS_PROBE_COMPLETE_FAILURE/2
    * instead. This will make sure that if this timeout
    * persists, server will be restarted.
    */
   if (time_remaining <= 0) {
      scds_syslog(LOG_ERR, "Probe timed out.");
      return (SCDS_PROBE_COMPLETE_FAILURE/2);
   }

   /*
    * The connection and disconnection to port is successful,
    * Run the fsinfo command to perform a full check of
    * server health.
    * Redirect stdout, otherwise the output from fsinfo
    * ends up on the 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);
}

Ensuite, 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écider de la mesure à prendre. La logique de scds_fm_action() est la suivante :

Par exemple, supposons que la sonde établisse une connexion au serveur xfs, mais qu'elle 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. L'échec de la déconnexion entraîne l'envoi d'un échec partiel ( 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, au cours de la détection suivante, le serveur n'arrive toujours pas à se déconnecter, une valeur de 50 est ajoutée à l'historique des pannes géré par scds_fm_action (). La valeur des pannes cumulées 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 un administrateur de cluster met à jour les propriétés de la ressource ou de son groupe. Le RGM appelle Validation avant la création ou la mise à jour, et un code de sortie avec échec issu de la méthode sur un noeud entraîne l'annulation de la création ou de la mise à jour.

Le RGM n'appelle Validate que lorsqu'un administrateur de cluster modifie les propriétés de la ressource ou du groupe de ressources, ou lorsqu'un dispositif de surveillance définit les propriétés Status et Status_msg de la ressource. Le RGM n'appelle pas Validate lorsque le RGM définit les propriétés.


Remarque –

La méthode Monitor_check appelle également explicitement la méthode Validate à chaque fois que la méthode PROBE tente de basculer le service de données sur un autre noeud.


Le RGM appelle Validate avec des arguments supplémentaires, en plus de ceux qui sont transmis à d'autres méthodes, dont les propriétés et les valeurs qui sont 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 l'argument 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 conditions suivantes :

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

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

   return (rc); /* return result of validation */

Remarque –

Avant de quitter, la méthode xfnts_validate 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.


Méthode Mise_à_jour_xfnts

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

  /* check if the Fault monitor is already running and if so stop
   * and restart it. The second parameter to scds_pmf_restart_fm()
   * uniquely identifies the instance of the fault monitor that needs
   * to be restarted.
   */

   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.");
      /* Free up all the memory allocated by scds_initialize */
      scds_close(&scds_handle);
      return (1);
   }

   scds_syslog(LOG_INFO,
   "Completed successfully.");

Remarque –

Le second argument destiné à scds_pmf_restart_fm() identifie uniquement l'instance du détecteur de pannes à redémarrer s'il y en a plusieurs. La valeur 0 dans l'exemple indique qu'il n'y a qu'une seule instance du détecteur de pannes.