Sun Cluster Entwicklerhandbuch Datendienste für Solaris OS

Kapitel 8 Beispielressourcentyp-Implementierung mit DSDL

Dieses Kapitel beschreibt einen Beispielressourcentyp, SUNW.xfnts, der mit der DSDL implementiert wird. Der Datendienst ist in C geschrieben. Die zugrunde liegende Anwendung ist X Font Server, ein TCP/IP-basierter Dienst.

In diesem Kapitel finden Sie folgende Informationen:

X Font Server

X Font Server ist ein einfacher, TCP/IP-basierter Dienst, der seinen Clients Schriftdateien zustellt. Clients stellen eine Verbindung mit dem Server her, um einen Schriftsatz anzufordern. Der Server liest die Schriftdateien von der Platte und stellt sie den Clients zu. Der X Font Server-Dämon besteht aus einer Server-Binärdatei, /usr/openwin/bin/xfs. Der Dämon wird in der Regel von inetd aus gestartet. In diesem Beispiel wird jedoch angenommen, dass der entsprechende Eintrag in der /etc/inetd.conf-Datei deaktiviert wurde (zum Beispiel durch den Befehl fsadmin -d). Daher befindet sich der Dämon unter alleiniger Steuerung durch Sun Cluster.

X Font Server-Konfigurationsdatei

Standardmäßig liest X Font Server die Konfigurationsinformationen aus der Datei /usr/openwin/lib/X11/fontserver.cfg. Der Katalogeintrag in diese Datei enthält eine Liste der Schriftverzeichnisse, die dem Dämon zur Verfügung stehen. Der Cluster-Verwalter kann die Schriftverzeichnisse im globalen Dateisystem ablegen. Dadurch wird die Verwendung von X Font Server unter Sun Cluster optimiert, da im System nur eine einzige Kopie der Schriftdatenbank verwaltet wird. Dann muss der Verwalter fontserver.cfg dahingehend bearbeiten, dass die neuen Pfade für die Schriftverzeichnisse enthalten sind.

Zur Vereinfachung der Konfiguration kann der Verwalter auch die Konfigurationsdatei selbst im globalen Dateisystem ablegen. Der xfs-Dämon stellt Befehlszeilenargumente bereit, mit denen der vorgegebene Standardspeicherort dieser Datei übersteuert wird. Der SUNW.xfnts-Ressourcentyp verwendet den folgenden Befehl zum Starten des Dämons unter Sun Cluster-Steuerung:


/usr/openwin/bin/xfs -config <Speicherort_der_CFG_Datei>/fontserver.cfg \
-port <Port-Nummer>

In der SUNW.xfnts-Ressourcentypimplementierung können Sie die Confdir_list-Eigenschaft zum Verwalten des Speicherortes der fontserver.cfg-Konfigurationsdatei verwenden.

TCP-Port-Nummer

Die TCP-Port-Nummer, die der xfs-Serverdämon abhört, ist normalerweise der “fs”-Port (üblicherweise als 7100 in der /etc/services-Datei definiert). Mit der Option -port an der xfs-Befehlszeile kann der Systemverwalter jedoch die Standardeinstellung übersteuern. Sie können die Port_list-Eigenschaft im SUNW.xfnts-Ressourcentyp verwenden, um den Standardwert einzustellen und um die Verwendung der Option -port an der xfs-Befehlszeile zu unterstützen. Der Standardwert dieser Eigenschaft wird als 7100/tcp in der RTR-Datei definiert. In der SUNW.xfnts-Start-Methode wird Port_list an die Option -port an der xfs-Befehlszeile übergeben. Daher muss der Benutzer dieses Ressourcentyps keine Port-Nummer angeben—der Standard-Port ist 7100/tcp—, er hat jedoch die Möglichkeit, bei der Konfiguration des Ressourcentyps einen anderen Port anzugeben, indem er einen anderen Wert für die Port_list -Eigenschaft angibt.

Namenskonventionen

Sie können die verschiedenen Teile des Beispielcodes identifizieren, indem Sie auf folgende Konventionen achten.

SUNW.xfnts-RTR-Datei

Dieser Abschnitt beschreibt mehrere Schlüsseleigenschaften in der SUNW.xfnts-RTR-Datei. Der Zweck der einzelnen Eigenschaften in der Datei wird nicht beschrieben. Diese Beschreibung finden Sie unter Einstellen der Ressourcen- und Ressourcentypeigenschaften.

