Machメッセージパッシングとポート権の仕組み
マイクロカーネルIPCの原典であるMachを、ポート権・メッセージ・out-of-line転送から正確に理解できます。ケーパビリティ型IPCの設計判断を原理から押さえられます。
- 1.Machのポートはカーネル内のメッセージキューで、プロセスは「ポートそのもの」ではなく送信権・受信権というケーパビリティを介してアクセスします。
- 2.受信権は系内で常に1つだけ移動し、送信権は複製可能という非対称が、サーバー・クライアント構造とアクセス制御を成立させます。
- 3.大きなデータはout-of-lineで仮想メモリ単位で渡し、コピーオンライトで物理コピーを遅延させることで、メッセージパッシングのコストを抑えます。
ポートは「カーネル内のメッセージキュー」
Machの世界では、ほぼすべてが**ポート(port)**を介してやり取りされます。タスク、スレッド、メモリオブジェクト、ホスト制御——これらの操作対象はいずれもポートとして抽象化され、操作は「そのポートへメッセージを送る」ことに還元されます。これがMachを「メッセージパッシング指向のマイクロカーネル」たらしめる中核です。
ポートの実体は、カーネル空間に置かれた有界のメッセージキューです。ユーザー空間のプロセスはこのキューを直接触れません。プロセスが持つのは整数のポート名(port name)で、これは自分のタスク内でのみ意味を持つ、ファイルディスクリプタに似たローカルなインデックスです。同じカーネル内ポートを2つのタスクが参照していても、各タスクでのポート名(整数値)は一致しません。カーネルはタスクごとに名前空間を持ち、名前から実際のポートと権利へと変換します。
この間接化が重要です。プロセスはポートの「中身」ではなく、そのポートに対して何ができるかという権利だけを保持します。これが次のケーパビリティの話につながります。前提として、特権境界の基礎は カーネルモードとユーザーモード を参照してください。
ポート権:送信権と受信権というケーパビリティ
Machのアクセス制御は**ケーパビリティ(capability)モデルです。ポート名には必ずポート権(port right)**が結び付き、権利を持たない相手はそのポートに一切触れられません。主要な権利は次の通りです。
| ポート権 | 意味 | 複製・移動の規則 | 個数 |
|---|---|---|---|
| 受信権 (receive right) | キューからメッセージを取り出せる。ポートの「所有」に相当 | 移動のみ可。複製は不可 | 系全体で常にちょうど1つ |
| 送信権 (send right) | そのポートへメッセージを送れる | 複製・移動とも可 | 複数存在しうる |
| 送信一回権 (send-once right) | ただ1通だけ送れる使い捨ての送信権 | 移動のみ。送信か破棄で消滅 | 用途ごとに発行 |
決定的なのは非対称性です。受信権は系全体でちょうど1つしか存在せず、複製できません。これにより「このポートのメッセージを読む主体」が一意に定まります。サーバーが受信権を握り、クライアントは送信権を持つ——この配置がサーバー・クライアント構造そのものになります。
送信権は複製可能なので、1つのサーバーポートへの送信権を多数のクライアントへ配れます。送信一回権は、リクエストに対する返信専用の宛先を1回だけ使う、というRPCの返信チャネルに最適化された軽量な権利です。
ポートへアクセスするには対応する権利を保持していなければならず、権利は推測や偽造ができません。整数のポート名を当て推量しても、その名前にカーネルが権利を結び付けていなければ無効です。「権利を持つこと自体がアクセス許可」というのがケーパビリティモデルの本質で、アクセス制御リストを別途引かずに権限委譲を表現できます。
メッセージとポート権の転送
Machのメッセージは、固定のヘッダに続いて型付けされたボディが並ぶ構造です。ヘッダには宛先ポート(送信権)と、任意で返信ポートを書きます。ボディの各要素には型タグが付き、単なるデータか、それともポート権かを区別します。
ここがMach IPCの特徴です。メッセージにはデータだけでなくポート権そのものを載せて転送できます。例えばクライアントがリクエストを送る際、メッセージのヘッダに「返信用ポートの送信一回権」を入れておくと、サーバーはその権利を受け取り、処理結果をそのポートへ送り返せます。クライアントは事前にサーバーと接続を確立する必要がなく、権利の受け渡しだけで動的に通信路が組み上がるのです。
/* Mach メッセージの概念的な構造 */
typedef struct {
mach_msg_header_t header; /* 宛先ポート・返信ポート・サイズ等 */
mach_msg_body_t body; /* 記述子の個数 */
/* 以下、データや権利・OOLメモリの記述子が並ぶ */
} message_t;
/* 送信と受信を1つの呼び出しで行える(RPC風) */
mach_msg(&msg.header,
MACH_SEND_MSG | MACH_RCV_MSG, /* 送って返信を待つ */
send_size, rcv_limit,
reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
権利を転送するとき、カーネルは送信側タスクの名前空間から権利を取り出し、受信側タスクの名前空間に新しいポート名を割り当てて結び付け直します。受信権を「移動」として載せれば、送信側はその受信権を失い、受信側がポートの新しい所有者になります。ポート名(整数値)は両タスクで異なっても、指しているカーネル内ポートは同一です。
out-of-line転送とコピーオンライト
小さなメッセージはボディに直接データを埋め込んで(in-line)渡せますが、これは中身を一度コピーすることを意味します。数MB規模のデータをそのままコピーするのは高コストです。
そこでMachは大きなデータをout-of-line(OOL)転送で渡します。メッセージ本体にはデータの実体ではなく、「この仮想アドレス範囲のメモリ領域」という記述子だけを載せます。カーネルはこれを仮想メモリ操作として扱い、受信側のアドレス空間に同じページ群をマップし直します。バイト列をバッファ間でコピーするのではなく、ページテーブルのエントリを張り替えるのが本質です。
さらにここにコピーオンライトが効きます。送信直後は送信側と受信側が同じ物理ページを共有し、両者のページテーブルで該当ページを書き込み禁止に設定します。どちらかが書き込もうとした瞬間に保護違反(ページフォルト)が起き、カーネルがそのページだけを複製して書き手に固有のコピーを与えます。実際に変更された分だけ遅延して物理コピーが発生するため、読むだけで終わるデータは物理コピーが一度も起きません。この仕組みの一般論は コピーオンライト(CoW) を、メモリ共有の基盤は メモリマップトファイル を参照してください。
大きなメッセージの典型は「サーバーがバッファを渡し、受け手はほぼ読むだけ」というパターンです。このときCoWなら物理コピーはゼロで、ページマップの張り替えコストだけで済みます。メッセージパッシングが共有メモリ並みに速くなりうるのは、この仮想メモリとの統合があるからです。Machで「IPCとVMが密結合している」と言われるのはこの点を指します。
なぜMachのIPCは重いと言われたのか
MachはマイクロカーネルIPCの設計を確立した一方、初期実装のIPCは重く、「マイクロカーネルは遅い」という評価を生みました。要因は、ポート名空間の変換、メッセージ記述子の型ごとの検査、権利の付け替えといった1メッセージあたりの処理項目の多さにあります。境界越えのたびに コンテキストスイッチ と同種の実行切り替えが走ることも積み重なります。
後継のL4系がこれをレジスタ渡しと極小化で打破し、macOS/iOSのXNUはMachのIPC・VM抽象を土台にしつつ、性能のためBSD層を同居させたハイブリッド構成を採りました。設計史の文脈は マイクロカーネルとモノリシックカーネルの設計比較 に詳しくあります。
受信権は「複製できない・系内に1つ」、送信権は「複製可能・複数可」という非対称が頻出の論点です。ポート名は整数ですがタスクローカルで、同じポートでもタスクが違えば名前は一致しません。「ポート名を知っていればアクセスできる」のではなく「権利を保持していること」がアクセスの条件である点も要注意です。
まとめ
- Machのポートはカーネル内のメッセージキューで、プロセスはタスクローカルなポート名と、それに結び付く**ポート権(ケーパビリティ)**を通じて操作する。
- 受信権は系内に1つで複製不可・送信権は複製可という非対称が、サーバー・クライアント構造とアクセス制御を成立させ、メッセージで権利そのものも転送できる。
- 大きなデータはout-of-line転送で仮想メモリ単位に渡し、コピーオンライトで物理コピーを遅延させることで、メッセージパッシングを効率化する。
通信全般の基礎は プロセス間通信(IPC)、遅延コピーの原理は コピーオンライト(CoW)、設計史は マイクロカーネルとモノリシックカーネルの設計比較 も合わせてどうぞ。
OS Article
Machメッセージパッシングとポート権の仕組みを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
Mach
比較で見る軸
難易度: advanced / カテゴリ: OS / タグ数: 6
導入後に効く点
受信権は系内で常に1つだけ移動し、送信権は複製可能という非対称が、サーバー・クライアント構造とアクセス制御を成立させます。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- OS
- タグ数
- 6
判断チェックリスト
- 自社の用途が「Mach / マイクロカーネル」に近いか確認する。
- 強みである「Machのポートはカーネル内のメッセージキューで、プロセスは「ポートそのもの」ではなく送信権・受信権というケーパビリティを介してアクセスします。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。