Sun Cluster 3.0 U1 データサービス開発ガイド

第 4 章 サンプルデータサービス

この章では、in.named アプリケーションを Sun Cluster データサービスとして稼働する HA-DNS について説明します。in.named デーモンは Solaris におけるドメインネームサービス (DNS) の実装です。サンプルのデータサービスでは、RMAPI を使用して、アプリケーションの高可用性を実現する方法を示します。

RMAPI は、シェルスクリプトと C プログラムの両方のインタフェースをサポートします。この章のサンプルアプリケーションはシェルスクリプトインタフェースで作成されています。

この章の内容は、次のとおりです。

サンプルデータサービスの概要

サンプルのデータサービスはクラスタのイベント (管理アクション、アプリケーションの異常終了、ノードの異常終了など) に応じて、DNS アプリケーションを起動、停止、再起動、およびラスタノード間の切り替えを行います。

アプリケーションの再起動は、プロセス監視機能 (PMF) によって管理されます。アプリケーションの障害が再試行最大期間または再試行最大回数を超えると、障害モニターはアプリケーションリソースを含むリソースグループを別のノードにフェイルオーバーします。

サンプルのデータサービスは、PROBE メソッドという形で障害監視機能を提供します。PROBE メソッドは、nslookup コマンドを使用し、アプリケーションが正常な状態であることを保証します。DNS サービスのハングを検出すると、PROBE メソッドは、DNS アプリケーションをローカルで再起動することによって、この状況を修正しようとします。この方法で状況が改善されず、サービスの問題が繰り返し検出される場合、PROBE メソッドは、サービスをクラスタ内の別のノードにフェイルオーバーしようとします。

サンプルのアプリケーションには、具体的に、次のような機能が含まれています。

リソースタイプ登録ファイルの定義

この例で使用するサンプルのリソースタイプ登録 (RTR) ファイルは、DNS リソースタイプの静的な構成を定義します。このタイプのリソースは、RTR ファイルで定義されているプロパティを継承します。

RTR ファイル内の情報は、クラスタ管理者が HA-DNS データサービスを登録したときに RGM によって読み取られます。

RTR ファイルの概要

RTR ファイルの形式は明確に定義されています。リソースタイププロパティ、システム定義リソースプロパティ、拡張プロパティという順番で並んでいます。詳細は、rt_reg(4) のマニュアルページと 「リソースとリソースタイププロパティの設定」を参照してください。

この節では、サンプルの RTR ファイルの特定のプロパティについて説明します。この節で扱うリストは、サンプルの 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 ファイルにおけるプロパティの規約としては、最初の文字は大文字で、残りの文字は小文字にします。ただし、メソッド名は例外で、プロパティ属性と同様に、すべての文字を大文字にします 。


次に、これらのプロパティについての情報を説明します。

この RTR ファイルに指定されていないリソースタイププロパティ (Single_instanceInit_nodesInstalled_nodes など) は、デフォルト値を取得します。リソースタイププロパティの完全なリストとそのデフォルト値については、表 A-1 を参照してください。

クラスタ管理者は、RTR ファイルのリソースタイププロパティに指定されている値を変更できません。

サンプル RTR ファイルのリソースプロパティ

慣習上、RTR ファイルでは、リソースプロパティをリソースタイププロパティの後に宣言します。リソースプロパティには、Sun Cluster が提供するシステム定義プロパティと、データサービス開発者が定義する拡張プロパティが含まれます。どちらのタイプの場合でも、Sun Cluster が提供するプロパティ属性の数 (最小、最大、デフォルト値など) を指定できます。

RTR ファイルのシステム定義プロパティ

次のリストは、サンプル 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 ファイル内のシステム定義リソースプロパティについては、次の点に注意してください。

RTR ファイルの拡張プロパティ

次のリストに示すように、サンプルの 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 つの拡張プロパティ、ConfdirProbe_timeout を定義します。Confdir は、DNS 構成ディレクトリへのパスを指定します。このディレクトリには、DNS が正常に動作するために必要な in.named ファイルが格納されています。サンプルのデータサービスの STARTVALIDATE メソッドはこのプロパティを使用し、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

PMF_TAGSYSLOG_TAG 変数の宣言

すべてのメソッドスクリプト (VALIDATE を除く) は、リソース名を渡し、pmfadm(1M) を使用してデータサービスまたはモニターのいずれかを起動 (または停止) します。各スクリプトは変数 PMF_TAG を定義し、pmfadm に渡すことによって、データサービスまたはモニターを識別できます。

同様に、各メソッドスクリプトは、logger(1) コマンドを使用してメッセージをシステムログに記録します。各スクリプトは変数 SYSLOG_TAG を定義し、-t オプションで logger に渡すことによって、メッセージが記録されるリソースのリソースタイプ、リソースグループ、リソース名を識別できます。

