Solaris のシステム管理 (基本編)

Reconfiguration Coordination Manager (RCM) スクリプトの概要

Reconfiguration Coordination Manager (RCM) は、システムコンポーネントの動的な除去を管理するフレームワークです。RCM を使用すると、システムリソースを順番に登録および解放することができます。

新しい RCM スクリプト機能を使用すると、アプリケーションを停止したり、動的な再構成の間にアプリケーションからデバイスを手際良く解放したりする独自のスクリプトを記述できます。スクリプトによって登録されたリソースに要求が影響を与える場合、RCM フレームワークは再構成要求に応じてスクリプトを自動的に起動します。

リソースを動的に除去する場合は、アプリケーションからリソースを手動で解放しておく必要があります。あるいは、-f オプションを指定して cfgadm コマンドを使用して再構成オペレーションを強制することも可能でした。ただし、このオプションはアプリケーションを認識不能な状態のままにする可能性があります。また、アプリケーションからリソースを手動で解放すると、一般にエラーが発生します。

RCM スクリプト機能を使うと、動的再構成処理を簡単かつ効果的に実行できます。RCM スクリプトを作成すると、次の操作を実行できます。

RCM スクリプトについて

RCM スクリプトは、次のとおりです。

RCM スクリプトで実行できること

RCM スクリプトを使用した場合、デバイスを動的に取り外すと、デバイスがアプリケーションから解放されます。デバイスが開いている場合には、RCM スクリプトによって閉じられます。

たとえば、テープバックアップアプリケーションで RCM スクリプトを使用して、テープドライブを終了させたり、テープバックアップアプリケーションをシャットダウンしたりすることができます。

RCM スクリプト処理の動作方法

次のようにしてスクリプトを起動します。


$ script-name command [args ...]

スクリプトにより、次の基本的な手順が実行されます。

  1. コマンド行引数から RCM コマンドを取得する

  2. コマンドを実行する

  3. 結果を名前と値のペアで stdout に記述する

  4. 適切な終了ステータスで終了する

RCM デーモンは、スクリプトのインスタンスを同時に 1 つ実行します。たとえば、RCM デーモンは、スクリプトの実行中には、そのスクリプトが終了するまで同じスクリプトを実行しません。

RCM スクリプトコマンド

次の RCM コマンドを RCM スクリプトに含める必要があります。

次の RCM コマンドの一部またはすべてを RCM スクリプトに含めることができます。

これらの RCM コマンドの詳細については、rcmscript(4) のマニュアルページを参照してください。

RCM スクリプト処理環境

デバイスを動的に取り外すと、RCM デーモンにより次のコマンドが実行されます。

RCM スクリプトでの作業

次の節では、アプリケーション開発者およびシステム管理者のために RCM スクリプト作業について説明します。

アプリケーション開発者 RCM スクリプト (作業マップ)

次の作業マップでは、RCM スクリプトを作成するアプリケーション開発者の作業について説明します。

作業 

説明 

参照先 

1. アプリケーションが使用するリソースを特定する 

アプリケーションが使用するリソース (デバイス名) を特定する。このデバイスは動的に取り外される可能性がある 

cfgadm(1M)

2. リソースを解放するコマンドを特定する 

アプリケーションからリソースを完全に解放するようにアプリケーションに通知するコマンドを特定する 

アプリケーションのマニュアル 

3. リソースを取り外した後に使用するコマンドを特定する 

リソースを取り外したことをアプリケーションに通知するコマンドを含める 

rcmscript(4)

4. リソースの取り外しに失敗した場合のコマンドを特定する 

使用可能なリソースについてアプリケーションに通知するコマンドを含める 

rcmscript(4)

5. RCM スクリプトを記述する 

前の作業で特定した情報に基づいて RCM スクリプトを記述する 

テープバックアップ用の RCM スクリプトの例

6. RCM スクリプトをインストールする 

適切なスクリプトディレクトリにスクリプトを追加する 

RCM スクリプトのインストール方法

7. RCM スクリプトをテストする 

手動でスクリプトコマンドを実行し、動的再構成操作を実行してスクリプトをテストする 

RCM スクリプトのテスト方法

システム管理者 RCM スクリプト (作業マップ)

ここでは、サイトをカスタマイズするために RCM スクリプトを作成するシステム管理者の作業について説明します。

作業 

説明 

参照先 

1. 動的に移動するリソースを特定する 

cfgadm -l コマンドを使って移動する可能性があるリソース (デバイス名) を特定する

cfgadm(1M)

2. 停止するアプリケーションを特定する 

アプリケーションを完全に停止させるコマンドを特定する 

アプリケーションのマニュアル 

