信頼性テストのための破壊工作実験

><

安心してバックアップするにはデータの信頼性も大切だ。万一ファイルが壊れたときに、どれだけの損失で済むのかを確かめるのは意味があるだろう。

比較対象は定番の.tgz、きくたにさんお勧めの.afz、そしてsquashfs

$ cd
$ files=".emacs .skk-jisyo .screenrc .zshrc .ratpoisonrc .aumixrc"
$ files=".emacs .screenrc .zshrc .ratpoisonrc .aumixrc"
$ # 各々のファイルを比較する関数を定義
$ compare () { for f in $files; do; cmp ~/$f $f; done }
$ ls -la $files
-rw-rw-r-- 1 rubikitch rubikitch   152 2007-07-09 18:02 .aumixrc
-rw-r--r-- 1 rubikitch users      5775 2007-07-31 18:46 .emacs
-rw-r--r-- 1 rubikitch users      6765 2007-08-13 04:01 .ratpoisonrc
-rw-r--r-- 1 rubikitch users     10021 2007-07-23 20:57 .screenrc
-rw-r--r-- 1 rubikitch users      3682 2007-08-16 20:34 .zshrc
$ rm -rf /tmp/destroy* /tmp/tmptmp # 準備
$ # tar+gz, squashfs, afio+gzの3種類のアーカイブを作成
$ tar czf /tmp/destroy.tgz $files
$ mksquashfs $files /tmp/destroy.squashfs -noappend > /dev/null
$ ls $files | afio -ovZU /tmp/destroy.afz
$ ls -l /tmp/destroy*
-rw-r--r-- 1 rubikitch users 15360 2007-08-21 22:15 /tmp/destroy.afz
-rwx------ 1 rubikitch users 12288 2007-08-21 22:15 /tmp/destroy.squashfs
-rw-r--r-- 1 rubikitch users 10606 2007-08-21 22:15 /tmp/destroy.tgz
$ # アーカイブを破壊!!
$ ruby -e 'ARGV.each{|fn| open(fn, "r+"){|f| f.seek(666); f.write("!")}}' /tmp/destroy*
$ mkdir /tmp/tmptmp; cd /tmp/tmptmp
$ tar xzvf /tmp/destroy.tgz 2>&1; ls -la; compare; rm -f .*

gzip: stdin: invalid compressed data--crc error

gzip: stdin: invalid compressed data--length error
.emacs
tar: 次のヘッダをスキップします
tar: Child returned status 1
tar: 処理中にエラーが起きましたが、最後まで処理してからエラー終了させました
合計 8
drwxr-xr-x  2 rubikitch users   60 2007-08-21 22:15 .
drwxrwxrwt 24 root      root  1960 2007-08-21 22:15 ..
-rw-r--r--  1 rubikitch users 5775 2007-07-31 18:46 .emacs
/m/home/rubikitch/.emacs .emacs 異なります: バイト 940、行 33
$ sudo mount -o loop -t squashfs /tmp/destroy.squashfs /mnt 2>&1; ls -la /mnt; compare; sudo umount /mnt
合計 29
drwxrwxrwx  2 rubikitch users        78 2007-08-21 22:15 .
drwxr-xr-x 29 root      root       1024 2007-08-19 00:00 ..
-rw-rw-r--  1 rubikitch rubikitch   152 2007-07-09 18:02 .aumixrc
-rw-r--r--  1 rubikitch users      5775 2007-07-31 18:46 .emacs
-rw-r--r--  1 rubikitch users      6765 2007-08-13 04:01 .ratpoisonrc
-rw-r--r--  1 rubikitch users     10021 2007-07-23 20:57 .screenrc
-rw-r--r--  1 rubikitch users      3682 2007-08-16 20:34 .zshrc
$ afio -ivZ /tmp/destroy.afz 2>&1; ls -la; compare; rm -f .*
.aumixrc -- uncompressed

gzip: stdin: invalid compressed data--crc error

gzip: stdin: invalid compressed data--length error
afio: "inentry xwait()": Exit 1
.emacs -- uncompressed
.ratpoisonrc -- uncompressed
.screenrc -- uncompressed
.zshrc -- uncompressed
合計 36
drwxr-xr-x  2 rubikitch users   140 2007-08-21 22:15 .
drwxrwxrwt 24 root      root   1960 2007-08-21 22:15 ..
-rw-rw-r--  1 rubikitch users   152 2007-07-09 18:02 .aumixrc
-rw-r--r--  1 rubikitch users  5820 2007-07-31 18:46 .emacs
-rw-r--r--  1 rubikitch users  6765 2007-08-13 04:01 .ratpoisonrc
-rw-r--r--  1 rubikitch users 10021 2007-07-23 20:57 .screenrc
-rw-r--r--  1 rubikitch users  3682 2007-08-16 20:34 .zshrc
/m/home/rubikitch/.emacs .emacs 異なります: バイト 615、行 21
$ rm -f /tmp/destroy*

ポイントは、わざとファイルを破壊すること。

ruby -e 'ARGV.each{|fn| open(fn, "r+"){|f| f.seek(666); f.write("!")}}' /tmp/destroy*

はファイルを破壊するワンライナー。引数で指定された各々のファイル(0から数えて)666バイト目(悪魔の数字)を'!'に変える。

さて、結果のほうは…

  • tgzは.emacsが生き残っていると思ったらcmpで比較したら違ってた。ゆえに全滅。ひでぇ〜そりゃきくたにさん*1にケチョンケチョンに言われるわけだ…。実際は壊れていない部分までは復元できて、壊れた部分より後は全滅する。
  • squashfsは1バイトくらい壊れてても動じず全部生き残っている!100点満点!!Development Status : 5 - Production/Stableは伊達じゃねえ
  • afzの方は損傷を受けた.emacsだけで残りは復元できている。10年くらい前から存在しているし、実績もあるだろう。

ファイルを増やしてみても、結果は変わらなかった。やはりバックアップ目的にはsquashfsがよさげだ。なんといってもmountさえすればcpで復元できるのが手軽。

*1:俺が駆け出しのころお世話になったのだが、今はどうしてるのだろうか…kikutani.comも消えとるし。あれから10年か…