Die Confdir_list-Erweiterungseigenschaft identifiziert das Konfigurationsverzeichnis (bzw. eine Verzeichnisliste) folgendermaßen:


{
        PROPERTY = Confdir_list;
        EXTENSION;
        STRINGARRAY;
        TUNABLE = AT_CREATION;
        DESCRIPTION = "The Configuration Directory Path(s)";
}

Die Confdir_list-Eigenschaft gibt keinen Standardwert an. Der Cluster-Verwalter muss zum Zeitpunkt der Ressourcenerstellung ein Verzeichnis angeben. Dieser Wert kann später nicht mehr geändert werden, da seine Einstellbarkeit auf AT_CREATION beschränkt ist.

Die Port_list-Eigenschaft identifiziert folgendermaßen den Port, den der Serverdämon abhört:


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

Da für die Eigenschaft ein Standardwert deklariert wird, kann der Cluster-Verwalter zum Zeitpunkt der Ressourcenerstellung entscheiden, ob er einen neuen Wert angibt oder den Standardwert akzeptiert. Dieser Wert kann später nicht mehr geändert werden, da seine Einstellbarkeit auf AT_CREATION beschränkt ist.

scds_initialize()-Funktion

Die DSDL erfordert, dass jede Rückmeldemethode zu Methodenbeginn die scds_initialize(3HA)-Funktion aufruft. Diese Funktion führt folgende Vorgänge aus:

Sie verwendet die scds_close()-Funktion, um die Ressourcen zurückzufordern, die von scds_initialize() zugewiesen wurden.

xfnts_start-Methode

RGM ruft die Start-Methode auf einem Cluster-Knoten auf, wenn die Ressourcengruppe mit der Datendienstressource auf diesem Knoten online gebracht wird bzw. wenn die Ressource aktiviert wird. Im SUNW.xfnts-Beispielressourcentyp aktiviert die xfnts_start-Methode den xfs-Dämon auf diesem Knoten.

Die xfnts_start-Methode ruft scds_pmf_start() auf, um den Dämon unter PMF zu starten. PMF verfügt über automatische Fehlerbenachrichtigungs- und Neustartfunktionen und ist in den Fehler-Monitor integriert.


Hinweis –

Der erste Aufruf in xfnts_start erfolgt an scds_initialize(). Diese Funktion führt einige notwendige Systemverwaltungs-Funktionen aus (weitere Einzelheiten hierzu finden Sie in der Online-Dokumentation unter scds_initialize()-Funktion und scds_initialize(3HA)).


Validieren des Dienstes vor dem Start

Vor dem Versuch, X Font Server zu starten, ruft die xfnts_start-Methode svc_validate() auf, um zu überprüfen, ob eine geeignete Konfiguration zur Unterstützung des xfs-Dämons eingerichtet ist (weitere Einzelheiten hierzu finden Sie unter xfnts_validate-Methode):


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

Starten des Dienstes

Die xfnts_start-Methode ruft die svc_start()-Methode auf, die in xfnts.c definiert ist, um den xfs-Dämon zu starten. Dieser Abschnitt beschreibt svc_start().

Folgender Befehl startet den xfs-Dämon:


xfs -config Konfig_verzeichnis/fontserver.cfg -port Port_Nummer

Die Confdir_list-Erweiterungseigenschaft identifiziert Konfig_verzeichnis, während die Port_list-Systemeigenschaft Port_Nummer identifiziert. Beim Konfigurieren des Datendienstes stellt der Cluster-Verwalter spezifische Werte für diese Eigenschaften bereit.

Die xfnts_start-Methode deklariert diese Eigenschaften als Zeichenketten-Arrays und ruft die Werte ab, die der Verwalter mit den Funktionen scds_get_ext_confdir_list() und scds_get_port_list() einstellt (beschrieben unter scds_property_functions(3HA)):


scha_str_array_t *confdirs;
scds_port_list_t    *portlist;
scha_err_t   err;

   /* get the configuration directory from the confdir_list property */
   confdirs = scds_get_ext_confdir_list(scds_handle);

   (void) sprintf(xfnts_conf, "%s/fontserver.cfg", confdirs->str_array[0]);

   /* obtain the port to be used by XFS from the Port_list property */
   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);
   }

