Skip to content

Instantly share code, notes, and snippets.

@nuta
Last active August 29, 2015 14:15
Show Gist options
  • Save nuta/1366f2b845c25843f4cd to your computer and use it in GitHub Desktop.
Save nuta/1366f2b845c25843f4cd to your computer and use it in GitHub Desktop.

UNIX

GNU/Hurd

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

POSIX APIとの関係

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

auth

ユーザのUIDとGIDを把握しているサーバ。プロセスはUIDでなく、 UID vectorsというcapabilityをもつ。プロセスAがプロセスBと 通信したいときは、authサーバにリクエストを送ってそれぞれ UID vectorsに追加してもらう。よくわらない。

fork & exec

fork(3)が呼ばれたら、libcはまずMachのシステムコールを 使って新しいタスクを作り、processサーバに登録する。

execve(3)が呼ばれると、libcはファイルサーバにリクエストを送る。その後の流れは以下の通り。

  1. ファイルサーバ: パーミッションのチェック等をしてexecサーバに任せる。
  2. execサーバ: メモリ上にコードを展開。
  3. 実行開始
  4. libc: execサーバにコマンドライン変数やカレントディレクトリを聞く。
  5. main()

ルートディレクトリ

以下の4つが追加されている。

  • /hurd: トランスレータの実行可能ファイルが置いてある
  • /servers: トランスレータにアクセスするためのファイル
  • /ftp: cat /ftp/ftp.example.com/foo.txtのように使える。
  • /http: HTTP版

その他

ひとつのMachの上でHurdを複数動かせたり、Hurdの上でHurdを 動かせるらしい。unionfsトランスレータがあるので、これを 応用すればDockerが動きそう。

Plan9

カーネルはオリジナル。マイクロカーネルではなく、徹底的にカーネルを小さく しようとはしていない。

システムコール

  • プロセス操作 (例: 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は

  1. /net/tcp/cloneに接続先とかを書き込むと整数が返ってくる
  2. /net/tcp/<返ってきた整数>ディレクトリが誕生
  3. その中のファイルをいじって通信したりコネクションの状態をみたりできる

という風に表現されている。

Minix

Plan9と同じく、徹底的にカーネルを小さくしようとはしていない。

サーバ

  • pm: プロセス管理
  • vfs: ファイルシステム
  • rs: あるサーバ落ちたら自動復旧を試みるサーバ
  • vm: 仮想メモリ

ルートディレクトリ

標準的な構成。

  • /service: サーバのバイナリたち

まとめ

  • プロセスを管理するサーバと、VFS(の名前空間を管理する)サーバは必須。
  • 当初は、read(2)やexec(2)を全てPOSIXサーバを経由して、他のサーバと やり取りをすることを考えていたが、GNU/Hurdみたいにlibcが直接他のサーバとの通信を頑張る方が楽そう。
  • GNU/Hurdのトランスレータと、Plan9の/netの概念を取り入れれば、 かなりシンプルにできる。

参考文献

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment