この投稿では、WSLでのVFS仮想ファイルシステムの実装に焦点を当てます。これは、ディスクファイルと、デバイス、ポート、プロセス、マイクロプロセッサなどを含む他のOSオブジェクトの両方にアクセスする際のLinuxの抽象化レベルとして使用されます。 Windows 10カーネルはサブシステム構造を持ち、元々はVFSセマンティクスを担当するPOSIXを含むさまざまなタイプの環境を実装するように設計されていました。LXCore.sysドライバーは、/ dev、/ proc、/ sysなどの対応するセマンティクスとディレクトリを実装することでこれらのカーネルサブシステムにアクセスします
図 WFSでVFSを実装するための一般的なスキーム。 最上位にはOS APIを呼び出すLinuxアプリケーションがあり、カーネルモードドライバーLXCore.sysが実装を担当します。 VFSセマンティクスを実装するために、ドライバーは、Windowsネームシステムとオブジェクトマネージャー名前空間を操作するためのオブジェクトマネージャー(ObMgr)、/ devディレクトリーを実装するためのI / Oマネージャー(IoMgr)、ファイルシステムドライバーなど、Windowsカーネルのさまざまなサブシステムにアクセスしますディスクファイルを操作するためのNTFS。
WSLは、Linuxアプリケーションに必要なVFSセマンティクスを提供する一方で、ファイルとディレクトリ、シンボリックリンク、特別なFIFOファイル、および上記のディレクトリ/ dev、/ proc、/ sysなどのパーミッションシステムをサポートします。アプリケーションが関数の1つを呼び出すときopen 、 read 、 chmod 、 statのように、対応するシステムコールがそれを処理し、制御をVFS実装層(LXCore.sys)に転送します。 さらに、ファイルパスを処理するとき(たとえば、 open関数やstat関数を実行するとき)、VFSは特別なキャッシュ(ディレクトリエントリキャッシュ)を使用して内部形式に変換します。 キャッシュに必要なパス要素がない場合、1つまたは複数の特別なプラグインが呼び出され(以下を参照)、この要素の既知のiノード構造が作成されます。 この構造は、WSLでアプリケーションによって開かれたファイルを表します。
Windowsには、開いているファイル記述子を表すiノードタイプの構造がありません。代わりに、 ファイルオブジェクトと呼ばれる既知の構造が使用され 、ファイルに関するいくつかの情報(サイズ、属性、アクセスマスクなど)が保存されます。 LXCore.sysは、iノードの実装時に内部的にこれに依存しています。 ただし、LinuxとWindowsはどちらも、ファイル記述子を使用して、開いているファイルを表します。LXCore.sysの詳細は隠されています。 VolFおよびDrvFという名前で、いわゆるプラグインのレベルを定義します。これらは、ディスクファイルの操作を担当し、TmpFはインメモリファイルシステムデータの操作を行い、擬似FS ProcF、SysF、およびCgroupFを操作します。
ボルフ
VolFsプラグインは、VFSがディスクファイルシステムを操作するために使用され、Linuxシステムファイルと/ホームディレクトリの内容を保存するために使用されます。 VolFsは、Linuxファイル許可、シンボリックリンク、ソケット、デバイスファイル、およびFIFOをサポートしています。 / rootおよび/ homeディレクトリは、%LocalAppData%\ lxss \ rootおよび%LocalAppData%\ lxss \ homeディレクトリにマウントされます。 WSLサブシステムを削除しても、これらのディレクトリに保存されているファイルは削除されません。 パスからわかるように、Linuxディレクトリのマウントディレクトリはユーザー固有です。つまり、各Windowsユーザーは独自のWSLディレクトリを持っています。 したがって、あるユーザーがLinuxアプリケーションをWSLにインストールしても、他のユーザーには影響しません。
WSLは、Windowsで直接サポートされていないLinuxファイルシステムの2つの機能をアプリケーションに提供します。 最初のそのような機能は、ファイル名の大文字と小文字に対するFSの感度です。この場合、VolFはオブジェクトマネージャーに単にアクセスし、操作の特定のフラグを示します。 NTFSはファイル名の大文字と小文字を区別する文字を内部で区別するため、この機能の実装は非常に簡単な作業です。
2番目の機能は、ファイル名に適用可能なほとんどすべての可能な文字のサポートです。 Windowsでは、ファイル名に厳しい制限があり、ファイル名の一部の文字は無効になりますが、ファイル内のデータの代替ストリームを表すコロン「:」などの特別な意味を持つものもあります。 この機能を実装する場合、VolFSは名前に無効な文字を使用しないようにします。
Linux iノードには、所有者とグループ、モードに関する情報など、Windowsにはない多くの属性があります。 これらの属性は、ディスク上のファイルに関連付けられているNTFS Ea拡張属性構造に格納されます。 次の情報は、このNTFS Eaファイル属性に保存されます。
- ファイルモード(モード):ファイルの種類(通常、シンボリックリンク、FIFOなど)、およびファイルのアクセス許可ビットが含まれます。
- 所有者情報:ファイルIDのグループIDとユーザー。
- デバイスID:デバイスを表すファイルの場合、メジャーおよびマイナーデバイス番号。 これまでのところ、WSLはユーザーがVolFSでデバイスファイルを作成することを許可していません。
- ファイルのタイムスタンプ:ファイルへの最後のアクセスとその変更のタイムスタンプ。 Linuxはタイムスタンプに異なる形式を使用するため、それらに関する情報は拡張属性に保存されます。
Drvfs
Windowsとの対話を容易にするために、WLSはDrvFsプラグインを使用します。 WSLは、サポートされているファイルシステムを持つすべてのディスクデバイスを/ mntディレクトリ(たとえば、/ mnt / c、/ mnt / d)に自動的にマウントします。 NTFSおよびReFSファイルシステムのボリュームは現在サポートされています。 DrvFはVolFと同じように機能します。 ストリームがファイル記述子を開くと、ファイルオブジェクトとiノード構造が作成されます。 ただし、VolFとは異なり、DrvFはファイルシステムを操作する際にWindowsの規則に従います。 有効なNTFSファイル名のみのWindowsからのファイルのアクセス許可を使用しますが、FIFOやソケットなどの特別なファイルは許可されません。
Linuxは、ファイルの所有者、グループ、または他の誰かがそれを実行、データの読み取りまたは書き込みを許可されている場合、かなり単純な許可モデルを使用することが知られています。 Windowsは、個々のファイルまたはディレクトリごとに複雑なアクセスルールを定義するアクセス制御リスト(ACL)に基づくより洗練されたモデルを使用します(LinuxもACLをサポートしていますが、現在この機能はWSLでサポートされていません)。
DrvFsプラグインを介してファイルを開くと、bash.exeシェルプロセスが起動されたコンテキスト内のユーザーのアクセストークンに基づいたWindows権限メカニズムが使用されます。 したがって、C:\ Windowsシステムディレクトリ内のファイルにアクセスするには、WSLでルート権限を提供できるsudoコマンドを使用するだけでは不十分です。 後者はプロセスのアクセストークンを変更しないため、指定された操作を実行するには、Windowsで昇格された権限でbashアプリケーションを実行する必要があります。
WSLは、ファイルにアクセスするときに持っているアクセス許可についてのヒントをユーザーに提供できます。一方、DrvFsは現在のユーザーアクセス許可を確認し、読み取り/書き込み/実行ビットに変換します。これはls -lコマンドの実行時に表示できます。 ただし、直接変換の可能性は常に存在するとは限りません。 たとえば、Windowsには、ディレクトリにファイルまたはサブディレクトリを作成するための個別のアクセス許可があります。 ユーザーがそのような権限を持っている場合、DrvFsはディレクトリへの書き込みアクセスの存在をユーザーに示しますが、それに対する操作の一部はユーザーが利用できない場合があります。
指定されたWLSファイルアクセスは、Windowsで実行されているbash.exeプロセスが持つ権限によって異なるため、異なる権限を持つbash.exeのコピーを切り替えると、指定されたファイルのアクセス許可が変更されます(単純なユーザーから実行され、管理者から2番目)。 ファイルのアクセス許可を計算するとき、DrvFsは読み取り専用属性を考慮します。 読み取り専用属性を持つファイルは、書き込み許可がないとしてWSLに表示されます。 chmodコマンドを使用して、読み取り専用属性を設定する(すべての書き込み許可を削除する、つまりchmod aw some_file )か、削除する(書き込み許可を設定する、つまりchmod u + w some_file )ことができます。 このWSLの動作は、Windows SMB共有にアクセスするときに使用されるLinux CIFSファイルシステムに似ています。
VolFとは異なり、DrvFは追加のファイル情報を保存しません。 代わりに、すべてのiノード属性は、有効なファイル属性、有効なアクセス許可、およびその他の情報を照会することにより、Windowsで使用される情報に基づいて生成されます。 DrvFsは、特別なディレクトリエントリキャッシュの使用も禁止しています。 これは、他のWindowsプロセスの1つがディレクトリの内容を変更した場合でも、最新の状態に保つために行われます。 したがって、DrvFsがファイルにアクセスできる限り、Windowsプロセスがファイルに対して実行できることに関する制限はありません。 DrvFsは、ファイルを削除するときにWindowsセマンティクスも使用するため、開いている記述子がある場合、ファイルのリンクを解除することはできません。
ProcFおよびSysF
Linuxの場合、これらのタイプの特別なディレクトリはディスクファイルでは機能せず、代わりにOSカーネルが使用するプロセス、スレッド、およびデバイスの実行に関する情報を提供します。 これらのディレクトリは、クライアントがそれらを読み取ろうとするときに動的に生成されます。 場合によっては、これらのディレクトリの情報はすべてLXCore.sysメモリに保存されます。 他の場合、たとえば、いずれかのプロセスでマイクロプロセッサを使用している場合、WSLはこの情報をWindowsカーネルに要求します。 ただし、どちらの場合も、プラグインはWindowsディスクファイルシステムと対話しません。