この章では、in.named アプリケーションを Sun Cluster データサービスとして稼働する HA-DNS について説明します。in.named デーモンは Solaris におけるドメインネームサービス (Domain Name Service、DNS) の実装です。サンプルのデータサービスでは、リソース管理 API を使用して、アプリケーションの高可用性を実現する方法を示します。
リソース管理 API は、シェルスクリプトと C プログラムの両方のインタフェースをサポートします。この章のサンプルアプリケーションはシェルスクリプトインタフェースで作成されています。
この章の内容は次のとおりです。
サンプルのデータサービスは、クラスタのイベント (管理アクション、アプリケーションエラー、ノード障害など) に応じて、DNS アプリケーションの起動、停止、再起動や、クラスタノード間での DNS アプリケーションの切り替えを行います。
アプリケーションの再起動は、プロセス監視機能 (Process Monitor Facility、PMF) によって管理されます。アプリケーションの障害が再試行最大期間または再試行最大回数を超えると、障害モニターは、アプリケーションリソースを含むリソースグループを別のノードにフェイルオーバーします。
サンプルのデータサービスは、nslookup コマンドを使用してアプリケーションが正常であることを確認する PROBE メソッドという形で障害監視機能を提供します。DNS サービスのハングを検出すると、PROBE は DNS アプリケーションをローカルで再起動することによって、この状況を修正しようとします。DNS アプリケーションをローカルで再起動することで状況が改善されず、サービスの問題が繰り返し検出される場合、PROBE は、サービスをクラスタ内の別のノードにフェイルオーバーしようとします。
サンプルのデータサービスには、具体的に、次のような要素が含まれています。
リソースタイプ登録ファイル - データサービスの静的なプロパティーを定義します。
Start コールバックメソッド - HA-DNS データサービスを含むリソースグループがオンラインになるときに RGM によって実行され、in.named デーモンを起動します。
Stop コールバックメソッド - HA-DNS を含むリソースグループがオフラインになるときに RGM によって実行され、in.named デーモンを停止します。
障害モニター - DNS サーバーが動作しているかどうかを確認することによって、サービスの信頼性を検査します。障害モニターはユーザー定義の PROBE メソッドによって実装され、Monitor_start と Monitor_stop コールバックメソッドによって起動および停止されます。
Validate コールバックメソッド - RGM によって実行され、サービスの構成ディレクトリがアクセス可能であるかどうかを検査します。
Update コールバックメソッド - クラスタ管理者がリソースプロパティーの値を変更したときに RGM によって呼び出され、障害モニターを再起動します。
この例で使用するサンプルのリソースタイプ登録 (Resource Type Registration、RTR) ファイルは、DNS リソースタイプの静的な構成を定義します。このタイプのリソースは、RTR ファイルで定義されているプロパティーを継承します。
RTR ファイル内の情報は、クラスタ管理者が HA-DNS データサービスを登録したときにリソースグループマネージャー (Resource Group Manager、RGM) によって読み取られます。 慣例により、RTR ファイルは /opt/cluster/lib/rgm/rtreg/ ディレクトリに置きます。パッケージインストーラは、Agent Builder が作成した RTR ファイルもこのディレクトリに置きます。
RTR ファイルの形式は明確に定義されています。リソースタイププログラム、システム定義リソースプロパティー、拡張プロパティーという順番で並んでいます。詳細は、rt_reg(4)のマニュアルページ、および「リソースとリソースタイププロパティーの設定」を参照してください。
以降の節では、サンプル RTR ファイルの特定のプロパティーについて説明します。これらの節には、ファイルのさまざまな部分のリストがあります。サンプル RTR ファイルの内容の完全なリストについては、「リソースタイプ登録ファイルのリスト」を参照してください。
次のリストに示すように、サンプルのRTR ファイルはコメントから始まり、そのあとに、HA-DNS 構成を定義するリソースタイププロパティーが続きます。
リソースグループ、リソース、およびリソースタイプのプロパティー名は大文字と小文字が区別されません。プロパティー名を指定する際には、大文字と小文字を任意に組み合わせることができます。
# # Copyright (c) 1998-2006 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 プロパティーを宣言する必要があります。最初のエントリで宣言されていない場合は、リソースタイプの登録に失敗します。
次に、これらのプロパティーについての情報を説明します。
リソースタイプ名は、Resource_type プロパティーだけで指定できます (例: sample)。あるいは、接頭辞 vendor-id + ピリオド (.) + リソースタイププロパティー (例: SUNW.sample) という形式でも指定できます。
vendor-id を指定する場合、リソースタイプを定義する企業の略号を使用します。リソースタイプ名はクラスタ内で一意である必要があります。
RT_version プロパティーは、ベンダーによって指定されたサンプルのデータサービスのバージョンを識別します。
API_version プロパティーは Sun Cluster のバージョンを識別します。たとえば、API_version = 2 は、データサービスが Sun Cluster 3.0 以降の任意のバージョンの Sun Cluster で動作できることを示します。API_version = 7 は、データサービスを Sun Cluster 3.2 以降の任意のバージョンの Sun Cluster にインストールできることを示します。ただし、API_version = 7 は、Sun Cluster 3.2 よりも前にリリースされたバージョンの Sun Cluster にはデータサービスをインストールできないことも示します。このプロパティーについては、「資源タイプのプロパティー」の API_version の項目で詳しく説明しています。
Failover = TRUE は、複数のノード上で同時にオンラインにできるリソースグループでは、データサービスが動作できないことを示します。
RT_basedir は相対パス (コールバックメソッドのパスなど) を補完するためのディレクトリパスで、/opt/SUNWsample/bin を指します。
Start、Stop、Validate は、RGM によって実行される個々のコールバックメソッドプログラムへのパスを提供します。これらのパスは、RT_basedir で指定されたディレクトリからの相対パスです。
Pkglist は、SUNWsample をサンプルのデータサービスのインストールを含むパッケージとして識別します。
この RTR ファイルに指定されていないリソースタイププロパティー (Single_instance、Init_nodes、Installed_nodes など) は、デフォルト値に設定されます。リソースタイププロパティーの完全なリストとそのデフォルト値については、「資源タイプのプロパティー」を参照してください。
クラスタ管理者は、RTR ファイルのリソースタイププロパティーの値を変更できません。
慣習上、RTR ファイルでは、次のリソースプロパティーをリソースタイププロパティーのあとに宣言します。リソースプロパティーには、Sun Cluster ソフトウェアが提供するシステム定義プロパティーと、データサービス開発者が定義する拡張プロパティーが含まれます。どちらのタイプの場合でも、Sun Cluster ソフトウェアが提供するプロパティー属性の数 (最小、最大、デフォルト値など) を指定できます。
次のリストは、サンプル RTR ファイルのシステム定義プロパティーを示しています。
# A list of bracketed resource property declarations follows the # resource type declarations. The property-name declaration must be # the first attribute after the open curly bracket of each entry. # The <method>_timeout properties set the value in seconds after which # the RGM concludes invocation of the method has failed. # The MIN value for all method timeouts is set to 60 seconds. This # prevents administrators from setting shorter timeouts, which do not # improve switchover/failover performance, and can lead to undesired # RGM actions (false failovers, node reboot, or moving the resource group # to ERROR_STOP_FAILED state, requiring operator intervention). Setting # too-short method timeouts leads to a *decrease* in overall availability # of the data service. { 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; } # The number of retries to be done within a certain period before concluding # that the application cannot be successfully started on this node. { PROPERTY = Retry_count; MIN=0; MAX=10; DEFAULT=2; TUNABLE = ANYTIME; } # Set Retry_interval as a multiple of 60 since it is converted from seconds # to minutes, rounding up. For example, a value of 50 (seconds) # is converted to 1 minute. Use this property to time the number of # retries (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 秒 = 1 時間) を提供します。サンプル RTR ファイルは、最小タイムアウトを 60 秒に変更し、デフォルト値を 300 秒に変更しています。クラスタ管理者は、このデフォルト値を使用することも、タイムアウト値を 60 秒以上の 別の値に変更することもできます。Sun Cluster は最大値を設定していません。
プロパティー Thorough_probe_interval、Retry_count、Retry_interval の TUNABLE 属性は ANYTIME に設定されています。これらの設定は、データサービスが動作中でも、クラスタ管理者がこれらのプロパティーの値を変更できることを意味します。上記のプロパティーは、サンプルのデータサービスによって実装される障害モニターによって使用されます。サンプルのデータサービスは、管理アクションによってさまざまなリソースが変更されたときに障害モニターを停止および再起動するように、Update を実装します。「Update メソッドの仕組み」を参照してください。
リソースプロパティーは次のように分類されます。
必須。クラスタ管理者はリソースを作成するときに値を指定する必要があります。
任意。クラスタ管理者が値を指定しない場合、システムがデフォルト値を提供します。
条件付き。RGM は、RTR ファイル内にプロパティーが宣言されている場合にかぎりプロパティーを作成します。
サンプルのデータサービスの障害モニターは、Thorough_probe_interval、Retry_count、Retry_interval、Network_resources_used という条件付きプロパティーを使用しているため、開発者はこれらのプロパティーを RTR ファイルで宣言する必要があります。プロパティーの分類の詳細については、r_properties(5)のマニュアルページ、または「リソースのプロパティー」を参照してください。
次に、RTR ファイルの最後の例として、拡張プロパティーを示します。
# Extension Properties # The cluster administrator must set the value of this property to point to the # directory that contains the configuration files used by the application. # For this application, DNS, specify the path of the DNS configuration file on # PXFS (typically named.conf). { PROPERTY = Confdir; EXTENSION; STRING; TUNABLE = AT_CREATION; DESCRIPTION = “The Configuration Directory Path”; } # Time out value in seconds before declaring the probe as failed. { PROPERTY = Probe_timeout; EXTENSION; INT; DEFAULT = 120; 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 コマンドを使用して、データサービスまたはモニターのいずれかを起動または停止するか、あるいはリソース名を渡します。各スクリプトは変数 PMF_TAG を定義し、pmfadm コマンドに渡すことによって、データサービスまたはモニターを識別できます。
同様に、各メソッドスクリプトは、logger コマンドを使用してメッセージをシステムログに記録します。各スクリプトは変数 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 # Send a SIGTERM signal to the data service and wait for 80% of the # total timeout value. 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_start、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 ... # See if the monitor is running, and if so, kill it. 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() 関数を示します。
######################################################################### # Parse program arguments. # function parse_args # [args ...] { typeset opt while getopts 'R:G:T:' opt do case "$opt" in R) # Name of the DNS resource. RESOURCE_NAME=$OPTARG ;; G) # Name of the resource group in which the resource is # configured. RESOURCEGROUP_NAME=$OPTARG ;; T) # Name of the resource type. 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 コマンドの機能として使用すると、エラーメッセージをクラスタログに記録できます。たとえば、サンプルのデータサービスの Start メソッドは、次に示すように、syslog() 関数を取得し、データサービスが起動したことを示すメッセージを記録します。
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() 関数を提供しています。
システム定義プロパティーと拡張プロパティーの両方が使用できます。システム定義プロパティーは事前に定義されています。拡張プロパティーは、データサービス開発者が 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 コマンドを使用して値だけを 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 の情報が重要です。
このコールバックメソッドは、PMF (pmfadm) を使って DNS デーモン (in.named) を起動します。DNS がクラッシュしたり、起動に失敗したりすると、PMF は、指定の期間に所定の回数だけ DNS デーモンの起動を試行します。再試行の回数と期間は、データサービスの RTR ファイル内のプロパティーで指定されます。
DNS が動作するためには、構成ディレクトリ内の named.conf ファイルからの情報が必要です。したがって、Start メソッドは、DNS を起動しようとする前にいくつかの妥当性検査を実行し、ディレクトリやファイルがアクセス可能であるかどうかを確認します。
Confdir 拡張プロパティーは、構成ディレクトリへのパスを提供します。プロパティー自身は RTR ファイルに定義されています。しかし、実際の位置は、クラスタ管理者がデータサービスを構成するときに指定します。
サンプルのデータサービスでは、Start メソッドは scha_resource_get() 関数を使用して構成ディレクトリの位置を取得します。
Confdir は拡張プロパティーであるため、scha_resource_get() はタイプと値の両方を戻します。したがって、awk コマンドで値だけを取得し、シェル変数 CONFIG_DIR にその値を格納します。
# find the value of Confdir set by the cluster administrator at the time of # adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the "type" as well as the "value" for the # extension properties. Get only the value of the extension property 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 メソッドはエラーメッセージを記録し、エラー状態で終了します。
# Change to the $CONFIG_DIR directory in case there are relative # pathnames in the data files. cd $CONFIG_DIR # Check that the named.conf file is present in the $CONFIG_DIR directory 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 は、アプリケーションを再起動する期間を指定します。
Start メソッドは、scha_resource_get() 関数を使用して Retry_count と Retry_interval の値を取得し、これらの値をシェル変数に格納します。次に Start メソッドは、-n オプションと -t オプションを使用し、これらの値を pmfadm に渡します。
# Get the value for retry count from the RTR file. RETRY_CNT=`scha_resource_get -O Retry_count -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` # Get the value for retry interval from the RTR file. This value is in seconds # and must be converted to minutes for passing to pmfadm. Note that the # conversion rounds up; for example, 50 seconds rounds up to 1 minute. ((RETRY_INTRVAL=`scha_resource_get -O Retry_interval -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME` / 60)) # Start the in.named daemon under the control of PMF. Let it crash and restart # up to $RETRY_COUNT times in a period of $RETRY_INTERVAL; if it crashes # more often than that, PMF will cease trying to restart it. # If there is a process already registered under the tag # <$PMF_TAG>, then PMF sends out an alert message that the # process is already running. pmfadm -c $PMF_TAAG -n $RETRY_CNT -t $RETRY_INTRVAL \ /usr/sbin/in.named -c named.conf # Log a message indicating that HA-DNS has been started. 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 は PMF (pmfadm) を使ってプロセスを停止します。
この Stop メソッドは何回か呼びだしてもその動作が変らないことが保証されます。RGM は、Start メソッドの呼び出しでまずデータサービスを起動せずに、Stop メソッドを 2 回呼び出すことはありません。しかし、RGM は、リソースが起動されていなくても、あるいは、リソースが自発的に停止している場合でも、Stop メソッドをリソース上で呼び出すことができます。つまり、DNS がすでに動作していない場合でも、この Stop メソッドは成功状態で終了します。
Stop メソッドは、データサービスを停止するために 2 段階の方法を提供します。pmfadm 経由で SIGTERM シグナルを使用する規則正しい方法と、SIGKILL シグナルを使用する強制的な方法です。Stop メソッドは、Stop メソッドが戻るまでの時間を示す Stop_timeout 値を取得します。Stop メソッドはこの時間の 80% を規則正しい方法に割り当て、15% を強制的な方法に割り当てます (5% は予約済み)。次の例を参照してください。
STOP_TIMEOUT='scha_resource_get -O STOP_TIMEOUT -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME' ((SMOOTH_TIMEOUT=$STOP_TIMEOUT * 80/100)) ((HARD_TIMEOUT=$STOP_TIMEOUT * 15/100))
Stop メソッドは pmfadm -q を使用し、DNS デーモンが動作しているかどうかを確認します。DNS デーモンが動作している場合、Stop はまず pmfadm -s を使用して TERM シグナルを送信し、DNS プロセスを終了します。このシグナルを送信してからタイムアウト値の 80% が経過してもプロセスが終了しない場合、Stop は SIGKILL シグナルを送信します。このシグナルを送信してからタイムアウト値の 15% 以内にプロセスが終了しない場合、Stop メソッドはエラーメッセージを記録し、エラー状態で終了します。
pmfadm がプロセスを終了した場合、Stop メソッドはプロセスが停止したことを示すメッセージを記録し、成功状態で終了します。
DNS プロセスが動作していない場合、Stop メソッドは DNS プロセスが動作していないことを示すメッセージを記録しますが、成功状態で終了します。次のコード例に、Stop メソッドがどのように pmfadm を使用して DNS プロセスを停止するかを示します。
# See if in.named is running, and if so, kill it. if pmfadm -q $PMF_TAG; then # Send a SIGTERM signal to the data service and wait for 80% of the # total timeout value. 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” # Since the data service did not stop with a SIGTERM signal, use # SIGKILL now and wait for another 15% of the total timeout value. 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 UNSUCCESSFUL” exit 1 fi fi else # The data service is not running as of now. Log a message and # exit success. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ “HA-DNS is not started” # Even if HA-DNS is not running, exit success to avoid putting # the data service resource in STOP_FAILED State. exit 0 fi # Could successfully stop DNS. Log a message and exit success. 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 を使用し、サンプルのデータサービスの制御下にある 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 を使用し、適切な 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 コマンドを使用します。
検証プログラム自身は、nslookup コマンドの while による無限ループです。while ループの前に、nslookup の応答を保管する一時ファイルを設定します。probefail 変数と retries 変数は 0 に初期化されます。
# Set up a temporary file for the nslookup replies. DNSPROBEFILE=/tmp/.$RESOURCE_NAME.probe probefail=0 retries=0
while ループは、次の作業を行います。
検証プログラム用の休眠期間を設定します。
hatimerun を使用して nslookup を起動し、Probe_timeout の値を渡し、ターゲットホストを指定します。
nslookup の戻りコード (成功または失敗) に基づいて、probefail 変数を設定します。
probefail が 1 (失敗) に設定された場合、nslookup への応答がサンプルのデータサービスから来ており、ほかの DNS サーバーから来ているのではないことを確認します。
次に、while ループコードを示します。
while : do # The interval at which the probe needs to run is specified in the # property THOROUGH_PROBE_INTERVAL. Therefore, set the probe to sleep # for a duration of THOROUGH_PROBE_INTERVAL. sleep $PROBE_INTERVAL # Run an nslookup command of the IP address on which DNS is serving. hatimerun -t $PROBE_TIMEOUT /usr/sbin/nslookup $DNS_HOST $DNS_HOST \ > $DNSPROBEFILE 2>&1 retcode=$? if [ $retcode -ne 0 ]; then probefail=1 fi # Make sure that the reply to nslookup comes from the HA-DNS # server and not from another nameserver mentioned in the # /etc/resolv.conf file. if [ $probefail -eq 0 ]; then # Get the name of the server that replied to the nslookup query. 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 ファイルでは、これらのプロパティーのデフォルト値は、再試行が 2 回、期間が 5 分 (300 秒) ですが、クラスタ管理者はこれらの値を変更できます。
restart_service() 関数は、同じノード上でデータサービスの再起動を試行する場合に呼び出されます。この関数の詳細については、次の節である「データサービスの再起動」を参照してください。
scha_control() API 関数を SCHA_GIVEOVER 引数付きで実行すると、サンプルデータサービスのあるリソースグループがオフラインになり、別ノード上でオンラインに戻ります。
restart_service() 関数は、decide_restart_or_failover() によって呼び出され、同じノード上でデータサービスの再起動を試行します。
この関数は次の作業を行います。
データサービスがまだ PMF 下に登録されているかどうかを判別します。
サービスがまだ登録されている場合、この関数は次の作業を行います。
データサービスの Stop メソッド名と Stop_timeout 値を取得します。
hatimerun を使用してデータサービスの Stop メソッドを起動し、Stop_timeout 値を渡します。
データサービスが正常に停止した場合は、データサービスの Start メソッド名と Start_timeout 値を取得します。
hatimerun を使用してデータサービスの Start メソッドを起動し、Start_timeout 値を渡します。
データサービスが PMF 下に登録されていない場合は、データサービスが PMF 下で許可されている再試行最大回数を超えていることを示しています。scha_control コマンドが GIVEOVER 引数付きで実行され、それによってデータサービスが別のノードにフェイルオーバーします。
function restart_service { # To restart the data service, first verify that the # data service itself is still registered under PMF. pmfadm -q $PMF_TAG if [[ $? -eq 0 ]]; then # Since the TAG for the data service is still registered under # PMF, first stop the data service and start it back up again. # Obtain the Stop method name and the STOP_TIMEOUT value for # this resource. 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 # Obtain the START method name and the START_TIMEOUT value for # 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 # The absence of the TAG for the dataservice # implies that the data service has already # exceeded the maximum retries allowed under PMF. # Therefore, do not attempt to restart the # data service again, but try to failover # to another node in the cluster. 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 メソッドのコードリスト」を参照してください。
このメソッドは PMF (pmfadm) を使って検証プログラムを起動します。
Monitor_start メソッドは、RT_basedir プロパティーの値を取得し、PROBE プログラムの完全パス名を構築します。このメソッドは、pmfadm の無限再試行オプション (-n -1、-t -1) を使用して検証プログラムを起動します。つまり、検証プログラムの起動に失敗しても、PMF は検証プログラムを無限に起動しようとします。
# Find where the probe program resides by obtaining the value of the # RT_basedir property of the resource. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME -G \ $RESOURCEGROUP_NAME` # Start the probe for the data service under PMF. Use the infinite retries # option to start the probe. Pass the resource name, type, and group to the # probe program. 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 メソッドのコードリスト」を参照してください。
このメソッドは、PMF (pmfadm) を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は検証プログラムを停止します。
Monitor_stop メソッドは、pmfadm -q を使用して検証プログラムが動作しているかどうかを判断し、動作している場合は pmfadm -s を使用して検証プログラムを停止します。検証プログラムがすでに停止している場合でも、このメソッドは成功状態でします。これによって、メソッドが呼び出し回数に依存しないことが保証されます。
必ず KILL シグナルと pmfadm を使用して検証プログラムを停止してください。TERM などのマスク可能なシグナルは使用しないでください。そうしないと、Monitor_stop メソッドが無限にハングし、結果としてタイムアウトする可能性があります。これは、データサービスを再起動またはフェイルオーバーする必要がある場合に PROBE メソッドは scha_control() を呼び出すためです。データサービスをオフラインにするプロセスの一部として scha_control() が Monitor_stop を呼び出す場合、Monitor_stop がマスクできるシグナルを使用すると、Monitor_stop は scha_control() の完了を待機してハングし、scha_control() は Monitor_stop の完了を待機してハングします。
# See if the monitor is running, and if so, kill it. 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 # could successfully stop the monitor. Log a message. logger -p ${SYSLOG_FACILITY}.err \ -t [$SYSLOG_TAG] \ "${ARGV0} Monitor for resource " $RESOURCE_NAME \ " successfully stopped" fi fi exit 0
PROBE メソッドを停止できない場合、Monitor_stop メソッドはエラーメッセージを記録します。RGM は、主ノード上でサンプルのデータサービスを MONITOR_FAILED 状態にするため、そのノードに障害が発生することがあります。
Monitor_stop メソッドは、検証プログラムが停止するまで終了してはなりません。
データサービスが含まれるリソースグループを PROBE メソッドが別のノードにフェイルオーバーしようとするたびに、RGM は Monitor_check メソッドを呼び出します。
この節では、サンプルアプリケーションの Monitor_check メソッドの重要な部分だけを説明します。parse_args() 関数など、すべてのコールバックメソッドに共通な機能については説明しません。また、syslog() 関数の使用法についても説明しません。共通の機能については、「すべてのメソッドに共通な機能の提供」を参照してください。
Monitor_check メソッドの完全なリストについては、「Monitor_check メソッドのコードリスト」を参照してください。
Monitor_check メソッドは、並行して実行中のそのほかのメソッドと競合しない方法で実装する必要があります。
Monitor_check メソッドは Validate メソッドを呼び出し、新しいノード上で DNS 構成ディレクトリが利用可能かどうかを確認します。Confdir 拡張プロパティーが DNS 構成ディレクトリを指します。したがって、Monitor_check は Validate メソッドのパスと名前、および Confdir の値を取得します。Monitor_check は、次のように、この値を Validate に渡します。
# Obtain the full path for the Validate method from # the RT_basedir property of the resource type. RT_BASEDIR=`scha_resource_get -O RT_basedir -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAMÈ # Obtain the name of the Validate method for this resource. VALIDATE_METHOD=`scha_resource_get -O Validate \ -R $RESOURCE_NAME -G $RESOURCEGROUP_NAMÈ # Obtain the value of the Confdir property in order to start the # data service. Use the resource name and the resource group entered to # obtain the Confdir value set at the time of adding the resource. config_info=`scha_resource_get -O Extension -R $RESOURCE_NAME \ -G $RESOURCEGROUP_NAME Confdir` # scha_resource_get returns the type as well as the value for extension # properties. Use awk to get only the value of the extension property. CONFIG_DIR=`echo $config_info | awk `{print $2}'` # Call the validate method so that the dataservice can be failed over # successfully to the new node. $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 メソッドを明示的に呼び出します。
RGM は、ほかのメソッドに渡す引数以外にも、引数を追加して Validate メソッドを呼び出します。この追加引数には、更新されるプロパティーと値が含まれます。したがって、サンプルのデータサービスの Validate メソッドは、追加の引数を処理する別の parse_args() 関数を実装する必要があります。
サンプルのデータサービスの Validate メソッドは、単一のプロパティーである Confdir 拡張プロパティーを確認します。このプロパティーは、DNS が正常に動作するために重要な DNS 構成ディレクトリを指します。
DNS が動作している間、構成ディレクトリは変更できないため、Confdir プロパティーは RTR ファイルで TUNABLE = AT_CREATION と宣言します。したがって、Validate メソッドが呼び出されるのは、更新の結果として Confdir プロパティーを確認するためではなく、データサービスリソースが作成されているときだけです。
Confdir が、RGM が Validate に渡すプロパティーの 1 つである場合、parse_args() 関数はその値を取得し、保存します。Validate メソッドは、Confdir の新しい値が指すディレクトリがアクセス可能であるかどうか、および、named.conf ファイルがそのディレクトリ内に存在し、データを持っているかどうかを確認します。
parse_args() 関数が、RGM から渡されたコマンド行引数から Confdir の値を取得できない場合でも、Validate は Confdir プロパティーの妥当性を検査しようとします。まず、Validate メソッドは scha_resource_get() 関数を使用し、静的な構成から Confdir の値を取得します。次に、Validate は同じ検査を実行し、構成ディレクトリがアクセス可能であるかどうか、および、空でない named.conf ファイルがそのディレクトリ内に存在するかどうかを確認します。
Validate メソッドが失敗で終了した場合、Confdir だけでなく、すべてのプロパティーの更新または作成が失敗します。
RGM は、ほかのコールバックメソッドとは異なる引数セットを Validate メソッドに渡すため、Validate メソッドには、ほかのメソッドとは異なる引数を構文解析する別の関数が必要です。Validate メソッドやそのほかのコールバックメソッドに渡される引数の詳細については、rt_callbacks(1HA)のマニュアルページを参照してください。次のコードサンプルに、Validate メソッドの parse_args() 関数を示します。
######################################################################### # Parse Validate arguments. # function parse_args # [args...] { typeset opt while getopts 'cur:x:g:R:T:G:' opt do case "$opt" in R) # Name of the DNS resource. RESOURCE_NAME=$OPTARG ;; G) # Name of the resource group in which the resource is # configured. RESOURCEGROUP_NAME=$OPTARG ;; T) # Name of the resource type. RESOURCETYPE_NAME=$OPTARG ;; r) # The method is not accessing any system defined # properties so this is a no-op ;; g) # The method is not accessing any resource group # properties, so this is a no-op ;; c) # Indicates the Validate method is being called while # creating the resource, so this flag is a no-op. ;; u) # Indicates the updating of a property when the # resource already exists. If the update is to the # Confdir property then Confdir should appear in the # command-line arguments. If it does not, the method must # look for it specifically using scha_resource_get. UPDATE_PROPERTY=1 ;; x) # Extension property list. Separate the property and # value pairs using "=" as the separator. PROPERTY=`echo $OPTARG | awk -F= '{print $1}'` VAL=`echo $OPTARG | awk -F= '{print $2}'` # If the Confdir extension property is found on the # command line, note its value. 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 がプロパティーの更新の結果として呼び出されているのかどうかを検査します。また 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 # Verify that the Confdir property has a value. If not there is a failure # and exit with status 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) を検査します。この場合、コードは scha_resource_get() 関数を使用して Confdir の既存の値を取得します。コマンド行で Confdir が見つかった場合 (CONFDIR_FOUND == 1)、CONFDIR の値は scha_resource_get() 関数からではなくparse_args() 関数から来ています。
Validate メソッドは CONFDIR の値を使用し、ディレクトリがアクセス可能であるかどうかを確認します。ディレクトリがアクセス可能ではない場合、Validate メソッドはエラーメッセージを記録し、エラー状態で終了します。
# Check if $CONFDIR is accessible. 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 メソッドはエラーメッセージを記録し、エラー状態で終了します。
# Check that the named.conf file is present in the Confdir directory 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 メソッドは、成功を示すメッセージを記録し、成功状態で終了します。
# Log a message indicating that the Validate method was successful. 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 メソッドが停止および再起動するプロセスです。
Update メソッドは、障害モニターが動作していることを確認してから、pmfadm コマンドを使用して障害モニターを強制終了する必要があります。このメソッドは、障害モニターを実装する検証プログラムの位置を取得し、pmfadm コマンドを使用して障害モニターを再起動します。
Update メソッドは、pmfadm -q を使用し、障害モニターが動作していることを確認します。動作している場合、pmfadm -s TERM で障害モニターを強制終了します。障害モニターが正常に終了した場合、その影響を示すメッセージがクラスタ管理者に送信されます。障害モニターを停止できない場合、Update メソッドは、エラーメッセージをクラスタ管理者に送信し、失敗状態で終了します。
if pmfadm -q $RESOURCE_NAME.monitor; then # Kill the monitor that is running already 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 # could successfully stop DNS. Log a message. 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() 関数を通じて、管理ツールへの更新アクションが失敗したことを示します。