Drive Network では現在 radserv をメインに使用しています。
RAID カードに Adaptec RAID 2405 または 5405 が搭載されていますが、Adaptec から FreeBSD 向けの CUI ツール arcconf が提供されているため、ステータスやリビルドの進捗等も確認出来て重宝しています。
レンタルサーバ (ホスティングサービス) では、特に共有サービスの場合は書き込み頻度も高いのでディスク障害には敏感にならざるを得ません。
Drive Network では、ディスク監視ツールを自製しており、毎分ディスクアレイの状態を監視、不具合が見つかると同時に警告メールが技術者に通知しています。
現在は hp DL360 G5 も一部使用しているため、どちらの機器で動作しても RAID カードを検出して動作する様に作成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | #!/usr/bin/perl -w use strict; #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Controller #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// ---------------------------------------------------------- #// Option Parse #// ---------------------------------------------------------- my @basename = split (/\//, $0 ); my $basename = pop ( @basename ); #// ---------------------------------------------------------- #// Item Set #// ---------------------------------------------------------- my $item = { mkdir => '/bin/mkdir' , cat => '/bin/cat' , chmod => '/bin/chmod' , ps => '/bin/ps' , hostname => '/bin/hostname' , mail => '/usr/bin/mail' , awk => '/usr/bin/awk' , grep => '/usr/bin/grep' , chown => '/usr/sbin/chown' , aac => '/dev/aac0' , arcconf => '/sbin/arcconf' , ciss => '/dev/ciss0' , camctrl => '/sbin/camcontrol inquiry da0 -D' , target => '/var/log/messages' , maddr => 'trouble@example.jp' , base => $basename , file => '/tmp/.' . $basename }; #// ---------------------------------------------------------- #// Start #// ---------------------------------------------------------- #// List if ( -e $item ->{aac} ) { check_aac( $item ); } if ( -e $item ->{ciss} ) { check_ciss( $item ); } #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #// Model #// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= sub check_aac { my ( $item ) = @_ ; my @line = ` $item ->{arcconf} getconfig 1`; my $level = 0; my $stat_cl = '' ; my $stat_ld = '' ; my $stat = {}; my $stat_sg = {}; my $stat_dv = {}; my $num_dv = '' ; foreach ( @line ) { chomp ; $_ =~ s/(\s+)/ /g; $_ =~ s/^ //g; if ( $_ =~ /^Controller Status : (.+)/) { $stat_cl = 'Controller Status : ' . $1 . "\n" ; $stat ->{cl} = ( $_ =~ /Optimal/) ? 2 : 1; } if ( $_ =~ /^Status of logical device : (.+)/) { $stat_ld = 'Status of logical device : ' . $1 . "\n" ; $stat ->{ld} = ( $_ =~ /Optimal/) ? 2 : 1; } if ( $_ =~ /^RAID level : (.+)/) { $level = 'RAID level : ' . $1 . "\n" ; next ; } if ( $_ =~ /^Segment (\d+) : (.+)/) { my $seg = 'Segment ' . $1 ; $stat_sg ->{ $seg } = $2 ; } if ( $_ =~ /^Device \ #(\d+)/) { $num_dv = '#' . $1 ; next ; } if ( $_ =~ /^State : (.+)/) { $stat_dv ->{ $num_dv } = $1 ; } } my $body = $stat_cl . $stat_ld . "\n" . $level ; foreach ( sort keys % $stat_sg ) { next unless ( $stat_sg ->{ $_ }); $body .= "$_ : " . $stat_sg ->{ $_ } . "\n" ; } foreach ( sort keys % $stat_dv ) { next unless ( $stat_dv ->{ $_ }); $body .= "Device $_ : " . $stat_dv ->{ $_ } . "\n" ; } if ( -e $item ->{file} ) { if ( $stat ->{cl} == 2 && $stat ->{ld} == 2) { report( $item , $body , 2); } } else { if ( $stat ->{cl} == 1 || $stat ->{ld} == 1) { report( $item , $body , 1); } } } sub check_ciss { my ( $item ) = @_ ; my $stat = 0; my $line = ` $item ->{camctrl} | $item ->{ grep } 'VOLUME OK' `; if ( $line ) { $stat = 1; unless ( -e $item ->{file} ) { return undef ; } } my @line = ` $item ->{cat} $item ->{target} | $item ->{ grep } ciss0:`; my $body = '' ; foreach ( @line ) { next if ( $_ =~ /HP Smart Array/ || $_ =~ /ITHREAD/); #// boot msg $body .= $_ ; } if ( -e $item ->{file} ) { if ( $stat == 1) { report( $item , $body , 2); } } else { report( $item , $body , 1); } } sub report { my ( $item , $body , $flag ) = @_ ; my $host = ` $item ->{hostname}`; chomp $host ; my $file = $item ->{file}; my $subj = "Disk Array: ($host)" ; if ( $flag == 2) { $subj = "Info: Disk Array ($host)" ; } open FILE, "+>$file" ; print FILE $body ; close FILE; ` $item ->{mail} -s "$subj" $item ->{maddr} < $file `; if ( $flag == 2) { unlink ( $file ); } } |
障害発生時 通知メール本文サンプル:
Controller Status : Optimal Status of logical device : Degraded RAID level : 1 Segment 0 : Present (0,0) 3NP3RY3P00009943XLP6 Segment 1 : Missing Device #0 : Online
障害復旧時 通知メール本文サンプル:
Controller Status : Optimal Status of logical device : Optimal RAID level : 1 Segment 0 : Present (0,0) 3NP3RY3P00009943XLP6 Segment 1 : Present (0,1) 3NP3JCEL00009920JP8D Device #0 : Online Device #1 : Online
arcconf は OS に依存しない出力結果のため、コマンドのパスや動作を事前確認すれば CentOS 等にも転用出来るでしょう。