Machベース。Hurd自体はMachのカーネルサーバたち。 Debian GNU/Hurd(ディスクイメージ)を試した。
Machを隠そうとはせず、POSIX APIを使いたい時にHurdのサーバを使うという雰囲気。
あるディレクトリやファイルへのアクセスを処理するプログラム(トランスレータ)を ユーザランドで実装できる。かなり柔軟なmount(8)のようなもので、シンボリックリンクや ソケットなどなどはこれで実装されている。
Hurdではsettransコマンドで以下のようにトランスレータを設定する。
$ settrans directory translator arg...
$ settrans -ca dir1 /hurd/tarfs myfile.tar
$ settrans -a dir2 /hurd/httpfs example.com
openするとき、libcはfile_name_lookup()
を呼んで対応するトランスレータへの
Machポートライトを取得して直接通信するらしい。file_name_lookup()
はDNS
の名前解決のようにrootトランスレータから再帰的にポートライトを貰いながら
聞いて回る。
- proc: UNIXの「プロセス」を実装
- pfinet: TCP/IP
- fifo: 名前付きパイプ
- exe: 実行可能ファイルをメモリ上に展開
- init: /sbin/initのようなもの(?)
- symlink: シンボリックリンク
- fwd: サーバへのリクエストの転送
- null: /dev/null
ユーザのUIDとGIDを把握しているサーバ。プロセスはUIDでなく、 UID vectorsというcapabilityをもつ。プロセスAがプロセスBと 通信したいときは、authサーバにリクエストを送ってそれぞれ UID vectorsに追加してもらう。よくわらない。
fork(3)
が呼ばれたら、libcはまずMachのシステムコールを
使って新しいタスクを作り、processサーバに登録する。
execve(3)
が呼ばれると、libcはファイルサーバにリクエストを送る。その後の流れは以下の通り。
- ファイルサーバ: パーミッションのチェック等をしてexecサーバに任せる。
- execサーバ: メモリ上にコードを展開。
- 実行開始
- libc: execサーバにコマンドライン変数やカレントディレクトリを聞く。
main()
以下の4つが追加されている。
- /hurd: トランスレータの実行可能ファイルが置いてある
- /servers: トランスレータにアクセスするためのファイル
- /ftp:
cat /ftp/ftp.example.com/foo.txt
のように使える。 - /http: HTTP版
ひとつのMachの上でHurdを複数動かせたり、Hurdの上でHurdを 動かせるらしい。unionfsトランスレータがあるので、これを 応用すればDockerが動きそう。
カーネルはオリジナル。マイクロカーネルではなく、徹底的にカーネルを小さく しようとはしていない。
- プロセス操作 (例: fork, exec, wait)
- 仮想メモリ操作 (例: segattach)
- ファイル操作 (例: open, create, read, write)
Hurdのトランスレータみたいな仕組みがある(?)。ディレクトリの名前空間はプロセスごとに
存在することが可能で、cat /proc/<pid>/ns
でどうなっているか確認できる。
名前空間を構築するにはbind(2)
を使う。
かなり違う。特に特徴的なところは以下の通り。
- /usr: Linuxの/homeディレクトリ
- /CPUアーキテクチャ名: 実行ファイルとか(?)
- /cron: crontabファイル
/net
ディレクトリのファイルに書き込んだり読み込んだりしてTCPやUDP
を表現している。TCPは
/net/tcp/clone
に接続先とかを書き込むと整数が返ってくる/net/tcp/<返ってきた整数>
ディレクトリが誕生- その中のファイルをいじって通信したりコネクションの状態をみたりできる
という風に表現されている。
Plan9と同じく、徹底的にカーネルを小さくしようとはしていない。
- pm: プロセス管理
- vfs: ファイルシステム
- rs: あるサーバ落ちたら自動復旧を試みるサーバ
- vm: 仮想メモリ
標準的な構成。
- /service: サーバのバイナリたち
- プロセスを管理するサーバと、VFS(の名前空間を管理する)サーバは必須。
- 当初は、read(2)やexec(2)を全てPOSIXサーバを経由して、他のサーバと やり取りをすることを考えていたが、GNU/Hurdみたいにlibcが直接他のサーバとの通信を頑張る方が楽そう。
- GNU/Hurdのトランスレータと、Plan9の
/net
の概念を取り入れれば、 かなりシンプルにできる。
- documentation (GNU Hurd)
- Plan9
- あなたの知らないネットワークプログラミングの世界
- developersguide:start [Wiki] (Minix)