3. リソースの取り外し前および取り外し後のコマンドを特定する 

リソースを取り外す前後の動作を特定する 

rcmscript(4)

4. RCM スクリプトを記述する 

前の作業で特定した情報に基づいて RCM スクリプトを記述する 

テープバックアップ用の RCM スクリプトの例

5. RCM スクリプトをインストールする 

適切なスクリプトディレクトリにスクリプトを追加する 

RCM スクリプトのインストール方法

6. RCM スクリプトをテストする 

手動でスクリプトコマンドを実行し、動的再構成操作を実行してスクリプトをテストする 

RCM スクリプトのテスト方法

RCM スクリプトに名前を付ける

次の規則に従って、スクリプトに vendorservice という名前を付ける必要があります。

vendor

スクリプトを提供するベンダーのストックシンボル、またはベンダーを識別する固有名 

service

スクリプトが表すサービス名 

RCM スクリプトのインストールまたは削除

RCM スクリプトのインストールまたは削除を行うには、スーパーユーザー (root) の権限が必要です。この表を使用して、RCM スクリプトをインストールするディレクトリを判断してください。

表 28–1 RCM スクリプトディレクトリ

ディレクトリの位置  

スクリプトタイプ 

/etc/rcm/scripts

特定のシステム用のスクリプト 

/usr/platform/`uname -i`/lib/rcm/scripts

特定のハードウェア実装用のスクリプト 

/usr/platform/`uname -m`/lib/rcm/scripts

特定のハードウェアクラス用のスクリプト 

/usr/lib/rcm/scripts

任意のハードウェア用のスクリプト 

RCM スクリプトのインストール方法

  1. スーパーユーザーになります。

  2. スクリプトを 表 28–1 で説明されている適切なディレクトリにコピーします。

    たとえば、次のようになります。


    # cp SUNW,sample.pl /usr/lib/rcm/scripts
    
  3. スクリプトのユーザー ID およびグループ ID を希望の値に変更します。


    # chown user:group /usr/lib/rcm/scripts/SUNW,sample.pl
    
  4. SIGHUP を RCM デーモンに送信します。


    # pkill -HUP -x -u root rcm_daemon
    

RCM スクリプトの削除方法

  1. スーパーユーザーになります。

  2. RCM スクリプトディレクトリからスクリプトを削除します。

    たとえば、次のようになります。


    # rm /usr/lib/rcm/scripts/SUNW,sample.pl 
    
  3. SIGHUP を RCM デーモンに送信します。


    # pkill -HUP -x -u root rcm_daemon
    

RCM スクリプトのテスト方法

  1. スクリプトを実行する前にコマンド行シェルに RCM_ENV_FORCE などの環境変数を設定します。

    たとえば、Korn シェルで次のように設定します。


    $ export RCM_ENV_FORCE=TRUE
    
  2. コマンド行から手動でスクリプトコマンドを実行してスクリプトをテストします。

    たとえば、次のようになります。


    $ script-name scriptinfo
    $ script-name register
    $ script-name preremove resource-name
    $ script-name postremove resource-name
    
  3. スクリプトの各 RCM スクリプトコマンドにより、適切な出力結果が stdout に印刷されるかどうかを確認します。

  4. 適切なスクリプトディレクトリにスクリプトをインストールします。

    詳細については、RCM スクリプトのインストール方法を参照してください。

  5. 動的な削除操作を実行してスクリプトをテストします。

    たとえば、スクリプトによってデバイス /dev/dsk/c1t0d0s0 が登録されたとします。次のコマンドを実行してください。


    $ cfgadm -c unconfigure c1::dsk/c1t0d0
    $ cfgadm -f -c unconfigure c1::dsk/c1t0d0
    $ cfgadm -c configure c1::dsk/c1t0d0
    

    注意 – 注意 –

    上記のコマンドは、システムの状態を変化させたり、システム障害を招くおそれもあるため、これらのコマンドを十分理解しておくことは大切です。


テープバックアップ用の RCM スクリプトの例

ここでは、RCM スクリプトを使用したテープバックアップの例を示します。

テープバックアップ用の RCM スクリプトの役割

