WSLではディストリビューション(環境)を簡単に削除・再作成できるが、削除時に作業中のデータも破棄されてしまう。 Dockerのデータボリュームコンテナのように、データを保持するためだけのディストリビューションを作成し、これをマウントすることで、データの永続化や共有が可能であることがわかった。

(普通はホストにファイルバックアップすると思いますけど)

注意

 これは WSL2 の(おそらく)明文化されていない挙動を利用した方法です。 いつかのタイミングで急に使えなくなるかもしれません。 「いやいや明文化されているよ~」っていうのを知ってる人がいれば @kunst1080 までどうかお知らせください🙏

検証環境

  • Microsoft Windows 10 Home
  • バージョン 10.0.19041 ビルド 19041
  • WSL 2

検証

作業用ディストリビューションの作成

 検証前の私のディストリビューションの一覧です。 既にいくつかのディストリビューションが存在しています。

1
2
3
4
5
6
PS D:\> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  Ubuntu                 Stopped         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2

ここに、作業用のディストリビューション(Ubuntu 18.04)を追加します。 ストアから入れてもいいのですが、なんとなくコマンドラインでやります。1

1
2
PS D:\> Invoke-WebRequest -Uri https://aka.ms/wsl-ubuntu-1804 -OutFile Ubuntu-1804.appx -UseBasicParsing
PS D:\> Add-AppxPackage .\Ubuntu-1804.appx

初回はWindowsのスタートメニューから起動する必要があるようです。 初回起動後、 wsl -l の一覧に登録されます。

1
2
3
4
5
6
7
PS D:\> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  Ubuntu                 Stopped         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
  Ubuntu-18.04           Stopped         2

“Ubuntu-18.04” が生えてきました。

データ用ディストリビューションの作成

 データ用のディストリビューションを登録します。 なるべく軽量にしたいので、ファイルが1つだけ入った tar ファイルをインポートしてみます。

 まず、Ubuntu-18.04 にログインし、tar ファイル work-data.tar を作成します。

1
2
3
4
5
6
PS D:\> wsl -d Ubuntu-18.04
testuser@MyComputer:/mnt/d$ touch this-is-work-data
testuser@MyComputer:/mnt/d$ tar cf work-data.tar this-is-work-data
testuser@MyComputer:/mnt/d$ ls -l work-data.tar
-rwxrwxrwx 1 testuser testuser 10240 Jun  6 23:20 work-data.tar
testuser@MyComputer:/mnt/d$ logout

次に wsl --import を使って work-data.tar をインポートします。ディストリビューションのインストール場所は D:\work-data にしておきます。

1
2
PS D:\> mkdir D:\work-data
PS D:\> wsl --import work-data D:\work-data .\work-data.tar

インストール場所に vhdx が作成されたようです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PS D:\> dir D:\work-data\


    ディレクトリ: D:\work-data


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2020/06/06     23:27       32505856 ext4.vhdx

ディストリビューション “work-data” も一覧に追加されていました。

1
2
3
4
5
6
7
8
PS D:\> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  Ubuntu                 Stopped         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
  Ubuntu-18.04           Stopped         2
  work-data              Stopped         2

データ用ディストリビューションのマウント

 Ubuntu-18.04 にログインし、 /dev/sd* を確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PS D:\> wsl -d Ubuntu-18.04
testuser@MyComputer:/mnt/d$ cd
testuser@MyComputer:~$ ls -l /dev/sd*
brw------- 1 root root 8,  0 Jun  1 21:53 /dev/sda
brw------- 1 root root 8, 16 Jun  1 21:53 /dev/sdb
brw------- 1 root root 8, 32 Jun  6 22:46 /dev/sdc
brw------- 1 root root 8, 48 Jun  6 22:48 /dev/sdd
brw------- 1 root root 8, 64 Jun  6 22:53 /dev/sde
brw------- 1 root root 8, 80 Jun  6 22:53 /dev/sdf
brw------- 1 root root 8, 96 Jun  6 23:27 /dev/sdg

