Sun Cluster データサービス開発ガイド (Solaris OS 版)

第 7 章 リソースタイプの設計。

この章では、リソースタイプの設計や実装で DSDL を通常どのように使用するかについて説明します。また、リソース構成を検証したり、リソースの開始、停止、および監視を行なったりするためのリソースタイプの設計についても説明します。そして、最後に、リソースタイプのコールバックメソッドを DSDL を使って導入する方法を説明します。

詳細は、rt_callbacks(1HA) のマニュアルページを参照してください。

これらの作業を行うには、リソースのプロパティ設定値にアクセスできなければなりません。DSDL ユーティリティー scds_initialize() を使用すると、統一された方法でリソースプロパティにアクセスできます。この機能は、各コールバックメソッドの始めの部分で呼び出す必要があります。このユーティリティー関数は、クラスタフレームワークからリソースのすべてのプロパティを取り出します。これによって、これらのプロパティは、scds_getname() 関数群からアクセスできるようになります。

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

RTR ファイル

RTR (Resource Type Registration 、リソースタイプ登録) ファイルは、リソースタイプの重要コンポーネントです。Sun Cluster は、リソースタイプの詳細な情報をこのファイルから取得します。この詳細情報には、この実装に必要なプロパティや、それらのデータタイプやデフォルト値、リソースタイプの実装に必要なコールバックメソッドのファイルシステムパス、システム定義プロパティのさまざまな設定値などがあります。

ほとんどのリソースタイプ実装では、DSDL に添付されるサンプル RTR ファイルだけで十分なはずです。必要な作業は、基本的な要素 (リソースタイプ名、リソースタイプのコールバックメソッドのパス名など) の編集だけです。リソースタイプを実装する際に新しいプロパティが必要な場合は、そのプロパティをリソースタイプ実装のリソースタイプ登録 (RTR) ファイルに拡張プロパティとして宣言します。新しいプロパティには、DSDL の scds_get_ext_property() ユーティリティーを使ってアクセスできます。

Validate メソッド

リソースタイプ実装の Validate メソッドは、次のどちらかの条件のときに RGM によって呼び出されます。

この 2 つの操作は、リソースの Validate メソッドに渡されるコマンド行オプション -c (作成) と -u (更新) によって区別されます。

Validate メソッドは、リソースタイププロパティ INIT_NODES の値で定義されるノード群の各ノードに対して呼び出されます。たとえば、INIT_NODESRG_PRIMARIES が設定されている場合、Validate は、そのリソースのリソースグループを収容できる (その主ノードになりうる) 各ノードに対して呼び出されます。INIT_NODESRT_INSTALLED_NODES に設定されている場合、 Validate は、リソースタイプソフトウェアがインストールされている各ノード (通常は、クラスタのすべてのノード) に対して呼び出されます。INIT_NODES のデフォルト値は RG_PRIMARIES です (rt_reg(4) のマニュアルページを参照)。Validate メソッドが呼び出される時点では、RGM はまだリソースを作成していません (作成コールバックの場合)。あるいは、更新するプロパティの更新値をまだ適用していません (更新コールバックの場合)。リソースタイプ実装の Validate コールバックメソッドの目的は、リソースの新しい設定値 (リソースに対して指定された新しいプロパティ設定値) がそのリソースタイプにとって有効であるかどうかを検査することにあります。


注 –

HAStoragePlus によって管理されるローカルファイルシステムを使用している場合は、scds_hasp_check を使って HAStoragePlus リソースの状態を検査します。この情報は、そのリソースが依存するすべての SUNW.HAStoragePlus(5) リソースの状態 (オンラインかどうか) から、そのリソースに定義されたシステムプロパティ Resource_dependencies または Resource_dependencies_weak を使って取得されます。scds_hasp_check 呼び出しから返される状態コードの完全なリストについては、scds_hasp_check(3HA) のマニュアルページを参照してください。


DSDL 関数 scds_initialize() は、リソースの作成や更新をそれぞれ次のように処理します。

次の図に示す svc_validate() は、リソースプロパティの検証を行う関数です。この関数は、scds_get_name() 関数群を使って、検証しようとするプロパティを検査します。リソースの設定が有効ならこの関数から戻りコード 0 が返されるとすると、リソースタイプの Validate メソッドは、次のコード部分のようになります。


int
main(int argc, char *argv[])
{
   scds_handle_t handle;
   int rc;

   if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR) {
   return (1);   /* 初期エラー */
   }
   rc = svc_validate(handle);
   scds_close(&handle);
   return (rc);
}