Beachten Sie, dass die confdirs-Variable auf das erste Element (0) im Array zeigt.

Die xfnts_start-Methode verwendet sprintf, um die Befehlszeile für xfs zu bilden:


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

Beachten Sie, dass die Ausgabe an dev/null umgeleitet wird, um die vom Dämon generierten Meldungen zu unterdrücken.

Die xfnts_start-Methode übergibt die xfs-Befehlszeile an scds_pmf_start(), um den Datendienst unter PMF-Steuerung zu starten:


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

Beachten Sie folgende Punkte bezüglich des Aufrufs an scds_pmf_start().

Vor der Rückgabe gibt svc_pmf_start() den der portlist-Struktur zugewiesenen Speicherplatz frei:


scds_free_port_list(portlist);
return (err);

Rückgabe von svc_start()

Auch wenn svc_start() Erfolg zurückgibt, kann es sein, dass die zugrunde liegende Anwendung nicht gestartet wurde. Daher muss svc_start() die Anwendung testen, um sicherzustellen, dass sie läuft, bevor eine Erfolgsmeldung zurückgegeben wird. Beim Testen muss beachtet werden, dass die Anwendung eventuell nicht sofort zur Verfügung steht, weil sie einige Zeit zum Starten benötigt. Die svc_start()-Methode ruft die in xfnts.c definierte svc_wait()-Funktion auf, um zu überprüfen, ob die Anwendung läuft:


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

Die svc_wait()-Funktion ruft scds_get_netaddr_list(3HA) auf, um die für das Testen der Anwendung erforderlichen Netzwerkadressressourcen abzurufen:


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

Dann ruft svc_wait() die start_timeout- und stop_timeout-Werte ab:


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

Um die Zeit zu berücksichtigen, die der Server zum Starten benötigt, ruft svc_wait() die scds_svc_wait()-Methode auf und übergibt einen Zeitüberschreitungswert, der drei Prozent des start_timeout-Wertes entspricht. Dann ruft svc_wait() die svc_probe()-Methode auf, um zu überprüfen, ob die Anwendung gestartet wurde. Die svc_probe()-Methode stellt eine einfache Socketverbindung mit dem Server auf dem angegebenen Port her. Wenn die Verbindung mit dem Port fehlschlägt, gibt svc_probe() den Wert 100 für Totalfehlschlag zurück. Wenn die Verbindung hergestellt werden kann, aber die Verbindungstrennung vom Port fehlschlägt, gibt svc_probe() den Wert 50 zurück.

Bei Fehlschlag oder Teilfehlschlag von svc_probe() ruft svc_wait() die scds_svc_wait()-Methode mit einem Zeitüberschreitungswert von 5 auf. Die scds_svc_wait()-Methode beschränkt die Testhäufigkeit auf ein Testsignal alle fünf Sekunden. Diese Methode zählt auch die Anzahl der Startversuche für den Dienst. Wenn die Anzahl der Versuche den Wert der Retry_count-Ressourceneigenschaft innerhalb des von der Retry_interval-Ressourceneigenschaft angegebenen Zeitraums überschreitet, gibt die scds_svc_wait()-Funktion Fehlschlag zurück. In diesem Fall gibt die svc_start()-Funktion ebenfalls Fehlschlag zurück.


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


Hinweis –

Vor der Beendigung ruft die xfnts_start-Methode scds_close() auf, um die von scds_initialize() zugewiesenen Ressourcen zurückzufordern. Weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_close(3HA).


xfnts_stop-Methode

Da die xfnts_start-Methode scds_pmf_start() verwendet, um den Dienst unter PMF zu starten, verwendet die xfnts_stop-Methode scds_pmf_stop() zum Stoppen des Dienstes.


Hinweis –

Der erste Aufruf in xfnts_stop erfolgt an scds_initialize(), um einige erforderliche Systemverwaltungs-Funktionen auszuführen (weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_initialize(3HA)).


Die xfnts_stop-Methode ruft die in xfnts.c definierte svc_stop()-Methode folgendermaßen auf.


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

Bezüglich des Aufrufs in svc_stop() an die scds_pmf_stop()-Funktion ist Folgendes zu beachten.


Hinweis –

Vor der Beendigung ruft die xfnts_stop-Methode scds_close() auf, um die von scds_initialize() zugewiesenen Ressourcen zurückzufordern. Weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_close(3HA).