適当なマウントポイントを作成し、 /dev/sdg 2をマウントします。 ext4 としてマウントされました。

1
2
3
4
5
6
7
8
testuser@MyComputer:~$ mkdir ~/work
testuser@MyComputer:~$ sudo mount /dev/sdg ~/work
testuser@MyComputer:~$ mount | grep /dev/sdg
/dev/sdg on /home/testuser/work type ext4 (rw,relatime)
testuser@MyComputer:~$ ls -l ~/work
total 16
drwx------ 2 root     root     16384 Apr 11  2019 lost+found
-rwxrwxrwx 1 testuser testuser     0 Jun  6 23:19 this-is-work-data

work-data.tar に入れていた this-is-work-data ファイルがありますね。 ここへ適当にファイルを追加しておきます。

1
2
3
4
5
6
7
testuser@MyComputer:~$ sudo mkdir ~/work/data
testuser@MyComputer:~$ sudo chown testuser. ~/work/data
testuser@MyComputer:~$ echo hoge > ~/work/data/new-file
testuser@MyComputer:~$ ls -l ~/work/data/
total 4
-rw-r--r-- 1 testuser testuser 5 Jun  6 23:42 new-file
testuser@MyComputer:~$ logout

作業用ディストリビューションの破棄と再作成

 作業用のディストリビューション(Ubuntu 18.04)を破棄します。

1
2
3
4
5
6
7
8
9
PS D:\> wsl --unregister Ubuntu-18.04
登録を解除しています...
PS D:\> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  Ubuntu                 Stopped         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
  work-data              Stopped         2

「作業用ディストリビューションの作成」の項目と同様に Ubuntu 18.04 を再度インストールします。

1
PS D:\> Add-AppxPackage .\Ubuntu-1804.appx

一覧の真ん中のあたりに追加されました。

1
2
3
4
5
6
7
8
PS D:\> wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         2
  Ubuntu                 Stopped         2
  Ubuntu-18.04           Running         2
  docker-desktop-data    Running         2
  docker-desktop         Running         2
  work-data              Stopped         2

データ用ディストリビューションの再マウント

 Ubuntu-18.04 にもう一度ログインし、 /dev/sd* を確認します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PS D:\> wsl -d Ubuntu-18.04
newuser@MyComputer:/mnt/d$ cd
newuser@MyComputer:~$ ls -l /dev/sd*
brw------- 1 root root 8,  0 Jun  1 21:53 /dev/sda
brw------- 1 root root 8, 16 Jun  1 21:53 /dev/sdb
brw------- 1 root root 8, 32 Jun  6 22:46 /dev/sdc
brw------- 1 root root 8, 48 Jun  6 23:47 /dev/sdd
brw------- 1 root root 8, 64 Jun  6 22:53 /dev/sde
brw------- 1 root root 8, 80 Jun  6 22:53 /dev/sdf
brw------- 1 root root 8, 96 Jun  6 23:27 /dev/sdg

適当なマウントポイントを作成し、 /dev/sdg をマウントして内容を確認します。

1
2
3
4
5
6
7
newuser@MyComputer:~$ mkdir ~/work
newuser@MyComputer:~$ sudo mount /dev/sdg ~/work
newuser@MyComputer:~$ ls -l ~/work
total 20
drwxr-xr-x 2 newuser newuser  4096 Jun  6 23:42 data
drwx------ 2 root    root    16384 Apr 11  2019 lost+found
-rwxrwxrwx 1 newuser newuser     0 Jun  6 23:19 this-is-work-data

当たり前ですが、前回マウントしたものと同じものにアクセスできました。

 Ubuntu-18.04 を起動したままの状態で、別のディストリビューション(Ubuntu-20.04)からもマウントしてみます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