すべてのメソッドは、次に示す例と同じ方法で SYSLOG_TAG を定義します。dns_probedns_svc_startdns_svc_stopdns_monitor_check の各メソッドは、次のように PMF_TAG を定義します (なお、pmfadmloggerdns_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_stopdns_monitor_stopdns_update の各メソッドは、次のように PMF_TAG を定義します (なお、pmfadmdns_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 メソッドを使用する場合は、STARTSTOP メソッドを使用するかどうかの決定」 を参照してください。

START メソッド

データサービスリソースを含むリソースグループがクラスタノード上でオンラインになるとき、あるいは、リソースグループがすでにオンラインになっていて、そのリソースが有効なとき、RGM はそのノード上で START メソッドを呼び出します。サンプルのアプリケーションでは、START メソッドはそのノード上で in.named (DNS) デーモンを起動します。

この節では、サンプルのアプリケーションの START メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。

START メソッドの完全なリストについては、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_countRetry_interval があります。Retry_count は、アプリケーションを再起動する回数を指定し、Retry_interval は、アプリケーションを再起動する期間を指定します。

START メソッドは、scha_resource_get コマンドを使用して Retry_countRetry_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 の終了状態

START メソッドは、実際のアプリケーションが本当に動作して実行可能になるまで、成功で終了してはなりません。特に、他のデータサービスが依存している場合は注意する必要があります。これを実現するための 1 つの方法は、START メソッドが終了する前に、アプリケーションが動作しているかどうかを確認することです。複雑なアプリケーション (データベースなど) の場合、RTR ファイルの Start_timeout プロパティに十分高い値を設定することによって、アプリケーションが初期化され、クラッシュ回復を実行できる時間を提供します。


注 -

サンプルのデータサービスのアプリケーションリソース DNS は直ちに起動するため、サンプルのデータサービスは、成功で終了する前に、ポーリングでアプリケーションが動作していることを確認していません。


このメソッドが DNS の起動に失敗し、失敗状態で終了すると、RGM は Failover_mode プロパティを検査し、どのように対処するかを決定します。サンプルのデータサービスは明示的に Failover_mode プロパティを設定していないため、このプロパティはデフォルト値 NONE が設定されています (ただし、クラスタ管理者がデフォルトを変更して異なる値を指定していないと仮定します)。したがって、RGM は、データサービスの状態を設定するだけで、他のアクションは行いません。同じノード上で再起動したり、別のノードにフェイルオーバーしたりするには、ユーザーの介入が必要です。

STOP メソッド

HA-DNS リソースを含むリソースグループがクラスタノード上でオフラインになるとき、あるいは、リソースグループがオンラインでリソースが無効なとき、RGM は STOP メソッドを呼び出します。このメソッドは、そのノード上で in.named (DNS) デーモンを停止します。

この節では、サンプルのアプリケーションの STOP メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。

STOP メソッドの完全なリストについては、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 の終了状態

STOP メソッドは、実際のアプリケーションが本当に停止するまで、成功で終了してはなりません。特に、他のデータサービスが依存している場合は注意する必要があります。そうしなければ、データが破壊される可能性があります。

複雑なアプリケーション (データベースなど) の場合、RTR ファイルの Stop_timeout プロパティに十分高い値を設定することによって、アプリケーションが停止中にクリーンアップできる時間を提供します。

このメソッドが DNS の停止に失敗し、失敗状態で終了すると、RGM は Failover_mode プロパティを検査し、どのように対処するかを決定します。サンプルのデータサービスは明示的に Failover_mode プロパティを設定していないため、このプロパティはデフォルト値 NONE が設定されています (ただし、クラスタ管理者がデフォルトを変更して異なる値を指定していないと仮定します)。したがって、RGM は、データサービスの状態を Stop_failed に設定するだけで、他のアクションは行いません。アプリケーションを強制的に停止し、Stop_failed 状態をクリアするには、ユーザーの介入が必要です。

障害モニターの定義

サンプルのアプリケーションは、DNS リソース (in.named) の信頼性を監視する、基本的な障害モニターを実装します。障害モニターは、次の要素から構成されます。

検証プログラム

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 がデータサービスを別のノードに再配置することを要求します。

プロパティ値の取得

このプログラムには、次のプロパティ値が必要です。

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

while ループ自身は、次の作業を行います。

次に、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 を参照してください)。

期限 (再試行最大期間) 内に再起動の回数 (再試行カウンタ) が制限 (再試行最大回数) に到達した場合、この関数は、RGM がデータサービスを別のノードに再配置することを要求します。再起動の回数が制限に到達していない場合、あるいは、再試行最大期間を過ぎていて、再試行カウンタをリセットする場合、この関数は DNS を同じノード上で再起動しようとします。この関数については、次の点に注意してください。

データサービスの再起動

restart_service 関数は、decide_restart_or_failover によって呼び出され、同じノード上でデータサービスの再起動を試行します。この関数は次の作業を行います。


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 (フェイルオーバーは失敗しました)" というエラーメッセージを記録します。

MONITOR_START メソッド

サンプルのデータサービスがオンラインになった後、RGM は MONITOR_START メソッドを呼び出し、dns_probe メソッドを起動します。

この節では、サンプルアプリケーションの MONITOR_START メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。

MONITOR_START メソッドの完全なリストについては、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

MONITOR_STOP メソッド

サンプルのデータサービスがオフラインになるとき、RGM は MONITOR_STOP メソッドを呼び出し、dns_probe の実行を停止します。

この節では、サンプルアプリケーションの MONITOR_STOP メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」 を参照してください。

MONITOR_STOP メソッドの完全なリストについては、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


注意 - 注意 -

検証プログラムを停止するときは、必ず、pmfadmKILL シグナルを使用するようにしてください。絶対に、マスク可能なシグナル (TERM など) は使用しないでください。そうしないと、MONITOR_STOP メソッドが無限にハングし、結果としてタイムアウトする可能性があります。この問題の原因は、PROBE メソッドがデータサービスを再起動またはフェイルオーバーする必要があるときに、scha_control を呼び出すところにあります。scha_control がデータサービスをオフラインにするプロセスの一部として MONITOR_STOP メソッドを呼び出したときに、MONITOR_STOP メソッドがマスク可能なシグナルを使用していると、MONITOR_STOP メソッドは scha_control が終了するのを待ち、scha_controlMONITOR_STOP メソッドが終了するのを待つため、結果として両方がハングします。


MONITOR_STOP の終了状態

PROBE メソッドを停止できない場合、MONITOR_STOP メソッドはエラーメッセージを記録します。RGM は、主ノード上でサンプルのデータサービスを MONITOR_FAILED 状態にするため、そのノードに障害が発生することがあります。

MONITOR_STOP メソッドは、検証プログラムが停止するまで終了してはなりません。

MONITOR_CHECK メソッド

PROBE メソッドが、データサービスを含むリソースグループを新しいノードにフェイルオーバーしようとするとき、RGM は MONITOR_CHECK メソッドを呼び出します。

この節では、サンプルアプリケーションの MONITOR_CHECK メソッドの重要な部分だけを説明します。parse_args 関数や syslog 機能番号を取得する方法など、すべてのコールバックメソッドに共通な機能については説明しません。このような機能については、「すべてのメソッドに共通な機能の提供」を参照してください。

MONITOR_CHECK メソッドの完全なリストについては、MONITOR_CHECK メソッドのコードリスト」を参照してください。

MONITOR_CHECK メソッドは VALIDATE メソッドを呼び出し、新しいノード上で DNS 構成ディレクトリが利用可能かどうかを確認します。Confdir拡張プロパティが DNS 構成ディレクトリを指します。したがって、MONITOR_CHECKVALIDATE メソッドのパスと名前、および 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 メソッドを実装します。

VALIDATE メソッド

リソースが作成されたとき、および、リソースまたは (リソースを含む) リソースグループのプロパティが管理アクションによって更新されるとき、RGM は VALIDATE メソッドを呼び出します。RGM は、作成または更新が行われる前に、VALIDATE メソッドを呼び出します。任意のノード上でメソッドから失敗の終了コードが戻ると、作成または更新は取り消されます。

RGM が VALIDATE メソッドを呼び出すのは、リソースまたはリソースグループのプロパティが管理アクションを通じて変更されたときだけです。RGM がプロパティを設定したときや、モニターがリソースプロパティ StatusStatus_msg を設定したときではありません。


注 -

PROBE メソッドがデータサービスを新しいノードにフェイルオーバーする場合、MONITOR_CHECK メソッドも明示的に VALIDATE メソッドを呼び出します。


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 だけでなく、すべてのプロパティの更新または作成が失敗します。

VALIDATE メソッドの構文解析関数

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) に設定されます。

