cow溢れ 1

MacBookが修理に行ってしまった今日このごろ、デスクトップマシンの直Linuxで開発中です。


cow溢れが悩ましい。
VIVERでは読み取り専用のディスクに対して書き込み可能な状態をエミュレートするために、いわゆる「Copy-on-Write」を使って、どこか別の書き込み可能な領域(RAMなどなど)に元ディスクに対する差分を書き込むという手法を使っています。が、別の書き込み領域の容量が元ディスクよりも小さいと、ディスク全体を書き込み可能にはできないわけです。
そこで差分データファイルのファイルをスパースファイルにして、書き込まれた分だけ使用容量が大きくなるようにして、見かけ上ディスク全体を書き込み可能にしているのですが、それでも当然、どんどん書き込まれて差分データファイルが大きくなっていくと、どこかで溢れるわけです。
で、これをcow溢れと勝手に命名しています。



この問題が非常に悩ましい。cowを構成する段階では、差分データは十分に大きく見え、一方で実際に差分データに書き込んでみると、差分データを保持する領域が差分データよりも小さい、書き込めない! カーネルがI/Oエラーを吐きまくる。なんてことになる。

そもそもディスクサイズよりも大きいファイルを設置してしまう時点でマズイわけで…。


元ディスクが確保した書き込み可能領域より小さければ良い、というわけでもないのがさらに問題。
100MBのディスクに、100MBいっぱいデータが書き込まれている。これに差分データをかぶせた所で、データの書き換えはできても追記ができない。100KBのファイルを101KBにすることもできないわけで。
ということで、元データの後ろに余分に空き領域を接続する。100MBの後ろに200MBの空き領域を接続して、300MBの差分をかぶせる。これで200MB分追記ができる。
がしかし、書き込み可能領域を300MB用意しないと、どこかで溢れることになる。


VIVER 0.2では、元データに接続する空き領域はディスクイメージ作成時に接続していて、デフォルトでは10GBになっています。なので、VIVERを起動してdfコマンドで/の空き領域を見ると、10GBになっているはず。
書き込み可能領域が128MBでも、元ディスクのサイズ分の書き換えと、10GB分の追記ができるという状態。…実際にはできない。やると動作が激しく重くなる。というか凍る。



空き領域の接続はディスクイメージ作成時では無く、VIVER起動時に行うということは決めたのだけど、どれだけ接続すれば良いのか?
とりあえず考えられる状況を4つにわける。
1. 元ディスクのサイズ > 書き込み可能領域のサイズ
2. 元ディスクのサイズ ≒ 書き込み可能領域のサイズ
3. 元ディスクのサイズ < 書き込み可能領域のサイズ
4. 元ディスクのサイズ << 書き込み可能領域のサイズ

1の場合は、どうやってもcow溢れは避けられない。が、書き込み可能領域にRAMを使う場合は、この状態になる可能性が高い。でも、どうしようもないのであきらめる。
2の場合は、何も接続しなければcow溢れしないけど、追記ができないので、1同様あきらめる。適当なサイズ接続して、cow溢れしたら…どうにしてね。うーむ…。
3の場合は、書き込み可能領域のサイズ - 元ディスクのサイズ 分の空き領域を接続する。これでcow溢れしない。USBメモリを書き込み可能領域に使ったときにこうなるかな?
4の場合は、(書き込み可能領域のサイズ - 元ディスクのサイズ) × 0.3 くらいの空き領域を接続しようかな。cow溢れしない。HDDを書き込み可能領域に使ったときに、こうなるかもしれない。



むむ。やっぱり1,2の対応策はマズイ気がする。2,3,4はその分かれ目境界が微妙。
悩ましい。