Restore from NetBSD fs on Compact Flash 

#背景
とあるサーバが見事に壊れたので、復旧を試みる。
ブーとしない、ではなく電源が入らないので単純に考えれば
データは生きていると想定。

ちょっと特殊な筐体と言うことも有り、ディスクを差し替えて復旧とはいかず
データディスクだけ取り出して他の筐体に取り付けようにもCompact Flash。orz…
従ってデータ抽出に際してはまず、disk dumpを取るか適当な機器に接続して
マウントした後に取り出し、という手順を踏むことにした。

# 復旧方法
データディスクをそのままマウントしてしまえば良いのだが
当然一つしかないのでバックアップの意味も込めてdisk dumpを取得しておく。
ブロックサイズなどは全くわからないのでデフォルトで取得
<pre>
 # dd if=/dev/sdb of=cf-data.img
</pre>

# 事前準備
ここで通常ならばloopマウントを書けてやればいい。
但し、そこはNetBSD。まずはディスク構成を見る必要がある
<pre>
# fdisk cf-data.img                                                                                                              
You must set cylinders.
You can do this from the extra functions menu.

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): p

Disk CF-idgw.img: 0 MB, 0 bytes
128 heads, 63 sectors/track, 0 cylinders
Units = cylinders of 8064 * 512 = 4128768 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

      Device Boot      Start         End      Blocks   Id  System
cf-data.img1   *           1         995     4011808+  a9  NetBSD
# mount -o loop,ro cf-data.img /mnt/                                                                                             
mount: you must specify the filesystem type
</pre>

System NetBSDと出る。この時点で少々やな予感。
Linuxでは見慣れないファイルシステムだと言うことが一目でわかる。
調べてみるとufsが該当するのだが残念ながらLinuxはufsをサポートしていない。
CentOS6は幸いにしてkmod-ufsが提供されているため、RPMを持ってきてインストール。
modprobeしてやれば扱えるようだが、CentOS7は「はー、kernel再構築だね」という回答。
流石にそのためだけにkernelを再構築する手間は掛けられないのでCentOS6を使うことにする。
え？OSから用意できるならNetBSD機器を用意すればいいじゃないかって？shut up!
Cent6とCent7は既に環境があると言うだけで新しく作るという意味ではない。

kmod-ufs をepelから取得してきてインストールすれば動く。
<pre>
 # rpm -ivh kmod-ufs-0.0-1.el6.elrepo.i686.rpm
 # modprobe ufs
</pre>

# マウント
これでufsがマウントできるはずなので以下のようにやってみたが
普通にエラーが発生。

<pre>
# mount -t ufs -o loop,ro cf-data.img /mnt/
mount: wrong fs type, bad option, bad superblock on /dev/loop2,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so
</pre>
- dmesg
<pre>
>>>WARNING<<< Wrong ufstype may corrupt your filesystem, default is ufstype=old
ufs_read_super: bad magic number
</pre>

magic numberがおかしいと言われる。
どうやらoffsetを正しく指定してやらないと駄目なようだ。
fdiskで探し回るのはなかなか手間なので怠惰にkpartxを使用してパーティションテーブルを確認する。
<pre>
# kpartx -a cf-data.img 
</pre>
- output
<pre>
# partx -l /dev/mapper/loop1p1 
# 1:         0-       -1 (        0 sectors,      0 MB)
# 2:         0-       -1 (        0 sectors,      0 MB)
# 3:         0-       -1 (        0 sectors,      0 MB)
# 4:         0-       15 (       16 sectors,      0 MB)
# 1:        63-    66527 (    66465 sectors,     34 MB)
# 2:     66528-  2164175 (  2097648 sectors,   1073 MB)
# 3:   2164176-  2689343 (   525168 sectors,    268 MB)
# 4:   2689344-  3214511 (   525168 sectors,    268 MB)
# 5:   3214512-  8026703 (  4812192 sectors,   2463 MB)
</pre>

ここまでわかればマウント可能。
調べたところこのCFのセクタサイズも一般的なHDD同様512だったので
offset を start x 512 で指定するとマウントできる。
fstype=ufs2はなく44bsdだったのはそもそもがふるいからか。

<pre>
# mount -r -t ufs -o loop,offset=$((63*512)),ufstype=44bsd cf-data.img /mnt/vol1/                                   
# mount -r -t ufs -o loop,offset=$((2164176*512)),ufstype=44bsd cf-data.img /mnt/vol3/                                   
# mount -r -t ufs -o loop,offset=$((2689344*512)),ufstype=44bsd cf-data.img /mnt/vol4/
# mount -r -t ufs -o loop,offset=$((3214512*512)),ufstype=44bsd cf-data.img /mnt/vol5/ 
</pre>

ちなみにvol2にマウントしようとした領域はどうやらswap領域のようだ。
そらまあ、マウントしても救い出す必要のあるデータはないわな。