Confdir の妥当性検査

VALIDATE メソッドはまず、その MAIN 関数において、CONFDIR 変数を空の文字列に設定し、UPDATE_PROPERTYCONFDIR_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 の終了状態

VALIDATE メソッドが成功 (0) で終了すると、新しい値を持つ Confdir が作成されます。VALIDATE メソッドが失敗 (1) で終了すると、Confdir を含むすべてのプロパティが作成されず、理由を示すメッセージがクラスタ管理者に送信されます。

UPDATE メソッド

リソースのプロパティが変更されたとき、RGM は UPDATE メソッドを呼び出し、動作中のリソースにその旨を通知します。RGM は、管理アクションがリソースまたはリソースグループのプロパティの設定に成功した後に、UPDATE を呼び出します。このメソッドは、リソースがオンラインであるノード上で呼び出されます。

UPDATE の概要

UPDATE メソッドはプロパティを更新しません。プロパティの更新は RGM が行います。その代わりに、動作中のプロセスに更新が発生したことを通知します。サンプルのデータサービスでは、プロパティの更新によって影響を受けるプロセスは障害モニターだけです。したがって、UPDATE メソッドは、障害モニターを停止および再起動します。

UPDATE メソッドは、障害モニターが動作していることを確認してから、pmfadm で障害モニターを強制終了する必要があります。UPDATE メソッドは、障害モニターを実装する検証プログラムの位置を取得し、その後、もう一度 pmfadm で障害モニターを再起動します。

UPDATE による障害モニターの停止

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 メソッドが失敗すると、リソースが "update failed" (更新失敗) の状態になります。この状態は RGM のリソース管理に影響しません。しかし、syslog 機能を通じて、管理ツールへの更新アクションが失敗したことを示します。