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

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().