Rocket Raid 2720 ホットスワップメモ

続きを書こうとおもったら
hptraidconfからドライブ認識されてない\(^o^)/
hotswapもうまく働いてないようなので解決方法探し中

  • > waiting for hptraidconf update :(

昨晩3時にrr2720からのエラー音を鳴らして近所迷惑だなと思い
羽毛布団でくるみながらやったテストした結果をチラ裏

ホットスワップ自体初めてだったのもので知識不足という面があった。
抜くとすぐにremovedとなるので刺し直した時もすぐに認識しなおすと思い
何度か抜いては刺してしてたけどremovedの後にrescanしなかった。
どうすんだこれと悩んで調べてみた。

# camcontrol eject /dev/da0
これで抜いた直後に
# camcontrol devlist
すると消える。(精神衛生上いいだけで実際は自動で消える
# camcontrol rescan all
rescanタイミングで自動的にrescanされるけどこれも気持ちで打っておきたい

結論

rr2720 rescan timing = 20sec
つまり抜いて20秒後にしか再認識してエラー音消えないからその間は耐えろと(;゚д゚)

WD15EARSのベンチのcountが1048になってるとのご指摘を頂きました。
違和感はあったけど気づかないとかだめぽすぎる俺。

zfs raidz on FreeBSD8.2 with Rocket Raid 2720

先週(?)IYHしたRocketRaid2720を使ってFreeBSD8.2上でzfs raidzの構築とベンチなメモ

最初にひっかかった問題とバグ

rr2720_bios_v10
> sata600対応ドライブ(WD20EARX)でもsata300表示される(実際は600で動いてる
> jbodをディスクごとに作ってもCHECKSUM ERRORが起きる
> raid arrayを組んでもFreeBSD8.2の/devに<del>生えてこない</del>
>>追記:
gの人「生えてきます。hptraidconfでステータスが見れないのでデグレに気づかないと終わり」
gの人「そもそもhptraidconfのバージョンが古い」
> non-rayd biosを使ってもFreeBSD8.2の/devに生えてこない
> S.M.A.R.Tとれなくね?
> Initializedかnewにしかならない
>> newの状態でRAIDBIOS(Ctrl+H)からInitializeすればInitializedのstatusになる
rr2720_bios_v12
> jbodがディスク1本で作れない
> raid0,raid1もディスク2本ずつで作れたのが認識してるドライブ全体を
使わないと作れない
> Initializedかnewにしかならない
(ry

対策方法

MBRもしくはGPTで初期化を必ず行う
zfsをディスク先頭から使うのを諦める(MBR|GPT->zfsでディスク先頭から始まる)

以降手順をつらつらと書きマッスル

手順その1下準備編

まず最初にディスク(WD20EARX)をFreeBSD8.2で認識させないことには何も始まらないので
legacyとしてrr2720に認識させる必要がある。

  1. まず全裸になります。
  2. 次にrr2720からHDDのケーブルをはずします。
  3. M/BのSATAポート(なければクロシコSATAカードなど)に繋ぎます。
  4. 徐に以下のコマンドを実行します。

ケーブルはずすのまんどくせな人用
説明しよう(CV:誰か)

MBR/GPTで初期化したディスクはRAID BIOSでもlegacyとして認識できるが
RR2720に繋いだ状態でMBR/GPT初期化したくても、new/initializedで認識されていれば
arrayを組まないと生えてこない。
なので別の環境/カードで初期化する必要があるため。

# gpart create -s gpt /dev/XXX
# XXX created
#  gpart add -b 40 -t freebsd-zfs /dev/XXX
gな人「(-b 40はAFTなディスクに対するおまじない。512B/sectorの場合は-b 34にする)」
※ XXXはデバイス名

WD15EARSでのベンチ結果

# dd if=/dev/zero of=dev/ad5p1 bs=1m count=1024
1048+0 records in
1048+0 records out
1098907648 bytes transferred in 11.128260 secs (96487846 bytes/sec)

# dd if=/dev/urandom of=dev/ad5p1 bs=1m count=1024
1048+0 records in
1048+0 records out
1098907648 bytes transferred in 22.273503 secs (48207137 bytes/sec)
手順その2(ドライバの導入)

某所ログからの甜菜

glxxxxxx > $ cd /tmp && fetch http://www.highpoint-tech.cn/BIOS_Driver/rr272x_1x/FreeBSD/rr272x_1x-bsd-8.0-v1.0.10.0108.tgz
glxxxxxx > $ mkdir /tmp/rr2720
glxxxxxx > $ cd /tmp && mv rr272x* rr2720/ && cd rr2720
glxxxxxx > $ tar zxf rr272x_1x-bsd-8.0-v1.0.10.0108.tgz
glxxxxxx > アーキテクチャにあわせてドライバーをコピーする
glxxxxxx > $ cp rr272x_1x-8.0-amd64.ko /boot/kernel/rr272x_1x.ko
glxxxxxx > 起動時にドライバーがロードされるようにloader.confを弄る
glxxxxxx > $ echo rr272x_1x_load=\"yes\" >> loader.conf
glxxxxxx > ドライバーを入れたら一度シャットダウンして、RR2720とさっきフォーマットしたHDDを繋いで起動する
glxxxxxx > 起動時のRAID BIOSの画面で、各HDDがlegacyとして認識されていればOK
glxxxxxx > 起動後、/devの下に da[0-9]* と da[0-9]p1 が生えているか確認する
glxxxxxx > 生えていれば正常に認識されている
glxxxxxx > da[0-9]*とda[0-9]p1が認識されていればzfsのプールを作成する
glxxxxxx > da[0-3]p1を使いtankという名前でRAID-Zを組む場合
glxxxxxx > $ zpool create tank raidz da0p1 da1p1 da2p1 da3p1
glxxxxxx > mount もしくは df で /tank が認識されていれば成功
番外S.M.R.Tの情報が知りたいですしおすし

某所ログからの甜(

glxxxxxx > SMARTを読む
glxxxxxx > smartmontoolsを入れる
glxxxxxx > $ pkg_add -r smartmontools
glxxxxxx > パスが通っているとこのコマンド名のキャッシュをリフレッシュ
glxxxxxx > $ rehash
glxxxxxx > SMARTを読む
glxxxxxx > RR2720のデバイス名が /dev/rr272x_1x で ポート1のSMARTを読む場合
glxxxxxx > # smartctl -a -d hpt,1/1 /dev/rr272x_1x
glxxxxxx > (1/1の部分はL/Mとして、LはコントローラーID、Mはチャンネル番号)
glxxxxxx > ディスクが複数の場合はMの部分を変えていけば順次取れる
glxxxxxx > SMART値のみ取りたい場合は -a の代わりに -A を使う

わっち的補足っぽいもの

  • よいこのみんなはsmartctlをsuで行うこと
  • L/Mな順番はRocketRAID BIOS Setting画面のChannelに対応?(2枚持ってないので要確認
番外編の番外編(計測ツールのいんすこ)

パフォーマンス計測のためいくつかツールを導入しまっする。

ネットワークのリアルタイムトラフィックを取得する(sambaによるwrite速度計測など)

glxxxxxx > vnstatを入れる
glxxxxxx > $ pkg_add -r vnstat
glxxxxxx > $ rehash
glxxxxxx > $ vnstat -l -i [if_name]
glxxxxxx > -l はリアルタイム表示
glxxxxxx > -i はインターフェース指定
glxxxxxx > if_nameにifconfigで取れるインターフェース名を入れる
interfacenaemeはifconfigあたりでとってくだしあ


zpoolのio状況確認

glxxxxxx > $ zpool iostat
glxxxxxx > iostat の後ろに数字をつけるとその秒間で自動更新がかかる
glxxxxxx > 1秒毎なら
glxxxxxx > $ zpool iostat 1
glxxxxxx > システムにぶら下がってるディスクのio状況を見る
glxxxxxx > $ systat -iostat
glxxxxxx > -iostat の後ろに数字をつけるとその秒間で自動更新がかかる
glxxxxxx > 1秒毎なら
glxxxxxx > $ systat -iostat 1
glxxxxxx > ステータス表示中に :number と入力するとグリッドっぽい感じになる
glxxxxxx > 詳しくはman systatのiostat参照
glxxxxxx > システムのアレやナニを見る
glxxxxxx > $ systat -vmstat
glxxxxxx > -vmstat の後ろに(ry
glxxxxxx > (ry


$ zpool iostat

               capacity     operations    bandwidth
pool         used  avail   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.34G  7.25T      0      0      8     39

$ systat -vmstat

    2 users    Load  0.00  0.00  0.00                  Jul 10 03:56

Mem:KB    REAL            VIRTUAL                       VN PAGER   SWAP PAGER
        Tot   Share      Tot    Share    Free           in   out     in   out
Act   18640    6064   236696     7016 7930100  count
All  120440    6536 1074060k    10188          pages
Proc:                                                            Interrupts
  r   p   d   s   w   Csw  Trp  Sys  Int  Sof  Flt        cow    4000 total
             19       354    5   46    2  137    4      4 zfod        uhci3+ 16
                                                          ozfod     1 uhci0 ehci
 0.0%Sys   0.0%Intr  0.0%User  0.0%Nice  100%Idle        %ozfod  1999 cpu0: time
|    |    |    |    |    |    |    |    |    |    |       daefr     1 ale0 256
                                                          prcfr  1999 cpu1: time
                                         4 dtbuf          totfr
Namei     Name-cache   Dir-cache    206501 desvn          react
   Calls    hits   %    hits   %       583 numvn          pdwak
      10      10 100                    35 frevn          pdpgs
                                                          intrn
Disks   da0   da1   da2   da3   ad4 pass0 pass1    152668 wire
KB/t   0.00  0.00  0.00  0.00 16.00  0.00  0.00     10448 act
tps       0     0     0     0     0     0     0      9396 inact
MB/s   0.00  0.00  0.00  0.00  0.01  0.00  0.00        36 cache
%busy     0     0     0     0     0     0     0   7930064 free
                                                    14288 buf

$ zpool iostat -v

               capacity     operations    bandwidth
pool         used  avail   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.34G  7.25T      0      0      5     28
  raidz1    1.34G  7.25T      0      0      5     28
    da0p1       -      -      0      0    221     22
    da1p1       -      -      0      0    281     19
    da2p1       -      -      0      0    281     23
    da3p1       -      -      0      0    280     21
----------  -----  -----  -----  -----  -----  -----

続くんじゃよ

jQueryからJSONを使ってPOST送信

デザインとデータ操作を分離汁。という世間の声がうるさいので
デザイン部分はHTML+JavaScript(jQuery)な環境にしようと思う。

jQueryからGETやPOSTしてスクリプト言語で生成されたJSONを食うサンプルは
よく見るが逆はあまり見ないので備忘録を兼ねて....φ(・ω・` )カキカキ


json形式のデータをjQuery.ajaxを使ってPOST
send_json.js

var func_send_json = function(){
    var json_data { id:'epy0n0ff', pw:'hogehoge' };
    $.ajax(
        {
            url:'receive_json.php',
            type:'POST',
            data:json_data,
            error:function(){},
            complete:function(data){alert(data.responseText)},
            dataType:'json'
        }
    );
}

jQuery('button#regist').live("click",func_send_json );


受信したPOSTデータを見てみる

receive_json.php

<?php
    header("Content-Type:text/html; charset=utf-8");
    print_r($_POST);
?>

stdout

Array(
    [id] => epy0n0ff
    [pw] => hogehoge
)

{ id:'epy0n0ff', pw:'hogehoge'}な文字列がPHP側にそのまま渡るのかと思ったら
$_POSTに入れられてるとは...

追記(20011/05/21)

hztのご指摘通りデフォルトはapplication/x-www-form-urlencodedで送信されるので
POSTすればPOST変数になるようです。

jQuery.ajax()より引用

contentTypeString
Default: 'application/x-www-form-urlencoded'

When sending data to the server, use this content-type. 
Default is "application/x-www-form-urlencoded", 
which is fine for most cases. If you explicitly pass
 in a content-type to $.ajax() then it'll always be sent to 
the server (even if no data is sent). Data will always be transmitted to the server
 using UTF-8 charset; you must decode this appropriately on the server side.

PHPのテスト環境を整える

JetBrainsのPhpStormとPHPUnitの組み合わせの記事があまりにも少ないので備忘録も兼ねて日記を書いてみる。

環境

Windows7(32bit)
PHP 5.3.6 (cli) (build: Mar 17 2011 10:37:07)
PEAR 1.9.2
PHPUnit 1.3.2

PHPのインストール

ここからインストーラーを落としてくる。ExtraのPEAR Installも選択
php.iniのextension_dirのコメントアウトをはずして、絶対パスで指定する。

PEARのインストール

  1. PHPインストールフォルダのgo-pear.batを実行
  2. 設定項目はお好みのように


PHPUnitのインストール

  1. pear upgrade-all
  2. pear channel-discover pear.phpunit.de
  3. pear channel-discover components.ez.no
  4. pear channel-discover pear.symfony-project.com
  5. pear install phpunit/PHPUnit

pearのバージョンが1.9.1だとPHPUnitがインストールできなかったのでupgradeは必須
channel-discoverも3つとも追加しないとだめです。

PhpStormの設定

  1. PHPUnitを使いたいプロジェクトを開く
  2. [File] => [Settings] => [PHP] =>[PHP homeを設定]
  3. 同様に[PHP]で[Include paths]にC:\PHP\PEAR\PHPUnitとC:\PHP\PEARを追加
  4. [Apply] => [OK]

前準備完了

下準備が終了したので次にテストケースの作成を行います。
Hoge.phpとHogeTest.phpを作成する。
テストケースのクラス名はXXXTest.phpです。(XXXは任意のテストしたいクラス名)

Hoge.php

<?php
class Hoge {
    private $hoge_;

    public function __construct($_hoge){ $this->hoge_ = $_hoge; }

    public function getHoge(){ return $this->hoge_; }
}
?>

HogeTest.php

<?php
require_once("Hoge.php");

class HogeTest extends PHPUnit_Framework_TestCase {
    private $hoge_;
    protected function setUp()
    {
        $this->hoge_ = new Hoge("hogetest");
    }

    public function testgetHoge()
    {
        $this->assertEquals("hogetest", $this->getHoge());
    }
}
?>

次にテストの設定を行います。
[Run] => [Edit Configurations]

[+] => [PHPUnit]

このように設定

All Tests passed

assert関数を使って値チェックを行う。
関数の種類についてはPHPUnitのドキュメントを参照してください。

jQueryでドはまり

ローカル環境でjQueryのload関数を使って後から読み込んだhtml内の要素に対して
bindでイベントを設定することはできるが

		$(document).ready(function() {
			jQuery('.hoge').bind('mouseover', {
				targetHtml:'hoge.html' },click_link
			);
		});
		
		
		function click_link(e)
		{
			$("#main_contents").load(e.data.targetHtml);
		}

サーバ上に置いたものでは、読み込んだhtmlの要素に対してイベントを設定することができなかった。
いろいろ調べた結果、bindを使わずliveを使うと読み込み後の要素に対してもイベントを設定することができる。

古いドキュメントではbindとliveの引数は違うが、新しいjQueryでは引数が同じになっているので安心。

		$(document).ready(function() {
			jQuery('.hoge').live('mouseover', {
				targetHtml:'hoge.html' },click_link
			);
		});
		
		
		function click_link(e)
		{
			$("#main_contents").load(e.data.targetHtml);
		}

jQueryでHP作ることになった

Ajaxでごりごり書くことはあったけども、jQueryは初めて書く。

<body>
<script src="jquery-1.5.2.js"></script>
<script type = "text/javascript" language="javascript"><!-- 
jQuery(document).ready(function(){
	//$("p").click(function(){	
		$("img").attr({ 
	      src: "dummy01.png",
	      title: "jQuery",
	      alt: "jQuery Logo"
	    });
	    alert("hoge");
    //});
});
-->
</script>
<img />

</body>

jQueryでHP作ることになった

Ajaxでごりごり書くことはあったけども、jQueryは初めて書く。

<body>
<script src="jquery-1.5.2.js"></script>
<script type = "text/javascript" language="javascript"><!-- 
jQuery(document).ready(function(){
	//$("p").click(function(){	
		$("img").attr({ 
	      src: "dummy01.png",
	      title: "jQuery",
	      alt: "jQuery Logo"
	    });
	    alert("hoge");
    //});
});
-->
</script>
<img />

</body>