テープバックアップ用の RCM スクリプトは、次の手順を実行します。

  1. RCM コマンドのディスパッチテーブルを設定します。

  2. 指定した RCM コマンドに対応するディスパッチルーチンを呼び出し、未実装の RCM コマンドのステータス 2 で終了させます。

  3. scriptinfo セクションを設定します。


    rcm_script_func_info=Tape backup appl script for DR
  4. すべてのテープドライブのデバイス名を stdout に印刷して、すべてのテープドライバをシステムに登録します。


    rcm_resource_name=/dev/rmt/$f
    エラーが発生した場合、エラー情報を stdout に印刷します。


    rcm_failure_reason=$errmsg
  5. テープデバイスのリソース情報を設定します。


    rcm_resource_usage_info=Backup Tape Unit Number $unit
  6. バックアップアプリケーションがそのデバイスを使用しているかどうか確認して、preremove 情報を設定します。バックアップアプリケーションがそのデバイスを使用していない場合、動的再構成操作が続行されます。バックアップアプリケーションがそのデバイスを使用している場合、スクリプトにより RCM_ENV_FORCE が検査されます。RCM_ENV_FORCEFALSE に設定されている場合、スクリプトにより動的再構成操作が拒否され、次のメッセージが印刷されます。


    rcm_failure_reason=tape backup in progress pid=...

    RCM_ENV_FORCETRUE に設定されている場合、バックアップアプリケーションが停止し、再構成操作が続行されます。

テープバックアップ再構成シナリオの結果

RCM スクリプトを使わずに cfgadm コマンドを使ってテープドライブを取り外した場合、次のような結果になります。

RCM スクリプトと cfgadm コマンドを使ってテープドライブを取り外した場合、次のような結果になります。

例 — テープバックアップ用の RCM スクリプト


#! /usr/bin/perl -w
   #
   # サイト用にカスタマイズされた RCM スクリプトの例
   #
   # RCM_ENV_FORCE が FALSE の場合、
   # RCM はテープドライブがバックアップのために
   # 使用されているときは、ドライブを解放できない
   #
   # RCM_ENV_FORCE が TRUE の場合、
   # DR はテープドライブをバックアップのために
   # 使用しているバックアップアプリケーションを終了してテープドライブを
   # 取り外すことができる。
   #
    
    use strict;
    
    my ($cmd, %dispatch);
    $cmd = shift(@ARGV);
# RCM コマンドのテーブルをディスパッチする
    %dispatch = (
            "scriptinfo"    =>      \&do_scriptinfo,
            "register"      =>      \&do_register,
            "resourceinfo"  =>      \&do_resourceinfo,
            "queryremove"   =>      \&do_preremove,
            "preremove"     =>      \&do_preremove
    );
    
    
    if (defined($dispatch{$cmd})) {
            &{$dispatch{$cmd}};
    } else {
            exit (2);
    }
    
    sub do_scriptinfo
    {
            print "rcm_script_version=1\n";
            print "rcm_script_func_info=Tape backup appl script for DR\n";
            exit (0);
    }
    
    sub do_register
{
            my ($dir, $f, $errmsg);
    
            $dir = opendir(RMT, "/dev/rmt");
            if (!$dir) {
                 $errmsg = "Unable to open /dev/rmt directory: $!";
                 print "rcm_failure_reason=$errmsg\n";
                 exit (1);
            }
    
            while ($f = readdir(RMT)) {
                # 非表示のファイルや同一デバイスの複数の名前を無視する
                if (($f !~ /^\./) && ($f =~ /^[0-9]+$/)) {
                        print "rcm_resource_name=/dev/rmt/$f\n";
                    }
                    
            }
    
            closedir(RMT);
            exit (0);
    }
sub do_resourceinfo
    {
      my ($rsrc, $unit);
    
      $rsrc = shift(@ARGV);
      if ($rsrc =~ /^\/dev\/rmt\/([0-9]+)$/) {
           $unit = $1;
           print "rcm_resource_usage_info=Backup Tape Unit Number $unit\n";
           exit (0);
       } else {
           print "rcm_failure_reason=Unknown tape device!\n";
            exit (1);
        }
    }
    
    sub do_preremove
    {
            my ($rsrc);
    
            $rsrc = shift(@ARGV);
    
            # このリソースをバックアップアプリケーションが
            # 使用している場合にチェックする
            # if ($rsrc 上でバックアップアプリケーション
            # が動作していない場合) {
                    # DR を続行させる
            #        exit (0);
            #}
            #
            # RCM_ENV_FORCE が FALSE の場合、処理を拒否する
            # RCM_ENV_FORCE が TRUE の場合、
            # バックアップアプリケーションを終了して
            # DR が処理を続行できるようにする
            #
            if ($ENV{RCM_ENV_FORCE} eq 'TRUE') {
                 if ($cmd eq 'preremove') {
                         # kill the tape backup application
                 }
                 exit (0);
            } else {
               #
               # テープバックアップアプリケーションによって
               # デバイスが使用されていたため、テープドライブを
               # 解放できなかったことを示す
               #
               print "rcm_failure_reason=tape backup in progress pid=...\n"
;
               exit (3);
            }
    }