本体プログラム残り

スパースの接続とルートファイルシステムの拡張…完了。
/dev/以下の引継…まだ。
pivot_root…完了。


/dev/以下の引継は、DeviceNodeクラスにメンバ関数を一個追加(void makeNodeOn(const std::string& base_path) という感じ)して、DeviceManagerクラスで呼び出しまくれば良いハズ。
…ということで今作成。完了。
無くても動きはする。


とういことで、動くぞ!

で、動いたぞ!ぃぇーい!
ふふふ…完璧だ!



…完璧なワケが無いわけで。
いろいろと問題が。


まず、pivot_rootがあまりに天変地異すぎるので、変数に格納しておいた各種パスが役に立たなくなる。
最初に考えておいたハズが…。
イタイのはマウントポイントのパスで、procのマウントポイントが/sysroot/procのときに/sysrootにpivot_root!すると、マウントポイントは/procになるのだけど、そこのところがうまくいってない。
その結果、アンマウントに失敗する。


何か根本的に設計変更〜という雰囲気が。


どうしようかなぁ…グローバル変数に std::string current_root を作って、最初は "/" を入れておいて、pivot_rootしたら "/sysroot/initrd" にする?
それだけじゃ足りないなぁ。 std::string future_root 変数も作って、最初は "/sysroot" を入れておいて、pivot_root 後に "/" にする、というのも要る。


/sysrootは今定数になっているから、これを変数にして、pivot_rootしたら中身を "/" に変えれば良いのかな。
むーいかん。/sysrootは常に参照かポインタで持っていてもらわないといけない。今はコピーしているからダメだ。
でもこの方法が一番スマートっぽいなぁ。

うむむ…どうしよう。マウントポイントのパスをpublicにするのはあり得ないな。



それから、同じデバイスを複数のマウントポイントにマウントできない問題。
/dev/hda1を/mnt/p1と/mnt/p2の両方にマウントできない。
なので、BootDiskとShadowScreenに同じパーティションを使うことができない。
これは実はVIVER 0.2でもそうだったんだけど、そういう使いかたをする場面が無かった。(0.3でも無いという可能性も多いにあるわけで…
解決策としては、/mnt/p1を/mnt/p2にbindすれば良い。あるいはシンボリックリンク。これだけだと/mnt/p1がリードオンリーだと/mnt/p2もリードオンリーになるから、/mnt/p2を書き込み可能にしたければ、/mnt/p1を書き込み可能でリマウントしないといけない。

やり方は分かるものの、どうやって実装しようか…。
あるデバイスが、今もうどこかにマウントされているのか否かが分かれば良いのだけど、今マウントされているものも含めたデバイスを一括管理するクラスが無いから、それを作る所から始めないといけない気がする。
あぁ…DeviceManagerクラスがヘタレすぎるなぁ。losetupとあるファイルを持ったデバイスを探す、という関数はかなり良い感じにできたけど。


マウントポイントを管理するクラスを作れば良いのかな。

MountPointManager::mount(const DeviceNode* dn, const std::string& mount_point, unsigned long mount_flags);

みたいなメンバ関数を作って、

std::map m_mp_map;

と言う感じのメンバ変数。
指定されたDeviceNodeがマウント済みだったら、こっちでbindしてやれば良い。

std::mapじゃダメか。std::multimapかな。


…いやいや、multimapこれだとオブジェクトの上ではひとつのDeviceNodeが複数のマウントポイントにマウントされていることになっている。何か気持ち悪い気が。
マウントオプションをDeviceNodeに持たせて、デバイスノード名にディレクトリへのパスを入れることを許容する、というのが良いかな。
ファイルシステムタイプをDeviceNodeに持たせていて、mount時にファイルシステムタイプを指定するのでは無く、DeviceNodeのコンストラクタで指定している。ファイルシステムタイプはDeviceNodeで決まる、ということで。リムーバブルなディスクだと話は違ってくるけど、VIVERの動作中にディスクを変えることも無いだろうと。
これと同じように、マウントオプションもDeviceNodeにもたせて、bindオプション+デバイスノードは/mnt/mp1。これならstd::multimapではなくてstd::mapになる。

あ、でもメジャー番号とかマイナー番号が困るなぁ。MS_BINDが指定されているときは特例的に扱う? いやいや、MS_BINDなDeviceNodeはPhysicalDeviceではなくてVirtualDeviceか。これならOKかな。


ふーむ。これで良さそうな気がする。
変更箇所がかなり多いなぁ。はぅ。