まずは、blktrace -d /dev/mmcblk0 -o - | blkparse -i - -a write
なりbtrace -a write /dev/mmcblk0
なりで書き込みを行っているプロセスを特定…しようと思ったが、kworkerやbtrfs-transactiの書き込みが多いという事しかわからなかった…
179,0 1 45 30.198921748 9215 M WS 3148800 + 64 [kworker/u8:2]
みたいな感じで出力されているのだが、
3148800 + 64
の部分がどうもkB単位のオフセットとサイズでは無いかと思い、dd if=/dev/mmcblk0 skip=3148800 count=64 bs=1024 | base64
で読み取ってみた。そしたら、軒並みAAAAAAAAAAAAAAAAAAAAAだった。/dev/zeroを読み込んでいるのと同じですな。ゼロクリアされている…。いくつか拾ってみて見ただけなので、もしかしたら何か有効なデータがある場所もあるのかもしれない。
いろいろ調べていたら、fatraceというコマンドで、どのプロセスが書き込みを行っているか調べられるらしい事がわかった。
しかし、apt-getで入れたfatraceは動いてくれなかった。Raspberry Pi 2なのに、Raspbianを使わずcdebootstrapでセットアップしたDebian 8が動いているのが原因かもしれない。実行すると、Cannot initialize fanotify: Invalid argument
と怒られる。仕方が無いので、fatraceのコードを拾ってきて、fatraceのfanotify_initをfanotify_init (0, KERNEL_O_LARGEFILE);
からfanotify_init (0, 0);
に書き換えたらうまく動いてくれた。
./fatrace | fgrep W
を動かしつつ、btrace -a write /dev/mmcblk0
を眺めていたら原因がわかったっぽい。ログの書き込みが原因だった。ログファイルの書き込みの後に、kworkerやbtrfs-transactiの書き込みが始まっている様だ。btrfsをファイルシステムとして使っているのだが、btrfsはcopy on writeらしい。ログファイルが丸ごとコピーされて、追記されて、元あった空き領域は用済みなのでゼロクリアでもされたんだろうか。それだとしたら、書き込んだところを読み取ってもゼロなのが納得できる。
今のところ、SamsungのmicroSDカードは半年間、問題無く動き続いているが、これだけ書き込んでいればいつ壊れてもおかしくは無さそうな気がする。iostat情報だと、38KB/sで書き込みされているらしいので、半年で315GBWか…。microSDの容量は32GBなので、理想的にウェアレベリングされていても約10回は書き込んだことになる。あれ?思ったよりも少ない…。