さらに、検証関数は、リソースの設定が有効でない場合は、その理由を記録する必要があります。svc_validate() 関数の例 (詳細は省略) は、次のようになります (実際的な検証ルーチンについては、次の章を参照)。


int
svc_validate(scds_handle_t handle)
{
   scha_str_array_t *confdirs;
   struct stat    statbuf;
   confdirs = scds_get_confdir_list(handle);
   if (stat(confdirs->str_array[0], &statbuf) == -1) {
   return (1);   /* 無効なリソースプロパティ設定 */
   }
   return (0);   /* 有効な設定 */
}

このように、リソースタイプの開発者は、svc_validate() 関数を使用することだけに集中できます。リソースタイプ実装の典型的な例としては、app.conf というアプリケーション構成ファイルを Confdir_list プロパティの下に置く処理があります。この処理は、Confdir_list プロパティから取り出した適切なパス名に対して stat() システム呼び出しを実行することによって実装できます。

Start メソッド

リソースタイプ実装の Start コールバックメソッドは、特定のクラスタノードのリソースを開始するときに RGM によって呼び出されます。リソースグループ名とリソース名、およびリソースタイプ名はコマンド行から渡されます。Start メソッドは、クラスタノードでデータサービスリソースを開始するために必要なアクションを行います。通常、このようなアクションには、リソースプロパティの取得や、アプリケーション固有の実行可能ファイルと構成ファイル (または、どちらか) の場所の特定、適切なコマンド行引数を使用したアプリケーションの起動などがあります。

DSDL では、リソース構成ファイルが scds_initialize() ユーティリティーによってすでに取得されています。アプリケーションの起動アクションは、svc_start() 関数に指定できます。さらに、アプリケーションが実際に起動されたかどうかを確認するために、svc_wait() 関数を呼び出すことができます。Start メソッドのコード (詳細は省略) は、次のようになります。


int
main(int argc, char *argv[])
{
   scds_handle_t handle;

   if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR) {
   return (1);   /* 初期化エラー */
   }
   if (svc_validate(handle) != 0) {
   return (1);   /* 無効な設定 */
   }
   if (svc_start(handle) != 0) {
   return (1);   /* 起動に失敗 */
   }
   return (svc_wait(handle));
}

この起動メソッドの実装では、svc_validate() を呼び出してリソース構成を検証します。検証結果が正しくない場合は、リソース構成とアプリケーション構成が一致していないか、このクラスタノードのシステムに関して何らかの問題があることを示しています。たとえば、リソースに必要な広域ファイルシステムが現在このクラスタノードで使用できない可能性などが考えられます。その場合には、このクラスタノードでこのリソースを起動しても意味がないので、RGM を使って別のノードのリソースを起動すべきです。ただし、この場合、svc_validate()は十分に限定的であるものとします。その場合、このルーチンは、アプリケーションが必要とするリソースがあるかどうかをそのクラスタノードだけで検査します。そうでないと、このリソースはすべてのクラスタノードで起動に失敗し、START_FAILED の状態になる可能性があります。この状態については、scswitch(1M) のマニュアルページおよび『 Sun Cluster データサービスの計画と管理 (Solaris OS 版)』を参照してください。

svc_start() 関数は、このノードでリソースの起動に成功した場合は戻りコード 0 を、問題を検出した場合は 0 以外の戻りコードをそれぞれ返す必要があります。この関数から 0 以外の値が返されると、RGM は、このリソースを別のクラスタノードで起動しようと試みます。

DSDL を最大限に活用するには、svc_start() 関数で scds_pmf_start() ユーティリティーを使って、アプリケーションを PMF (プロセス管理機能) のもとで起動できます。このユーティリティーは、PMF の障害コールバックアクション機能 (pmfadm(1M)-a アクションフラグを参照) を使って、プロセス障害の検出を実装します。

Stop メソッド

リソースタイプ実装の Stop コールバックメソッドは、特定のクラスタノードでアプリケーションを停止するときに RGM によって呼び出されます。Stop メソッドのコールバックが有効であるためには、次の条件が必要です。

ほとんどのアプリケーションには、DSDL ユーティリティー scds_pmf_stop() で十分なはずです。このユーティリティーは、まず、アプリケーションが PMF の scds_pmf_start() で起動されたものとみなして、アプリケーションを SIGTERM で「静かに」停止しようとします。これで停止しない場合は、プロセスに対して SIGKILL を適用します。このユーティリティーの詳細については、「PMF 関数」を参照してください。

