USBメモリでRAID 5を構築(3)
ファイルシステムを作成してマウントします
7. ファイルシステムの作成
RAIDアレイをフォーマットしてファイルシステムを作成する際には、I/O性能を最適化するために、ストライド(stride)とストライプ幅(stripe-width)を適切な値に設定してやる必要があると言います。値は以下の計算式で求められます。
- ストライド(stride)=チャンクサイズ/ブロックサイズ(4KB)
- ストライプ幅(stripe-width)=データディスク数×ストライド
今回の場合、チャンクサイズが256KB、USBメモリ 3本のRAID 5構成なのでデータディスク数は 2になり、
- ストライド(stride)=256/4=64
- ストライプ幅(stripe-width)=2×64=128
となります。これを mkfsの -Eオプションに以下のように指定してファイルシステムを作成しろと言うのですが、
# mkfs -t ext4 -b 4096 -E stride=64,stripe-width=128 /dev/md0
|
-Eオプションなんか省略して以下のようにファイルシステムを作成しても、ちゃんと最適なストライド、ストライプ幅を設定してくれました。
# mkfs -t ext4 /dev/md0
mke2fs 1.42.12 (29-Aug-2014)
Creating filesystem with 30842368 4k blocks and 7716864 inodes
Filesystem UUID: f8b8beba-56e0-4f91-a717-8f2bc7459453
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
|
どのように設定されたかはtune2fsコマンドで確認できます。出力量がちょっと多い(*3)ので関係ある部分だけ抜粋すると、
# tune2fs -l /dev/md0
Block size: 4096
RAID stride: 64
RAID stripe width: 128
|
という具合です。なかなかに賢いですね。ただ、後日更にUSBメモリ(データディスク)を追加したりした際には、値を変更する必要が生じます。その時には、
# tune2fs -E stride=64,stripe-width=192 /dev/md0
|
とかすれば良いです。(上記の例はUSBメモリを1本追加した場合)
ストライド、ストライプ幅の値は後からでも変更可能で、変更しても内容が消去されてしまうような事はありません。
8. マウント設定
試しに手動でマウントしてみます。
# mkdir /media ※/dev/md0のマウントポイントを作る。既にある場合は不要。
# mount /dev/md0 /media
# df -k
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/md0 121301108 60984 115055268 1% /media
|
無事にマウントできましたので、システム起動時にマウントされるよう"/etc/fstab" ファイルに記述します。
今後、複数のRAIDアレイを繋げるような事はないと思いますが、万一そのような事になっても問題が起きないよう、UUIDを使ってマウントするようにしてみます。UUIDの取得は、
# tune2fs -l /dev/md0 | grep UUID
Filesystem UUID: f8b8beba-56e0-4f91-a717-8f2bc7459453
|
または、
# ls -l /dev/disk/by-uuid/
lrwxrwxrwx 1 root root 9 7月 31 11:17 f8b8beba-56e0-4f91-a717-8f2bc7459453 -> ../../md0
|
でできます。UUIDはf8b8beba-56e0-4f91-a717-8f2bc7459453 であることが分かったので、以下を"/etc/fstab" に追加します。
UUID=f8b8beba-56e0-4f91-a717-8f2bc7459453 /media ext4 defaults,noatime,nofail 0 2
|
第4パラメタの"nofail"は、システム起動時にRAIDアレイのマウントに失敗してもブート処理を継続するという意味で、指定していない場合はマウント失敗でブート処理が停止します。Raspberry Piをネット経由で使用している場合には"nofail"を指定しておいた方が無難です。
9. 再起動(動作確認)
Raspberry Piを再起動して正常にRAIDアレイが起動されてマウントされるか確認します。
そうしたら、な、な、何と/dev/md0 が消えていました!(当然マウントも失敗!早速"nofail"設定が役立ちました。)そんな場合は、以下のようにすると/dev/md0 が復旧し、マウントされます。
# mdadm --assemble --scan
|
どうやら、タイミングによってUSBメモリが認識される前にmdadmが走ってしまうと、RAIDアレイ構成に失敗して/dev/md0 が作られずマウントが失敗したり、縮退状態(degrade:USBメモリが1本足りない、つまり冗長化されていない状態で運転継続している状態のこと)になる事がある様子です。
それならシステム起動時にRAID構成するのを少し遅らせて、USBメモリが認識される時間をかせいでやれば良いのではないかな?起動時のRAID構成は"/etc/init.d/mdadm-raid" で行われているようなので、ここで10秒ほどsleepして時間をかせぐようにしてみました。システム起動が若干遅くなるかもしれませんが、他のサービスと並列に起動されているので、丸々10秒遅くなるなんてことはないはず。
case "${1:-}" in
start)
PREFIX="Assembling MD array"
if [ ! -f /proc/mdstat ] && [ -x "$(command -v modprobe)" ] ; then
modprobe -q md 2>/dev/null || :
fi
if [ ! -f /proc/mdstat ]; then
log_problem "failed to load MD subsystem"
exit 0
fi
if [ ! -f $CONFIG -a ! -f $ALTCONFIG ]; then
log_problem "no $CONFIG file"
exit 0
fi
# handle devfs-style names and version-1 devices
# fail gracefully in case we're on a read-only filesystem, in which
# case it's safe to assume that the admin knows what s/he's doing.
# See (#382876).
mkdir --parent /dev/md || :
# ugly hack because shell sucks
IFSOLD=${IFS:-}
IFS='
'
# wait 10 seconds for USB memory detected.
/bin/sleep 10
for line in $($MDADM --assemble --scan --auto=yes --symlink=no 2>&1); do
〜以下略〜
|
何度かシャットダウンや再起動をして試しましたが、今のところこの方法で大丈夫な様子です。
この方法以外にも"/boot/cmdline.txt" ファイルに"rootdelay=10" を追加する方法もあるようです。
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1
root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline
fsck.repair=yes rootdelay=10 rootwait
|
注)長いので行を折り返していますが、実際には1行です。
[続く]
(*3):tune2fs -l /dev/md0 の全出力(1行が長い行は途中折り返しています。)
tune2fs 1.42.12 (29-Aug-2014)
Filesystem volume name:
Last mounted on: /media
Filesystem UUID: f8b8beba-56e0-4f91-a717-8f2bc7459453
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index
filetype needs_recovery extent flex_bg sparse_super
large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags: unsigned_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Continue
Filesystem OS type: Linux
Inode count: 7716864
Block count: 30842368
Reserved block count: 1542118
Free blocks: 25169957
Free inodes: 7716833
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 1016
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8192
Inode blocks per group: 512
RAID stride: 64
RAID stripe width: 128
Flex block group size: 16
Filesystem created: Sat Jul 30 12:55:47 2016
Last mount time: Sun Jul 31 20:18:27 2016
Last write time: Sun Jul 31 20:18:27 2016
Mount count: 3
Maximum mount count: -1
Last checked: Sun Jul 31 16:17:15 2016
Check interval: 0 ()
Lifetime writes: 30 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 28
Desired extra isize: 28
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 1e1fd590-13a1-46f6-8052-4ce74b240892
Journal backup: inode blocks
root@Acrux:/boot# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdc1[0] sda1[3] sdb1[1]
123369472 blocks super 1.2 level 5, 256k chunk, algorithm 2 [3/3] [UUU]
unused devices: <none>
|
|