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
SUNWsasnx
これらのパッケージは Solaris オペレーティング環境の一部なので、パッケージの選択をインストール時に変更したり、最小限のパッケージ群だけをインストールしたりしなければ、通常はデフォルトでインストールされます。pkginfo pkgname コマンド (たとえば、pkginfo SUNWsasnx) を使って5つのパッケージが存在することを確認したら、次の各項の説明に従って Solaris ボリュームマネージャ SNMP エージェントを構成します。
Solaris ボリュームマネージャ SNMP エージェントはデフォルトでは有効にされていません。 SNMP トラップを有効にするには、次の手順を実行します。
スーパーユーザーになります。
/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
}
|
次に、/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
}
|
/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 オペレーティング環境をアップグレードするたびに、/etc/snmp/conf/enterprises.oid ファイルを編集し、その終わりに 手順 6 の行を追加してから、Solaris Enterprise Agents サーバの停止と再起動を行う必要があります。
この手順が終わると、SNMP トラップが、指定されたホストに送信されるようになります。送信されたトラップを表示するためには、Solstice Enterprise Agents ソフトウェアなど、適切な SNMP モニターを使用する必要があります。
問題が発生したときにトラップを受信するためには、mdmonitord コマンドを設定してシステムを定期的にチェックする必要があります。詳細は、エラーを周期的にチェックするための mdmonitord デーモンの設定を参照してください。 また、その他のエラーチェックオプションについては、cron ジョブによる Solaris ボリュームマネージャの監視を参照してください。
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
# metadbs のアクセスに問題がないかチェックする。
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
exit $retval
|
cron ユーティリティを使ってスクリプトを起動する手順については、cron(1M) のマニュアルページを参照してください。