この章では、in.named アプリケーションを Sun Cluster データサービスとして稼働する HA-DNS について説明します。in.named デーモンは Solaris におけるドメインネームサービス (DNS) の実装です。サンプルのデータサービスでは、RMAPI を使用して、アプリケーションの高可用性を実現する方法を示します。
RMAPI は、シェルスクリプトと C プログラムの両方のインタフェースをサポートします。この章のサンプルアプリケーションはシェルスクリプトインタフェースで作成されています。
サンプルのデータサービスはクラスタのイベント (管理アクション、アプリケーションの異常終了、ノードの異常終了など) に応じて、DNS アプリケーションを起動、停止、再起動、およびラスタノード間の切り替えを行います。
アプリケーションの再起動は、プロセス監視機能 (PMF) によって管理されます。アプリケーションの障害が再試行最大期間または再試行最大回数を超えると、障害モニターはアプリケーションリソースを含むリソースグループを別のノードにフェイルオーバーします。
サンプルのデータサービスは、PROBE メソッドという形で障害監視機能を提供します。PROBE メソッドは、nslookup コマンドを使用し、アプリケーションが正常な状態であることを保証します。DNS サービスのハングを検出すると、PROBE メソッドは、DNS アプリケーションをローカルで再起動することによって、この状況を修正しようとします。この方法で状況が改善されず、サービスの問題が繰り返し検出される場合、PROBE メソッドは、サービスをクラスタ内の別のノードにフェイルオーバーしようとします。
サンプルのアプリケーションには、具体的に、次のような機能が含まれています。
リソースタイプ登録ファイル - データサービスの静的なプロパティを定義します。
START コールバックメソッド - HA-DNS データサービスを含むリソースグループがオンラインになるときに RGM によって呼び出され、in.named デーモンを起動します。
STOP コールバックメソッド - HA-DNS データサービスを含むリソースグループがオフラインになるときに RGM によって呼び出され、in.named デーモンを停止します。
障害モニター - DNS サーバーが動作しているかどうかを確認することによって、サービスの信頼性を検査します。障害モニターはユーザー定義の PROBE メソッドによって実装され、MONITOR_START と MONITOR_STOP コールバックメソッドによって起動および停止されます。
VALIDATE コールバックメソッド - RGM によって呼び出され、サービスの構成ディレクトリがアクセス可能であるかどうかを検査します。
UPDATE コールバックメソッド - システム管理者がリソースプロパティの値を変更したときに RGM によって呼び出され、障害モニターを再起動します。
この例で使用するサンプルのリソースタイプ登録 (RTR) ファイルは、DNS リソースタイプの静的な構成を定義します。このタイプのリソースは、RTR ファイルで定義されているプロパティを継承します。
RTR ファイル内の情報は、クラスタ管理者が HA-DNS データサービスを登録したときに RGM によって読み取られます。
RTR ファイルの形式は明確に定義されています。リソースタイププロパティ、システム定義リソースプロパティ、拡張プロパティという順番で並んでいます。詳細は、rt_reg(4) のマニュアルページと 「リソースとリソースタイププロパティの設定」を参照してください。
この節では、サンプルの RTR ファイルの特定のプロパティについて説明します。この節で扱うリストは、サンプルの RTR ファイルの一部だけです。サンプルの RTR ファイルの完全なリストについては、「リソースタイプ登録ファイルのリスト」を参照してください。
次のリストに示すように、サンプルの RTR ファイルはコメントから始まり、その後に、HA-DNS 構成を定義するリソースタイププロパティが続きます。
# # Copyright (c) 1998-2001 by Sun Microsystems, Inc. # All rights reserved. # # Registration information for Domain Name Service (DNS) # #pragma ident "@(#)SUNW.sample 1.1 00/05/24 SMI" RESOURCE_TYPE = "sample"; VENDOR_ID = SUNW; RT_DESCRIPTION = "Domain Name Service on Sun Cluster"; RT_VERSION ="1.0"; API_VERSION = 2; FAILOVER = TRUE; RT_BASEDIR=/opt/SUNWsample/bin; PKGLIST = SUNWsample; START = dns_svc_start; STOP = dns_svc_stop; VALIDATE = dns_validate; UPDATE = dns_update; MONITOR_START = dns_monitor_start; MONITOR_STOP = dns_monitor_stop; MONITOR_CHECK = dns_monitor_check;
RTR ファイルの最初のエントリには、Resource_type プロパティを宣言する必要があります。宣言しないと、リソースタイプの登録は失敗します。
RGM はプロパティ名の大文字と小文字を区別します。Sun が提供する RTR ファイルにおけるプロパティの規約としては、最初の文字は大文字で、残りの文字は小文字にします。ただし、メソッド名は例外で、プロパティ属性と同様に、すべての文字を大文字にします 。
リソースタイプ名は、Resource_type プロパティだけで指定できます (例 : sample)。あるいは、Vendor_id、"."、Resource_type という形式でも指定できます (例 : SUNW.sample)。
Vendor_id を接頭辞として使用する場合、リソースタイプを定義している企業の会社名を使用します。リソースタイプ名はクラスタ内で一意である必要があります。
Rt_version プロパティは、ベンダーによって指定されたサンプルのデータサービスのバージョンを識別します。
API_version プロパティは Sun Cluster のバージョンを識別します。たとえば、「API_version =2」はデータサービスが Sun Cluster バージョン 3.0 の管理下で動作していることを示します。
Failover = TRUE は、同時に複数のノード上でオンラインになることができるリソースグループでは、データサービスが動作できないことを示します。
RT_basedir は相対パス (コールバックメソッドのパスなど) を補完するためのディレクトリパスで、/opt/SUNWsample/bin を指します。
START、STOP、VALIDATE などは、RGM によって呼び出される個々のコールバックメソッドプログラムへのパスを提供します。これらのパスは、RT_basedir に指定されたディレクトリからのパスになります。
Pkglist は、SUNWsample をサンプルのデータサービスのインストールを含むパッケージとして識別します。
この RTR ファイルに指定されていないリソースタイププロパティ (Single_instance、Init_nodes、Installed_nodes など) は、デフォルト値を取得します。リソースタイププロパティの完全なリストとそのデフォルト値については、表 A-1 を参照してください。
クラスタ管理者は、RTR ファイルのリソースタイププロパティに指定されている値を変更できません。
慣習上、RTR ファイルでは、リソースプロパティをリソースタイププロパティの後に宣言します。リソースプロパティには、Sun Cluster が提供するシステム定義プロパティと、データサービス開発者が定義する拡張プロパティが含まれます。どちらのタイプの場合でも、Sun Cluster が提供するプロパティ属性の数 (最小、最大、デフォルト値など) を指定できます。
次のリストは、サンプル RTR ファイルのシステム定義プロパティを示しています。
# リソースタイプ宣言の後に、中括弧に囲まれたリソースプロパティ宣言のリスト # が続く。プロパティ名宣言は、各エントリの左中括弧の直後にある最初 # の属性である必要がある。 # # <method>_timeout プロパティは、RGM がメソッドの呼び出しが失敗 # したという結論を下すまでの時間 (秒) を設定する。 # すべてのメソッドタイムアウトの MIN 値は 60 秒に設定されている。こ # れは、管理者が短すぎる時間を設定することを防ぐためである。短すぎ # る時間を設定すると、スイッチオーバーやフェイルオーバーの性能が上 # がらず、さらには、予期せぬ RGM アクションが発生する可能性がある # (間違ったフェイルオーバー、ノードの再起動、リソースグループの # ERROR_STOP_FAILED 状態への移行、オペレータの介入の必要性など)。 # メソッドタイムアウトに短すぎる時間を設定すると、データサービス全 # 体の可用性を下げることになる。 { PROPERTY = Start_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Stop_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Validate_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Update_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Monitor_Start_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Monitor_Stop_timeout; MIN=60; DEFAULT=300; } { PROPERTY = Thorough_Probe_Interval; MIN=1; MAX=3600; DEFAULT=60; TUNABLE = ANYTIME; } # 当該ノード上でアプリケーションを正常に起動できないと結論を下すま # でに、指定された期間内 (Retry_Interval) に行う再試行の回数 { PROPERTY = Retry_Count; MIN=0; MAX=10; DEFAULT=2; TUNABLE = ANYTIME; } # Retry_Interval には 60 の倍数を設定する。これは、秒から分に変換さ # れ、端数が切り上げられるためである。たとえば、60 (秒) という値を指 # 定すると、1 分に変換される。 # このプロパティは再試行回数 (Retry_Count) のタイミングを決定する。 { PROPERTY = Retry_Interval; MIN=60; MAX=3600; DEFAULT=300; TUNABLE = ANYTIME; } { PROPERTY = Network_resources_used; TUNABLE = AT_CREATION; DEFAULT = ""; }
Sun Cluster はシステム定義プロパティを提供しますが、リソースプロパティ属性を使用すると、異なるデフォルト値を設定できます。リソースプロパティに適用するために利用できる属性の完全なリストについては、「リソースプロパティの属性」 を参照してください。
サンプルの RTR ファイル内のシステム定義リソースプロパティについては、次の点に注意してください。
Sun Cluster は、すべてのタイムアウトに最小値 (1 秒) とデフォルト値 (3600 秒) を提供します。サンプルの RTR ファイルは、最小値をそのまま (60 秒) にし、デフォルト値を 300 秒に変更しています。クラスタ管理者は、このデフォルト値を使用することも、タイムアウト値を変更することもできます (たとえば、60秒以上)。Sun Cluster は正当な最大値を持っていません。
Thorough_Probe_Interval、Retry_count、Retry_interval プロパティの TUNABLE 属性は ANYTIME に設定されています。この設定は、データサービスが動作中でも、クラスタ管理者がこれらのプロパティの値を変更できることを意味します。上記のプロパティは、サンプルのデータサービスによって実装される障害モニターによって使用されます。サンプルのデータサービスは、管理アクションによってさまざまなリソースが変更されたときに障害モニターを停止および再起動するように、UPDATE を実装します。「UPDATE メソッド」 を参照してください。
リソースプロパティは次のように分類されます。
必須-クラスタ管理者はリソースを作成するときに必ず値を指定する必要があります。
任意-クラスタ管理者が値を指定しない場合、システムがデフォルト値を提供します。
条件付き-RTR ファイルで宣言されている場合だけ、RGM はプロパティを作成します。
サンプルのデータサービスの障害モニターは、Thorough_probe_interval、 Retry_count、Retry_interval、Network_resources_used という条件付きプロパティを使用しているため、開発者はこれらのプロパティを RTR ファイルで宣言する必要があります。プロパティを分類する方法については、r_properties(5) のマニュアルページまたは 「リソースプロパティ」を参照してください。
次のリストに示すように、サンプルの RTR ファイルの終わりには拡張プロパティがあります。
# 拡張プロパティ # # クラスタ管理者はこのプロパティの値を設定し、アプリケーションが使用 # する構成ファイルが入っているディレクトリを示す必要がある。このアプリ # ケーションの場合、DNS は PXFS (通常は named.conf) 上の DNS # 構成ファイルのパスを指定する。 { PROPERTY = Confdir; EXTENSION; STRING; TUNABLE = AT_CREATION; DESCRIPTION = "The Configuration Directory Path"; } # 検証が失敗したと宣言するまでのタイムアウト値 (秒) { PROPERTY = Probe_timeout; EXTENSION; INT; DEFAULT = 30; TUNABLE = ANYTIME; DESCRIPTION = "Time out value for the probe (seconds)"; }
サンプルの RTR ファイルは 2 つの拡張プロパティ、Confdir と Probe_timeout を定義します。Confdir は、DNS 構成ディレクトリへのパスを指定します。このディレクトリには、DNS が正常に動作するために必要な in.named ファイルが格納されています。サンプルのデータサービスの START と VALIDATE メソッドはこのプロパティを使用し、DNS を起動する前に、構成ディレクトリと in.named ファイルがアクセス可能であるかどうかを確認します。
データサービスが構成されるとき、VALIDATE メソッドは、新しいディレクトリがアクセス可能であるかどうかを確認します。
サンプルのデータサービスの PROBE メソッドは、Sun Cluster コールバックメソッドではなく、ユーザー定義メソッドです。したがって、Sun Cluster は この Probe_timeout プロパティを提供しません。開発者はこの拡張プロパティを RTR ファイルに定義し、クラスタ管理者が Probe_timeout の値を構成できるようにする必要があります。
この節では、サンプルのデータサービスのすべてのメソッドで使用される次のような機能について説明します。
シェルスクリプトの最初の行は、コマンドインタプリタを指定します。サンプルのデータサービスの各メソッドスクリプトは、次に示すように、コマンドインタプリタを指定します。
#!/bin/ksh |
サンプルアプリケーション内のすべてのメソッドスクリプトは、Sun Cluster のバイナリとライブラリへのパスをエクスポートします。ユーザーの PATH 設定には依存しません。
######################################################################## # MAIN ######################################################################## export PATH=/bin:/usr/bin:/usr/cluster/bin:/usr/sbin:/usr/proc/bin:$PATH |
すべてのメソッドスクリプト (VALIDATE を除く) は、リソース名を渡し、pmfadm(1M) を使用してデータサービスまたはモニターのいずれかを起動 (または停止) します。各スクリプトは変数 PMF_TAG を定義し、pmfadm に渡すことによって、データサービスまたはモニターを識別できます。
同様に、各メソッドスクリプトは、logger(1) コマンドを使用してメッセージをシステムログに記録します。各スクリプトは変数 SYSLOG_TAG を定義し、-t オプションで logger に渡すことによって、メッセージが記録されるリソースのリソースタイプ、リソースグループ、リソース名を識別できます。
すべてのメソッドは、次に示す例と同じ方法で SYSLOG_TAG を定義します。dns_probe、dns_svc_start、dns_svc_stop、dns_monitor_check の各メソッドは、次のように PMF_TAG を定義します (なお、pmfadm と logger は dns_svc_stop メソッドのものを使用しています)。
###################################################################### # MAIN ###################################################################### PMF_TAG=$RESOURCE_NAME.named SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME # SIGTERM シグナルをデータサービスに送信し、合計タイムアウト値の 80% だけ待機する。 pmfadm -s $PMF_TAG.named -w $SMOOTH_TIMEOUT TERM if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.info ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Failed to stop HA-DNS with SIGTERM; Retry with ¥ SIGKILL" |
dns_monitor_stop、dns_monitor_stop、dns_update の各メソッドは、次のように PMF_TAG を定義します (なお、pmfadm は dns_monitor_stop メソッドのものを使用しています)。
###################################################################### # MAIN ###################################################################### PMF_TAG=$RESOURCE_NAME.monitor SYSLOG_TAG=$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME ... # モニターが動作しているかどうかを調べ、動作している場合は強制終了する。 if pmfadm -q $PMF_TAG.monitor; then pmfadm -s $PMF_TAG.monitor KILL |
RGM は、次に示すように、すべてのコールバックメソッド (VALIDATE を除く) を呼び出します。
method_name -R resource_name -T resource_type_name -G resource_group_name |
method_name は、コールバックメソッドを実装するプログラムのパス名です。データサービスは、各メソッドのパス名を RTR ファイルに指定します。このようなパス名は、RTR ファイルの Rt_basedir プロパティに指定されたディレクトリからのパスになります。たとえば、サンプルのデータサービスの RTR ファイルでは、ベースディレクトリとメソッド名は次のように指定されます。
RT_BASEDIR=/opt/SUNWsample/bin; START = dns_svc_start; STOP = dns_svc_stop; ... |
コールバックメソッドの引数はすべて、フラグ付きの値として渡されます。-R
はリソースインスタンスの名前を示し、-T
はリソースのタイプを示し、-G
はリソースが構成されているグループを示します。コールバックメソッドについての詳細は、rt_callbacks(1HA) のマニュアルページを参照してください。
VALIDATE メソッドを呼び出すときは、追加の引数 (リソースのプロパティ値と呼び出されるリソースグループ) を使用します。詳細は、「プロパティ更新の処理」を参照してください。
各コールバック、メソッドには、渡された引数を構文解析する関数が必要です。すべてのコールバックメソッドには同じ引数が渡されるので、データサービスは、アプリケーション内のすべてのコールバックメソッドで使用される単一の構文解析関数を提供します。
次に、サンプルのアプリケーションのコールバックメソッドで使用される parse_args 関数を示します。
###################################################################### # プログラム引数を解析する。 # function parse_args # [args ...] { typeset opt while getopts 'R:G:T:' opt do case "$opt" in R) # DNS リソースの名前 RESOURCE_NAME=$OPTARG ;; G) # リソースが構成されているリソース # グループの名前 RESOURCEGROUP_NAME=$OPTARG ;; T) # リソースタイプの名前 RESOURCETYPE_NAME=$OPTARG ;; *) logger -p ${SYSLOG_FACILITY}.err ¥ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] ¥ "ERROR: Option $OPTARG unknown" exit 1 ;; esac done } |
サンプルのアプリケーションの PROBE メソッドはユーザー定義メソッドですが、Sun Cluster コールバックメソッドと同じ引数で呼び出されます。したがって、このメソッドには、他のコールバックメソッドと同じ構文解析関数が含まれています。
構文解析関数は、次に示すように、MAIN の中で呼び出されます。
parse_args "$@" |
エラーメッセージをエンドユーザーに出力するには、syslog 機能をメソッドに使用することを推奨します。サンプルのデータサービスのすべてのコールバックメソッドは、次に示すように、scha_cluster_get コマンドを使用し、クラスタログ用に使用されている syslog 機能番号を取得します。
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY` |
この値はシェル変数 SYSLOG_FACILITY に格納されます。logger(1) コマンドの機能として使用すると、エラーメッセージをクラスタログに記録できます。たとえば、サンプルのデータサービスの START メソッドは、次に示すように、SYSLOG_FACILITY を取得し、データサービスが起動したことを示すメッセージを記録します。:
SYSLOG_FACILITY=`scha_cluster_get -O SYSLOG_FACILITY` ... if [ $? -eq 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} HA-DNS successfully started" fi |
詳細は、scha_cluster_get(1HA) のマニュアルページを参照してください。
ほとんどのコールバックメソッドは、データサービスのリソースとリソースタイプのプロパティについての情報を取得する必要があります。このために、API は scha_resource_get コマンドを提供しています。
リソースプロパティには 2 種類 (システム定義プロパティと拡張プロパティ) あります。システム定義プロパティは事前に定義されており、拡張プロパティはデータサービス開発者が RTR ファイルに定義します。
scha_resource_get を使用してシステム定義プロパティの値を取得するときは、-O パラメータでプロパティの名前を指定します。このコマンドは、プロパティの値だけを戻します。たとえば、サンプルのデータサービスの MONITOR_START メソッドは検証プログラムを特定し、起動できるようにしておく必要があります。検証プログラムはデータベースのベースディレクトリ (RT_BASEDIR プロパティが指す位置) 内に存在します。したがって、MONITOR_START メソッドは、次に示すように、RT_BASEDIR の値を取得し、その値を RT_BASEDIR 変数に格納します。
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G ¥ $RESOURCEGROUP_NAME` |
拡張プロパティの場合、データサービス開発者は、これが拡張プロパティであることを示す -O パラメータを指定し、最後のパラメータとしてプロパティの名前を指定する必要があります。拡張プロパティの場合、このコマンドは、プロパティのタイプと値の両方を戻します。たとえば、サンプルのデータサービスの検証プログラムは、次に示すように、probe_timeout 拡張プロパティのタイプと値を取得し、次に awk(1) コマンドを使用して値だけを PROBE_TIMEOUT シェル変数に格納します。
probe_timeout_info=`scha_resource_get -O Extension -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME Probe_timeout` PROBE_TIMEOUT=`echo $probe_timeout_info | awk '{print $2}'` |
データサービスは、クラスタ上でアプリケーションデーモンを起動するために START メソッドまたは PRENET_START メソッドを提供し、クラスタ上でアプリケーションデーモンを停止するために STOP メソッドまたは POSTNET_STOP メソッドを提供する必要があります。サンプルのデータサービスは、START メソッドと STOP メソッドを実装します。代わりに PRENET_START メソッドと POSTNET_STOP メソッドを使用する場合は、「START と STOP メソッドを使用するかどうかの決定」 を参照してください。
データサービスリソースを含むリソースグループがクラスタノード上でオンラインになるとき、あるいは、リソースグループがすでにオンラインになっていて、そのリソースが有効なとき、RGM はそのノード上で START メソッドを呼び出します。サンプルのアプリケーションでは、START メソッドはそのノード上で in.named (DNS) デーモンを起動します。
この節では、サンプルのアプリケーションの START メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。
START メソッドの完全なリストについては、「START メソッドのコードリスト」 を参照してください。
DNS を起動する前に、サンプルのデータサービスの START メソッドは、構成ディレクトリと構成ファイル (named.conf) がアクセス可能で利用可能であるかどうかを確認します。DNS が正常に動作するためには、named.conf の情報が重要です。
このコールバックメソッドは、プロセス監視機能 (pmfadm) を使用し、DNS デーモン (in.named) を起動します。DNS がクラッシュしたり、起動に失敗したりすると、このメソッドは、一定の期間に一定の回数だけ DNS の起動を再試行します。再試行の回数と期間は、データサービスの RTR ファイル内のプロパティで指定されます。
DNS が動作するためには、構成ディレクトリ内の named.conf ファイルからの情報が必要です。したがって、START メソッドは、DNS を起動しようとする前にいくつかの妥当性検査を実行し、ディレクトリやファイルがアクセス可能であるかどうかを確認します。
Confdir 拡張プロパティは、構成ディレクトリへのパスを提供します。プロパティ自身は RTR ファイルに定義されています。しかし、実際の位置は、クラスタ管理者がデータサービスを構成するときに指定します。
サンプルのデータサービスでは、START メソッドは scha_resource_get(1HA) コマンドを使用して構成ディレクトリの位置を取得します。
Confdir は拡張プロパティであるため、scha_resource_get はタイプと値の両方を戻します。したがって、awk(1) コマンドで値だけを取得し、シェル変数 CONFIG_DIR に格納します。
# リソースを追加するときにクラスタ管理者が設定した Confdir の値を見つける。 config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get は拡張プロパティの「タイプ」と「値」を戻す。拡 # 張プロパティの値だけを取得する。 CONFIG_DIR=`echo $config_info | awk '{print $2}'` |
次に、START メソッドは CONFIG_DIR の値を使用し、ディレクトリがアクセス可能であるかどうかを確認します。アクセス可能ではない場合、START メソッドはエラーメッセージを記録し、エラー状態で終了します。「START の終了状態」 を参照してください。
# Check if $CONFIG_DIR is accessible. if [ ! -d $CONFIG_DIR ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Directory $CONFIG_DIR is missing or not mounted" exit 1 fi |
アプリケーションデーモンを起動する前に、このメソッドは最終検査を実行し、named.conf ファイルが存在するかどうかを確認します。存在しない場合、START メソッドはエラーメッセージを記録し、エラー状態で終了します。
# データファイルへの相対パス名が存在する場合、$CONFIG_DIR ディレク # トリに移動する。 cd $CONFIG_DIR # named.conf ファイルが $CONFIG_DIR ディレクトリ内に存在するかどうか # を検査する。 if [ ! -s named.conf ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} File $CONFIG_DIR/named.conf is missing or empty" exit 1 fi |
このメソッドは、プロセス監視機能 (pmfadm) を使用してアプリケーションを起動します。pmfadm コマンドを使用すると、アプリケーションを再起動するときの期間と回数を指定できます。このため、RTR ファイルには 2 つのプロパティ Retry_count と Retry_interval があります。Retry_count は、アプリケーションを再起動する回数を指定し、Retry_interval は、アプリケーションを再起動する期間を指定します。
START メソッドは、scha_resource_get コマンドを使用して Retry_count と Retry_interval の値を取得し、これらの値をシェル変数に格納します。次に、-n オプションと -t オプションを使用し、これらの値を pmfadm に渡します。
# RTR ファイルから再試行最大回数の値を取得する。 RETRY_CNT=`scha_resource_get -O Retry_Count -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME` # RTR ファイルから再試行最大期間の値を取得する。この値の単位は秒であり、 # pmfadm に渡すときは分に変換する必要がある。変換時、端数は切り捨て # られるので注意すること。たとえば、50 秒は 1 分に切り上げられる。 ((RETRY_INTRVAL=`scha_resource_get -O Retry_Interval -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME` / 60)) # PMF の制御下で in.named デーモンを起動する。RETRY_INTERVAL の期間、 # $RETRY_COUNT の回数だけ、クラッシュおよび再起動できる。どちらかの # 値以上クラッシュした場合、PMF は再起動をやめる。 # <$PMF_TAG> というタグですでにプロセスが登録されている場合、 # PMF はすでにプロセスが動作していることを示す警告メッセージを送信する。 # pmfadm -c $PMF_TAAG -n $RETRY_CNT -t $RETRY_INTRVAL ¥ /usr/sbin/in.named -c named.conf # # HA-DNS が起動していることを示すメッセージを記録する。 if [ $? -eq 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} HA-DNS successfully started" fi exit 0 |
START メソッドは、実際のアプリケーションが本当に動作して実行可能になるまで、成功で終了してはなりません。特に、他のデータサービスが依存している場合は注意する必要があります。これを実現するための 1 つの方法は、START メソッドが終了する前に、アプリケーションが動作しているかどうかを確認することです。複雑なアプリケーション (データベースなど) の場合、RTR ファイルの Start_timeout プロパティに十分高い値を設定することによって、アプリケーションが初期化され、クラッシュ回復を実行できる時間を提供します。
サンプルのデータサービスのアプリケーションリソース DNS は直ちに起動するため、サンプルのデータサービスは、成功で終了する前に、ポーリングでアプリケーションが動作していることを確認していません。
このメソッドが DNS の起動に失敗し、失敗状態で終了すると、RGM は Failover_mode プロパティを検査し、どのように対処するかを決定します。サンプルのデータサービスは明示的に Failover_mode プロパティを設定していないため、このプロパティはデフォルト値 NONE が設定されています (ただし、クラスタ管理者がデフォルトを変更して異なる値を指定していないと仮定します)。したがって、RGM は、データサービスの状態を設定するだけで、他のアクションは行いません。同じノード上で再起動したり、別のノードにフェイルオーバーしたりするには、ユーザーの介入が必要です。
HA-DNS リソースを含むリソースグループがクラスタノード上でオフラインになるとき、あるいは、リソースグループがオンラインでリソースが無効なとき、RGM は STOP メソッドを呼び出します。このメソッドは、そのノード上で in.named (DNS) デーモンを停止します。
この節では、サンプルのアプリケーションの STOP メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。
STOP メソッドの完全なリストについては、「STOP メソッドのコードリスト」 を参照してください。
データサービスを停止するときは、考慮すべきことが 2 点あります。1 点は、停止処理を規則正しく行うことです。これを実現する最良の方法は、pmfadm 経由で SIGTERM シグナルを送信することです。
もう 1 点は、データサービスが本当に停止していることを保証することによって、データベースが Stop_failed 状態にならないようにすることです。これを実現する最良の方法は、pmfadm 経由で SIGKILL シグナルを送信することです。
サンプルのデータサービスの STOP メソッドは、このような点を考慮しています。まず、 SIGTERM シグナルを送信し、このシグナルがデータサービスの停止に失敗した場合は、SIGKILL シグナルを送信します。
DNS を停止しようとする前に、この STOP メソッドは、プロセスが実際に動作しているかどうかを確認します。プロセスが動作している場合、STOP メソッドはプロセス監視機能 (pmfadm) を使用してプロセスを停止します。
この STOP メソッドは呼び出し回数に依存しないことが保証されます。RGM は、START の呼び出しでデータサービスを起動せずに、STOP メソッドを 2 回呼び出すことはありません。しかし、RGM は、リソースが起動されていなくても、あるいは、リソースが自発的に停止している場合でも、STOP メソッドをそのリソース上で呼び出すことができます。つまり、DNS がすでに動作していない場合でも、この STOP メソッドは成功で終了します。
STOP メソッドは、データサービスを停止するために二段階の方法を提供します。pmfadm 経由で SIGTERM シグナルを使用する規則正しい方法と、SIGKILL シグナルを使用する強制的な方法です。STOP メソッドは、STOP メソッドが戻るまでの時間を示す Stop_timeout 値を取得します。次に、STOP メソッドはこの時間の 80% を規則正しい方法に割り当て、15% を強制的な方法に割り当てます (5% は予約されています)。次の例を参照してください。
STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAM� ((SMOOTH_TIMEOUT=$STOP_TIMEOUT * 80/100)) ((HARD_TIMEOUT=$STOP_TIMEOUT * 15/100))
STOP メソッドは pmfadm -q を使用し、DNS デーモンが動作しているかどうかを確認します。動作している場合、STOP メソッドはまず pmfadm -s を使用して TERM シグナルを送信し、DNS プロセスを終了します。このシグナルを送信してからタイムアウト値の 80% が経過してもプロセスが終了しない場合、STOP メソッドは SIGKILL シグナルを送信します。このシグナルを送信してからタイムアウト値の 15% が経過してもプロセスが終了しない場合、STOP メソッドはエラーメッセージを記録し、エラー状態で終了します。
pmfadm がプロセスを終了した場合、STOP メソッドはプロセスが停止したことを示すメッセージを記録し、成功で終了します。
DNS プロセスが動作していない場合、STOP メソッドは DNS プロセスが動作していないことを示すメッセージを記録しますが、成功で終了します。次のコード例に、STOP メソッドがどのように pmfadm を使用して DNS プロセスを停止するかを示します。
# in.named が動作しているかどうかを調べて、動作していれば停止する。 if pmfadm -q $PMF_TAG; then # SIGTERM シグナルをデータサービスに送信し、合計タイムアウト値 # の 80% だけ待つ。 pmfadm -s $RESOURCE_NAME.named -w $SMOOTH_TIMEOUT TERM if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] ¥ "${ARGV0} Failed to stop HA-DNS with SIGTERM; Retry with ¥ SIGKILL" # SIGTERM シグナルでデータサービスが停止しないので、今度 # SIGKILL を使用し、合計タイムアウト値の 15% だけ待つ。 pmfadm -s $PMF_TAG -w $HARD_TIMEOUT KILL if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] "${ARGV0} Failed to stop HA-DNS; Exiting UNSUCCESFUL" exit 1 fi fi else # この時点でデータサービスは動作していない。メッセージを記録し、 # 成功で終了する。 logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "HA-DNS is not started" # HA-DNS が動作していない場合でも、成功で終了し、データサービス # リソースが STOP_FAILED 状態にならないようにする。 exit 0 fi # DNS の停止に成功。メッセージを記録し、成功で終了する。 logger -p ${SYSLOG_FACILITY}.err ¥ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] ¥ "HA-DNS successfully stopped" exit 0 |
STOP メソッドは、実際のアプリケーションが本当に停止するまで、成功で終了してはなりません。特に、他のデータサービスが依存している場合は注意する必要があります。そうしなければ、データが破壊される可能性があります。
複雑なアプリケーション (データベースなど) の場合、RTR ファイルの Stop_timeout プロパティに十分高い値を設定することによって、アプリケーションが停止中にクリーンアップできる時間を提供します。
このメソッドが DNS の停止に失敗し、失敗状態で終了すると、RGM は Failover_mode プロパティを検査し、どのように対処するかを決定します。サンプルのデータサービスは明示的に Failover_mode プロパティを設定していないため、このプロパティはデフォルト値 NONE が設定されています (ただし、クラスタ管理者がデフォルトを変更して異なる値を指定していないと仮定します)。したがって、RGM は、データサービスの状態を Stop_failed に設定するだけで、他のアクションは行いません。アプリケーションを強制的に停止し、Stop_failed 状態をクリアするには、ユーザーの介入が必要です。
サンプルのアプリケーションは、DNS リソース (in.named) の信頼性を監視する、基本的な障害モニターを実装します。障害モニターは、次の要素から構成されます。
dns_probe - nslookup(1M) を使用し、サンプルのデータサービスの制御下にある DNS リソースが動作しているかどうかを確認するユーザー定義プログラム。DNS が動作していない場合、このメソッドは DNS をローカルで再起動しようとします。あるいは、再起動の再試行回数によっては、RGM がデータサービスを別のノードに再配置することを要求します。
dns_monitor_start - dns_probe を起動するコールバックメソッド。監視が有効である場合、RGM は、サンプルのデータサービスがオンラインになった後、自動的に dns_monitor_start を呼び出します。
dns_monitor_stop - dns_probe を停止するコールバックメソッド。RGM は、サンプルのデータサービスがオフラインになる前に、自動的に dns_monitor_stop を呼び出します。
dns_monitor_check - PROBE プログラムがデータサービスを新しいノードにフェイルオーバーするとき、VALIDATE メソッドを呼び出し、構成ディレクトリが利用可能であるかどうかを確認するコールバックメソッド。
dns_probe プログラムは、サンプルのデータサービスの管理下にある DNS リソースが動作しているかどうかを確認する、連続して動作するプロセスを実行します。dns_probe は、サンプルのデータサービスがオンラインになった後、RGMによって自動的に呼び出される dns_monitor_start メソッドによって起動されます。データサービスは、サンプルのデータサービスがオフラインになる前、RGM によって呼び出される dns_monitor_stop メソッドによって停止されます。
この節では、サンプルのアプリケーションの PROBE メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。
PROBE メソッドの完全なリストについては、「PROBE プログラムのコードリスト」 を参照してください。
検証プログラムは無限ループで動作します。検証プログラムは、nslookup(1M) を使用し、適切な DNS リソースが動作しているかどうかを確認します。DNS が動作している場合、検証プログラムは一定の期間 (Thorough_probe_interval システム定義プロパティに設定されている期間) だけ休眠し、その後、再び検証を行います。DNS が動作していない場合、検証プログラムは DNS をローカルで再起動しようとするか、再起動の再試行回数によっては、RGM がデータサービスを別のノードに再配置することを要求します。
Thorough_probe_interval - 検証プログラムが休眠する期間を設定します。
Probe_timeout - nslookup コマンドが検証を行う期間 (タイムアウト値) を設定します。
Network_resources_used - DNS が動作するサーバーを設定します。
Retry_count と Retry_interval - 再起動を行う回数と期間を設定します。
Rt_basedir - PROBE プログラムと gettime ユーティリティが格納されているディレクトリを設定します。
scha_resource_get コマンドは、次に示すように、上記プロパティの値を取得し、シェル変数に格納します。
PROBE_INTERVAL=`scha_resource_get -O THOROUGH_PROBE_INTERVAL ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME` probe_timeout_info=`scha_resource_get -O Extension -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME Probe_timeout` PROBE_TIMEOUT=`echo $probe_timeout_info | awk '{print $2}'` DNS_HOST=`scha_resource_get -O NETWORK_RESOURCES_USED -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME` RETRY_COUNT=`scha_resource_get -O RETRY_COUNT -R $RESOURCE_NAME -G¥ $RESOURCEGROUP_NAME` RETRY_INTERVAL=`scha_resource_get -O RETRY_INTERVAL -R $RESOURCE_NAME -G¥ $RESOURCEGROUP_NAME` RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G¥ $RESOURCEGROUP_NAME`
システム定義プロパティ (Thorough_probe_intervalなど) の場合、scha_resource_get は値だけを戻します。拡張プロパティ (Probe_timeout など) の場合、scha_resource_get はタイプと値を戻します。値だけを取得するには awk(1) コマンドを使用します。
検証プログラム自身は、nslookup(1M) コマンドの while による無限ループです。while ループの前に、nslookup の応答を保管する一時ファイルを設定します。probefail 変数と retries 変数は 0 に初期化されます。
# nslookup 応答用の一時ファイルを設定する。 DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0 |
検証プログラム用の休眠期間を設定する。
hatimerun(1M) を使用し、nslookup に Probe_timeout の値とターゲットホストを渡して起動する。
nslookup の戻りコード (成功または失敗) に基づいて、probefail 変数を設定する。
probefail が 1 (失敗) に設定された場合、nslookup への応答がサンプルのデータサービスから来ており、他の DNS サーバーから来ているのではないことを確認する。
次に、while ループコードを示します。
while : do # 検証が動作すべき期間は THOROUGH_PROBE_INTERVAL プロパティに指 # 定されている。したがって、THOROUGH_PROBE_INTERVAL の間、検証 # プログラムが休眠するように設定する。 sleep $PROBE_INTERVAL # DNS がサービスを提供している IP アドレス上で nslookup コマンド # を実行する。 hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST ¥ > $DNSPROBEFILE 2>&1 retcode=$? if [ $retcode -ne 0 ]; then probefail=1 fi # nslookup への応答が HA-DNS サーバーから来ており、 # /etc/resolv.conf ファイル内に指定されている他のネームサーバー # から来ていないことを確認する。 if [ $probefail -eq 0 ]; then # nslookup 照会に応答したサーバーの名前を取得する。 SERVER=` awk ' $1=="Server:" { print $2 }' ¥ $DNSPROBEFILE | awk -F. ' { print $1 } ' ` if [ -z "$SERVER" ]; then probefail=1 else if [ $SERVER != $DNS_HOST ]; then probefail=1 fi fi fi |
probefail 変数が 0 (成功) 以外である場合、nslookup コマンドがタイムアウトしたか、あるいは、サンプルのサービスの DNS 以外のサーバーから応答が来ていることを示します。どちらの場合でも、DNS サーバーは期待どおりに機能していないので、障害モニターは decide_restart_or_failover 関数を呼び出し、データサービスをローカルで起動するか、RGM がデータサービスを別のノードに再配置することを要求するかを決定します。probefail 変数が 0 の場合、検証が成功したことを示すメッセージが生成されます。
if [ $probefail -ne 0 ]; then decide_restart_or_failover else logger -p ${SYSLOG_FACILITY}.err¥ -t [$SYSLOG_TAG]¥ "${ARGV0} Probe for resource HA-DNS successful" fi |
decide_restart_or_failover 関数は、再試行最大期間 (Retry_interval) と再試行最大回数 (Retry_count) を使用し、DNS をローカルで再起動するか、RGM がデータサービスを別のノードに再配置することを要求するかを決定します。この関数は、次のような条件付きコードを実装します (コードリストについては、「PROBE プログラムのコードリスト」にある decide_restart_or_failover を参照してください)。
最初の障害である場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
最初の障害ではなく、再試行時間が再試行最大期間を過ぎている場合、データサービスをローカルで再起動します。エラーメッセージを記録し、再試行カウンタをリセットし、再試行時間をリセットします。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えている場合、別のノードにフェイルオーバーします。フェイルオーバーが失敗すると、エラーメッセージを記録し、検証プログラムを状態 1 (失敗) で終了します。
再試行時間が再試行最大期間を過ぎておらず、再試行カウンタが再試行最大回数を超えていない場合、データサービスをローカルで再起動します。エラーメッセージを記録し、retries 変数の再試行カウンタをインクリメントします。
期限 (再試行最大期間) 内に再起動の回数 (再試行カウンタ) が制限 (再試行最大回数) に到達した場合、この関数は、RGM がデータサービスを別のノードに再配置することを要求します。再起動の回数が制限に到達していない場合、あるいは、再試行最大期間を過ぎていて、再試行カウンタをリセットする場合、この関数は DNS を同じノード上で再起動しようとします。この関数については、次の点に注意してください。
gettime ユーティリティを使用すると、再起動間の時間を追跡できます。このユーティリティは C プログラムで、(Rt_basedir) ディレクトリ内にあります。
Retry_count と Retry_interval のシステム定義リソースプロパティは、再起動を行う回数と期間を決定します。RTR ファイルのデフォルト値は、Retry_count が 2 回、Retry_interval が 5 分 (300 秒) です。クラスタ管理者はこのデフォルトを変更できます。
restart_service 関数は、同じノード上でデータサービスの再起動を試行する場合に呼び出されます。詳細は、「データサービスの再起動」を参照してください。
API コマンド scha_control は、GIVEOVER オプションを指定すると、サンプルデータサービスを含むリソースグループをオフラインにし、別のノード上でオンラインにし直します。
restart_service 関数は、decide_restart_or_failover によって呼び出され、同じノード上でデータサービスの再起動を試行します。この関数は次の作業を行います。
データサービスが PMF 下にまだ登録されているかどうかを調べます。サービスが登録されている場合、この関数は次の作業を行います。
データサービスの STOP メソッド名と Stop_timeout 値を取得します。
hatimerun を使用してデータサービスの STOP メソッドを起動し、Stop_timeout 値を渡します。
(データサービスが正常に停止した場合) データサービスの START メソッド名と Start_timeout 値を取得します。
hatimerun を使用してデータサービスの START メソッドを起動し、Start_timeout 値を渡します。
データサービスが PMF 下に登録されていない場合は、データサービスが PMF 下で許可されている再試行最大回数を超えていることを示しています。したがって、GIVEOVER オプションを指定して scha_control 関数を呼び出し、データサービスを別のノードにフェイルオーバーします。
function restart_service { # データサービスを再起動するには、まず、データサービス自身が # PMF 下に登録されているかどうかを確認する。 pmfadm -q $PMF_TAG if [[ $? -eq 0 ]]; then # データサービスの TAG が PMF 下に登録されている場合、データサービスを # 停止し、起動し直す。 # 当該リソースの STOP メソッド名と STOP_TIMEOUT 値を取得する。 STOP_TIMEOUT=`scha_resource_get -O STOP_TIMEOUT ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� STOP_METHOD=`scha_resource_get -O STOP ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� hatimerun -t $STOP_TIMEOUT $RT_BASEDIR/$STOP_METHOD ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME ¥ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] ¥ "${ARGV0} Stop method failed." return 1 fi # 当該リソースの START メソッド名と START_TIMEOUT 値を取得する。 # this resource. START_TIMEOUT=`scha_resource_get -O START_TIMEOUT ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� START_METHOD=`scha_resource_get -O START ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� hatimerun -t $START_TIMEOUT $RT_BASEDIR/$START_METHOD ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME ¥ -T $RESOURCETYPE_NAME if [[ $? -ne 0 ]]; then logger-p ${SYSLOG_FACILITY}.err -t [$SYSLOG_TAG] ¥ "${ARGV0} Start method failed." return 1 fi else # データサービスの TAG が PMF 下に登録されていない場合、 # データサービスが PMF 下で許可されている再試行最大回数を # 超えていることを示す。したがって、データサービスを再起動 # してはならない。代わりに、同じクラスタ内にある別のノード # へのフェイルオーバーを試みる。 scha_control -O GIVEOVER -G $RESOURCEGROUP_NAME ¥ -R $RESOURCE_NAME fi return 0 } |
ローカルでの再起動が失敗したり、別のノードへのフェイルオーバーが失敗したりすると、サンプルのデータサービスの PROBE プログラムは失敗で終了し、"Failover attempt failed (フェイルオーバーは失敗しました)" というエラーメッセージを記録します。
サンプルのデータサービスがオンラインになった後、RGM は MONITOR_START メソッドを呼び出し、dns_probe メソッドを起動します。
この節では、サンプルアプリケーションの MONITOR_START メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。
MONITOR_START メソッドの完全なリストについては、「MONITOR_START メソッドのコードリスト」 を参照してください。
このメソッドは、プロセス監視機能 (pmfadm) を使用して検証プログラムを起動します。
MONITOR_START メソッドは、Rt_basedir プロパティの値を取得し、PROBE プログラムへの完全パス名を構築します。このメソッドは、pmfadm の無限再試行オプション (-n -1, -t -1) を使用して検証プログラムを起動します。つまり、検証プログラムの起動に失敗しても、PMF メソッドは検証プログラムを無限に再起動します。
# リソースの RT_BASEDIR プロパティを取得することによって、検証プログラ # ムが存在する場所を見つける。 RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G ¥ $RESOURCEGROUP_NAME` # PMF の制御下でデータサービスの検証を開始する。無限再試行オプショ # ンを使用して検証プログラムを起動する。リソースの名前、タイプ、 # グループを検証プログラムに渡す。 pmfadm -c $RESOURCE_NAME.monitor -n -1 -t -1 ¥ $RT_BASEDIR/dns_probe -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME ¥ -T $RESOURCETYPE_NAME |
サンプルのデータサービスがオフラインになるとき、RGM は MONITOR_STOP メソッドを呼び出し、dns_probe の実行を停止します。
この節では、サンプルアプリケーションの MONITOR_STOP メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。
MONITOR_STOP メソッドの完全なリストについては、「MONITOR_STOP メソッドのコードリスト」 を参照してください。
このメソッドは、プロセス監視機能 (pmfadm) を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は検証プログラムを停止します。
MONITOR_STOP メソッドは、pmfadm -q を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は pmfadm -s を使用して検証プログラムを停止します。検証プログラムがすでに停止している場合でも、このメソッドは成功で終了します。これによって、メソッドが呼び出し回数に依存しないことが保証されます。
# 検証プログラムが動作しているかどうかを判断し、動作している場合、 # 検証プログラムを停止する。 if pmfadm -q $PMF_TAG; then pmfadm -s $PMF_TAG KILL if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Could not stop monitor for resource " ¥ $RESOURCE_NAME exit 1 else 検証プログラムの停止に成功。メッセージを記録する。 logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Monitor for resource " $RESOURCE_NAME ¥ " successfully stopped" fi fi exit 0 |
検証プログラムを停止するときは、必ず、pmfadm で KILL シグナルを使用するようにしてください。絶対に、マスク可能なシグナル (TERM など) は使用しないでください。そうしないと、MONITOR_STOP メソッドが無限にハングし、結果としてタイムアウトする可能性があります。この問題の原因は、PROBE メソッドがデータサービスを再起動またはフェイルオーバーする必要があるときに、scha_control を呼び出すところにあります。scha_control がデータサービスをオフラインにするプロセスの一部として MONITOR_STOP メソッドを呼び出したときに、MONITOR_STOP メソッドがマスク可能なシグナルを使用していると、MONITOR_STOP メソッドは scha_control が終了するのを待ち、scha_control は MONITOR_STOP メソッドが終了するのを待つため、結果として両方がハングします。
PROBE メソッドを停止できない場合、MONITOR_STOP メソッドはエラーメッセージを記録します。RGM は、主ノード上でサンプルのデータサービスを MONITOR_FAILED 状態にするため、そのノードに障害が発生することがあります。
MONITOR_STOP メソッドは、検証プログラムが停止するまで終了してはなりません。
PROBE メソッドが、データサービスを含むリソースグループを新しいノードにフェイルオーバーしようとするとき、RGM は MONITOR_CHECK メソッドを呼び出します。
この節では、サンプルアプリケーションの MONITOR_CHECK メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」を参照してください。
MONITOR_CHECK メソッドの完全なリストについては、「MONITOR_CHECK メソッドのコードリスト」を参照してください。
MONITOR_CHECK メソッドは VALIDATE メソッドを呼び出し、新しいノード上で DNS 構成ディレクトリが利用可能かどうかを確認します。Confdir拡張プロパティが DNS 構成ディレクトリを指します。したがって、MONITOR_CHECK は VALIDATE メソッドのパスと名前、および Confdir の値を取得します。MONITOR_CHECK は、次のように、この値を VALIDATE に渡します。
# リソースタイプの RT_BASEDIR プロパティから VALIDATE メソッドの # 完全パスを取得する。 RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAM� # 当該リソースの VALIDATE メソッド名を取得する。 VALIDATE_METHOD=`scha_resource_get -O VALIDATE ¥ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAM� # データサービスを起動するための Confdir プロパティの値を取得する。入力された # リソース名とリソースグループを使用し、リソースを追加するときに設定した # Confdir の値を取得する。 config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get は、Confdir 拡張プロパティの値とともにタイプも戻す。 # awk を使用し、Confdir 拡張プロパティの値だけを取得する。 CONFIG_DIR=`echo $config_info | awk `{print $2}'` # VALIDATE メソッドを呼び出し、データサービスを新しいノードにフェイルオーバー # できるかどうかを確認する。 $RT_BASEDIR/$VALIDATE_METHOD -R $RESOURCE_NAME -G $RESOURCEGROUP_NAME ¥ -T $RESOURCETYPE_NAME -x Confdir=$CONFIG_DIR |
ノードがデータサービスのホストとして最適であるかどうかをサンプルアプリケーションが確認する方法については、「VALIDATE メソッド」を参照してください。
サンプルのデータサービスは、クラスタ管理者によるプロパティの更新を処理するために、VALIDATE メソッドと UPDATE メソッドを実装します。
リソースが作成されたとき、および、リソースまたは (リソースを含む) リソースグループのプロパティが管理アクションによって更新されるとき、RGM は VALIDATE メソッドを呼び出します。RGM は、作成または更新が行われる前に、VALIDATE メソッドを呼び出します。任意のノード上でメソッドから失敗の終了コードが戻ると、作成または更新は取り消されます。
RGM が VALIDATE メソッドを呼び出すのは、リソースまたはリソースグループのプロパティが管理アクションを通じて変更されたときだけです。RGM がプロパティを設定したときや、モニターがリソースプロパティ Status や Status_msg を設定したときではありません。
PROBE メソッドがデータサービスを新しいノードにフェイルオーバーする場合、MONITOR_CHECK メソッドも明示的に VALIDATE メソッドを呼び出します。
VALIDATE メソッドを呼び出すとき、RGM は追加の引数 (更新されるプロパティとその値など) を他のメソッドに渡します。したがって、サンプルのデータサービスの VALIDATE メソッドは、追加の引数を処理する別の parse_args 関数を実装する必要があります。
サンプルのデータサービスの VALIDATE メソッドは、単一のプロパティである Confdir 拡張プロパティを確認します。このプロパティは、DNS が正常に動作するために重要な DNS 構成ディレクトリを指します。
DNS が動作している間、構成ディレクトリは変更できないため、Confdir プロパティは RTR ファイルで TUNABLE = AT CREATION と宣言します。したがって、VALIDATE メソッドが呼び出されるのは、更新の結果として Confdir プロパティを確認するためではなく、データサービスリソースが作成されているときだけです。
RGM が VALIDATE メソッドに渡すプロパティの中に Confdir が存在する場合、parse_args 関数はその値を取得および保存します。次に、VALIDATE メソッドは、Confdir の新しい値が指すディレクトリがアクセス可能であるかどうか、および、named.conf ファイルがそのディレクトリ内に存在し、データを持っているかどうかを確認します。
parse_args 関数が、RGM から渡されたコマンド行引数から Confdir の値を取得できない場合でも、VALIDATE メソッドは Confdir プロパティの妥当性を検査しようとします。まず、VALIDATE メソッドは scha_resource_get 関数を使用し、静的な構成から Confdir の値を取得します。次に、同じ検査を実行し、構成ディレクトリがアクセス可能であるかどうか、および、空でない named.conf ファイルがそのディレクトリ内に存在するかどうかを確認します。
VALIDATE メソッドが失敗で終了した場合、Confdir だけでなく、すべてのプロパティの更新または作成が失敗します。
RGM は、他のコールバックメソッドとは異なるパラメータを VALIDATE メソッドに渡します。したがって、VALIDATE メソッドには、他のメソッドとは異なる引数を構文解析する関数が必要です。VALIDATE メソッドや他のコールバックメソッドに渡される引数についての詳細は、rt_callbacks(1HA) のマニュアルページを参照してください。次に、VALIDATE メソッドの parse_args関数を示します。
################################################################ # Validate 引数を構文解析する。 # function parse_args # [args...] { typeset opt while getopts 'cur:x:g:R:T:G:' opt do case "$opt" in R) # DNS リソースの名前 RESOURCE_NAME=$OPTARG ;; G) # リソースが構成されるリソースグループ # の名前 RESOURCEGROUP_NAME=$OPTARG ;; T) # リソースタイプの名前 RESOURCETYPE_NAME=$OPTARG ;; r) # メソッドはシステム定義プロパティ # にアクセスしていない。したがって、 # このフラグは動作なし。 ;; g) # メソッドはリソースグループプロパティ # にアクセスしていない。したがって、 # このフラグは動作なし。 ;; c) # Validate メソッドがリソースの作成中に # 呼び出されていることを示す。したが # って、このフラグは動作なし。 ;; u) # リソースがすでに存在しているときは、 # プロパティの更新を示す。Confdir # プロパティを更新する場合、Confdir # がコマンド行引数に現れるはずである。 # 現れない場合、メソッドは # scha_resource_get を使用して # Confdir を探す必要がある。 UPDATE_PROPERTY=1 ;; x) # 拡張プロパティのリスト。プロパティ # と値のペア。区切り文字は「=」 PROPERTY=`echo $OPTARG | awk -F= '{print $1}'` VAL=`echo $OPTARG | awk -F= '{print $2}'` |
# If # Confdir 拡張プロパティがコマンド行 # 上に存在する場合、その値を記録する。 if [ $PROPERTY == "Confdir" ]; then CONFDIR=$VAL CONFDIR_FOUND=1 fi ;; *) logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "ERROR: Option $OPTARG unknown" exit 1 ;; esac done } |
他のメソッドの parse_args 関数と同様に、この関数は、リソース名を取得するためのフラグ (R)、リソースグループ名を取得するためのフラグ (G)、RGM から渡されるリソースタイプを取得するためのフラグ (T) を提供します。
このメソッドはリソースが更新されるときに拡張プロパティの妥当性を検査するために呼び出されるため、r フラグ (システム定義プロパティを示す)、g フラグ (リソースグループプロパティを示す)、c フラグ (リソースの作成中に妥当性の検査が行われていることを示す) は無視されます。
u フラグは、UPDATE_PROPERTY シェル変数の値を 1 (TRUE) に設定します。x フラグは、更新されているプロパティの名前と値を取得します。更新されているプロパティの中に Confdir が存在する場合、その値が CONFDIR シェル変数に格納され、CONFDIR_FOUND 変数が 1 (TRUE) に設定されます。
VALIDATE メソッドはまず、その MAIN 関数において、CONFDIR 変数を空の文字列に設定し、UPDATE_PROPERTY と CONFDIR_FOUND を 0 に設定します。
CONFDIR="" UPDATE_PROPERTY=0 CONFDIR_FOUND=0 |
次に、VALIDATE メソッドは parse_args 関数を呼び出し、RGM から渡された引数を構文解析します。
parse_args "$@" |
次に、VALIDATE は、VALIDATE メソッドがプロパティの更新の結果として呼び出されているのかどうか、および、Confdir 拡張プロパティがコマンド行上に存在するかどうかを検査します。次に、VALIDATE メソッドは、Confdir プロパティが値を持っているかどうかを確認します。値を持っていない場合、VALIDATE メソッドはエラーメッセージを記録し、失敗状態で終了します。
if ( (( $UPDATE_PROPERTY == 1 )) && (( CONFDIR_FOUND == 0 )) ); then config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME ¥ -G $RESOURCEGROUP_NAME Confdir` CONFDIR=`echo $config_info | awk '{print $2}'` fi # Confdir プロパティが値を持っているかどうかを確認する。持っていな # い場合、状態 1 (失敗) で終了する。 if [[ -z $CONFDIR ]]; then logger -p ${SYSLOG_FACILITY}.err ¥ "${ARGV0} Validate method for resource "$RESOURCE_NAME " failed" exit 1 fi |
上記コードにおいて、VALIDATE メソッドが更新の結果として呼び出されているのか ($UPDATE_PROPERTY == 1)、および、プロパティがコマンド行上に存在しないのか (CONFDIR_FOUND == 0) を検査し、両者が TRUE である場合に、scha_resource_get 関数を使用して Confdir の既存の値を取得するところに注目してください。Confdir がコマンド行上に存在する (CONFDIR_FOUND == 1) 場合、CONFDIR の値は、scha_resource_get 関数からではなく、parse_args 関数から取得されます。
次に、VALIDATE メソッドは CONFDIR の値を使用し、ディレクトリがアクセス可能であるかどうかを確認します。アクセス可能ではない場合、VALIDATE メソッドはエラーメッセージを記録し、エラー状態で終了します。
# $CONFDIR がアクセス可能であるかどうかを検査する。 if [ ! -d $CONFDIR ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Directory $CONFDIR missing or not mounted" exit 1 fi |
Confdir プロパティの更新の妥当性を検査する前に、VALIDATE メソッドは最終検査を実行し、named.conf ファイルが存在するかどうかを確認します。存在しない場合、VALIDATE メソッドはエラーメッセージを記録し、エラー状態で終了します。
# named.conf ファイルが Confdir ディレクトリ内に存在するかどうかを # 検査する。if [ ! -s $CONFDIR/named.conf ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} File $CONFDIR/named.conf is missing or empty" exit 1 fi |
最終検査を通過した場合、VALIDATE メソッドは、成功を示すメッセージを記録し、成功状態で終了します。
# Validate メソッドが成功したことを示すメッセージを記録する。 logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Validate method for resource "$RESOURCE_NAME ¥ " completed successfully" exit 0 |
VALIDATE メソッドが成功 (0) で終了すると、新しい値を持つ Confdir が作成されます。VALIDATE メソッドが失敗 (1) で終了すると、Confdir を含むすべてのプロパティが作成されず、理由を示すメッセージがクラスタ管理者に送信されます。
リソースのプロパティが変更されたとき、RGM は UPDATE メソッドを呼び出し、動作中のリソースにその旨を通知します。RGM は、管理アクションがリソースまたはリソースグループのプロパティの設定に成功した後に、UPDATE を呼び出します。このメソッドは、リソースがオンラインであるノード上で呼び出されます。
UPDATE メソッドはプロパティを更新しません。プロパティの更新は RGM が行います。その代わりに、動作中のプロセスに更新が発生したことを通知します。サンプルのデータサービスでは、プロパティの更新によって影響を受けるプロセスは障害モニターだけです。したがって、UPDATE メソッドは、障害モニターを停止および再起動します。
UPDATE メソッドは、障害モニターが動作していることを確認してから、pmfadm で障害モニターを強制終了する必要があります。UPDATE メソッドは、障害モニターを実装する検証プログラムの位置を取得し、その後、もう一度 pmfadm で障害モニターを再起動します。
UPDATE メソッドは、pmfadm -q を使用し、障害モニターが動作していることを確認します。動作している場合、pmfadm -s TERM で障害モニターを強制終了します。障害モニターが正常に終了した場合、その影響を示すメッセージが管理ユーザーに送信されます。障害モニターが停止できない場合、UPDATE メソッドは、エラーメッセージを管理ユーザーに送信し、失敗状態で終了します。
if pmfadm -q $RESOURCE_NAME.monitor; then # すでに動作している障害モニターを強制終了する。 pmfadm -s $PMF_TAG TERM if [ $? -ne 0 ]; then logger -p ${SYSLOG_FACILITY}.err ¥ -t [$SYSLOG_TAG] ¥ "${ARGV0} Could not stop the monitor" exit 1 else # DNS の停止に成功。メッセージを記録する。 logger -p ${SYSLOG_FACILITY}.err ¥ -t [$RESOURCETYPE_NAME,$RESOURCEGROUP_NAME,$RESOURCE_NAME] ¥ "Monitor for HA-DNS successfully stopped" fi |
障害モニターを再起動するために、UPDATE メソッドは検証プログラムを実装するスクリプトの位置を見つける必要があります。検証プログラムはデータサービスのベースディレクトリ (Rt_basedir プロパティが指すディレクトリ) 内にあります。UPDATE は、次に示すように、Rt_basedir の値を取得し、RT_BASEDIR 変数に格納します。
RT_BASEDIR=`scha_resource_get -O RT_BASEDIR -R $RESOURCE_NAME -G ¥ $RESOURCEGROUP_NAME` |
次に、UPDATE は、RT_BASEDIR の値を pmfadm で使用し、dns_probe プログラムを再起動します。検証プログラムを再起動できた場合、UPDATE メソッドはその影響を示すメッセージを管理ユーザーに送信し、成功で終了します。pmfadm が検証プログラムを再起動できない場合、UPDATE メソッドはエラーメッセージを記録し、失敗状態で終了します。
UPDATE メソッドが失敗すると、リソースが "update failed" (更新失敗) の状態になります。この状態は RGM のリソース管理に影響しません。しかし、syslog 機能を通じて、管理ツールへの更新アクションが失敗したことを示します。