PS D:\> wsl -d Ubuntu-20.04 bash
kunst@MyComputer:/mnt/d$ cd
kunst@MyComputer:~$ ls -l /dev/sd*
brw------- 1 root root 8,  0 Jun  1 21:53 /dev/sda
brw------- 1 root root 8, 16 Jun  1 21:53 /dev/sdb
brw------- 1 root root 8, 32 Jun  6 22:46 /dev/sdc
brw------- 1 root root 8, 48 Jun  6 23:47 /dev/sdd
brw------- 1 root root 8, 64 Jun  6 22:53 /dev/sde
brw------- 1 root root 8, 80 Jun  6 22:53 /dev/sdf
brw------- 1 root root 8, 96 Jun  6 23:27 /dev/sdg
kunst@MyComputer:~$ mkdir test-data
kunst@MyComputer:~$ sudo mount /dev/sdg ~/test-data
kunst@MyComputer:~$ ls -l ~/test-data/
total 20
drwxr-xr-x 2 kunst kunst  4096 Jun  6 23:42 data
drwx------ 2 root  root  16384 Apr 11  2019 lost+found
-rwxrwxrwx 1 kunst kunst     0 Jun  6 23:19 this-is-work-data

こちら(Ubuntu-20.04)からファイルを足します。

1
2
3
4
5
kunst@MyComputer:~$ echo hogehoge > ~/test-data/data/new-file2
kunst@MyComputer:~$ ls -l ~/test-data/data/
total 8
-rw-r--r-- 1 kunst kunst 5 Jun  6 23:42 new-file
-rw-r--r-- 1 kunst kunst 9 Jun  6 23:59 new-file2

追加したファイルは Ubuntu-18.04 からも見えました。

1
2
3
4
newuser@MyComputer:~$ ls -l work/data/
total 8
-rw-r--r-- 1 newuser newuser 5 Jun  6 23:42 new-file
-rw-r--r-- 1 newuser newuser 9 Jun  6 23:59 new-file2

検証のまとめ

 データを保持するためだけの空ディストリビューションを作成し、複数のディストリビューションからマウントし共有することができました。

ベンチマーク

 ディスクアクセスの速度を dd コマンドを使って雑に計測してみました。(書き込みのみ)

 データ用ディストリビューションへのアクセスも、ローカルアクセスと同じ性能と言えそうです。 ホストへアクセスするするよりは明らかに早いです。

ディストリビューション内でのファイルアクセス速度

1
2
3
4
5
6
7
8
newuser@MyComputer:~$ time dd if=/dev/zero of=~/bench ibs=1M obs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.0565 s, 1.0 GB/s

real    0m1.150s
user    0m0.052s
sys     0m1.040s

データ用ディストリビューション内のファイルへのアクセス速度

1
2
3
4
5
6
7
8
newuser@MyComputer:~$ time dd if=/dev/zero of=~/work/data/bench ibs=1M obs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.11631 s, 962 MB/s

real    0m1.206s
user    0m0.041s
sys     0m1.129s

ホストファイルへのアクセス速度

1
2
3
4
5
6
7
8
newuser@MyComputer:~$ time dd if=/dev/zero of=/mnt/d/bench ibs=1M obs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.69681 s, 290 MB/s

real    0m3.700s
user    0m0.121s
sys     0m0.570s

補足

思いついたきっかけ

 これを思いついたきっかけは2つあって、

  • Docker Desktop for Windows をバックエンドを WSL にしてセットアップすると、“docker-desktop"と"docker-desktop-data"が作成され、Ubuntu内にそれっぽいマウントポイントが生えてきた
  • たまたま /dev/sd* をマウントしてみたら他のディストリビューションのルートディレクトリが見えた

この辺の挙動から連想した感じです。

ディスクの拡張方法

 これで拡張できるらしい。(未確認) → WSL 2 仮想ハードウェア ディスクのサイズの拡張

 そしてこの資料から、ディストリビューションのファイルシステムが /dev/sd* であることが読み取れる。(この仕様に関しては)ちゃんとドキュメントに表れている――


  1. 参考: Linux 用 Windows サブシステム ディストリビューション パッケージを手動でダウンロードする ↩︎

  2. 実際は /dev/sd* をひとつずつマウントして正解を探しました ↩︎