xfnts_monitor_start-Methode

RGM ruft die Monitor_start-Methode auf einem Knoten auf, um den Fehler-Monitor zu starten, nachdem eine Ressource auf diesem Knoten gestartet wurde. Die xfnts_monitor_start-Methode verwendet scds_pmf_start(), um den Monitor-Dämon unter PMF zu starten.


Hinweis –

Der erste Aufruf in xfnts_monitor_start erfolgt an scds_initialize(). Diese Funktion führt einige wichtige Systemverwaltungs-Funktionen aus (weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_initialize(3HA)).


Die xfnts_monitor_start-Methode ruft die in xfnts.c definierte mon_start-Methode folgendermaßen auf:


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

Bezüglich des Aufrufs in svc_mon_start() an die scds_pmf_start()-Funktion ist Folgendes zu beachten.


Hinweis –

Vor der Beendigung ruft die xfnts_monitor_start-Methode scds_close() auf, um die von scds_initialize() zugewiesenen Ressourcen zurückzufordern. Weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_close(3HA).


xfnts_monitor_stop-Methode

Da die xfnts_monitor_start-Methode scds_pmf_start() zum Starten des Monitor-Dämons unter PMF verwendet, setzt xfnts_monitor_stop die scds_pmf_stop()-Methode zum Stoppen des Monitor-Dämons ein.


Hinweis –

Der erste Aufruf in xfnts_monitor_stop erfolgt an scds_initialize(). Diese Funktion führt einige wichtige Systemverwaltungs-Funktionen aus (weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_initialize(3HA)).


Die xfnts_monitor_stop()-Methode ruft die in xfnts.c definierte mon_stop-Methode folgendermaßen auf:


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

Bezüglich des Aufrufs in svc_mon_stop() an die scds_pmf_stop()-Funktion ist Folgendes zu beachten.


Hinweis –

Vor der Beendigung ruft die xfnts_monitor_stop-Methode scds_close() auf, um die von scds_initialize() zugewiesenen Ressourcen zurückzufordern. Weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_close(3HA).


xfnts_monitor_check-Methode

RGM ruft die Monitor_check-Methode immer dann auf, wenn der Fehler-Monitor versucht, für die Ressourcengruppe der Ressorce ein Failover auf einen anderen Knoten auszuführen. Die xfnts_monitor_check-Methode ruft die svc_validate()-Methode auf, um zu überprüfen, ob eine geeignete Konfiguration zum Unterstützen des xfs-Dämons vorhanden ist (Einzelheiten finden Sie unter xfnts_validate-Methode). Der Code für xfnts_monitor_check sieht folgendermaßen aus:


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

SUNW.xfnts-Fehler-Monitor

RGM ruft die PROBE-Methode nicht direkt auf. Es wird vielmehr die Monitor_start -Methode aufgerufen, um den Monitor zu starten, nachdem eine Ressource auf einem Knoten gestartet wurde. Die xfnts_monitor_start-Methode startet den Fehler-Monitor unter PMF-Steuerung. Die xfnts_monitor_stop-Methode stoppt den Fehler-Monitor.

Der SUNW.xfnts-Fehler-Monitor führt folgende Aufgaben aus:

xfonts_probe-Hauptschleife

Die xfonts_probe -Methode implementiert eine Schleife. Vor dem Implementieren der Schleife führt xfonts_probe folgende Aktionen aus:

Die xfnts_probe-Methode implementiert die Schleife folgendermaßen:


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

Die svc_probe()-Funktion implementiert die Testsignallogik. Der Rückgabewert von svc_probe() wird an scds_fm_action() übergeben. Diese Funktion entscheidet, ob die Anwendung neu gestartet, ein Failover der Ressourcengruppe ausgeführt werden oder nichts geschehen soll.

svc_probe()-Funktion

Die svc_probe()-Funktion stellt eine einfache Socketverbindung mit dem angegebenen Port her, indem sie scds_fm_tcp_connect() aufruft. Wenn die Verbindung fehlschlägt, gibt svc_probe() den Wert 100 für Totalfehlschlag zurück. Wenn die Verbindung hergestellt werden kann, aber die Verbindungstrennung fehlschlägt, gibt svc_probe() den Wert 50 für Teilfehlschlag zurück. Wenn sowohl die Verbindung als auch die Verbindungstrennung erfolgreich verlaufen, gibt svc_probe() den Wert 0 für Erfolg zurück.

