前回は、完璧にファームウェアが吹っ飛んだTerastationPROを完璧に復活させるところまで行きました。

完璧に復活させたので、このまま大容量NASとして完璧に使用することにしましょう!

      / ̄ ̄\      /ノ( _ノ  \     | ⌒(( ●)(●)     .|     (__人__) /⌒l      |     ` ⌒´ノ |`'''|     / ⌒ヽ     }  |  |                  /  へ  \   }__/ /             / ̄ ̄\  / / |      ノ   ノ           / ●)) ((●\’, ・ ( _ ノ    |      \´       _    (   (_人_)’∴ ),  ’        |       \_,, -‐ ''"   ̄ ゙̄''―---└'´ ̄`ヽ   て        .|                  ______ ノ    (        ヽ           _,, -‐ ''"  ノ       ヽ   r'" ̄          \       , '´        し/..     | J           \     (           /      |             \    \         し-  '^`-J

そうっスよねー。

ということで後編として、宣言通りTerastationPROのLinuxBox化に取り組みます。

\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 引 き 続 き 超 濃 厚 な L i n u x 長 編 に な り ま す。            ご 承 知 く だ さ い ! ! /\/\/\/\/\/\/\/\/\/\/\/\/\/\

いや冗談抜きで同じ事やる人以外には全く役に立たない情報だと思いますよ。
長いし...

rootで乗り込む

前回も少し触れましたが、TerastationPROはPowerPCベースのCPU。その上でLinuxが動き、その上で各種アプリが動いています。
シリアルコンソールでブート時のログを眺めるとよく分かるのですが、kernel2.4系のLinuxが動いていて、その上でsambaやapacheが動いてNASとして動作しているという、まあ言うなれば単純明快な仕掛けです。

とは言えその箱の中身をいじるには、箱をこじ開ける必要があります。
シリアルコンソールにはログインプロンプトが表示されるので、ユーザIDとパスワードが分かればログインは可能。
IDとパスワードは何だろう?

試しにweb管理画面へのログインIDとパスワードを入れてみると......おお、通った!(・∀・)!

でもこれ一般ユーザ権限...(´・ω・`)
名前はアドミンなのにな....(´・ω・`)

    〃〃∩  _, ,_      ⊂⌒( `Д´) < ヤダヤダ!        `ヽ_つ ⊂ノ               ジタバタ       _, ,_      (`Д´ ∩ < root権限無きゃヤダヤダ!      ⊂   (        ヽ∩ つ  ジタバタ          〃〃

先人達も同じように悩んでいて、いくつかの解決方法が編み出されていますが、 その方法の一つとして、root権限で乗り込む術が提供されているカスタムファームに書き換えるというものがあります。

ファームをリカバる時に、最初っからそれ入れろよ ( ´∀`)σ)∀`) って言いたいでしょうが、それはそれ。
手を入れる際には、まずはまともな状態に戻して、それがまともに動くことを確認してから手を入れるのが鉄則です。
そうしないと、まともじゃない動きをしたときに、何処に原因があるのか分からなくなりますからね。

で、そのカスタムファームウェアはここで手に入ります。

"TeraStation firmware + telnet + root access" と、ド直球なサブタイトルですが、まあ、そういうことです。

ページ下部に、機種毎のカスタムファームが一覧になって置いてあるのでダウンロード。
配布物の中にはファームのアップデートツールも一緒に入っているので、Buffalo社純正のファームウェアアップデート方法と同じやり方で流し込んであげればOK。
今回は、"Firmware releases without AD support"のVersion1.12を使用しました。

カスタムファームで起動すると、telnetでログイン出来るようになっているはず。
ユーザIDは myroot パスワードは無し。

いざ!

  _n                 n_  ( l    _、_     _、_    l ) oh, yeah.   \ \ ( <_,` ) ( ,_ノ` )  / /    ヽ___ ̄ ̄  )  (   ̄ ̄___/      /    /   \   \

何故わざわざmyrootという変なIDで入る必要があるかというと、これは憶測ですが、既存rootユーザのパスワード保護の為ではないかと思われます。
rootのパスワードを変えてしまうのが一番簡単ですが、それより何らかの影響が出ないとも限らないので、それはそのままにしておいて、root相当のidを1個新規に作ったという次第ですね。
myrootアカウントのuid,gidはrootと同じなので、OSやアプリからは同じユーザと見なされますから。

さてうまく乗り込めたので早速中身を探ってみることにしましょうか。
なお、以下の記述は上記カスタムファームウェアで起動した状態での記述であり、完全な純正状態のものとは細かい点では異なる場合があります。その点ご承知ください。

仕組みを知る

OSは見ての通りKernel2.4系のLinuxです。

# uname -a
Linux TS-TGLR5 2.4.20_mvl31-ppc_terastation #36 Fri Aug 24 18:20:13 JST 2007 ppc unknown

このカーネル本体は基板上のフラッシュメモリに搭載されており、ディスク上にはカーネル本体のファイルはありません。
カーネル入れ替えを行うには、ファームウェアファイルに細工をした上でアップデータで流し込んだり、JTAGを使ったフラッシュメモリの書き換えが必要になります。

標準状態で搭載されているコマンド類は基本的にはBusyBoxによるものが使用されており、そのため通常のコマンドとは機能や挙動が異なる場合がある点に注意する必要があります。

なお、glibcのバージョンは3.3.1でした。

# /lib/libc.so.6
GNU C Library stable release version 2.3.2, by Roland McGrath et al.
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.3.1 (MontaVista 3.3.1-7.0.5.0401600 2004-11-18).
Compiled on a Linux 2.4.20_dev system on 2004-11-18.
Available extensions:
        GNU libio by Per Bothner
        crypt add-on version 2.1 by Michael Glad and others
        linuxthreads-0.10 by Xavier Leroy
        BIND-8.2.3-T5B
        libthread_db work sponsored by Alpha Processor Inc
        NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
        software FPU emulation by Richard Henderson, Jakub Jelinek and others
Report bugs using the `glibcbug' script to <bugs@gnu.org>.

HDDはSATA接続のHDDが4発入っていて、OSからは/dev/sda〜sddとして認識されています。
今回入手したTeraStationPROは1TBモデルでしたので、250GBのHDDが4発搭載されています。

そして各々のHDDはそれぞれ4つのパーティションに区切られており、第1パーティションがOS部分、第2パーティションはswap、第3パーティションがデータ部分として使われています。
Terastationの管理web画面から見ることができる「ディスク1〜4」は、この第3パーティションの部分になります。

第4パーティションはディスクのチェック用領域として使われているようです。スクリプト類をざっと見てみた感じだと、RAIDをリビルドする際の読み書きチェックに使ってる程度で、それ以外には特に使われてはいないようです。
(/usr/local/bin/agingtest.sh で EN_ZEROFILL=1 の場合は使われるけど、ここはデフォルトで 0 固定。また、/usr/local/bin/raid_rebuild.sh の TestPartitions() でバッドブロックのチェックとアレイ組み直しの際に mdadm --zero-superblock している程度)

OS部分はLinuxのソフトミラー(mdデバイス使用)によりディスク4発をフルに使った4重ミラーが組まれています。
こうすることで、1本しかディスクが生き残ってなくてもOS部分だけは守られるって寸法ですね。

図にするとこんな感じ。

パーティションテーブルはこう。

Disk /dev/sdd: 255 heads, 63 sectors, 30401 cylinders
Units = cylinders of 16065 * 512 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/sdd1             1        48    385528+  83  Linux
/dev/sdd2            49        65    136552+  82  Linux swap
/dev/sdd3            66     30378 243481141   83  Linux
/dev/sdd4         30378     30401    192779   83  Linux

第3パーティションはユーザが好きに使える領域です。
ソフトRAIDを組んでも良いし、そのまま単体で使っても構いません。

このパーティションは、RAIDを組まずに単体で使う場合は /mnt/disk1〜4 としてマウントされ、RAIDを組んだ場合は /mnt/array1〜2 としてマウントされます。
また、本体のUSBポートへUSBメモリやUSBディスクを接続した場合は、murasakiによるUSBホットプラグ機能を利用して /mnt/usbdisk1〜2としてマウントされます。

ちなみに /dev/sda〜sdd は /dev/ts_disk1〜4 としてもアクセスできます。パーティション名は後ろにアンダースコア+数字の形式で付与され、/dev/sda1 は /dev/ts_disk1_1 となります。
呼び名が違うだけで実体は同じ(rcスクリプト中でts_diskX→sdXへのシンボリックリンクを張ってる)なので、用途や分かりやすさに応じて使い分ければ良いでしょう。
TeraStationのスクリプト内では ts_disk1〜4 形式で記述されているので、自前スクリプトを書いたり既存のスクリプトに手を入れる場合は ts_disk 形式で統一すると混乱しなくて良いかもしれません。

注意すべき点として、上記の通りts_diskX形式が使えるようになるのはrcスクリプトが流れた後になるので、それ以前の段階でディスクを触るような操作(mount等)の際には、sdX形式で書く必要があります。

次はファイルサーバ機能について。
Windows向けにはsambaで、MacintoshのAppleTalk向けにはnetatalkでサービスを提供しています。
ディスク管理やRAIDの組み直し、ユーザの追加などはwebの管理画面を通じてOS標準のコマンドや自前スクリプトを叩いているという仕組みです。

またwebの管理画面自体も、これまた予想通りApache+CGIで組んであります。
CGIはPerlなので、手を入れるにしても簡単で素敵な感じですね。

このように、sambaやnetatalkやLinuxのシステム管理コマンドや設定ファイルに対して、web画面を被せて統一的な管理機能を提供しているというのがソフト面の仕組みです。
最近よく見るNAS特化型のLinuxやBSD系ディストリビューション(例:FreeNAS)と大きな違いはありません。

リフォーム計画

さてこれがデフォルトの状態。
これをどう劇的ビフォーアフターするかですが、今回の方針としては、元々のTeraStationPROの機能はそのまま残しつつ、Linuxとしての動作環境を追加していくという形のアプローチを取っていこうと思います。

具体的には、

  • OS基本コマンド類の拡充・補充
  • 開発環境の追加
  • それに伴う各種サービス群の追加

といった内容です。

さて、この目的を達成する為にどこから手を付けましょうかね。
Linux化するにはルートパーティションの容量が心許ないので、何はともあれここを拡大させるようにしましょうか。

ルートパーティション拡大

約300MBちょっとのOS領域は、さすがにコマンド類をぼんぼん放り込んでいくには小さいので、まずはここを広げることにします。
なお、サイズを拡大するだけで4重ミラー構成は変えない事にします。

これは、先にも述べた通り、なるべくTeraStationPROとしての使い勝手を維持しつつ、追加の機能としてLinuxBoxとしての機能を持たせたいという考えからです。
こうすることで、純正状態で提供されているディスク管理スクリプトやWEBインターフェース類に手を入れるのを極力避けることができるメリットもあります。

その後スクリプトを読んでみたのですが、スクリプト的には4重ミラーである必要は特になさそうです。
なのでRAID5とかRAID1+0構成でも問題なく行けるかも知れません。
スクリプトをチラ見しただけで深く追ってないので、志ある方は追試してみてください。

作業の流れは以下の通り。

  1. ユーザデータ領域としてアレイが組まれているなら解除しておく
  2. 4重ミラーとなっているルートパーティションからディスクを1本引っぺがす
  3. 引っぺがしたディスクのパーティションテーブルを新パーティションテーブルへ変更
  4. そのディスクに仮ルート環境を作り、そこからブート
  5. 仮ルート環境でブートしたら、ルートパーティションの4重ミラーを解除・アレイ削除
  6. 残りの3本も新パーティションテーブルへ変更し、ルートパーティションの4重ミラーを再作成
  7. 新ルートミラーに新ルート環境を作成
  8. swap領域を有効・追加し、新ルートミラーからブート
  9. 最後に各種スクリプト類を書き換え

それでは、いってみよう!

切り込み隊長ディスクの作成

/dev/md0 から1本引っぺがして

root@TS-TGL5A9:/# mdadm --fail /dev/md0 /dev/sda1
mdadm: set /dev/sda1 faulty in /dev/md0
root@TS-TGL5A9:/# mdadm --remove /dev/md0 /dev/sda1
mdadm: hot removed /dev/sda1
root@TS-TGL5A9:/# mdadm --zero-superblock /dev/ts_disk1_1

パーティションを切り直す。

root@TS-TGL5A9:/# mfdisk -g 40960 /dev/ts_disk1
part_type=0x83
delete partition 1
delete partition 2
delete partition 3
delete partition 4
create partitions...
limit = 83875364
start = 63, stop(limit) = 83875364
limit = 84405509
start = 83875365, stop(limit) = 84405509
limit = 488392064
start = 84405510, stop(limit) = 488392064
The partition table has been altered!

Syncing disks.

パーティションサイズを確認して問題が無ければ

root@TS-TGL5A9:/# mfdisk -c /dev/ts_disk1

Command (m for help): p

Disk /dev/ts_disk1: 255 heads, 63 sectors, 30401 cylinders
Units = cylinders of 16065 * 512 bytes

         Device Boot    Start       End    Blocks   Id  System
/dev/ts_disk1p1             1      5221  41937651   83  Linux
/dev/ts_disk1p2          5222      5254    265072+  82  Linux swap
/dev/ts_disk1p3          5255     30401 201993277+  83  Linux

Command (m for help):

3番パーティション(ユーザ領域)にファイルシステムを作成して切り込み隊長の任務完了。

root@TS-TGL5A9:/# mkfs.xfs -s size=4k -b size=4k -f /dev/ts_disk1_3
mkfs.xfs: warning - cannot get sector size from block device /dev/ts_disk1_3: Invalid argument
meta-data=/dev/ts_disk1_3        isize=256    agcount=40, agsize=262144 blks
         =                       sectsz=4096
data     =                       bsize=4096   blocks=10484384, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096
log      =internal log           bsize=4096   blocks=5119, version=2
         =                       sectsz=4096  sunit=1 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0

さて、さらっと「切り直す」と書いてますが、ここで使っている mfdisk というコマンドはTeraStationPROオリジナルのfdiskコマンド。
引数に何も付けずに実行するとヘルプが表示されます。

root@TS-TGL5A9:/# mfdisk
Partition table manipulator for BUFFALO INC. LinkStation series. ver 2.0, Nov  5 2005

Usage: mfdisk DISK     Create partition tables for HD-LAN ver 1.xx
       mfdisk -f DISK  Create partition tables for HD-LAN ver 2.xx
       mfdisk -h DISK  Create partition tables for HD-HLAN
       mfdisk -g [1:2:3:5:10:20:50] DISK  Create partition tables
       mfdisk -a DISK  Create partition table for HD-HLAN's USB Disk
       mfdisk -c DISK  Create partition table(s) with menu
       mfdisk -p DISK  Check partition table(s)
       mfdisk -e DISK  Deleate all partition tables
       mfdisk -d [1:2:3:4:5:6:7] DISK  Create partition tables for LinkStation/TeraStation
Here DISK is something like /dev/hda or /dev/sda

mfdisk -d の後の数字を1〜7まで変えることで、規定のルールに従いパーティションを切ってくれるという仕組み。
d1の時にはこういうテーブル、d2の時にはこう.....というルールがある。
TeraStationPROの場合は、mfdisk -d7 デバイス名 とすることで、純正状態のパーティションテーブルが作成されます。

また、mfdisk -c デバイス名 とすることで、いわゆる普通のfdiskと同じメニューモードになり、手でパーティションテーブルを表示したり編集することができるようになります。

このコマンドの仕様は開示されていないので、一つ一つ引数を試していくしか無いのですが、先人達がトライ&エラーで探り出した方法によると -g オプションを使うことで第1パーティションの容量を変えることができる模様。
-g の後に第1パーティションに割り当てたいサイズを指定すれば、後は良きに計らってくれるようです。

いくつか試してみましたが、大凡以下のような感じでした。

引数パーティション1の容量ブロックサイズ
-g 20 2GB2096451
-g 50 5GB5237158
-g 200200MB200781
-g 500500MB506016
-g 20002GB2040223
-g 50005GB5142317
-g 2000020GB20474811
-g 4096040GB41937651

ある点を境に、-g の後の数字がどう解釈されるか変わってくるというのが面白いですね。

今回は -g 40960 とした事からも分かるとおり、ルートパーティションのサイズを40GBとして切り直しました。
利用形態や好みによりサイズを変えたい場合は、引数の値を変えて切り直して下さい。

このように便利なコマンドですが1点問題が有って、 -g オプションで作ったパーティションテーブルには4番パーティションが有りません。
もとより存在意義が問われる4番パーティションなので、無くても構わないっちゃ構わないっぽいのですが、先にも書いたとおり、無きゃ無いで地味に問題を起こす場面もあるので、純正状態で提供されているスクリプト類を総ざらいして、4番パーティションに対して何かやってる箇所があればそこを潰しておく等の対処が必要になります(後述)。

仮ルート環境の構築

先ほどファイルシステムを作った領域に、現在のルートパーティションの中身をコピーして仮ルート環境とします。

ルートパーティションの中身をコピー

root@TS-TGL5A9:/# mount /dev/ts_disk1_3 /mnt/disk1
root@TS-TGL5A9:/# cd /
root@TS-TGL5A9:/# tar -l -cf - / | (cd /mnt/disk1; tar xvfp -)

仮ルート中のfstabを書き換え

root@TS-TGL5A9:~# vi /mnt/disk1/etc/fstab
# /etc/fstab: static file system information.
#
#                        
/dev/sda3       /               auto    defaults,noatime                0 0
proc            /proc           proc    defaults                        0 0
/.swapfile      swap            swap    defaults                        0 0

コピーが完了したら、次はこの仮ルート環境をルートパーティションとして起動させます。

仮ルート領域からの起動

仮ルート領域から起動するには、Linuxカーネルパラメータにルートパーティションの情報を明示的に与える必要があります。
TeraStationPROの場合、カーネルパラメータに引数を与えるにはシリアルコンソールを使う必要があります。

シリアルコンソールを使うには、ファームリカバリの際に紹介した基板上にあるシリアルポートを使うか、もしくは以下のコマンドを実行して本体背面のUPSコネクタ(Dサブ9ピンのシリアルコネクタ)をシリアルコンソールとして機能するよう設定すればOK。

root@TS-TGL5A9:/# /usr/sbin/miconapl -a serialmode_console

この設定はOSの起動状態に関わらず電源を切るまで有効なので、再起動のように本体の電源が切れない場合は引き続きUPSコネクタがシリアルコンソールとして機能し続けます。

シリアルコンソールを掴んだ上で再起動すると、マザーボードの起動メッセージが表示され、その後カーネル引数の入力待ちになるので仮ルート領域のデバイス名を入力。

******* Product Information *******
----------------------------------
Product Name: TS-TGL(IENARI)
          VER: 3.16
         Date: 2007/4/16 9:57:12
----------------------------------
Firmware check:done.

>>root=/dev/md0
hit any key to Enter cmd mode. ← ここで何か入力するとコマンドモードへ
>command mode
arg:
 root=/dev/ram0 : initrd
 root=/dev/md0  : hdd-rootfs
 root=/dev/nfs ip=192.168.19.114:192.168.19.219  nfsroot=/tera_root : nfs-rootfs
root=/dev/sda3
(以下略)

無事に起動すれば最大の難関は通過。
df -h / してみて、/dev/sda3 がルートパーティションとしてマウントされていればOK。

なお、Terastationの機能により、/dev/sda3(ts_disk1_3)は /mnt/disk1 としてもマウントされているはず。
多重マウントはあまり宜しいものではないので、ここで手でumountしておきましょう。

root@TS-TGL5A9:/# umount /mnt/disk1

既存ルートミラーの解除・アレイ削除

ルートパーティション = md0 と決め打ちされているので、新ルートも md0 で作らないといけない。
その為に現在の md0 を削除し、同じ名前で新ルートミラーを作る。

root@TS-TGL5A9:/# mdadm --stop /dev/md0

これで md0 が削除される。
mdstat を見て、何も出てこないことを確認。

root@TS-TGL5A9:/# cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid5]
read_ahead 1024 sectors

root@TS-TGL5A9:/#

元アレイ構成ディスクに記録されている、アレイ構成情報を削除

root@TS-TGL5A9:/# mdadm --zero-superblock /dev/ts_disk2_1
root@TS-TGL5A9:/# mdadm --zero-superblock /dev/ts_disk3_1
root@TS-TGL5A9:/# mdadm --zero-superblock /dev/ts_disk4_1

ここまでやると、もう元には戻れないぞ!
前進あるのみ!

残りのディスクのパーティションテーブル変更

まだ手を付けていない2〜4本目のディスクに手を付けよう。

パーティション切り直し

root@TS-TGL5A9:/# mfdisk -g 40960 /dev/ts_disk2
root@TS-TGL5A9:/# mfdisk -g 40960 /dev/ts_disk3
root@TS-TGL5A9:/# mfdisk -g 40960 /dev/ts_disk4

ユーザ領域パーティションへのファイルシステム作成

root@TS-TGL5A9:/# mkfs.xfs -s size=4k -b size=4k -f /dev/ts_disk2_3
root@TS-TGL5A9:/# mkfs.xfs -s size=4k -b size=4k -f /dev/ts_disk3_3
root@TS-TGL5A9:/# mkfs.xfs -s size=4k -b size=4k -f /dev/ts_disk4_3

新ルートミラーの作成

40GBに拡大された各ディスクの1番パーティションを使い、新ルートミラーを作成する。

root@TS-TGL5A9:/# mdadm --create /dev/md0 --level=raid1 \
   --raid-devices=4 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1
mdadm: array /dev/md0 started.

うまくできたかな?確認

root@TS-TGL5A9:/# cat /proc/mdstat
Personalities : [linear] [raid0] [raid1] [raid5]
read_ahead 1024 sectors
md0 : active raid1 sdd1[4] sda1[0] sdc1[3] sdb1[1]
      41937536 blocks [4/4] [UUUU]
      [======>..............]  resync = 32.6% (13700016/41937536) finish=17.0min speed=27548K/sec
      recovery mode = 2, limit = 20


unused devices: 

よさそうですね。

!注意!
md0のsyncが終わるまで再起動しないように。
もしsyncが完了するまでの間に再起動 or シャットダウンしてしまうと、次回の起動途中でアレイのフルsyncが走ってしまい、起動に非常に時間がかかる。

特に今回のようにルートミラーのサイズが(ノーマル時よりも)激しく大きい場合は、sync完了までに時間が掛かり過ぎるため起動時のwatchdog timerに引っかかり、sync完了する前にシステムが強制停止されてしまう場合がある。

もしそうなってしまった場合は、赤ボタン長押しで強制的にEMモードで起動させた上でsyncを完了させれば良い(EMモード時はwatchdog timerが無効になるみたい)。
syncが完了したら、再起動すればよい。

ミラーデバイスができたらファイルシステムを作成し、仮ルート領域のファイルをコピーする。

root@TS-TGL5A9:/# mkfs.xfs -s size=4k -b size=4k -f /dev/md0
root@TS-TGL5A9:/# mount /dev/md0 /mnt/array1
root@TS-TGL5A9:/# cd /
root@TS-TGL5A9:/# tar -l -cf - / | (cd /mnt/array1; tar xvfp -)

新ミラー領域のfstab書き換えを忘れないように。

root@TS-TGL5A9:~# vi /mnt/array1/etc/fstab
# /etc/fstab: static file system information.
#
#                        
/dev/md0       /               auto    defaults,noatime                0 0
proc            /proc           proc    defaults                        0 0
/.swapfile      swap            swap    defaults                        0 0

スワップ領域の追加

パーティションを切り直したので、デフォルトの状態ではスワップ領域がOSに組み込まれていない状態となる。
このまま放っておくと、でかいプログラムを動かした際にメモリ不足に陥るので、スワップを有効にして組み込んでおこう。

スワップ領域の作成

root@TS-TGL5A9:~# mkswap /dev/sda2
root@TS-TGL5A9:~# mkswap /dev/sdb2
root@TS-TGL5A9:~# mkswap /dev/sdc2
root@TS-TGL5A9:~# mkswap /dev/sdd2

スワップ領域の追加

root@TS-TGL5A9:~# swapon /dev/sda2
root@TS-TGL5A9:~# swapon /dev/sdb2
root@TS-TGL5A9:~# swapon /dev/sdc2
root@TS-TGL5A9:~# swapon /dev/sdd2

確認

root@TS-TGL5A9:~# cat /proc/swaps
Filename                        Type            Size    Used    Priority
/dev/sda2                       partition       265064  37876   -1
/dev/sdb2                       partition       265064  0       -2
/dev/sdc2                       partition       265064  0       -3
/dev/sdd2                       partition       265064  0       -4

良きかな良きかな。

さあ、ここまで来たら再起動!
再起動後は新ミラーから起動するはず!

各種スクリプトの書き換え

ディスクを交換した際、murasakiの制御により自動的に再パーティショニングやファイルシステムの作成、RAIDアレイの再構築が行われる。
その際のパーティショニングオプションをデフォルトの "mfdisk -d 7"から今回の "mfdisk -g 40960" に変えておくことで、もしディスクがfailして交換した際でも今回のパーティション構造になるように仕込んでおく。

書き換え対象ファイルは以下の通り  (grep -r mfdisk /etc/* した結果なので漏れがあるかも..)

  • /etc/murasaki/bin/raid_rebuild.sh  (実体は /usr/local/bin/raid_rebuild.sh )
  • /etc/murasaki/bin/hdd_format.sh  (実体は /usr/local/bin/hdd_format.sh )

これらの中にある "mfdisk -d 7" を mfdisk -g 40960 としておく。

なお、hdd_format.shの場合は、judge_newdisk() で何かしらのパーティションテーブルが存在する場合はパーティションの切りなおしを行ってくれないため、judge_newdiskの判定ルーチンをすっ飛ばして無条件にパーティションテーブルを切りなおすように編集する。

## for SATA device
/sbin/mfdisk -g 40960 "$TARGET_DEVICE" > /dev/null 2>&1
sync
sleep 1
mdadm --add /dev/md0 "$TARGET_DEVICE"_1 > /dev/null
create_mdadm_conf
TARGET_DEVICE="$TARGET_DEVICE"_3
/sbin/mkfs.xfs -f "$TARGET_DEVICE" > /dev/null 2>&1

更に、mfdisk -g で作成されたパーティションテーブルには4番パーティションが存在しないため、4番パーティションを使って何かしている箇所にも手当をする必要がある。

具体的には

  • /usr/local/bin/raid_rebuild.sh の TestPartitions() と raid_rebuild()
  • /usr/local/bin/agingtest.sh の zerofill()

と思ったけどagingtest.shのzerofill()は呼ばれないみたい。
というか4番パーティションはゼロフィル用のパーティションだったのか?

なお、フラッシュメモリ中に書かれるtmpimage中のスクリプトは書き換えない。
これは、フラッシュメモリ中のlinuxで起動する事態は即ちディスク全損のような事態であり、そのような場合はそもそもゼロからの環境作り直しになるので、その過程でルートパーティションを拡大すれば良く、ここでわざわざ手間を掛ける意味がないとの判断から。

書き換え対象ファイルの洗い出しと書き換えが終わったら、実際にディスクを1本交換してみて、意図した通りにパーティショニングやリビルドが行われるか確認してみよう!

そして最後に、TeraStationPROのweb管理画面から、ディスク1〜4のユーザ領域がきちんと認識できているか、フォーマットはできるか、フォーマットしたディスクはマウントできるか、RAIDは組めるか等も、一通り確認しましょう。
ここまで行けば、ディスク周りは完了です!

コマンド類の拡充・補充

ディスク容量が増えたので、勝利の美酒に酔った勢いでコマンド類を足していきます。

幸いなことに、Kernel2.4系のPowerPCで動くLinuxディストリビューションがいくつかあるので、それ用に用意されたパッケージ類を流用すれば簡単至極にコマンド類を増やすことができます。

具体的には、VineLinux 3.1/PPC 用のrpmパッケージ類がそのまま使えます!
これはでかい!

             ___        n:     /  R /\     n:         ||   /   /\  \    ||    < ふぅおほほほっ!       f「| |^ト  |  / /=ヽ \  |  「| |^|`|       |: ::  ! } |/ (゚)  (゚) \|  | !  : ::}        ヽ  ,イ \── ゝ── ノ  ヽ  ,イ              \____/

コマンドを足していく際には、先にも少し触れましたが「既存のコマンドはできるだけ触らない」ことを心がける必要があります。

TeraStationPRO標準のスクリプト類はBusyBox版コマンドでの挙動をもとに作成されています。
ここで非BusyBox版のコマンドを無条件に投入・上書きしてしまうと、至る所で不具合が発生し、さらにコマンドを上書きしてしまうと元に戻したくても戻せないという状況に陥ります。

実際、loggerコマンドはBusyBox版と標準版ではコマンドライン引数が違うらしく、起動時に盛大にエラーメッセージを吐いてくれました。それ以外にもinit系でエラーを吐くものが居るなど、何処に何が潜んでいるか分からない状態です。
触らぬ神に祟りなし、君子危うきに近寄らずということで既にBusyBox版で存在するコマンドはそのままにしておき、足りない物を追加するだけにしておきましょう。

先に紹介したカスタムファームウェア配布サイトでも、OpenTeraと称してTeraStationPRO用Linuxコマンド・ライブラリ盛り合わせキット的なものやコンパイル済みファイル群が配布されていますが、上記の理由によりここではその導入は行いません。
ていうか導入したら上記のようなエライ目に遭いました。テストしてねえのかよ。畜生。検収しねえぞ。

rpmパッケージを使うための準備

前述の通り、大変ありがたいことにVine3.1/PPCのrpmを放り込めば、それがそのまま使えます。

TeraStationPROにはrpmコマンドが無いので、rpm形式のアーカイブを扱うことができません。
rpm2cpioコマンドとcpioコマンドを使ってrpmアーカイブの中からファイルを抽出し、ファイルを個別に放り込む必要があります。

そのrpm2cpioやcpioコマンドもrpmアーカイブで提供されています( ´Д⊂ヽ
まさに金庫の鍵は金庫の中状態....

しょうがないので別のlinuxマシンでこれらを展開・抽出し、tarで固めてTeraStationPROへ持って行きましょう!

Vine3.1/PPC用のcpioとrpmパッケージを用意し、rpm2cpioとcpioコマンドが既に入っているLinuxマシンの適当な場所で、

# rpm2cpio cpio-2.5-1vl1.ppc.rpm | cpio -idv ./bin/cpio
# rpm2cpio rpm-4.0.5-1vl8.ppc.rpm | cpio -idv usr/bin/rpm2cpio usr/lib/librpm\*.so
# tar zcvf ts_rpm2cpio.tar.gz bin usr

とやってcpioやrpm2cpioとlibrpm*.soをルートからの相対パス込みで展開し、さらにtarで固めます。
ほんで、その出来上がったtarファイルを TeraStationPROへ持って行き、ルートディレクトリからの相対パスで展開すればインストールできます。

# tar zxvf ts_rpm2cpio.tar.gz -C /
# which rpm2cpio
/usr/bin/rpm2cpio
# which cpio
/bin/cpio

よさそうですね。

これでrpmパッケージからファイルを抽出しインストールする準備が整いました。
早速rpmパッケージ類を取りに行きましょう!

VineLinux3.1/PPC用のRPMを足す

Vine3.1/PPC用のrpmがそのまま使えるとは言え、Vine3.1がリリースされたのは2004年11月。今から5年以上前です。
さすがに古いので、ここでは必要最低限の物を放り込み、それ以外の物は最新版を自前でコンパイルして入れることにします。

その為にも、真っ先に開発環境を構築することにします。
この辺を持ってきて入れればOKでしょう。

  • initscripts-6.51-1vl26.ppc.rpm
  • autoconf-2.59-2vl3.noarch.rpm
  • binutils-2.14.90.0.7-1vl2.ppc.rpm
  • diffutils-2.8.1-11vl1.ppc.rpm
  • ftp-0.17-15vl2.ppc.rpm
  • gcc-3.3.2-0vl8.ppc.rpm
  • gcc-cpp-3.3.2-0vl8.ppc.rpm
  • gcc-c++-3.3.2-0vl8.ppc.rpm
  • glibc-devel-2.3.3-3vl1.ppc.rpm
  • glibc-common-2.3.3-3vl1.ppc.rpm
  • kernel-headers-2.4.26-0vl17.ppc.rpm
  • pkgconfig-0.15.0-0vl2.ppc.rpm
  • less-358-0vl9.ppc.rpm
  • ntp-4.2.0-0vl3.ppc.rpm
  • make-3.80-0vl3.ppc.rpm
  • popt-1.6.5-1vl8.ppc.rpm
  • sh-utils-2.0.11-9vl6.ppc.rpm
  • textutils-2.0.17-0vl4.ppc.rpm
  • vim-6.3.31-0vl1.ppc.rpm
  • unzip-5.50-5vl2.ppc.rpm
  • automake-1.8.5-0vl1.noarch.rpm

Vine3.1/PPCは ftp.jaist.ac.jpftp.kddilabs.jp あたりにミラーされているので、そこからwgetで引っ張ってくれば楽ちんです。
これまたありがたいことに、wgetは既に入っているようなので、スクリプト書いて一気に落とすなんて事も出来ますね。

さてrpm類を適当な場所へ配置したら、次はそのrpmの中に入っているファイルをルートディレクトリからの相対パス付きで適当な場所へ展開していきます。

これはrpmファイルの中に入っているコマンドが標準状態で提供されているコマンドを上書きしないかのチェックを行うため。
手間は掛かりますが、変に手を抜くと後で自分が苦しみます。ここは着実に行きましょう。

rpmファイルを /mnt/disk1/rpms に置き、展開先を /mnt/disk1/newroot としたとすると、/mnt/disk1/newroot に cd して

# rpm2cpio /mnt/disk1/rpms/rpmファイル名 | cpio -idv

のようにすれば、カレントディレクトリ(この場合は/mnt/disk1/newroot)をルートディレクトリと見立てて、そこからの相対パス付きでrpmファイルの中にあるファイルが展開されていきます。

手でひとつひとつ展開していってもいいですし、シェルスクリプトを組んでfor文で回してもいいですが、とにかくrpmファイルを仮のルートディレクトリ以下へ根こそぎ展開していきます。

展開し終わったら、既存コマンドと被るものがないかチェックします。
今回の例だと、/mnt/disk1/newroot が / と等価になるので、 /mnt/disk1/newroot/usr/bin 以下に展開されたコマンドが /usr/bin 以下に無いかといったようにチェックしていきます。

さすがにこれは手でやっていくとしんどいので、スクリプト書いてささっと流すのが良いでしょう。
find コマンドで newroot 以下にあるファイルのリストを作り、そのリストを元に / 以下に被るものが無いか ls していって、被るものがあれば表示する...みたいな感じですかね。

#!/bin/sh

CWD=`pwd`
cd newroot
find . -type f > ${CWD}/newfile

cd $CWD
rm -f newfile.dup && touch newfile.dup
for i in `cat newfile`
do
        ls /${i} > /dev/null 2>&1
        if [ $? -eq 0 ]; then
                echo ${i} >> newfile.dup
        fi
done
cat newfile.dup

このスクリプトを/mnt/disk1 以下で実行すると、被るファイルが以下のように表示されます。

./usr/bin/head
./usr/bin/sum
./usr/bin/tail
./usr/bin/tr
./usr/bin/wc
./usr/bin/env
./usr/bin/expr
./usr/bin/id
./usr/bin/tty
./usr/lib/libpopt.so.0.0.0
./usr/sbin/ntpdate
./bin/cat
./bin/date
./bin/echo
./bin/false
./bin/sleep
./bin/stty
./bin/su
./bin/true
./bin/uname
./etc/ntp.conf

sttyとか、結構エグいものが被りますなあ...
被ったものは、リネームしておきましょうかね。

# mv newroot/bin/cat newroot/bin/cat.vine

また、rpmを展開しただけでは賄えないシンボリックリンク張り等の微調整をここでやっておきます。

# cd /mnt/disk1/newroot
# cd usr/bin
# ln -s gcc-3.3.2 gcc
# ln -s gcc-3.3.2 cc
# ln -s g++-3.3.2 g++
# ln -s vim.normal vim
# cd /mnt/disk1/newroot
# mv usr/src/linux-2.4.26/include/* usr/include/
# cd usr/include
# ln -s asm-ppc asm

他にも、マニュアルは要らねえよ等の好みがあれば、ここで調整しておきます。

これで、追加導入されるコマンド・ファイル類が newroot 以下へ揃いました。
いよいよインストールです。

newroot上でtarボールを作成。

# cd /mnt/disk1/newroot
# tar zcvf ../TeraLinuxKit.tar.gz bin/ etc/ usr/

これで今回新たにインストールされるコマンド類が TeraLinuxKit.tar.gz へ格納されました。
これをルートディレクトリ以下で展開すれば、コマンドの追加が完了です。
心配な場合は、ここでルートディレクトリ以下のバックアップを取っておくと良いでしょう。

準備が出来たら、覚悟を決めて、いざ展開!

# tar zxvfk /mnt/disk1/TeraLinuxKit.tar.gz -C /

gccやmakeは使えますか?
また、再起動してみて問題は起きていませんか?

何れも大丈夫ならば、大成功!
あとは貴方色に染めていってください。

サービス群の追加

開発環境が整ったので、あとはお気に召すままアズ・ユー・ライク、後は若い人同士ご自由に....なのですが、ちょっとだけおせっかい。

sambaをバージョンアップしてみる

今回使用したカスタムファームに含まれるsambaは2.X系。しかもActiveDirectoryサポート無し版です。

AD環境が無かったり、Samba2系の機能で良ければこれでも全く問題はないのでしょうが、Samba3系の新機能を使いたかったり、AD環境に組み込みたい場合はちょっと何だかなあ、との思いを禁じ得ません。よね?

 _人人人人人人人人人人人人人人人_  >     わりとどうでもいい      <   ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^^Y^ ̄            ヘ(^o^)ヘ                |∧                 /

まあそう言わず。
ちょっとだけ棘の道を突き進んでみましょうよ。

ていうか、インストールした段階から各種ライブラリ類やフリーウェアが盛りだくさんで入っていて、自ら環境構築を行う必要が無いほどお膳立てが整っているようなLinuxディストリビューションとは異なり、TeraStationPROの場合ほぼドンガラ状態のLinux箱に自分の世界を作り上げていく必要があるので遅かれ早かれ避けては通れない棘の道になります。

以下、アップグレードの手順をさらっと説明しますので、覚悟を決めてみて下さい。

まずはビルドツール系を最新版に上げちゃいます。
既にrpmからの投入で古いバージョンが入っている場合は、prefix=/usr として上書きインストールし、新規のものは /usr/local 以下に入れていきます。

  • m4 1.4.13
    ./configure && make && make install
  • autoconf 2.65
  • automake 1.11.1
  • gettext-0.14.1
  • pkgconfig-0.18(※ln -s /usr/lib/pkgconfig /usr/local/lib/pkgconfig をやってない場合は、今後大量のpcファイルが置かれる前にやっておく)
  • libtool-2.2.6b
    ./configure --prefix=/usr && make && make install
  • glib-2.23.1
  • readline-6.1
    ./configure && make && make install

あらかた入ったらsambaに必要なライブラリ類から攻めていきます。

  • libiconv 1.13
    ビルドする前に、eucjp-msを利用可能にするパッチをここから落としてきて当てる。
    ※gnu patchが必要なので事前にインストールしておく
    gzip -dc ../libiconv-1.13-ja-1.patch.gz | patch -p1
    ./configure && make && make install
    
    インストール後、iconv -l して MS932とかWINDOWS-31JとかEUCJPMSとか出てくればOK
    デフォルトでもiconvライブラリは入っているけど、eucjp-ms等日本語処理周りが若干おかしいので、今後コンパイルするソフトのうちiconv を使う物はこれを見るように指定すると良い。

  • BerkeleyDB 4.7.25
    cd build_unix
    ../dist/configure
    make && make install
    
  • openldap 2.4.19
    CPPFLAGS="-I/usr/local/BerkeleyDB.4.7/include" \ 
    LDFLAGS="-L/usr/local/BerkeleyDB.4.7/lib -R/usr/local/BerkeleyDB.4.7/lib" \
    ./configure
    make depend
    make
    make install
    
  • krb5-1.6.3
    ./configure && make && make install
  • samba 3.0.37
    OpenTeraのsamba3 with AD Supportをインストールして、一度起動してみる。
    起動時に色々とライブラリが必要だと言われた場合は、適宜コンパイルしてインストールするか、さもなくばOpenTeraのLibraries_ppc_v1.zipあたりから必要な物だけを選んで入れておく。

    問題なく起動して稼働することが確認できたら、その上でsamba3.0.37を上書きインストール。
    CPPFLAGS="-I/usr/local/include" LDFLAGS="-R/usr/local/lib -L/usr/local/lib" \ 
    ./configure --prefix=/usr
       --with-piddir=/var/run \ 
       --with-configdir=/usr/lib/samba \ 
       --with-krb5=/usr/local \ 
       --with-libiconv=/usr/local \ 
       --with-ads
    make
    make install
    
    その後OpenTera版sambaに付いてきた/etc/samba/smb2smb3.plを編集。
    coding systemを削除して、代わりにdisplay charset等を追記するようスクリプトへ追記する。
            elsif ($line =~ m/code page/)
            {
                    # Remove line - this is not used by Samba 3
            }
            elsif ($line =~ m/coding system/)
            {
                    print SMB3_CONF "    display charset = CP932\n";
                    print SMB3_CONF "    dos charset = UTF-8\n";
                    print SMB3_CONF "    unix charset = CP932\n";
                    print SMB3_CONF "    load printers = no\n";
                    print SMB3_CONF "    disable spoolss = yes\n";
            }
    

    これで完成です。
    意外と面倒でしょ?

    何故OpenTera版sambaを一度入れるか:

      デフォルトで入っているsambaはsamba2のため、smb.conf等の書式に異なる点が多々ある。
      OpenTera版のsambaキットには、それらを吸収するための細かな仕掛けが随所に設けられており、その仕組みを流用するため。

      ちなみにTeraStationのwebインターフェースからsambaの設定を変えると、設定内容を /etc/samba/smb.conf に出力した後、CGIから /etc/init.d/smbd を呼んで samba の再起動を行っている。
      OpenTera版でのハックは、上記 /etc/init.d/smbd によるsamba起動プロセスの過程で、/etc/samba/smb2smb3.pl を実行することにより、/etc/samba/smb.conf(samba2形式) から /usr/lib/samba/smb.conf(samba3形式) への変換を行っている。
      configureの際に --with-configdir=/usr/lib/samba としたのはそのため。

    何故OpenTera版をそのまま使わないか:

      OpenTera版のsambaは、ビルド時に使用したと思われるlibiconv が日本語文字コード周りの処理がおかしい版らしく、ファイル名やフォルダ名等がことごとく文字化けを起こしてしまう。
      従って前述のパッチ版libiconvをインストールした上でsamba3をビルドする必要がある。

    その他のソフトを野良ビルドしていく

      ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;  {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;  gccさえ入ってれば何とでもなる・・・   ヾ;;;ハ    ノ       .::!lリ;;r゙      `Z;i   〈.,_..,.      ノ;;;;;;;;>  そんなふうに考えていた時期が    ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f     俺にもありました    ~''戈ヽ   `二´    r'´:::. `!

    野良ビルドってのは、rpm等のパッケージシステムを使ってコンパイル済みバイナリファイルを簡単にぽいっと追加するのではなく、前項のsambaインストール周りのようにソースファイルをダウンロード・展開し、configure して make して make install するという、フリーウェアをインストールする上での基本的なやりかたの俗称です。

    RedHat系のrpmやBSD系のports/packagesのような、管理されたパッケージシステムとの対義語としての「野良」ですね。
    野良ってなんか印象悪いですが、まあ正統派というか原始的と言うか、パッケージ管理システムのおかげで楽ができるというだけで、これが普通なんですけどね...。

    冒頭に不吉なAAを貼りましたが、各種ライブラリ類の依存関係を自分で解決しなければいけなかったりと勉強になる代償として、時間と手間がかかります。
    あまりにも複雑に絡み合った依存関係の場合は、途中で投げ出したくなる事もしばしば。
    そんなときには冒頭のAAが頭をよぎります。

    TeraStationPROの場合、それに輪を掛けるのがCPUの遅さ。
    bogomipsを見ると174.48となっています。

    # cat /proc/cpuinfo
    cpu             : 82xx
    revision        : 16.20 (pvr 8081 1014)
    bogomips        : 174.48
    vendor          : Motorola SPS
    machine         : Sandpoint
    

    BogoMips mini-Howtoによると、Pentium MMX/133で265.77となっているので、それ以下。
    単純計算だとPentium MMX/86MHz相当??
    OpenSSLのコンパイルに約40分かかりました。

    make叩いて怒濤のようにコンパイルが進んでいくと、その様を見るだけでもテンション上がるってもんですが、長考入ってたまにログが流れる程度の遅々とした進捗のうえに、散々待たされた挙げ句依存関係エラーでコンパイル失敗なんて事が何度も続くと、次第にやる気も削がれていきます。

    正面から敵に挑み再び勝利の美酒に酔いしれるも良し、はたまたDebian sargeのようにKernel2.4系でPPCアーキテクチャをサポートしているディストリビューションのパッケージを引っ張って来て簡単手軽に環境を整えるも良し。今度こそ本当に「As You Like It」です。

    なお、CPUの遅さに加えて実メモリが128MBしかないので、あまり大物ソフトは入れない方が良いですよ。
    Linux+Apache+MySQL+PHPの、いわゆるLAMP環境を構築してMediaWiki動かしてみましたが、1ページ表示するのに数秒かかって使い物になりませんでした(´・ω・`)
    このマシンでWikiるならPHPのみで軽く動くPukiWikiがお勧めです。

    XOOPSも動くとは思いますが、MySQLを使う関係上どうしても遅くなっちゃいますね。
    いかんせんメモリが少ないんでDBが絡むアプリはちょっと避けた方が良さそうです。

    本業であるファイルサーバ機能を活かして、DLNAサーバとして使うか、同じく大容量を活かしてIMAPなメールサーバとして使うのが妥当なところかなーって感じです。

    最後にベンチマーク

    CPUが遅いって話題を振ったので最後にベンチマーク結果を紹介して終わりにしましょう。

    opensslにはベンチマークモードがあり、

    # openssl speed rsa dsa

    とすることで、rsa512〜4096bit鍵長とdsa512〜2048bit鍵長での署名・ベリファイ速度を表示することができます。
    比較対象として、手元にあった他の3台のマシンでも試してみました。
    XeonだのAtomだの、ちっとも一般的じゃない変態CPUだらけで比較になんねーよと言う声が聞こえてきそうですが、今俺の周りにあるのはこんなマシンしかねーのだよ!ヽ(`Д´)ノ

    で、その貴重な結果はこちら!

     Xeon E5420
    2.5GHz
    Xeon
    2.80BGHz
    Atom230
    1.6GHz
    TeraStation
    PRO
    sign/sverify/ssign/sverify/ssign/sverify/ssign/sverify/s
    RSA512bit 1796.221956.21184.213809.8627.77463.3107.11300.1
    1024bit 380.17756.1239.24548.6137.52574.421.7444.1
    2048bit 65.22368.739.91353.524.3861.33.6128.9
    4096bit 10.0666.55.9377.83.8246.20.535.7
    DSA512bit 2407.51981.51453.41222.6804.7677.9130.7113.7
    1024bit 826.8680.0491.7395.1290.9239.544.637.5
    2048bit 238.8205.6141.3115.990.174.013.010.7

    遅っそ!

    もとより、速度重視のプログラムを動かす箱ではないので、あとはアイデア勝負ですね。
    大きなストレージにギガビットイーサ、加えてUSBポートもあるので、可能性は無限大です。

    このページが、これからTeraStationPROをハックしていこうと考えている方々の助けになれば幸いです。
    また、名も無き先人達の努力とその情報なくしてはここまで辿り着くことはできませんでした。
    末筆ながら感謝の言葉を述べさせて頂きます。ありがとうございました。