WSL2では、/etc/wsl.conf(以下wsl.confと表記する)でドライブファイルシステム(Win32側NTFSドライブをWSL側にマウントする機能)の自動マウント機能を、オフにすることが可能で、/etc/fstab(以下fstabと表記)によるLinux側の自動マウントを使う方法が利用できる。ここでは、ドライブファイルシステム固有のオプション指定とその動作について解説する。
ただし、WSL2の場合、ドライブファイルシステムは、Windows 11とWindows 10で挙動が異なる。また、Windows 10では、wsl.confとfstabでも挙動が異なるため注意が必要だ。
Windows 10/11のWSL正式版(プレビュー版ではないもの)では、WSL自体のバージョンを表示する機能がないため、wsl.exeのファイルバージョンを手がかりとした。本記事では、以下のバージョンで確認を行った。
Windows 10 : 10.0.19044.1706 | wsl.exe : 10.0.19041.1566 |
Windows 11 : 10.0.22000.675 | wsl.exe : 10.0.22000.675 |
・【前回の記事】Windows Subsystem for Linuxガイド 第6回 ドライブファイルシステムの設定と挙動 その1
https://news.mynavi.jp/article/20220425-2329578/
ドライブファイルシステムの設定
結論から言うとドライブファイルシステムの設定はデフォルト値のままとし変更しないほうが良い結果につながる。そもそも、ドライブファイルシステムの設定項目の多くは、WSL1を想定したもので、WSL2でも指定は可能だが、指定しても意味のないもの、問題が生じるものがあり、原則、オプション指定を行わないで使うべきものと考えられる。
前回解説したようにドライブファイルシステムの設定は、wsl.confの“[automount]”セクションで行うことができる(表01)。
また、Linuxの標準的な機能であるfstabを使うことで、ドライブファイルシステムのマウントを制御することもできる。注意が必要なのはmountFsTabのデフォルト値がtrue、つまりfstabによるマウントがデフォルトで有効になっている点だ。wsl.conf自体が存在しない場合でも、このデフォルト値は有効なので、wsl.confで明確にmountFsTab=falseとして禁止しない限り、fstabにドライブファイルシステムのマウント指示があれば、それが有効になる。自動マウントが有効で、fstabにドライブファイルシステムのマウント指示がある場合、fstab側の設定が優先される。
これを理解していないと、wsl.confでのoption指定の挙動がおかしく見えてしまう、指定と異なるオプションでマウントされる、といった問題が発生する。
Windows 10のWSL2では、fstabによるマウントでは、ドライブファイルシステム固有のオプション指定がほとんどできない(表02)。ただし、wsl.conf内での指定は可能だ。
Windows 11では、この部分が改良されており、fstabでもwsl.confのoption指定とほぼ同等の指定が可能だ。ただし、“case”(文字ケースの区別)指定に関しては、可能だが、WSL2側からは、NTFSディレクトリの文字ケースの区別設定を変更できないため、caseの設定が“dir”または“force”の場合には、ディレクトリを作成することができなくなる。これは、NTFSの文字ケース区別の設定に管理者権限が必要なためだ。
Windows 10では、“case”の指定が“dir”または“force”の場合、内部的に昇格して文字ケースの区別を設定してしまう。このため、どのオプションも利用できる。この場合、WSL側から新規に作成したディレクトリは、必ず文字ケースを区別する設定になる点に注意が必要だ。
Win32側でも同じフォルダーを利用することを考えると、基本的には、デフォルト値であるcase=offで利用するべきだろう。
fstabによるドライブファイルシステムのマウント
Linuxではマウント時に図01のような情報を指定する必要がある。さらにfstabでは、ダンプやfsck(ファイルシステムチェックのコマンド)などの追加記述があるが、ドライブファイルシステムの場合には、どちらも不要で、形式合わせに“0 0”(スペースを挟んでゼロを2つ)を指定すればよい。
マウント先およびマウントするファイルシステムデバイスは、Windows 10の場合前回解説したように“/mnt”および“C:\134”(C:\を表す)である。なお、Windows 11では、/etc/mtabを見ると先頭の表記が“drvfs”になっているが、“C:\134”でも同様にマウントできる。
ファイルシステム固有オプションは少し複雑だ。基本的には、自動マウントを行わせたあと/etc/mtabに記録されるマウント情報(fstab形式になっている)をコピーして使う。この一部は、wsl.confのoption指定と共通だが、それ以外の9pfs固有の部分もある。また、/etc/mtabに記録されるマウント情報はWindows 10、11で違いがある。WSLでは、こうした細かい部分に関しての情報は公開されていない。
コマンドによるマウント、アンマウント
wsl.confの設定やfstabでマウントしたドライブファイルシステムはWSL2のシェル内では、
sudo umount /mnt/c
とすることでアンマウントが可能で、再度マウントする場合には、
sudo mount -t drvfs "C:\\" /mnt/c -o rw,noatime,dirsync
とする。オプションは、mountコマンド汎用のもののみの指定が必要で、ドライブファイルシステムのオプション指定は行う必要がない(指定するとエラー)。
LinuxパーミッションとWindows ACL
WSL2のドライブファイルシステムでは、NTFSのACLから、アクセス権が計算される。WSL側からのアクセスは、Everyoneグループからのアクセスとして解釈され、Everyoneのアクセス権限が計算される(図02)。
WindowsのEveryoneは標準で組み込まれる特殊なユーザーグループで、「すべての対話型、ネットワーク、ダイヤルアップ、および認証されたユーザー」がメンバーとなる。具体的には、Everyoneには、“BUILTIN\Users”と、WSLを実行しているユーザーが含まれ、“BUILTIN\Users”には、“NT AUTHORITY\Authenticated Users”が含まれる。このため、それぞれでWindowsのACLが定義されている場合、それぞれのアクセス権をOR演算でまとめたものがEveryoneの実効アクセス権になる。
WSL側でのモードビット表示は、Everyoneの最終的なアクセス権のパターンが変換されて表示される(表03)。Linuxパーミッションでは「所有者」、「グループ」、「その他のユーザー」に対してモードビットを設定できるが、ドライブファイルシステムの場合、WindowsのACLから求められたアクセス権は、この3つですべて同じものが使われる。
Linuxパーミッションのモードビットをオンオフするには、Windows標準コマンドのicacls.exe(写真01)で、アクセス権を設定する(表04)。ただし、ACLの設定ではディレクトリに対しては、必ず実行権(--x)が付加される。
また、ドライブファイルシステムのumask、fmask、dmaskにマスクビットを設定すると、ACLから求めたパーミッションにマスクを適用したパーミッションが表示されるようになる。umaskに077を設定すると、グループ、その他ユーザーのパーミッションがすべてオフになる。
WSL側ではモードビットの「書き込み禁止」だけは設定が可能だ。書き込みが可能なファイル/ディレクトリに対して書き込み禁止が設定できる。しかし、Win32側で書き込み禁止とされたファイル/ディレクトリを書き込み可にすることはできない。
このため書き込み以外のビットは、WSL側からは、プログラムで想定したパーミッションにできないことがある。こうした背景があるため、パーミッションを変更、確認するようなLinuxのプログラムはext4などWSL側ファイルシステムで動作させたほうがいいようだ。
ドライブファイルシステムとNTFSの拡張属性
ドライブファイルシステムのmetadataオプションは、NTFSの拡張属性(EA)を使って、Linux側のパーミッションを記録するものだ。
前述のようにファイル、ディレクトリのアクセス権は、実際には、Windows側のACLで決まる。しかし、拡張属性は、ACLとは無関係にWSL側で指定されたパーミッションを記録する。
一回、ファイルやディレクトリにWSLの拡張属性が記録されると、lsコマンドなどは、拡張属性から読み出したパーミッションを表示するため、実際のアクセス権とは異なるパーミッションが表示されることがある。
また、この拡張属性を読み出す挙動は、metadataの指定とは無関係に行われるため、WSLの拡張属性を持つファイルやディレクトリは、常に実際のアクセス権とは異なるものを表示する可能性がある。
Windows 10のWSL2では、拡張属性にアクセスできない場合に“Permission Denied”(権限がない)のエラーが発生する。
拡張属性は、NTFSの属性の1つで、管理者として以下のコマンドで表示させることができる(写真02)。
fsutil.exe file queryea 〈ファイル名〉
記録された拡張属性を削除する方法はWindowsの標準ツールにはなく、ユーザーが拡張属性を削除するプログラムを用意する必要がある。このため、このオプションはWSL2では設定しないほうがよい。
NTFSの大文字小文字の区別
Windows 10/11のNTFSでは、ディレクトリごとに文字ケースの区別(大文字と小文字を区別するかどうか)を設定できる。ディレクトリが文字ケースを区別する設定になっているかどうかは、
fsutil.exe file queryCaseSensitiveInfo 〈ディレクトリパス〉
で調べることがでる。また以下のコマンドで文字ケースの区別の有効、無効を設定できる(要管理者権限)。
文字ケースの区別を無効にする
fsutil file setCaseSensitiveInfo 〈ディレクトリパス〉 disable
文字ケースの区別を有効にする
fsutil file setCaseSensitiveInfo 〈ディレクトリパス〉 enable
WSLは、WSL側ファイルシステム上では、常に文字ケースを区別する。これに対して、ドライブファイルシステム上では、Win32側の設定とマウントオプションにより挙動が変わる。
ドライブファイルシステムのマウントオプション“case”では、“case=off”、“case=dir”、“case=force”の3つのキーワードのどれか1つを指定する(表05)。
現状、このcaseオプションの設定以外では、WSL側からNTFS上のファイル、ディレクトリに対して文字ケースの区別を設定するコマンドはないが、Win32相互運用性により、fsutil.exeをWSL側から実行することはできる。