Solaris ボリュームマネージャは、スライスレベルの物理エラーのためにボリュームに書き込みできないなどの問題を検出すると、システム管理者に通知するためにボリュームの状態を変更します。 ただし、Solaris 管理コンソールを通じて Solaris ボリュームマネージャのグラフィカルユーザーインタフェースを使用したり、 metastat コマンドを実行してボリューム状態の変化を定期的にチェックしないと、状態の変化をタイムリーに把握することはできません。
この章では、Solaris ボリュームマネージャ SNMP エージェント (Solstice Enterprise AgentsTM 監視ソフトウェアのサブエージェント) など、Solaris ボリュームマネージャのさまざまな監視ツールについて説明します。 Solaris ボリュームマネージャ SNMP エージェントを設定して SNMP トラップを報告する方法の他にも、シェルスクリプトを作成して Solaris ボリュームマネージャのさまざまな機能を能動的に監視することができます。 このようなシェルスクリプトは cron ジョブとして動作し、潜在的な問題が顕在化する前にそれらを検出する上で役立ちます。
この章の内容は次のとおりです。
次の表に、Solaris ボリュームマネージャのエラーレポート機能を管理するのに必要な作業を示します。
作業 |
説明 |
参照先 |
---|---|---|
mdmonitord デーモンを設定してエラーを周期的にチェックする |
/etc/rc2.d/S95svm.sync ファイルを編集して、mdmonitord デーモンが使用するエラーチェックの間隔を設定します。 | |
Solaris ボリュームマネージャ SNMP エージェントを構成する |
/etc/snmp/conf ディレクトリの構成ファイルを編集して、Solaris ボリュームマネージャが適切なシステムにトラップを送信できるようにします。 | |
cron コマンドでスクリプトを実行して Solaris ボリュームマネージャを監視する |
エラーをチェックするスクリプトを作成または変更し、 cron コマンドでスクリプトを実行します。 |
Solaris ボリュームマネージャには、Solaris ボリュームマネージャボリュームのエラーをチェックする /usr/sbin/mdmonitord デーモンが含まれています。 デフォルトでは、このプログラムは、書き込みエラーなどにより、いずれかのボリュームでエラーが検出された場合にのみ、すべてのボリュームのエラーをチェックします。 ただし、指定の間隔でエラーを能動的にチェックするようにこのプログラムを設定することもできます。
/etc/rc2.d/S95svm.sync スクリプトは、起動時に mdmonitord コマンドを実行します。 /etc/rc2.d/S95svm.sync スクリプトを編集して、チェックする間隔を追加します。
スーパーユーザーになります。
/etc/rc2.d/S95svm.sync スクリプトを編集し、mdmonitord コマンドで始まる行に - t フラグとチェックする間隔 (秒数) を指定します。
if [ -x $MDMONITORD ]; then $MDMONITORD -t 3600 error=$? case $error in 0) ;; *) echo "Could not start $MDMONITORD. Error $error." ;; esac fi |
mdmonitord コマンドを停止し、再起動して変更を有効にします。
# /etc/rc2.d/S95svm.sync stop # /etc/rc2.d/S95svm.sync start |
詳細については、mdmonitord(1M) を参照してください。
Solaris ボリュームマネージャ SNMP トラップエージェントには、コアパッケージ SUNWlvmr と SUNWlvma、それに Solstice Enterprise Agent パッケージが必要です。 必要なパッケージは、次のとおりです。
SUNWmibii
SUNWsacom
SUNWsadmi
SUNWsasnm
これらのパッケージは Solaris オペレーティングシステムの一部なので、パッケージの選択をインストール時に変更したり、最小限のパッケージ群だけをインストールしなければ、通常はデフォルトでインストールされます。 pkginfo pkgname コマンド (たとえば、pkginfo SUNWsasnx) を使って5つのパッケージが存在することを確認したら、次の各項の説明に従って Solaris ボリュームマネージャ SNMP エージェントを構成します。
Solaris ボリュームマネージャ SNMP エージェントはデフォルトでは有効にされていません。 SNMP トラップを有効にするには、次の手順を実行します。
おそらく、Solaris オペレーティングシステムをアップグレードするたびに、/etc/snmp/conf/enterprises.oid ファイルを編集し、その終わりに 手順1 の行を追加してから、Solaris Enterprise Agents サーバーの停止と再起動を行う必要があります。
この手順が終わると、SNMP トラップが、指定されたホストに送信されるようになります。 送信されたトラップを表示するためには、Solstice Enterprise Agents ソフトウェアなど、適切な SNMP モニターを使用する必要があります。
問題が発生したときにトラップを受信するためには、mdmonitord コマンドを設定してシステムを定期的にチェックする必要があります。 「エラーを周期的にチェックするための mdmonitord デーモンの構成」を参照してください。 また、その他のエラーチェックオプションについては、「cron ジョブによる Solaris ボリュームマネージャの監視 」を参照してください。
スーパーユーザーになります。
/etc/snmp/conf/mdlogd.rsrc 構成ファイルを /etc/snmp/conf/mdlogd.rsrc に移動します。
# mv /etc/snmp/conf/mdlogd.rsrc- /etc/snmp/conf/mdlogd.rsrc |
/etc/snmp/conf/mdlogd.acl ファイルを編集して、SNMP トラップをどのホストに送信するかを指定します。 次の部分を探してください。
trap = { { trap-community = SNMP-trap hosts = corsair { enterprise = "Solaris Volume Manager" trap-num = 1, 2, 3 } |
hosts = corsair の行に、Solaris ボリュームマネージャ SNMP トラップの送信先ホストを指定します。 たとえば、SNMP トラップを lexicon に送信する場合は、この行を hosts = lexicon に変更します。 複数のホストを指定する場合は、hosts = lexicon, idiom のように、ホスト名をコンマで区切って指定します。
次に、/etc/snmp/conf/snmpdx.acl ファイルを編集して、SNMP トラップをどのホストに送信するかを指定します。
trap = で始まるブロックを探し、ここに前の手順で指定したのと同じホスト名のリストを指定します。 このセクションは # でコメント文にされていることがあります。 その場合は、必要な行の始めにある # を取り除いてください。 このセクションでは他の行もコメント文にされている場合がありますが、それらの行はそのまま残しておいても、見やすくするために削除してもかまいません。 必要な行のコメントを解除し、ホスト名の行を変更した後のセクションは次のようになります。
################### # trap parameters # ################### trap = { { trap-community = SNMP-trap hosts =lexicon { enterprise = "sun" trap-num = 0, 1, 2-5, 6-16 } # { # enterprise = "3Com" # trap-num = 4 # } # { # enterprise = "snmp" # trap-num = 0, 2, 5 # } # } # { # trap-community = jerry-trap # hosts = jerry, nanak, hubble # { # enterprise = "sun" # trap-num = 1, 3 # } # { # enterprise = "snmp" # trap-num = 1-3 # } } } |
/etc/snmp/conf/snmpdx.acl ファイルに同じ数の左括弧と右括弧があることを確認してください。
前の手順でコメントを解除した、/etc/snmp/conf/snmpdx.acl ファイルのセクションの中に新しい Solaris ボリュームマネージャセクションを追加します。
trap-community = SNMP-trap hosts = lexicon { enterprise = "sun" trap-num = 0, 1, 2-5, 6-16 } { enterprise = "Solaris Volume Manager" trap-num = 1, 2, 3 } |
追加する 4 行は、enterprise = sun ブロックのすぐ後に挿入する必要があります。
/etc/snmp/conf/enterprises.oid ファイルの最後に次の行を追加します。
"Solaris Volume Manager" "1.3.6.1.4.1.42.104" |
Solstice Enterprise Agents サーバーを停止し、再起動します。
# /etc/init.d/init.snmpdx stop # /etc/init.d/init.snmpdx start |
Solaris ボリュームマネージャ SNMP エージェントには一定の制約があります。そのため、SNMP エージェントは、システム管理者が把握する必要がある、 Solaris ボリュームマネージャのすべての問題をトラップできるわけではありません。 具体的には、このエージェントは、次の場合にのみトラップを送信します。
RAID 1 または RAID 5 のサブコンポーネントが「保守が必要」状態に移行した場合
ホットスペアが、障害のあるディスクに代わって使用されるようになった場合
ホットスペアが再同期処理を開始した場合
ホットスペアが再同期処理を完了した場合
ミラーがオフライン状態になった場合
ディスクセットが別のホストに予約されたため、現在のホストがパニック状態になった場合
RAID 0 ボリュームやソフトパーティションが定義されているディスクが使用不能な場合など、問題が発生しても、SNMP トラップが送信されない状況は少なくありません。これは、このデバイスに対する読み取りや書き込みが行われた場合でも同様です。 そのような場合、一般に SCSI や IDE のエラーは検出されますが、このようなエラーが監視コンソールに報告されるためには、他の SNMP エージェントがトラップを送信する必要があります。
Solaris ボリュームマネージャ構成のエラーを自動的にチェックするために、cron ユーティリティで定期的に実行できるスクリプトを作成します。
次のスクリプト例は、必要に応じて変更することができます。
このスクリプトは、Solaris ボリュームマネージャのエラーチェック機能を自動化するための基本的なスクリプトです。 独自の構成に合わせて変更する必要があります。
# #ident "@(#)metacheck.sh 1.3 96/06/21 SMI" #!/bin/ksh #!/bin/ksh -x #!/bin/ksh -v # ident='%Z%%M% %I% %E% SMI' # # Copyright (c) 1999 by Sun Microsystems, Inc. # # metacheck # # メタデバイス構成の状態をチェックする。問題がある場合は、 # ゼロ以外の終了コードを返す。オプションに応じて e メール通知を送信する。 # # -h # ヘルプ # -s setname # チェックするセットを指定する。デフォルトでは「local」セットがチェックされる。 # -m recipient [recipient...] # 指定された受信者に e メール通知を送信する。これは # 最後の引数でなければならない。この通知は簡単な e メールメッセージ # として送信される。その件名は次のとおり。 # "Solaris Volume Manager Problem: metacheck.who.nodename.setname" # これには、問題の要約と詳しい情報の入手方法が示されている。 # 「setname」は -s オプションから、「who」は # -w オプションからそれぞれとられ、「nodename」は uname(1) によって報告される。 # e メール通知は次のオプションによっても影響される。 # -f 問題が検出された後の追加メッセージを抑制する # -d 抑制を制御する # -w だれが e メールを生成したのかを示す # -t 問題がないときでも e メールを強制的に送る # -w who # だれがコマンドを実行しているのかを示す。デフォルトでは、これは # id(1M) によって報告される user-name である。これは、 # e メール通知を送信する (-m) ときに使用される。 # -f # フィルタ機能を有効にする。フィルタ機能は e メール通知 (-m) に適用される。 # フィルタ機能にはルート権限が必要。e メール通知を送信するときに、 # /etc/lvm/metacheck.setname.pending ファイルを使って # フィルタを制御する。次のマトリクスは # フィルタの動作を指定する。 # # 問題の発見 ファイルあり # yes no ファイルを作成し、通知を送信する。 # yes yes 現在の日付 (-d datefmt で指定された) が # ファイルの日付と異なる場合は、 # 通知を再び送信する。 # no yes ファイルを削除し、問題が解決したことを示す # 通知を送信する。 # no no -t が指定されている場合は、通知を送信する。 # # -d datefmt # フィルタ機能 (-f) の日付形式を指定する。このオプションは、 # e メールで通知を再送する頻度を制御する。 # 指定された形式 (strftime(3C)) に基づく現在の日付が # /etc/lvm/metacheck.setname.pending ファイルに含まれている日付 # と同じなら、メッセージは抑制される。 # デフォルトの日付形式は「%D」で、通知を 1 日に 1 回再送する # ことを意味する。 # -t # テストモード。問題がない場合でも、e メールの生成を有効にする。 # この機構や e メールアドレスを全体的に確認するときに使用する。 # # # 次のオプションは、メタチェックを crontab に組み込む。 # たとえば、次の root crontab エントリがあるとする。 # # 0,15,30,45 * * * * /usr/sbin/metacheck -f -w SVMcron \ # -d '\%D \%h' -m notice@example.com 2148357243.8333033@pager.example.com # # 15 分ごとに問題をチェックし、問題がある場合には、1 時間ごとに # e メールを notice@example.com 宛てに生成する (そして、e メール # ページャサービスに送信する)。crontab エントリの「%」文字の前にある \ に注意。 # 戻ってくる e メールは root@nodename に返される。 # 上の行によって生成される e メールメッセージの件名は次のようになる。 # Solaris Volume Manager Problem: metacheck.SVMcron.nodename.local # # 制御端末にデバッグ行を表示する (一連のパイプとして動作)。 decho() { if [ "$debug" = "yes" ] ; then echo "DEBUG: $*" /dev/null> /dev/tty 2>1 fi } # $1 文字列が $2-* に含まれる場合は $1 を返す。それ以外の場合は "" を返す。 strstr() { typeset look="$1" typeset ret="" shift # decho "strstr LOOK .$look. FIRST .$1." while [ $# -ne 0 ] ; do if [ "$look" = "$1" ] ; then ret="$look" fi shift done echo "$ret" } # $1 文字列が $2-* に含まれる場合は、削除して結果を返す。 strdstr() { typeset look="$1" typeset ret="" shift # decho "strdstr LOOK .$look. FIRST .$1." while [ $# -ne 0 ] ; do if [ "$look" != "$1" ] ; then ret="$ret $1" fi shift done echo "$ret" } merge_continued_lines() { awk -e '\ BEGIN { line = "";} \ $NF == "\\" { \ $NF = ""; \ line = line $0; \ next; \ } \ $NF != "\\" { \ if ( line != "" ) { \ print line $0; \ line = ""; \ } else { \ print $0; \ } \ }' } # メタデバイスと関係ない部分を破棄する。 find_meta_devices() { typeset devices="" # decho "find_meta_devices .$*." while [ $# -ne 0 ] ; do case $1 in d+([0-9]) ) # メタデバイス名 devices="$devices $1" ;; esac shift done echo "$devices" } # トップレベルのメタデバイスのリストを返す。 toplevel() { typeset comp_meta_devices="" typeset top_meta_devices="" typeset devices="" typeset device="" typeset comp="" metastat$setarg -p | merge_continued_lines | while read line ; do echo "$line" devices=find_meta_devices $line set -- $devices if [ $# -ne 0 ] ; then device=$1 shift # デバイスがコンポーネントとしてすでに参照されているかチェックする。 comp=strstr $device $comp_meta_devices if [ -z $comp ] ; then top_meta_devices="$top_meta_devices $device" fi # コンポーネントリストにコンポーネントを追加し、トップリストから削除する。 while [ $# -ne 0 ] ; do comp=$1 comp_meta_devices="$comp_meta_devices $comp" top_meta_devices=strdstr $comp $top_meta_devices shift done fi done> /dev/null 2>1 echo $top_meta_devices } # # - MAIN # METAPATH=/usr/sbin PATH=//usr/bin:$METAPATH USAGE="usage: metacheck [-s setname] [-h] [[-t] [-f [-d datefmt]] \ [-w who] -m recipient [recipient...]]" datefmt="%D" debug="no" filter="no" mflag="no" set="local" setarg="" testarg="no" who=id | sed -e 's/^uid=[0-9][0-9]*(//' -e 's/).*//' while getopts d:Dfms:tw: flag do case $flag in d) datefmt=$OPTARG; ;; D) debug="yes" ;; f) filter="yes" ;; m) mflag="yes" ;; s) set=$OPTARG; if [ "$set" != "local" ] ; then setarg=" -s $set"; fi ;; t) testarg="yes"; ;; w) who=$OPTARG; ;; \?) echo $USAGE exit 1 ;; esac done # mflag が指定されている場合は、他のすべての部分が受信者に属す。 shift expr $OPTIND - 1 if [ $mflag = "no" ] ; then if [ $# -ne 0 ] ; then echo $USAGE exit 1 fi else if [ $# -eq 0 ] ; then echo $USAGE exit 1 fi fi recipients="$*" curdate_filter=date +$datefmt curdate=date node=uname -n # ファイルを確立する。 msg_f=/tmp/metacheck.msg.$$ msgs_f=/tmp/metacheck.msgs.$$ metastat_f=/tmp/metacheck.metastat.$$ metadb_f=/tmp/metacheck.metadb.$$ metahs_f=/tmp/metacheck.metahs.$$ pending_f=/etc/lvm/metacheck.$set.pending files="$metastat_f $metadb_f $metahs_f $msg_f $msgs_f" rm -f $files > /dev/null 2>1 trap "rm -f $files> /dev/null 2>1; exit 1" 1 2 3 15 # metadb が動作可能かチェックする。 have_metadb="yes" metadb$setarg > $metadb_f 2>1 if [ $? -ne 0 ] ; then have_metadb="no" fi grep "there are no existing databases" $metadb_f > /dev/null 2>1 if [ $? -eq 0 ] ; then have_metadb="no" fi grep "/dev/md/admin" $metadb_f > /dev/null 2>1 if [ $? -eq 0 ] ; then have_metadb="no" fi # metadb のアクセスに問題がないかチェックする。 retval=0 if [ "$have_metadb" = "no" ] ; then retval=1 echo "metacheck: metadb problem, can't run '$METAPATH/metadb$setarg'" \ >> $msgs_f else # 状態のスナップショット metadb$setarg 2>1 | sed -e '1d' | merge_continued_lines > $metadb_f metastat$setarg 2>1 | merge_continued_lines > $metastat_f metahs$setarg -i 2>1 | merge_continued_lines > $metahs_f # # 複製の問題をチェックする。フラグの中の大文字は # エラーを意味する。フィールドはタブで区切られる。 # problem=awk $metadb_f -F\t '{if ($1 /[A-Z]/) print $1;}' if [ -n "$problem" ] ; then retval=expr $retval + 64 echo "\ metacheck: metadb problem, for more detail run:\n\t$METAPATH/metadb$setarg -i" \ >> $msgs_f fi # # メタデバイスの状態をチェックする。 # problem=awk $metastat_f -e \ '/State:/ {if ($2 != "Okay" $2 != "Resyncing") print $0;}' if [ -n "$problem" ] ; then retval=expr $retval + 128 echo "\ metacheck: metadevice problem, for more detail run:" \ >> $msgs_f # 問題があるトップレベルメタデバイスへのメッセージの精度を高める。 top=toplevel set -- $top while [ $# -ne 0 ] ; do device=$1 problem=metastat $device | awk -e \ '/State:/ {if ($2 != "Okay" $2 != "Resyncing") print $0;}' if [ -n "$problem" ] ; then echo "\t$METAPATH/metastat$setarg $device" >> $msgs_f # デバイスに何がマウントされているかを調べる。 mp=mount|awk -e '/\/dev\/md\/dsk\/'$device'[ \t]/{print $1;}' if [ -n "$mp" ] ; then echo "\t\t$mp mounted on $device" >> $msgs_f fi fi shift done fi # # ホットスペアが使用されているかチェックする。 # problem="" grep "no hotspare pools found" $metahs_f > /dev/null 2>1 if [ $? -ne 0 ] ; then problem=awk $metahs_f -e \ '/blocks/ { if ( $2 != "Available" ) print $0;}' fi if [ -n "$problem" ] ; then retval=expr $retval + 256 echo "\ metacheck: hot spare in use, for more detail run:\n\t$METAPATH/metahs$setarg -i" \ >> $msgs_f fi fi # エラーが発生している場合は、レポートを送信する。 if [ $retval -ne 0 ] ; then if [ -n "$recipients" ] ; then re="" if [ -f $pending_f ] [ "$filter" = "yes" ] ; then re="Re:" # 保留された通知がある。日付をチェックして再送するか決める。 penddate_filter=cat $pending_f | head -1 if [ "$curdate_filter" != "$penddate_filter" ] ; then rm -f $pending_f > /dev/null 2>1 else if [ "$debug" = "yes" ] ; then echo "metacheck: email problem notification still pending" cat $pending_f fi fi fi if [ ! -f $pending_f ] ; then if [ "$filter" = "yes" ] ; then echo "$curdate_filter\n\tDate:$curdate\n\tTo:$recipients" \ > $pending_f fi echo "\ Solaris Volume Manager: $node: metacheck$setarg: Report: $curdate" >> $msg_f echo "\ --------------------------------------------------------------">> $msg_f cat $msg_f $msgs_f | mailx -s \ "${re}Solaris Volume Manager Problem: metacheck.$who.$set.$node" $recipients fi else cat $msgs_f fi else # 問題は検出されていない。 if [ -n "$recipients" ] ; then # デフォルトでは、メールを送信しない。また、何も印刷しない。 echo "\ Solaris Volume Manager: $node: metacheck$setarg: Report: $curdate" >> $msg_f echo "\ --------------------------------------------------------------">> $msg_f if [ -f $pending_f ] [ "$filter" = "yes" ] ; then # 保留されたフィルタが存在する。削除し、OK を送信する。 rm -f $pending_f > /dev/null 2>1 echo "Problem resolved" >> $msg_f cat $msg_f | mailx -s \ "Re: Solaris Volume Manager Problem: metacheck.$who.$node.$set" $recipients elif [ "$testarg" = "yes" ] ; then # テストのため、問題がなくても、毎回、メールを送信する。 echo "Messaging test, no problems detected" >> $msg_f cat $msg_f | mailx -s \ "Solaris Volume Manager Problem: metacheck.$who.$node.$set" $recipients fi else echo "metacheck: Okay" fi fi rm -f $files > /dev/null 2>1 |
cron ユーティリティを使ってスクリプトを起動する手順については、cron(1M) のマニュアルページを参照してください。