Der Code für svc_probe() sieht folgendermaßen aus:


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

Nach Beendigung gibt svc_probe() einen Wert für Erfolg (0), Teilfehlschlag (50), oder Totalfehlschlag (100) zurück. Die xfnts_probe-Methode übergibt diesen Wert an scds_fm_action().

Festlegen der Fehler-Monitor-Aktion

Die xfnts_probe-Methode ruft scds_fm_action() auf, um die auszuführende Aktion festzulegen. Die Logik in scds_fm_action() sieht folgendermaßen aus:

Angenommen, das Testsignal stellt eine Verbindung mit dem XFS-Server her, kann die Verbindung jedoch nicht trennen. Das bedeutet, dass der Server läuft, aber vielleicht hängt oder nur momentan überlastet ist. Bei Fehlschlag der Verbindungstrennung wird ein Teilfehlschlag (50) an scds_fm_action() gesendet. Dieser Wert liegt unter dem Schwellenwert für das Neustarten des Datendienstes. Der Wert wird jedoch in der Fehlerhistorie festgehalten.

Wenn während des nächsten Tests die Verbindungstrennung vom Server erneut fehlschlägt, wird ein Wert von 50 der von scds_fm_action() verwalteten Fehlschlaghistorie hinzugefügt. Der kumulative Fehlschlagwert beträgt nun 100, so dass scds_fm_action() den Datendienst neu startet.

xfnts_validate-Methode

RGM ruft die Validate-Methode auf, wenn eine Ressource erstellt wird und wenn eine Verwaltungsaktion die Eigenschaften der Ressource bzw. deren Gruppe aktualisiert. RGM ruft Validate auf, bevor die Erstellung bzw. Aktualisierung angewendet wird. Ein Fehlerbeendigungscode der Methode auf einem Knoten führt zum Abbruch der Erstellung bzw. Aktualisierung.

RGM ruft Validate nur dann auf, wenn Ressourcen- bzw. Gruppeneigenschaften über eine Verwaltungsaktion geändert werden, und nicht, wenn RGM Eigenschaften einstellt oder wenn ein Monitor die Ressourceneigenschaften Status und Status_msg einstellt.


Hinweis –

Die Monitor_check-Methode ruft auch ausdrücklich jedes Mal dann die Validate-Methode auf, wenn die PROBE-Methode versucht, ein Failover für den Datendienst auf einen neuen Knoten auszuführen.


RGM ruft Validate mit zusätzlichen Argumenten zu denjenigen auf, die von anderen Methoden übergeben wurden, einschließlich der aktualisierten Eigenschaften und Werte. Bei Aufruf von scds_initialize() zu Beginn von xfnts_validate werden alle Argumente analysiert, die RGM an xfnts_validate übergibt, und die Informationen werden im scds_handle-Parameter gespeichert. Die Unterroutinen, die xfnts_validate aufruft, verwenden diese Informationen.

Die xfnts_validate-Methode ruft svc_validate() auf, um Folgendes zu prüfen:

Vor der Rückgabe gibt svc_validate() alle zugewiesenen Ressourcen frei.


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

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


Hinweis –

Vor der Beendigung ruft die xfnts_validate-Methode scds_close() auf, um die von scds_initialize() zugewiesenen Ressourcen zurückzufordern. Weitere Einzelheiten finden Sie unter scds_initialize()-Funktion und in der Online-Dokumentation unter scds_close(3HA).


xfnts_update-Methode

RGM ruft die Update-Methode auf, um eine laufende Ressource darüber zu benachrichtigen, dass ihre Eigenschaften geändert wurden. Die einzigen Eigenschaften des xfnts-Datendienstes, die geändert werden können, betreffen den Fehler-Monitor. Wenn daher eine Eigenschaft aktualisiert wird, ruft die xfnts_update-Methode scds_pmf_restart_fm() auf, um den Fehler-Monitor neu zu starten.


* 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.");


Hinweis –

Der zweite Parameter von scds_pmf_restart_fm() identifiziert eindeutig die Instanz des Fehler-Monitors, die neu gestartet werden muss, wenn mehrere Instanzen vorhanden sind. Der Wert 0 im Beispiel gibt an, dass nur eine Instanz des Fehler-Monitors vorhanden ist.