WSL2上のLinuxマシンへホスト上の物理ディスクをマウントしよう(永続化もあるよ)

# 自己紹介
**社長！12月ですぞー！**

AdventCalenderでは休日ですが
ノウハウができたので記事書いてる m10i と申します。

普段はサイバーセキュリティ関係をしてますが、
過去はネットワーク(バックボーン設計・構築・運用)とか
それに関わるLinuxサーバ(構築・運用)とかとか
してました。

今日は自宅のWSL2(以後、WSL)にまつわるお話です

ではやっていきましょう💪

# WSLで物理ディスクをマウントするメリット
下記のようなメリットがあります
- (WSLの)ルートディレクトリ容量を超える大容量・高速ディスクが利用可能
- WSLのvhdxファイル肥大化を抑えられる

やり方なのですがMicrosoftの公式ドキュメントにあります
`wsl.exe --mount ` コマンドで行けるとなってます
https://learn.microsoft.com/ja-jp/windows/wsl/wsl2-mount-disk

> ⚠ 注意
> WSL 2 にディスクをアタッチするには、管理者アクセス権が必要です。
> wsl --mount を使用すると、パーティションのみが要求された場合でも、常にディスク全体がアタッチされます。 Windows インストール ディスクをマウントすることはできません。

# まずはマウントする物理ディスクを用意しよう
手元にあったSSD(128GB)を用意して**SATA接続**しました
なお、USB接続の場合は手順が異なるため今回は説明しません
https://learn.microsoft.com/ja-jp/windows/wsl/connect-usb

では`wsl --mount`で引き渡すディスクパスを確認しましょう
なお、ややこしいことに私の環境では全く同じ機種のSSDが2個ついてます
```powershell
PS> GET-CimInstance -query "SELECT * from Win32_DiskDrive" | Sort-Object DeviceID

DeviceID           Caption               Partitions Size          Model
--------           -------               ---------- ----          -----
\\.\PHYSICALDRIVE0 TOSHIBA THNSNH128GCST 1          128034708480  TOSHIBA THNSNH128GCST
\\.\PHYSICALDRIVE1 TOSHIBA THNSNH128GCST 1          128034708480  TOSHIBA THNSNH128GCST
\\.\PHYSICALDRIVE2 WDS100T1X0E-00AFY0    3          1000202273280 WDS100T1X0E-00AFY0
```

「どれが新設SSDか分からねぇ～～🤔」となったので
「タスクマネージャー」の「パフォーマンス」を見ると
ディスク 0, 1, 2 と番号が割り振られており
Windowsにマウントされていない **\\.\PHYSICALDRIVE0** が今回新設したSSDと分かりました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15104/09bacf8a-15b8-ce56-2868-71a9d60fb4b3.png)

# WSL上から`wsl.exe --mount`しよう
では試しに新設されたSSDをマウントしてみましょう

ポイントですが
- WSLでinterop enabled=trueにてWindows EXEを実行可能なこと
- WSL→Windowsで管理者権限になるため、Windows sudoを有効化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15104/4f2b3e9e-aba5-01e6-225d-81abae7d41d6.png)
- Windows sudoを使うためPowserShellのファイルパスを確認しておく
私の環境ではPowerShell7をインストールしてますので、`/mnt/c/Program\ Files/PowerShell/7/pwsh.exe` で実行しております
- バックスラッシュでPHYSICALDRIVEしていするので、必ずシングルクォーテーションで囲む

そしてWSL上で確認しつつマウントした結果です
```bash
$ # Before
$ lsblk
NAME MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda    8:0    0 388.4M  1 disk
sdb    8:16   0     1T  0 disk /mnt/wslg/distro

$ /mnt/c/Program\ Files/PowerShell/7/pwsh.exe \
-Command 'sudo wsl.exe --mount \\.\PHYSICALDRIVE0'
# Windows上でUAC許可

$ # After
$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 388.4M  1 disk
sdb      8:16   0     1T  0 disk /mnt/wslg/distro
                                 /
sdc      8:32   0 119.2G  0 disk  # WSLにマウントされた！
└─sdc1   8:33   0 119.2G  0 part
```

無事にsdcが生えてますね！
あとは sdc1をお好みのフォーマット形式にして、WSLのディレクトリ内でマウントすれば利用可能になります

ただ、このままだと端末を再起動してしまうとマウントが外れた状態となるため、
永続化する設定をします

# 永続化設定
マウントするUUID(What)やマウント先ディレクトリ(Where)は環境に合わせてください

```bash
# pwsh.exe -> sudo付 wsl.exe でmount
$ cat << '_EOL_' | sudo tee /etc/systemd/system/mount-ls.service
[Unit]
Description=mount local storage
After=local-fs.target

[Service]
User=root
ExecStart=bash -c "/mnt/c/Program\\ Files/PowerShell/7/pwsh.exe -Command 'sudo wsl.exe --mount \\\\.\\PHYSICALDRIVE0 --bare'"
Restart=no
Type=simple

[Install]
WantedBy=multi-user.target
_EOL_

# /opt に mountするための設定
$ cat << '_EOL_' | sudo tee /etc/systemd/system/opt.mount
[Unit]
Description=mount local storage to WSL /opt
After=mount-ls.service

[Mount]
What=/dev/disk/by-uuid/43714464-7a35-4d5b-8357-746295b2afbd
Where=/opt
Type=ext4
Options=defaults,noatime,discard

[Install]
WantedBy=multi-user.target
_EOL_

# service,mountファイルをロード
$ sudo systemctl daemon-reload

# 有効化
$ sudo systemctl enable mount-ls.service
$ sudo systemctl enable opt.mount
```

この後、`wsl --shutodwn` でWSLを停止させたとしても
次回以降のWSL起動時にマウントされます

これで大変ファイル操作が楽になりました

# お知らせ
こちらの記事はctc Advent Calendar 2024の記事となります
この後もctc(中部テレコミュニケーション株式会社)のメンバーが技術にまつわる知見を投稿していきますのでご期待ください

https://qiita.com/advent-calendar/2024/ctc