アプリケーションを停止するそのアプリケーション固有の関数を svc_stop() とし、これまで使用してきたコードモデルに従うとするなら、Stop メソッドは、次のように実装できます。svc_stop() の実装で scds_pmf_stop() が使用されているかどうかは、ここでは関係ありません。それが使用されているかどうかは、アプリケーションが PMF のもとで Start メソッドによって起動されているかどうかに依存します。

if (scds_initialize(&handle, argc, argv)!= SCHA_ERR_NOERR)
{
   return (1);   /* 初期化エラー */
}
return (svc_stop(handle));

Stop メソッドの実装では、svc_validate() メソッドは使用されません。システムに問題があったとしても、Stop メソッドは、このノードでこのアプリケーションを停止すべきだからです。

Monitor_start メソッド

RGM は、Monitor_start メソッドを呼び出して、リソースに対する障害モニターを起動します。障害モニターは、このリソースによって管理されているアプリケーションの状態を監視します。リソースタイプの実装では、通常、障害モニターはバックグラウンドで動作する独立したデーモンとして実装されます。このデーモンの起動には、適切な引数をもつ Monitor_start コールバックメソッドが使用されます。

モニターデーモン自体は障害が発生しやすいため (たとえば、モニターは、アプリケーションを、監視されない状態にしたまま停止することがある)、モニターデーモンは、PMF を使って起動すべきです。DSDL ユーティリティー scds_pmf_start() には、障害モニターを起動する機能が組み込まれています。このユーティリティーは、モニターデーモンプログラムの相対パス名 (リソースタイプコールバックメソッド実装の場所を表す RT_basedir との相対パス) を使用します。さらに、ユーティリティーは、DSDL によって管理される Monitor_retry_intervalMonitor_retry_count 拡張プロパティを使って、デーモンが際限なく再起動されるのを防止します。モニターデーモンのコマンド行構文には、コールバックメソッドに対して定義されたコマンド行構文と同じものが使用されます (-R resource -G resource_group -T resource_type)。ただし、モニターデーモンが RGM から直接呼び出されることはありません。このユーティリティーでは、モニターデーモン実装自体が scds_initialize() ユーティリティーを使って独自の環境を設定できます。したがって、主な作業は、モニターデーモン自体を設計することです。

Monitor_stop メソッド

RGM は、Monitor_stop メソッドを使って、Monitor_start メソッドで起動された障害モニターデーモンを停止します。このコールバックメソッドの失敗は、Stop メソッドの失敗とまったく同じように処理されます。したがって、Monitor_stop メソッドは、Stop メソッドと同じように強固なものでなければなりません。

障害モニターデーモンを scds_pmf_start() ユーティリティーを使って起動したら、scds_pmf_stop() ユーティリティーで停止する必要があります。

Monitor_check メソッド

クラスタノードが特定のリソースを支配できるかどうかを確認するために (つまり、そのリソースによって管理されるアプリケーションがそのノードで正常に動作するかどうかを確認するために)、そのリソースの Monitor_check コールバックメソッドがそのリソースのノードで呼び出されます。)。通常、この状況では、アプリケーションに必要なすべてのシステムリソースが本当にクラスタノードで使用可能かどうかが確認されます。Validate メソッド」 で述べたように、開発者が使用する svc_validate() 関数では、少なくともこの確認が行われなければなりません。

リソースタイプ実装によって管理されているアプリケーションによっては、Monitor_check メソッドでその他の作業を行うことがあります。Monitor_check メソッドは、並行して実行中のその他のメソッドと競合しない方法で実装する必要があります。DSDL を使用する場合には、リソースプロパティに対するアプリケーション固有の検証を行なうために作成された svc_validate() 関数を Monitor_check メソッドで活用することをお勧めします。

Update メソッド

RGM は、リソースタイプ実装の Update メソッドを呼び出して、システム管理者が行なったすべての変更をアクティブリソースの構成に適用します。Update メソッドは、そのリソースがオンラインになっているすべてのノードに対して呼び出されます。

リソースの構成に対して行われた変更は、リソースタイプ実装にとって必ず有効なものです。RGM は、リソースタイプの Update メソッドを呼び出す前に Validate メソッドを呼び出すからです。Validate メソッドは、リソースやリソースグループのプロパティが変更される前に呼び出されます。したがって、Validate メソッドは新しい変更を拒否できます。変更が適用されると、Update メソッドが呼び出され、新しい設定値がアクティブ (オンライン) リソースに通知されます。

