【WSL 2互換性チェック】NTFSのシンボリックリンクやジャンクションは使い物になるのか?:Windows 10 The Latest
開発が進んでいる次期「Windows Subsystem for Linux」(WSL 2)で新たにサポートされたNTFSのソフトリンク対応が行われた。実際にいろいろなパターンでソフトリンクの対応状況を確認してみた。
Windows 10の開発中のバージョンをいち早く試すことができるWindows Insider Programでは、2019年10月上旬現在、2019年秋の機能アップデート「19H2」と、2020年春の機能アップデート「20H1」の2つのWindows 10 Insider Preview版が提供されている(Windows Insider Programの参加方法は、Tech TIPS「Windows 10のプレビュー版をダウンロードする方法」参照のこと)。
「20H1」向けのプレビュー版では、Windows 10上でLinux環境が実行できる「Windows Subsystem for Linux(WSL)」の新しいバージョンである「WSL 2」の開発が進んでいる。
ビルド18980では、Windows OS(NTFS)のソフトリンクに対応できるようになった。
ビルド18980以前は、NTFSのソフトリンクに対応しておらず、lsコマンドなどでエラーが表示され、またリンク先も得られなかった。Linuxにもソフトリンク/ハードリンクがあり、コマンドによってはソフトリンクでリンク先を処理しなければならない場合もある。このため、実質上、ソフトリンクのあるWin32側のファイルやフォルダをLinux側コマンドで処理できなかった。
現行のWSL(以下、WSL 1)に関しても、当初はNTFSリンクを扱うことができなかったが、現在のWindows 10 May 2019 Update(バージョン1903)では正しくリンクを扱えるようになっている。
Windows OSのリンクを整理しておこう
Windows OSのNTFSには、ハードリンクとソフトリンクの機能がある。ハードリンクとは、記憶デバイス上で同一の場所にあるファイルに対して別の名前(パス)を付けるものだ。違う場所にはあるものの、記憶装置上は同一なので、同一ファイルをコピーする場合に比べて、記憶容量の消費が少なくて済む。ただし、ファイルとしては同一になるため、ハードリンクされたファイル同士は常に同じ内容となる。1つを書き換えると、他のハードリンクされたファイルも書き換わる。
タイプ | ファイル | フォルダ | 管理者権限 | 対応コマンド | 概要 |
---|---|---|---|---|---|
ハードリンク | ○ | × | 不要 | mklink /H | 同一の場所にあるファイルに別のパスを付ける |
シンボリックリンク | ○ | ○ | 必要 | mklink、mklink /D | 他のファイル/フォルダを指し示すリンク |
ジャンクション | × | ○ | 不要 | mklink /J | 他のフォルダを指し示すリンク |
Windows OSにおけるハードリンクとソフトリンクの機能の違い |
これに対してソフトリンクは、単に他のファイルを指し示すものだ。このため、リンク先のファイルは存在している必要もない。Windows OSのソフトリンクには、「シンボリックリンク」と「ジャンクション」の2つがある。この辺りについては、Tech TIPS「Windowsのシンボリックリンクとジャンクションとハードリンクの違い」を参照いただきたい。
Windows OSでは、リンクの作成に「mklinkコマンド」を使う。これは、「内部コマンド」(cmd.exe内部に実装されているコマンド)である。一応、このコマンドで、3種のリンク全てに対応ができる。また、ハードリンクに関してのみ「fsutil.exe hardlinkコマンド」でも作成が可能だ。なお、3種のリンクのうち、シンボリックリンクのみフォルダへのリンク作成に管理者権限が必要になる。
ファイルのリストを表示させるdirコマンドは、シンボリックリンクとジャンクションを区別して表示できる。シンボリックリンクに関しては、リンク先がフォルダ(ディレクトリ)の場合には<SYMLINKD>、ファイルの場合には<SYMLINK>と表示する。
ジャンクションはリンク先がフォルダに限定されるため、表記は<JUNCTION>のみだ。ハードリンクは、特に表記はなく、DIRコマンドでは通常のファイルと区別できない。ただし、fsutil hardlink listコマンドを使うと、ファイルを指定して、同じ記憶域を使う他のハードリンクされたファイルを表示させることができる。
Linuxのリンクと区別するため、以下、Windowsの3種のリンクをそれぞれ「NTFSハードリンク」「NTFSシンボリックリンク」「ジャンクション」と表記することにする。
Linuxのリンクとは
Linuxにもハードリンクやソフトリンクがある。ソフトリンクは、「シンボリックリンク」と呼ばれ、多くの場合「symlink」などと表記される。こちらについても、NTFSのリンクと区別するため、「Linuxハードリンク」「Linuxシンボリックリンク」と表記することにする。
タイプ | ファイル | フォルダ | 管理者権限 | 対応コマンド | 概要 |
---|---|---|---|---|---|
ハードリンク | ○ | (システム依存) | 不要 | lnコマンド | 同じ記憶装置上で別のパスを付ける |
シンボリックリンク | ○ | ○ | 不要 | ln -s コマンド | 他のファイル/フォルダを指し示すリンク |
Linuxにおけるハードリンクとシンボリックリンクの違い |
Linuxハードリンクは、Windows OSと同じく、記憶装置上で同一の場所を占める複数のファイルを作る機能だ。Linux系のファイルシステムでは、inodeというデータ構造を使ってファイルを管理している。このinodeには重複しないinode番号が割り振られえいる。個々のファイルは、システムでユニークなinode番号を持つ。inode番号を指定することで、inodeを指定できるため、inode番号はファイルを区別するIDとしても利用できる。ハードリンクの場合、このinode番号が同じになる。
これに対してシンボリックリンクは、リンク先を記録した特殊なファイルとして実現している。実装方法はいろいろあり、過去には、必要な情報をテキストで入れた小さなファイルだったこともあるが、inodeを利用して高速化した実装もある。Linuxのシンボリックリンクも、デバイス(Windows OSでいうボリューム)をまたがってリンクを張ることができるし、必ずしもリンク先が存在している必要もない。
Linuxでリンクを扱うには、「ln(リンク)コマンド」を使う。このコマンドで、ハードリンクとシンボリックリンクの両方を作成できる。ただし、ディレクトリのハードリンクのみ作成に管理者権限が必要になる。また、ファイルのリストを表示する「lsコマンド」は、オプション「-l」と「-i」を使うことで、シンボリックリンクやハードリンク関連の情報を表示できる。
Linuxには、複数のファイルシステムがあるが、全てのファイルシステムは、VFSという仮想的なファイルシステムとしてカーネル内で扱われている。ファイルに関する全ての機能はVFSに対するファンクションコールとして実装されており、Linuxのリンクに関連するプログラムも全てVFSの上で動作している。このため、ファイルシステムが変わっても、リンクの表示や作成などは全て同じコマンドで同じように操作できる。
WSL2のNTFSリンク対応をテストする
ここでは、ビルド18990を使って、WSL 2のNTFSリンク対応について調べて見た。結果からいうとWSL 2は、以下の通りとなった。
- Windowsで作成したNTFS上の3種類のリンクを正しく扱える
- NTFS上にハードリンクを正しく作成できる(Win32側から正しくアクセスできる)
- 開発者用モードを有効にするとNTFS上に正しくシンボリックリンクを作成できる
具体的に動作を見ていこう。先に、Win32側で3種のリンクを作成しておく。
実際には、下画面のようなリンクを作成した。まずは、このフォルダをWSL 2側から開き、「ls -liコマンド」を実行する。これにより、ファイルの詳細とinode番号が表示される。結果の先頭にあるのがinode番号で、それ以降が“-l”オプションの出力である。この例で2つ目のフィールドの先頭が「l」になっているものがシンボリックリンクである。また、3つ目のフィールドの数値は、リンクカウントを示し、ハードリンクの存在を示す。
テスト用に作成したNTFSのリンク
WSL 2のNTFSリンク対応を調べるため、ハードリンクとソフトリンクを作成した。ソフトリンクでは、Cドライブ上のWSL 2からアクセス可能なリンクと、WSL 2からはアクセスできないDドライブ上のリンクを作った。また、シンボリックリンクは、ファイルとディレクトリへのリンクを用意した。
ハードリンクの例を見てみよう
まずは、ハードリンクを見てみよう。この例では、Win32側で「text.txt」というファイルを作り、そのハードリンクを「mklink /Hコマンド」で「Hardlink-text.txt」という名前で作成した。lsコマンドで見ると、「text.txt」と「Hardlink-text.txt」は、リンクカウントが「2」となっており、先頭にあるinode番号が同じだ。Linuxでは、ハードリンクは同じinode番号を持ち、ハードリンクの数に応じてリンクカウントが加算されていく。つまり、WSL 2はNTFSのハードリンクを正しく認識しているといえる。
WSL 2上でのNTFSハードリンクの扱い
WSL 2でNTFSハードリンクを扱う。「lsコマンド」は、「iオプション」で先頭にinode番号を表示する。このinode番号が同じファイルはハードリンクされたファイルになる。また、3つ目のフィールドは、ファイルのリンクカウント(ハードリンクが幾つあるか)を示す。
シンボリックリンクとジャンクションの例を見てみよう
NTFSのシンボリックリンクとジャンクションは、どちらもWSL 2では、シンボリックリンクとして表示される。リンクかどうかはパーミッション表示の先頭が「l」になっていることで分かる。
Copyright© Digital Advantage Corp. All Rights Reserved.