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

><

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

比較対象は定番の.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年か…

Hashは順序を保存するべきか否か

RubyのHashは登録順を保存すべきか否かについてruby-listで議論になっている。俺はHashクラスには順序を保存する必要がないと覆うが、 { 1=>"one", 2=>"two" } というリテラルが表すオブジェクト(今はHashだが)には順序が保存されてればいいなーと思った。俺はこのリテラルの見た目が大好きなんだが、あの記法で順序が保存されていないのが少し嫌だった。rubyistの立場から、そういうものだと受け入れてはいるけど。リテラルから生成されるHashの要素数ってたいていの場合たかが知れてるから、OrderedHashに変更したとしてもあまり影響がないかも?でかいHashはeachなりinjectなりで生成するだろうから。
「大人」になった言語だと互換性の問題で気楽に仕様変更できないのが欠点かもね。

ファイルをファイルホスティングサービスにアップロードするツール開発中

d:id:rubikitch:20070819でydevilというhttp://upload2.netにファイルを分割→(暗号化)→アップロードするツールを考案したが、Upload2へのアップロード・ダウンロードについては今のところうまくいっている。実運用して問題なければRAAにでも公開するつもり。

ydevilはRubyで書かれていて、curl、split、ccryptなどの外部ツールを呼出しまくり。pure rubyで書けないこともないけど、面倒なのでやらない。

他にも強力なホスティングサービスがたくさんあるから他のサイトにも対応していきたい。アップロード・ダウンロードの部分をクラスに分ければいいだけだから楽勝と思われる。

リモートバックアップのためにydevilを開発している。今はCD-RWDVD-RAMにバックアップしているけど、CD-RWの部分は曜日ごとに別サービスを利用したリモートバックアップにしてもいいかも?

無料ホスティングサービスのリンク集

Free Webspace and Free Web Hosting Services

ウェブスペースだったり、ファイルホスティングサービスだったりそういう無料ホスティングサービスの情報を集めている。無料じゃなくなったものを削除したりするなど、活発に更新している。先日25MBまでのファイルならいくらでもダウンロード・アップロードしてもいいサイトを見つけて驚いていたところ、他にもそういうサイトがたくさん見つかった!さすがWeb2.0時代、スケールが違いすぎる。

http://www.free-webhosts.com/free-file-hosting.php:ファイルホスティングサービスの比較で1位のQuickShareingなんて500MBまでのファイルをアップロードしまくれるんだから恐れ入る。500MBなんて俺のホームディレクトリを固めてもそこまでいかないのに!ただ、そこはJavaScriptが使われててw3mじゃアップロードできないorz

swapoffしてみた

メモリは1GB塔載、使用量は多くて600MBくらいなので残りはキャッシュ。それでもなぜかswapを使いだすのでいっそのことswapoffしてしまえ。正直スワップしたら負けだと思う。
swapoffした後もmencoderでTVの録画ができるので大丈夫だろう、きっと。