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

テープバックアップ用の 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);
            }
    }