オレ「truncateで作ったファイルはまだブロックが確保されてないからduで見ると0なんだよ」Mac「」
- gtruncate –size 100m 100m
- gdu -sh 100m
- 100M 100m
え?
これに気づいたのは、会社の仕事中でした。Linuxで400Gのmkfs済みイメージをtarでholeつきファイルとして作って持ってきて(ext4だと27MBくらいになる)、ちょっと展開して中身を…と思ったらものすごい勢いでNo space left on device。Ctrl-cとかCtrl-z、kill -9でも落ちないのね。
実際これはbsdtarでもgtarでもダメだった。bsdtarはzombieになったので書き込みエラーでexitしようとしたんだろうけど、バッファがflushできなくて死にきれなかった。gtarはもっとひどくて、どうやっても殺せなくて、結局リブートしたよ…
まあ2回試すのがバカって話もあるんだけど、まさかファイルシステムが対応してないと思わないじゃん? で、最初はbsdtarが悪いと思ったのよ。そしたらgtarまでダメで、リブートかけてトイレに行っている間に、ああそうか、これはMacのHFSが悪いんだなと悟ったわけ。ただ、この状況で無事にリブートできたところは偉い。Linuxならリブートが刺さってるところだよね。
その他。
- holeつきファイルの扱いが最も上手いファイル形式はsparseファイル向けのフォーマットを何種類も持っているtarの1択なのだが、Linuxのtarもその処理は決して賢くない
- 単に中身を読んでゼロだったところを抜いてく処理をしていくため、CPUが1コア、長時間100%で回り続けて小さいtarファイルを吐き出すという…
- FIEMAPとかSEEK_DATA/SEEK_HOLEでデータブロックを探していけば一瞬で済むはずなのに…
- というわけで、上記のように400GBの内27MBしかブロックがないようなケースでは異常に長い時間がかかったりする
- しかもGNU tarはゼロブロックの判定も良くないみたいで、starの2倍の時間がかかったりする。どういう処理したらそんなに差がつくんだろう…
- あとext4のmkfsはふざけていて、無駄に何GBもゼロデータを書いて埋めてくのよね(笑)。昔からどうかと思ってたけど
- だからFIEMAPで探したとしても、400GBの中から27MBを探す仕事ではなく、数GBの中から27MBを探す仕事に変わる
- それでも時間は1/100に短縮されるわけだが