リソースタイプの開発者は、どのプロパティを動的に変更できるようにするかを慎重に決定し、RTR ファイルでこれらのプロパティに TUNABLE = ANYTIME を設定する必要があります。通常、障害モニターデーモンによって使用される、リソースタイプ実装のプロパティは、すべて動的に変更できるように設定できます。ただし、Update メソッドの実装が少なくともモニターデーモンを再起動できなければなりません。

このようなプロパティの候補には次のものがあります。

これらのプロパティは、障害モニターデーモンがサービスの状態をどのようにチェックするかや、このチェックをどのような頻度で行うか、エラーをどのような履歴間隔で追跡管理するか、あるいは、PMF がどのような再起動しきい値を設定するかに影響を及ぼします。DSDL には、これらのプロパティの更新を行なうための scds_pmf_restart() ユーティリティーが備わっています。

リソースプロパティを動的に更新できなければならないがプロパティの変更によって動作中のアプリケーションに影響が及ぶ可能性があるという場合は、適切なアクションを行なうことによって、プロパティに対する変更が動作中のアプリケーションインスタンスに正しく適用されるようにしなければなりません。DSDL には、現在のところ、この問題をサポートする機能はありません。変更されたプロパティをコマンド行から Update に渡すことはできません (Validate に渡すことは可能)。

InitFini Boot の各メソッド

これらのメソッドは、「1 度だけのアクション」を行うためのものです (リソース管理 API 仕様の定義を参照)。DSDL のサンプル実装には、これらのメソッドの使い方は示されていません。しかし、これらのメソッドを使用する必要がある場合には、DSDL のすべての機能をこれらのメソッドでも使用できます。通常、「1 度だけのアクション」を使用するリソースタイプ実装では、Init メソッドと Boot メソッドはまったく同じように機能します。Fini メソッドは、一般に、Init メソッドや Boot メソッドのアクションを「取り消す」ためのアクションに使用されます。

障害モニターデーモンの設計

DSDL を使用したリソースタイプ実装の障害モニターデーモンには、通常、次の役割があります。

DSDL ユーティリティーの設計では、障害モニターデーモンの主要ループは次のようになっています。

DSDL を使って実装された障害モニターでは、

ほとんどの場合、アプリケーション固有の状態検査アクションは、スタンドアロンの別個のユーティリティー (たとえば、svc_probe()) として実装してから、この汎用的なメインループに統合できます。


for (;;) { 

   / * 正常な検証と検証の間の thorough_probe_interval
   *  だけスリープする。 */
   (void) scds_fm_sleep(scds_handle,
   scds_get_rs_thorough_probe_interval(scds_handle));

   /* 使用するすべての ipaddress を検証する。
  * 次の各要素を繰り返し検証する。
  * 1. 使用するすべてのネットリソース
  * 2. 特定のリソースのすべての ipaddresses
  * 検証する ipaddress ごとに
  * 障害履歴を計算する。*/
   probe_result = 0;
   /* すべてのリソースを繰り返し調べて、
* svc_probe() の呼び出しに使用する各 IP アドレスを取得する。*/
   for (ip = 0; ip < netaddr->num_netaddrs; ip++) {
   /* 状態を検証する必要があるホスト名とポート
   * を取得する。
   */
   hostname = netaddr->netaddrs[ip].hostname;
   port = netaddr->netaddrs[ip].port_proto.port;
   /*
   * HA-XFS は、1 つのポートしかサポートしないため
   * ポート配列の最初のエントリから
   * ポート値を取得する。
   */
   ht1 = gethrtime(); /* Latch probe start time */
   probe_result = svc_probe(scds_handle, 

   hostname, port, timeout);
   /*
   * サービス検証履歴を更新し、
   * 必要に応じてアクションを実行する。
   * 検証終了時刻を保存する。
   */
   ht2 = gethrtime();
   /* ミリ秒に変換する。 */
   dt = (ulong_t)((ht2 - ht1) / 1e6);

   /*
   * 障害履歴を計算し、
   * 必要に応じてアクションを実行する。
   */
   (void) scds_fm_action(scds_handle,
   probe_result, (long)dt);
   }       /* 各ネットワークリソース */
   }       /* 検証を続ける */