プロジェクト
PennOS — Unix 風の教育用 OS
C で実装したユーザーランドシェル、優先度スケジューラ、シグナル、リダイレクト、PennFAT ファイルシステム——ブラウザで動くライブターミナル付き。
CPOSIX threads (spthread)Operating SystemsShellsSchedulingSignalsFilesystemsWebSocketsnode-ptyNext.jsxterm.jsprlimit / systemd sandboxing

概要
Unix 風 OS 機能の C 実装:ジョブ制御と I/O リダイレクトを備えたシェル、spthread 上で動く SIGALRM 駆動の優先度スケジューラ、シグナルとゾンビを含む完全なプロセスライフサイクル、そしてオンディスクの PennFAT ファイルシステム——これらすべてを本サイトのサンドボックス化されたライブターミナルに接続しています。
課題
授業規模の OS は容赦がありません。不正な入力、部分的な書き込み、シグナルの競合、誤ったスケジューリングの判断は、プロセスとディスク上の状態を破壊します。課題は、そうした状況すべての下で予測どおりに振る舞い、かつ実際の訪問者がホストを危険にさらすことなくブラウザから操作できる OS コンポーネントを構築することでした。
実装したこと
OS を階層化された C で実装しました:最上位にシェルのパーサーと組み込みコマンド、中間にユーザー向けの s_* システムコール、下位にスケジューラ / プロセスと PennFAT の k_* プリミティブ、基盤に spthread(POSIX スレッド + SIGALRM)です。その後、バイナリを型付きの Node WebSocket サイドカーの背後に置き、セッションごとの prlimit サンドボックスで実行することで、誰でもブラウザで本物の PennOS を起動できるようにしました。
アーキテクチャ
- シェル層 — パーサー、組み込みコマンド(ls、cat、ps、jobs、fg、bg、kill、chmod、nice、sleep)、I/O リダイレクト(< > >>)、非同期バックグラウンドジョブ
- ユーザー API(s_*)— シェルとカーネルの間のシステムコール境界としての s_spawn、s_waitpid、s_kill、s_open、s_read、s_write、s_lseek
- プロセス / スケジューラ — PCB テーブル、9:6:4 のスケジュール比率を持つ 3 段階の優先度、SIGALRM 駆動のプリエンプション、ゾンビの回収、孤児プロセスの init への付け替え
- PennFAT(k_*)— 明示的なスーパーブロック、FAT テーブル、ディレクトリエントリを持つ FAT 風のオンディスク形式に加え、シェルの fd をカーネルオブジェクトに対応付ける fd テーブル
- spthread 基盤 — コンテキストスイッチとシグナル配送の実装に用いる、協調型の suspend / resume プリミティブを備えた POSIX スレッド
- ライブターミナル — 127.0.0.1:3100 で動く Node + ws + node-pty サイドカー。prlimit でラップ(CPU 120s、RSS 96 MiB、FSIZE 2 MiB、NOFILE 32、NPROC 24)、セッションごとの一時的な PennFAT イメージ、アイドル / ハードタイムアウト、Nginx 配下で /ws/pennos としてリバースプロキシし IP 単位のレート制限ゾーンを適用
技術的ハイライト
- 9:6:4 のクォンタム比率を持つ 3 段階の優先度スケジューラ。SIGALRM でプリエンプトし、spthread の suspend / resume プリミティブ上で動作。
- ターミナルのジョブ制御:jobs、fg %N、bg %N、Ctrl-C / Ctrl-Z の転送、孤児プロセスの init への付け替え、s_waitpid によるゾンビの回収。
- I/O リダイレクト(<、>、>>)を、PennFAT の k_* ファイル操作をラップする s_* fd テーブル経由で実装。
- シェルコマンドとして公開したストレスデモ:busy、hang、nohang、recur、crash、zombify、orphanify——カーネルを壊すために作り、壊れないことを証明するためのもの。
- PennFAT のオンディスク形式:明示的なスーパーブロック、FAT 風のチェーンテーブル、単一のルートディレクトリ、chmod +/-rwx で設定できるファイル権限ビット(r/w/x)。
- ブラウザ上のライブセッションは、WS 上の型付き JSON ワイヤプロトコル、IP 単位およびグローバルのセッション上限、prlimit でラップした子プロセス、切断時のセッション別一時ディレクトリのクリーンアップを使用。
成果
- 小さいながらも現実的な OS カーネルの表面を構築し、敵対的な入力の下でスケジューリング、シグナル、ファイルシステムのコードを鍛えました。
- tarball ではなく実際に触れる成果物として公開:訪問者は、私が何かを代わりに実行することなく、ブラウザ上でサンドボックス化された PennOS を起動できます。
実際に動かす
このプロジェクトはこのサイト上で動作します。インストールも設定も不要です。