2012.03.04

GPTでミラー化したHDDの初期化と再組み込み・・・(FreeBSD)

以前に「FreeBSD 9.0のGPTでのミラー構築」を書いたが、HDDの故障に際しての交換作業を行なうことを試みた。現在、ミラーはドライブada0とada1で構成されているが、ada1が故障したとの前提で行うこととした。現実的には、ada1を外して新しいHDDを取り付けることとなるが、新しいHDDの代わりにada1として使っていたHDDを初期化して、再度使うこととし、GPTでミラー化されたHDDを初期化することも合わせて試みることとした。

以下説明のためミラー構成でada0となっていたドライブをdv#0 、ada1となっていたドライブをdv#1と呼ぶこととする。

1. HDDの初期化

dv#1を初期化するため、dv#0のケーブルを抜き、dv#1のみ実装した状態で、FreeBSD 9.0のインストールCDで立ち上げ、Live CDを選択してrootでログインする。
プロンプトが現れたら、HDDの状態を調べる。

# gpart show
=>         34      312581741 ada0   GPT    (149G)
              34                  128     1   freebsd-boot  (64k)
            162      136314880     2   freebsd-ufs     (65G)
136315042        19986412     3   freebsd-swap   (9.5G)
156301454      156280321          - free -   (74G)

このことから、

  • bootレコードは、34セクター目から161セクターまで
  • データー領域は、162 – 136315041
  • スワップ領域は、136315042 – 156301453

となっていることが分かる。最後の156301454以降312581775までが空きである。最後のセクターが表示の1行目の312581741と僅かに異なるが、理由は分からない。
そして、ミラーのメタデーターはそれぞれの領域の最終セクターに書かれているので、境界を跨ぐようにddで消去する。以下のように行った。

# dd if=/dev/zero of=/dev/ada0 bs=512 count=2000
# dd if=/dev/zero of=/dev/ada0 seek=136314000 bs=512 count=2000
# dd if=/dev/zero of=/dev/ada0 seek=156301000 bs=512 count=2000
# dd if=/dev/zero of=/dev/ada0 seek=312581000 bs=512 count=2000

最後の行の空き領域の最後にzeroを書き込む必要はないと思われるが、以前にもHDD全体でgmirrorで使用した痕跡が残っているかも知れず、念のため消去を行った。
なお、bs=100mとして全領域消去したら約42分かかった。150GBの小容量のHDDでも42分だから、大容量HDDだと丸1日かかるかも知れない。

2. ミラーの再構築の事前確認

Shutdownして、dv#0, dv#1とも接続して普通に立ち上げる。
gpartで確認すると、dv#0の情報のみ表示される。

# gpart show
=>         34      156301421 ada0   GPT    (74G)
              34                  128     1   freebsd-boot   (64k)
            162      136314880     2   freebsd-ufs      (65G)
136315042        19986412     3   freebsd-swap   (9.5G)
156301454                      1          - free -   (512B)

gmirrorのステータスを見ると、

# gmirror status
mirror/p1 DEGRADED ada0p1  (ACTIVE)
mirror/p2 DEGRADED ada0p2  (ACTIVE)
mirror/p3 DEGRADED ada0p3  (ACTIVE)

となっていて、すべてDegradeした状態で動いている。

3. ミラーの再構築

ここで、ada1をada0と同じ分割となるように作る。

# gpart backup ada0 > ada0.gpt
# gpart restore -F ada01 < ada0.gpt

再度、gpart showで情報を見ると、ada0とada1が同じ構成で現れる。ただしdv#1の方が容量が大きいので、最後に付いている空き領域が74Gにもなっている。

# gpart show
=>         34      156301421   ada0   GPT    (74G)
              34                  128     1   freebsd-boot  (64k)
            162      136314880     2   freebsd-ufs     (65G)
136315042        19986412     3   freebsd-swap   (9.5G)
156301454                      1          - free -   (512B)

=>         34      312581741 ada1   GPT    (149G)
              34                  128     1   freebsd-boot  (64k)
            162      136314880     2   freebsd-ufs     (65G)
136315042        19986412     3   freebsd-swap   (9.5G)
156301454      156280321          - free -   (74G)

ここで、ada1にbootレコードを書き込む。
boot領域をミラー化してもbootコードだけは、gmirrorの対象外であるため、マニュアルで書いておく必要がある。最初これが分からず、起動しなくて散々悩むこととなった。

# gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1

gmirrorの構成情報をリセットして状態を確認する。

# gmirror forget p1
# gmirror forget p2
# gmirror forget p3
# gmirror status
mirror/p1 COMPLETE ada0p1  (ACTIVE)
mirror/p2 COMPLETE ada0p2  (ACTIVE)
mirror/p3 COMPLETE ada0p3  (ACTIVE)

構成情報がリセットされたので、それぞれの領域のミラーを構築する。

# gmirror insert p1 /dev/ada1p1
# gmirror insert p2 /dev/ada1p2
# gmirror insert p3 /dev/ada1p3
# gmirror status
Name         status     Components
mirror/p1    COMPLETE   ada0p1 (ACTIVE)
                        ada1p1 (ACTIVE)
mirror/p2    DEGRADED   ada0p2 (ACTIVE)
                        ada1p2 (SYNCRONIZING 1%)
mirror/p3    COMPLETE   ada0p3
                        ada1p3 (SYNCRONIZING 20%)

p1はboot領域で64kBしかないので、同期化は一瞬で終わる。
次にswap領域が、比較的小容量なので短時間で完了する。swap領域の同期化が完了すれば、サーバーは使用可能になる。コマンドの入力に対して通常と思える応答を示す。
本当に、HDDが壊れて新しいHDDを接続したときは、3.項のミラーの再構築のみなので、作業は簡単である。


2012.02.19

Apacheのログファイルの分割保存・・・(Apache)

Apacheのログファイルで特にアクセスログは、そのままではどんどん肥大化する。
それで、/etc/newsyslog.confに分割保存の設定をした。
newsyslog.confの最後に下の赤字の2行を追加。

# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
/var/log/all.log                            600  7     *    @T00  J
/var/log/amd.log                         644  7     100  *     J
/var/log/auth.log                         600  7     100  *     JC

/log/httpd-access.log                   644  12    *    $M1D0  J  /var/run/httpd.pid 30
/var/log/httpd-error.log                644  12    *    $M1D0  J  /var/run/httpd.pid 30

ログファイルの各設定の意味は、center>

logfilename /var/log/httpd-access.log ログァイルの場所。
[owner:group] 普通はブランクで、rootになっている。
mode 600, 644 ログァイルのパーミッション。
count 7 ログァイルの世代数
size 100, * ログファイルをローテイトする容量でKB単位。
なお*は容量を特に指定せず、時刻で切り替えるときに用いる。
when @T100, @01T05, $M1D0等 @T00 は、毎日午前 0:00 にローテーションさせると
いう意味で、@01T05 は、毎日午前 1:05 に$W6D0 は、
毎週土曜日の午前 0:00 に$M1D0 は、毎月1日の
午前 0:00にローテーションさせるという意味になる。
flags J, JC, Z等 Jはbzip2で圧縮することを意味し、ファイルがないときに新たに生成するときはCを付ける(JCと表記)。また、
Bはバイナリーで、Zはgzipで圧縮する。
[/pid_file] /var/run/httpd.pid ログの切り出しを行った際にSIGNALを飛ばす先の
プロセスのpidファイルを指定。
[sig_num] 30 送信するSIGNAL で30はSIGUSR1。
ApcheはSignalを送らないと掴んだファイルを離さない。

2012.02.17

Movabletypeを別サーバーに移動/コピー・・・(Movabletype)

Movable typeの最新版は、MT-5.xだが、今でも3.35を使っている。
理由は、MT-3.xの時代に散々カスタマイズを施し、TextのFormatterなどもこのブログの記事のようにコマンドラインの記述に都合が良いように書き直して、Pluginとして使っているからである。さらには、数人の友人がブログページを開いているので、MMIが変わると戸惑うことを恐れるからである。
さて、自宅内で運用しているサーバーが壊れたことを考え、別の予備サーバーを立ち上げ色々なサービスの設定を行っているが、ブログを移設するのに手間取ったので、下記にその顛末を書いておく。

1. ディレクトリーのコピー

(1) mt.cgiの入っているディレクトリーならびにブログの公開ディレクトリーをrsyncなどを使って全て
予備サーバーにコピーする。
(2) CGIPathの変更
mt-config.cgiに書かれているCGIPathを予備サーバーのURLに変更する。

例: CGIPath http://abc.myhome.jp  → CGIPath http://xyz.myhome.jp

2. 元のサーバーでブログのDBをdump

# mysqldump --default-character-set=binary -u USER -pPASS BLOGDB > abcblogdb

USER, PASS, BLOGDBは、設定した正しい値を入れること。

  • 予備サーバーでリストア
  •  (1) 元のサーバーでdumpしたDBデーターをftpなどで予備サーバーにコピーする。
     (2) sedを使ってURL名を変更

  • 10MB近いデーター量で、数分要した。
  • # sed -e "s/abc.myhome.jp/xyz.myhome.jp/g" abcblogdb > xyzblogdb

    (3) DBのリストア

    # mysql -u USER -pPASS BLOGDB <  xyzbogdb

    ERROR 2006 (HY000) at line 66: MySQL server has gone awayとエラーになる。
    66行目でエラーというので66行目を見ると、
    LOCK TABLES `mt_author` WRITE; となっている。
    ここで、LOCK TABLESとなっているのが悪いのかと思って、UNLOCK TABLESにsedを使って書き換えてみたが、今度は別のエラーになって、構文のエラーなのでマニュアルをよく読めと言ってくる。
    ここでお手上げかと思ったが、Netで色々調べたら、mysqlの転送の最大パケット数が不足していることが分かった。
    エラーになった行に、たまたまLOCK TABLESの語句があったので、これが原因かと思って混乱してしまった。ともかく、以下のようにpacket数を修正した。

    # vi /etc/my.cnf
    ・
    [mysqld]
    ・
    max_allowed_packet = 1M → 32Mに修正した

    ちなみに、[mysqldump]のセクションでは、max_allowed_packet = 16M となっていた。
    mysqlを再スタート

    # /usr/local/etc/rc.d/mysql-server restart

    ここで、再度DBのリストア

    # mysql -u USER -pPASS BLOGDB <  xyzbogdb

    今度はエラーなく無事終了した。

    3.ブログの再構築

    mt.cgiをブラウザで開いて、ユーザー名。パスワードを元のサーバーで用いていたのを使いログインし、複数のブログを順次開いて、公開パスが予備サーバに対応したものになっていることを確認し、サイトの再構築を行う。
    blogurl.jpg
    これで、無事終了である。書くと複雑のようだが、分かってしまうと沢山のページを有するブログであっても短時間で引越しができる。


    2012.02.02

    Majordomoをソースからインストール・・・(mail)

    FreeBSD 9.0を入れてportsでMajordomoを入れようとすると、古いのでMailmanを使えと言ってくる。以前はそれでもインストールできたのだが、いよいよportsでは入れられないらしい。Mailmanを使うことも考えたが、MLの運用上色々と細かいカスタマイズを行なっているので、なかなか止められない。
    そこで、久々にソースを取ってきてインストールしたのだが、だいぶやり方を忘れていたので、改めてインストール方法を書いておくことにした。

    まず、下記からmajordomoのソースのgzipファイルをダウンロードしてくる。
    http://www.greatcircle.com/majordomo/
    そして、適当なフォルダーで解凍する。

    # tar xvzf majordomo-1.94.5.tar.gz

    majordomo-1.94.51のフォルダーができる。
    majordomoのユーザー名、グループ名を決める必要があるので、下記を追加する。
    /etc/passwdに

    majordom:*:54:54:Majordomo Pseudo User:/usr/local/majordomo:/nonexistent

    /etc/groupに

    majordom:*:54:

    ユーザーIDとグループIDはportsでインストールしたときと同じに54とした。
    次にmajordomo-1.94.51に入って、Makefileの編集をする。

    # cd majordomo-1.94.51
    # vi Makefile
    PERL = /usr/bin/perl         ← perlの位置の指定の修正
    W_HOME = /usr/local/majordomo ← 自分のmajordomoのインストール先を指定
    W_USER = 54          ← user ID
    W_GROUP = 54          ← group ID
    TMPDIR = /usr/tmp        ← tmpディレクトリーの指定

    次にsample.cfをmajordomo.cfとしてコピーし、編集する。

    # cp sample.cf majordomo.cf
    # vi majordomo.cf
    $whereami = "host.example.com"; ← 運用するホスト名を入れる。
    #if ( defined $ENV{"HOME"}) {   
    #     $homedir = $ENV{"HOME"};
    #} else {
    #     $homedir = "/usr/test/majordomo";
    #}
    
          $homedir = "/usr/local/majordomo"; ← $homedirの場所を単純に指定
    
    $sendmail_command = "/usr/sbin/sendmail"; ← sendmailの場所の指定
    
    $TMPDIR = "/usr/tmp"; ← tmpディレクトリーの指定

    ここで、/usr/tmpを作成し、パーミッションを書き込みを可能にしてMajordomoをインストール

    # mkdir /usr/tmp
    # chmod 777 /usr/tmp
    # make install

    そして、wrapperのインストールとテスト

    # make install-wrapper
    # cd /usr/local/majordomo
    # ./wrapper test-config

    エラーがでなければ、インストールは終了である。
    以降の設定はportsで入れた場合と同じなので省略する。

    ****インストール後に散々トラブった事****

    (1) wrapperの実行権限

    インストールして./wrapper config-testは無事に終了したが、FreeBSD 9.0になって、メールの実行権限はrootでなくなったようで、majordomoのwrapperがPermission deniedになってしまう。
    この対策として、/etc/groupのmajordomにmailnullを追加する必要があった。

    # vi /etc/group
    majordom:*:54:mailnull   ← mailnullを追加する

    (2) majordomo.plの修正

    lists内にtestのディレクトリーを作りowner, groupともにmajordomにして後に、majirdomoにsubscribe testとメールを出すと動作せず、majordomoディレクトリー内のLogに以下のエラーが記録されていた。

    ABORT Majordomo@abc.def.jp: HOGEHOGE <hogehoge@abc.def.jp> is not a valid return address.

    PackageでMajordomoを入れると正常に動作するので、色々調べたらmajordomo.plに修正が必要であった。
    sub main’ParseAddrsの中の記述である。(98行付近から始まっている)

    sub main'ParseAddrs {
        local($_) = shift;
        1 while s/\([^\(\)]*\)//g;      # strip comments
        1 while s/"[^"]*"\s//g;     # strip comments"
        split(/,/);     → my @parts = split(/,/);        # split into parts
      foreach (@_) {  →   foreach (@parts) {
        1 while s/.*<(.*)>.*/$1/;
        s/^\s+//;
        s/\s+$//;
        }
    
        @_;    →  @parts;
    }

    後に調べたら、perl 5.12.以降で修正が必要となったとのこと。マジック変数の@_を使うのが、そもそも間違いだが、以前のperlでは何とか動いていた。
    参考URL: http://henrysnotes.org/?p=448

    (3) Sequencer

    majordomo-1.94.5-jp.patch.gzを/usr/local/majordomoに入れ、日本語化のパッチを行い、resendで動作確認してからsequencerに変えたら動かなくなった。
    何のことはない、sequencerの中にもsendmailコマンドに/usr/lib/sendmailをしているところが3箇所あった。/usr/sbin/sendmailに書き直した。

    # vi sequencer
    
    $sendmail_cmd = "/usr/sbin/sendmail $opt_m -f$sendmail_sender " .
    
            print MAIL ">>> /usr/sbin/sendmail -f$sendmail_sender -t\n";
    
        local(@mailer) = split(' ',"/usr/sbin/sendmail -f$sendmail_sender -t");

    なお、Majordomoを日本語化したい場合は、日本語化のパッチ(majordomo-1.94.5-jp.patch.gz → 遂にリンク先がなくなった。)をあてた後に下記のようにjsendmailをつくり、majordomo.cfの$sendmail_commandを書き換える。

    # vi jsendmail
    #! /bin/sh
    /usr/local/bin/nkf -j | /usr/sbin/sendmail $*
    # chmod +x jsendmail
    # vi majordomo.cf
    # $sendmail_command = "/usr/sbin/sendmail"; 
    $sendmail_command = "/usr/local/majordomo/jsendmail"; 

    jsendmailに書き換えるのはmajordomo.cfのみで、sequencerなどにある/usr/sbin/sendmailは書き換えてはならない。書き換えるとSubjectのMIME変換がなされなくなる。

    (4) その他

    sequencerに変えたのはメールのタイトルに[Test:00123]タイトル のようにメールの件名に連番をつけたいからであるが、このためmajordomo/lists内にtest.seq(testの名のML名の場合)のファイルを作り、例えば00001のように最初の番号を入れておく。0の数は、連番の桁数合せのためで、この例の場合は5桁になる。


    2012.01.29

    FreeBSD 9.0のGPTでのミラー構築・・・(FreeBSD)

    FreeBSD 9.0では、GUIDパーティション(GPT)がサポートされたが、そこでミラー構成がMLの助けも借りて成功したので、記述しておくことにした。
    既に、GUIDEDでFreeBSD 9.0がインストールされているものとする。
    なお、画面キャプチャーなどで便利なので、VMWareで構成したが、もちろんこの方法で実環境でも問題なく構成でき、サーバーを立ち上げた。

    1. HDDの追加

    ミラーにするHDDを追加して、普通に起動し、ログインしてrootで下記の操作を行う
    最初にFreeBSDをインストールしたドライブ名と追加したドライブ名を確認する。

    # camcontrol devlist
    <VMware Virtual IDE Hard Drive 00000001> at scbus0 target 0 lun 0 (pass0,ada0)
    <VMware Virtual IDE Hard Drive 00000001> at scbus0 target 1 lun 0 (pass1,ada1)

    次にada1をada0と同じパーティションとなるように合わせる。

    # gpart backup ada0 > ada0.gpt
    # gpart restore -F ada1 < ada0.gpt

    内容の確認をする。

    # gpart show
    =>       34  20971487  ada0  GPT  (10G)
            34            128     1  freebsd-boot  (64k)
              1 62  19920768     2  freebsd-ufs   (9.5G)
      19920930   1048576     3  freebsd-swap  (512M)
      20969506         1981        - free -  (990k)
    
    =>         34  25165791  ada0  GPT  (12G)
                  34            128     1  freebsd-boot  (64k)
                162  19920768     2  freebsd-ufs   (9.5G)
       19920930   1048576     3  freebsd-swap  (512M)
       20969506   4196285        - free - (2.0G)

    ada1にbootレコードを書き込む。

    # gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1

    2. ミラーの構築

    ここで、shutdownして、インストールCDで起動して、Live CDを選択する。loginのpromptが出たらrootでログインする。パスワードは不要である。(クリックで画像拡大)

    mirror01.jpgmirror02.jpg

    geom_mirrorをロードし、各スライス毎にround robinで構築する。

    # kldload geom_mirror
    # gmirror label -vb round-robin p1 /dev/ada0p1
    # gmirror label -vb round-robin p2 /dev/ada0p2
    # gmirror label -vb round-robin p3 /dev/ada0p3

    内容を確認する。

    # gmirror status
    Name         status     Components
    mirror/p1    COMPLETE    ada0p1 (ACTIVE)
    mirror/p2    COMPLETE   ada0p2 (ACTIVE)
    mirror/p3    COMPLETE    ada0p3 (ACTIVE)

    ada1の各スライスをinsertする。

    # gmirror insert p1 /dev/ada1p1
    # gmirror insert p2 /dev/ada1p2
    # gmirror insert p3 /dev/ada1p3

    gmirrorのステータスを確認する。

    # gmirror status
    Name         status     Components
    mirror/p1    COMPLETE   ada0p1 (ACTIVE)
                            ada1p1 (ACTIVE)
    mirror/p2    DEGRADED   ada0p2 (ACTIVE)
                            ada1p2 (SYNCRONIZING 91%)
    mirror/p3    COMPLETE   ada0p3
                            ada1p3 (ACTIVE)

    p1とp3が同期化完了で、p2のみ進行中を示している。
    全てCOMPLETEになるのを待ち、fstabとloader.confを編集する。

    # mount /dev/mirror/p2 /mnt
    # cd /mnt/etc
    # vi fstab
    # Device                 Mountpoint       FStype    Option   Dump   Pass#
    /dev/ada0p2          /                       ufs           rw          1           1
    /dev/ada0p3         none                  swap       sw          0           0

    下記になるように修正する。

    /dev/mirror/p2          /                       ufs           rw          1           1
    /dev/mirror/p3         none                  swap       sw          0           0

    次にloader.confにgeom_mirrorの読み込みを追加。

    # cd /mnt/boot
    # vi loader.conf
    ここで、
    geom_mirror_load="YES" を追加

    これで終了である。rebootしてHDDから起動して使用する。
    Swapも確認しておく。

    # pstat -sh  または swapinfo -h
    Device                     1K-blocks  Used    Avail Capacity
    /dev/mirror/p3         418812   0B  418MB

    « Previous | Next »