完全なLinuxがWindows 10上で稼働する? 「WSL 2」とは:Windows 10 The Latest
MicrosoftがBuild 2019でWSLの強化版「WSL 2」を発表した。WSL 2は、現行のWSLと何が違うのかだろうか。Microsoftの開発者向けBlog「Devblog」で公開された情報から、WSL 2の概要を解説する。
2019年5月に米国シアトルで開催されたMicrosoftの開発者向けイベント「Build 2019」で、現在のWindows Subsystem for Linux(WSL)を強化した「WSL 2」が発表された(Microsoft Devblog「Announcing WSL 2」「WSL 2 Post BUILD FAQ)。本稿では、発表されたWSL 2のアーキテクチャを紹介しつつ、その特徴や現行のWSL(以下区別のためにWSL 1と表記する)との違い、そして今後の予定について解説する。
WSL 2とは何か?
WSL 2最大の特徴は、仮想マシンを使い、Linuxカーネルが動作する「本物のLinux環境」であるということだ。
WSL 1は、Linux実行環境をLinuxカーネルではなく、LXCore と呼ばれる「サブシステム」が作り出しており、カーネルへのファンクションコールをWindowsカーネルへのファンクションコールに変換して動作している。
これに対してWSL 2は、専用の仮想マシン環境である「Light Weight utility Virtual Machine」(軽量ユーティリティーVM)を使い、ローカルパッチ(Microsoftによる独自パッチ)を当てたLinuxカーネルバイナリを動作させ、仮想マシン内にLinuxの実行環境を作る。
WSL 1とWSL 2のアーキテクチャの違い
WSL 1は、サブシステムが特殊なプロセス環境を作り、Linuxのカーネル機能をNTカーネルの機能呼び出しに変換してLinuxプログラムを実行する環境を作っていた。このためWSL 1ではLinuxカーネル自体は存在していなかった。これに対してWSL 2では仮想マシン内に専用パッチを当てたLinuxカーネルを動かし、Linuxの実行環境を作る。Linuxカーネルが動作するためほとんどのLinuxプログラムを動作させることができる。
「Hyper-V仮想マシンサービスを使ったLinuxの仮想マシンならば、これまでもあったではないか!」と思われる方もいるかもしれない。だが、この軽量ユーティリティーVMを使ったWSL 2では、仮想マシン環境が起動し、bashがコマンドを受け付けるまで2秒程度という速度で起動できる。
このため、コマンドプロンプトなどからwsl.exeなどを使ってbashコマンドを処理する時間は、現在のWSL 1とほとんど変わらない。また、本物のLinux実行環境であるため、これまで正しく動作できなかったアプリケーション、例えばコンテナシステム(Dockerなど)やユーザーファイルシステム(FUSEなど)も動作させることができる。その上で、現在のWSL 1と同等の機能と使い勝手を実現するという。
WSL 2はWSL 1を置き換えずに併存する
WSL 2が登場したからといって、WSL 1は廃止になるわけではなく、引き続き利用可能である。Windows OSの仮想マシン支援機能は、Intel VTおよびAMDvにのみ対応しているため、現時点では、Hyper-Vが組み込まれていないARM64版(Windows On ARM。WOA)では、WSL 1が引き続き使われるものと考えられる。
また、Hyper-Vでは動作条件として最低4GBのメモリが指定されているため、メモリ2GBといった低スペックのマシンなどもWSL 1がカバーすることになると考えられる。
さらに、Hyper-Vベースの仮想マシン技術を使うものの、WSL 2は、Windows 10 Homeに対しても提供が行われるという(HomeではHyper-Vが無効にされている)。
WSL 2はいつリリースされるのか?
WSL 2は、2019年6月末には、Windows Insider Programでのプレビューが開始されるという。おそらく、現在プレビュー中のWindows 10の2020年春にリリース予定の機能アップデート「20H1」のプレビュー版に入る形で配布が行われるのではないかと考えられる。
つまり、正式配布は2020年5月のWindows 10バージョン2003となる。ただし、まだ、「19H2」と呼ばれる2019年10月に提供予定のWindows 10バージョン1909のプレビューは開始されておらず、そのタイミングは6月後半といわれている。そのため、「19H2」「20H1」の両方でプレビューが行われ、2019年内に正式配布が開始される可能性もある。
コンソールを一新する「Windowsターミナル」
同イベントでは、新しいコンソールプログラムとなるWindowsターミナルも同時に発表されている。これは、タブ形式で複数セッションを同時に行えるコンソールウィドウプログラムで、DirectWrite(Microsoft DirectXのコンポーネントの1つ)などを使い、「近代的」な文字表示システムを持つ。これにより、絵文字の表示や「合字」、Programming Ligature(プログラミング用に、同一文字でも前後の文字により区別して表示するなどのフォントの機能)などに対応できるようになった。
Windowsターミナルについては、別途解説する予定だ。
WSL 1を振り返る
WSL 2の具体的な実装について解説する前に、少しだけWSL 1について復習しておく。WSL 1は、Windows NT時代からある「サブシステム」を利用している。サブシステムとは、異なるOS環境を実現するための仕組みで、当初は、Windows OS内でPOSIX準拠アプリケーションを実行するために作られた。当時、米国政府調達に応じるコンピュータシステムには、全てPOSIX対応が義務付けられていたからだ(現在は義務化されていない)。1993年にリリースされた最初のWindows NTには、POSIX、OS/2およびWin32サブシステムなどが組み込まれていた。
その後、POSIX SubsystemはWindows XPでSFU(Service for UNIX)となり、Windows 7のSUA(Subsystem for UNIX-Based Application)まで、オプション機能などで利用されることになったが、Windows 8で廃止された。
この仕組みを改良し、OS側がまったく見えない「プレーン」な実行環境であるpicoプロセスをベースに開発されたのがWSL 1である。WSL 1には、Linuxカーネルは存在せず、Linuxカーネルへのファンクションコールをサブシステム側で受け、これを解釈してWindowsカーネルへのファンクションコールに変換している。
また、専用のinitプロセス(Linuxで最初に起動するプログラム。通常は初期設定や常駐デーモンの起動などを行う)が起動し、実行環境を整備する。Linuxアプリケーション側からは、通常のLinux環境のように見えるが、全てのカーネルファンクションコールに対応しているわけではない。結局、WindowsとLinuxカーネルの違いなどから完全にLinuxとの互換性を持たせることができない。
ファイルシステムに関しては、NTFS上の特定フォルダ以下を利用し、Windows OSで使わないメタデータなどを使ってアクセス制御などを可能にした「VolFs」が使われる。なお、VolFsやWSL 1内からWin32側のファイルシステムにアクセスする「DrvFs」などは、LinuxのVFS(仮想ファイルシステム)の仕組みを使う。
こうした構造であるため、まとめるとWSL 1には以下のようなLinuxと非互換の部分がある。
- 全てのカーネルファンクションが実装されていない
- 一部のカーネルファンクションでは、Linuxと完全な互換性が取れない(ファイルがオープンされているとき、ファイル名を変更することはWindows OSではできないが、Linuxのネイティブファイルシステムでは可能など)
- スケジューリングやメモリ管理、デバイス管理などはWindowsカーネルが行う
WSL 2では性能と互換性が向上
WSL 2では、特にカーネルファンクションの互換性を高めるため、Linuxカーネルそのものを使う。ただし、公開されているカーネルのソースコードに対して、WSL 2専用のパッチを適用してバイナリコードを生成して利用する。とはいえ、カーネルはLinuxそのものであるため、ファンクションコールの互換性はそのままである。
また、Linuxの起動ファイルシステムには、ext4を利用する。ただし、仮想環境内であるため、Windows OSの仮想ディスクを利用し、NTFS上のVHDXファイル上に構築される。これをアクセスするコードもLinuxのext4ファイルシステムのコードであり、従来のVolFsに比べて高速化が期待できる。
Microsoftによれば、ファイルアクセス中心のアプリケーションでは、WSL 1のVolFsに対して「git clone」(gitでリポジトリ内の全ソースコード全てをコピーするコマンド)で2.5倍、cmakeで3.1倍、npm install(Node.jsのパッケージインストールコマンド)で4.7倍に高速化されたという。ただし、WSL 1のVolFsとWSL 2のネイティブファイルシステムがあるVHDXは、直接の互換性がない。Microsoftは変換コマンドを用意し、相互に変換できるようにするとのことだ。
WSL 2の実装
ここからは、WSL 2の具体的な実装に踏み込み、WSL 1と比べて何が変わるのか、どのようなメリット/デメリットがあるのか解説していく。
WSL 2は専用の仮想マシン内で起動
WSL 2は、専用の仮想マシン内で起動するが、その起動はWSL 1と同じくwsl.exe(あるいはbash.exeやubuntu.exe)から行われる。wsl.exeは、WSL 1と同じく、Win32側でWSLを制御する「Lxssマネージャーサービス」を呼び出して、Linux環境の起動を要求する。仮想マシンの立ち上げは、Windows OSのコンテナ支援サービスである「ホストコンピュートサービス」を介して行われる。
その後、Lxssは、仮想マシンでLinuxディストリビューションを起動する(どのディストリビューションを起動するのかはwsl.exeの引数やデフォルト設定から決定される)。Linux環境では、最初のプロセスとしてWSL専用のinitが起動し、デーモンなどを起動することなく、bash.exeが起動される。このとき、bashには、wsl.exeに指定された引数や標準出力などが渡され、bashの出力は、wsl.exeが起動していたコンソールへと接続されることになる。
WSL 2の構成
wsl.exeなどのWSL起動コマンドから、WSLの起動を依頼されたLxssマネージャーサービスは、ホストコンピュートサービス(Windows OSのコンテナ機能関連サービス)を介して軽量ユーティリティーVM環境を起動する。その後、initがbashを起動し、wsl.exeの動作しているコンソールを介して入出力を行う。
標準ファイルシステムはext4、実体はHyper-Vの仮想ディスク
WSL 1には、VolFs、DrvFsが実装され、自身のファイルシステム(VolFs)に加えて、Win32側のストレージデバイスへのアクセス(DrvFs)が行えた。また、Windows 10 May 2019 Update(バージョン1903)からは、「wsl$」という仮想ホストを使ったWin32からVolFsへのアクセス機能が搭載されている。WSL 2でも、同様に、「Win32からWSL 2のファイルシステム」へのアクセス、「WLS 2からWin32のファイルシステム」へのアクセスが可能になる。
ただし、その実装はWSL 1と異なる。1つは、WSL 2のネイティブファイルシステムがext4ファイルシステムとなり、Hyper-Vを介して、仮想HDDで構築されることになる。
ファイル共有プロトコル「9P」でWSL 1との互換性を確保
しかし、wsl$によるファイルアクセスは、WSL環境専用のinitプロセスに含まれる9Pサーバと、Windows 10側の9Pクライアント(ネットワークプロバイダー)によりネットワークファイルシステムとして実現されているため、実は、この部分は変更なく利用可能となる。
9Pは、Plan 9 from Bell Labs(Plan 9と略すことが多い)というOS用に開発されたファイル共有プロトコルで、もともとはPlan 9 Filesystem Protocolと呼ばれていた。WSLに使われているのは、9P2000.Lと呼ばれるLinux向けのバージョンだ。ネットワークファイルシステムなら、MicrosoftのSMBを使えばいいのではという話もあるが、Linuxには、SMBの実装であるSambaやこれを使った仮想ファイルシステムがある。
しかし、これはそもそもLinuxの標準的なパッケージではあるものの、必ずしも全てのLinuxディストリビューションに含まれているわけではないし、ユーザーがSambaを別の目的に利用したいこともあるだろう。
Sambaの設定ファイルはシステムに1つであり、これをWSLで占有してしまうと、ユーザーの利用に制限が出てしまう。またゼロから作るにしては、SMBは複雑すぎる。このためMicrosoftは、SMBによるVolFsの共有を断念し、別のプロトコルを探すことにした(Microsoftには、WindowsにGPLソフトウェアを同梱できないという社内問題もあったようだ)。
Microsoftは、Linuxコンテナ用にWindows OS用の9Pサーバを開発していた。Linuxカーネルには、9Pクライアントが組み込まれていて、対応が容易だったからだ。そのため、これを利用することにした。なお、9Pの制御はLxssマネージャーサービスが行うが、9Pサーバとクライアントの通信は、UNIXソケット(AF_UNIX)を介して行われる。WSL 2でもこの仕組みは維持されるようだ。
WSL 2でもWindowsカーネルとLinuxユーザーモード間は9Pで通信
WSL 2のext4へのWin32からのアクセスは、WSL 1同様に9Pを介して行われる。なおこの機能はWindows 10 May 2019 Update(バージョン1903)から組み込まれている。
ただし、Windows 10 May 2019 Updateに含まれるwsl$ファイルシステムは、UNCとして「//wsl$/<ディストリビューション名>/パス」という構造を取るため、このままでは、WSL 1とWSL 2の同一ディストリビューション同士のパス名が同じになってしまう可能性がある。Microsoftによれば、WSL 1とWSL 2を同時に利用することも可能だとしている。おそらくは、「wsl2$のような仮想ホスト名を使うなどして、両者を区別できるようなUNCを使うことになると考えられる。
WSLからWin32へのアクセス方法
前述のようにWSL 1では、WSL内からWin32側へのアクセスは、LinuxのVFSによるDrvFsを利用することで、NTFSへのアクセスをWindowsカーネル経由で行っていた。しかし、仮想マシンを使うWSL 2では、逆にWindowsカーネルへ直接ファンクションコールを出すことができない。
このため、WSLからWin32ファイルシステムのアクセスに関しても、9Pを利用する。このとき、Windows側の9Pサーバは、VMのワーカープロセス内にあるという。VMのワーカープロセスは、Hyper-Vで仮想マシンに対して、ホストOS側からファイルアクセスやネットワークサービスなどを提供する「受け口」となるプロセスだ。仮想マシンごとにワーカープロセスが対で作られる。
WSL 2からWin32側ファイルシステムへのアクセス
WSL 2からWin32側ファイルシステム(いわゆるC:ドライブなど)へのアクセスは、やはり9Pで行われる。9PサーバがVMのワーカープロセスに組み込まれており、これがC:ドライブなどにアクセスを行う。
このように、WSL 2とWin32環境の間のファイル共有は、どちらも9Pを使うことになる。なお、現在WSL 1では、9Pの接続にUNIXソケット(AF_UNIX)を利用している。おそらくは、WSL 2では、何らかの形で、仮想マシンとWin32環境の間でUNIXソケットによる接続が可能な仕組みが提供されると思われる。
また、WSLからWin32プログラムを起動する「Win32相互運用性」では、最初にWSL側で、実行ファイルを判別する必要がある。具体的には、実行ファイル先頭のマジックナンバー(Win32ではMZ)を見て、LinuxのELF64か、Win32の実行ファイルなのかを判断する。
その上で、Linuxの「binfmt_misc」(指定されたマジックバイトシーケンスとファイルの先頭の何バイトかを比較して、バイナリタイプを判定する)という機能を使い、対象のファイルを実行できる「インタープリター」を使って指定されたファイルを実行する。
これは本来、スクリプトやJavaのjar(Javaアーカイブ)ファイルなどを実行するためのものだ。WSL 1では、インタープリターとしてinitが指定されていた。このような仕組みであるため、WSL 2でも、まずは、9Pを使って、Win32側にある実行ファイルを読み出す必要がある。その後、wsl.exeなどのWSL 2を起動した環境側と連携して、Win32実行ファイルを起動する。
WSL 2のWin32相互運用性
Win32相互運用性では、最初にLinux側で実行対象がWin32実行ファイルなのかを判断するため、ファイルを読み込む必要がある。このとき、Linuxカーネル内の9Pクライアントを介して、Win32側のファイルをアクセスする。その後、登録されているインタープリターを介して実行を行う。最終的にはWin32側のwsl.exeに実行が依頼され、Win32実行ファイルが起動される。
WSL 2が実現可能になったのは、WSL 1開発後にWindows OSの仮想マシン技術が進歩したからだという。WSL 1は、2016年3月に開催されたBuild 2016で発表され、その後プレビュー版、β版を経てWindows 10 Fall Creators Update(バージョン1709)より正式版となった。
この2年の間にMicrosoftは、仮想マシンを高速起動が可能なように改良したわけだ。この仮想マシン技術は、Windowsサンドボックス(Windows Sandbox)やWDAG(Windows Defender Application Guard)などに使われているものと同種のものだという。Build 2019のセッションビデオなどを見ると、確かに高速に起動しており、体感的にはWSL 1とほとんど違いを感じなさそうだ。WSL 2でもWSL 1同様にディストリビューションをWSL用に変換することが可能であり、しかも完全なLinuxとなることから対応するディストリビューションも増えそうだ。
Copyright© Digital Advantage Corp. All Rights Reserved.