Posted at

Windows Subsystem for Linuxのファイルシステムにおける注意点

More than 3 years have passed since last update.


Disclaimer

ビルド14393.10時点の情報を書いている。後のアップデートで変更される場合がある。

より正確・詳細な説明は参考資料を見てほしい。


はじめに

Windows 10 Ver. 1607で搭載されたWindows Subsystem for Linux(WSL)は、まだbeta版であるためかファイルシステム周りで歯がゆい点があるので書いておく。

便宜的にWSLのプロセスをWSL側、通常のWindowsのプロセスや環境をWindows側という風に表現する。


TL;DR


  • WSL側では常にパスがcase-sensitive

  • Windows側から%LocalAppData%\lxss以下をいじるとハマる


    • Windows側で追加したファイルはWSL側から見えない

    • WSL側でディレクトリエントリがキャッシュされるため、Windows側からの変更が正確に見えないかも



  • /mnt/c/以下ではもろもろの制約を食らう


    • パーミッションが変えられない

    • 一部の文字がパスに使えない




  • ln -s /home/fuga /mnt/c/Users/Fuga/とかすると制約でハマることがあるため、お勧めしない


WSLにおけるファイルシステム

Windowsで見るファイルもWSLで見るファイルも同じNTFSボリュームのファイルであるが、WSL側ではWindows側と比べて以下の違いがある。


  • MAX_PATHの影響を全く受けない

  • ファイルパスはcase-sensitive

  • symlinkが張れる(NTFSのシンボリックリンクとは別物)

これらは以下で説明するVolFsとDrvFsに共通する。/mnt/c/以下にもsymlinkは作れるが、Windowsからは謎のファイルとして見える。


VolFs and DrvFs

WSLから見る/と/mnt/c/は異なるファイルシステムとしてマウントされている。この二つは使い勝手が違うため注意が必要。


VolFs

/mnt/*、/tmp、/sys、/proc以外で使われるファイルシステム。Linuxにおけるファイルシステムの使い勝手を再現するように実装されている。例えば



  • :などもパスに使える


    • 本来NTFSでは使えないが、Windows側からはエスケープされて見える



  • FIFOやnamed socketが作れる

  • closeされていないファイルを削除できる

その実態はNTFSのサブツリーで、UNIXパーミッションや所有権、アクセス時間の情報はNTFSの拡張属性として記録される。

VolFsは、Windows側とのinteropはサポートされない。

Windows側からは%LocalAppData%\lxss以下からWSL側のファイルシステムを参照できるが、編集しようとすると落とし穴が待ち受ける。

まず重要なことは、VolFsは必要な拡張属性が書かれていないファイルを扱えないこと。

Windows側で作られたファイルには拡張属性が書き込まれないため、たとえ%LocalAppData%\lxss\rootfs以下に作られてもVolFsではそのファイルは存在しないという扱いになる。

また、VolFsではWindows側からファイルが編集されないことを前提にディレクトリエントリがWSLでキャッシュされる。

Windows側からVolFsを操作してもこのキャッシュは更新されない。


DrvFs

/mnt/c/などのファイルシステム。WSLからWindowsのファイルシステムを叩くためのもので、制約付き。


  • 前節で挙げたVolFsの特徴はDrvFsにはない

  • パーミッションなどはWindowsのものを元に決まり、WSL側からは変更できない(所有者は常にroot:root、権限はchmod 777ないしはchmod 555)

  • ディレクトリエントリがキャッシュされないため、ファイルのルックアップが遅い

WindowsとWSLでホームディレクトリのファイルを共通化する目的で、WSLの$HOMEにWindows側へのsymlinkを張るのは便利である。だが、ハマることもある。

例えば、.ssh/configをWindows側へのsymlinkにしていると、パーミッションがおかしいとWSL側のsshに怒られる。

こういった場合に、対象のファイルをcpしてくる以外に上手い解決法があるなら教えてほしい。


まとめ

現状、WSLでVolFsとDrvFsは相補的(あちらが立てばこちらが立たず)な関係。

タスクに応じて適切な方に作業ディレクトリを置きましょう。

まだBetaなのでフィードバック投げると良さそう。


参考資料



  1. WSL File System Support(公式ブログによる解説。長い)