Uniforceのインフラ担当のニシです。

この記事を書いている頃は、グラノーラのいちごづくしにハマっています(甘い飲み物、食べ物、好き🤤)。

今回はWSL2の仮想ディスクのファイルサイズを減らすことに挑戦したときのお話です。

きっかけ

ある日、普段通りに作業をしていると “ディスク容量がいっぱいです” との通知がデスクトップ上に表示されました。

エクスプローラーからドライブのディスク容量を確認してみると、1TBディスクの空き容量が14.6GBまで減っていました。

直近で大きなファイルをダウンロードしたり、アプリケーションをインストールしたりした記憶はなかったので不思議に思いましたが、ストレージの利用状況を確認してみるとインストールしているアプリケーションが大幅にディスク容量を圧迫していることがわかりました。

さらにインストールされているアプリケーションを見ていくと、”Ubuntu 22.04.5 LTS(=WSL2)” が852GBも使用していることが確認できましたので、こちらの容量の削減に挑戦してみることにしました。

解決 (WSL2の仮想ディスクのファイルサイズを削減)

インストールしている ”Ubuntu 22.04.5 LTS(=WSL2)” によりディスク容量が圧迫されていることがわかりましたので、不要なファイルなどを削除してみたのですが、ディスク容量は変わりませんでした。

調べてみると、WSL2内のファイルを削除したとしてもホストOSからすると、ディスク領域が解放されることはないようです。

https://github.com/microsoft/WSL/issues/4699

上記、Issuesにディスク領域を解放するための方法がいくつか書かれています。

1つはOptimize-VHDを使う方法ですが、こちらはコマンドがある場合とない場合があるようです。私の使用しているPCにはコマンドが存在しなかったため、Optimize-VHDによる解決はできませんでした。

他にはexperimental implementation(実験的な機能) であるsparseVhd設定を有効にする方法があるようですが、ゲストおよびホストのファイルシステムを破損する可能性があるようで使用するの現実的ではありません。

https://github.com/microsoft/WSL/issues/4699#issuecomment-2527186463

Also, current experimental implementation of sparse vhd works (shrinks disk), but may damage guest and host(!) filesystem data on SSDs. There's already GitHub issue on that. #10609

ということで、Issuesのコメントにあった方法の中で今回はdiskpartを使用した仮想ディスクの最適化を行ってみることにしました。

https://github.com/microsoft/WSL/issues/4699#issuecomment-627133168

wsl --shutdown diskpart

open window Diskpart

select vdisk file="C:\WSL-Distros\…\ext4.vhdx" attach vdisk readonly compact vdisk detach vdisk exit

書かれていた手順に則って作業してみます。まずは、WSLの停止からです。

> wsl --shutdown
(何も表示されません)

diskpartコマンドを実行します。DiskPartを実行して良いかのダイアログが出てくるので許可をすると、DiskPart専用のウィンドウが立ち上がります。

> diskpart

次にDiskPartで仮想ディスクのファイルパスを指定することになるのですが、WSLの仮想ディスクのファイルパスはインストール方法によって異なるのでMicrosoftのドキュメントを参考に仮想ディスクのパスを見つけてみます。

https://learn.microsoft.com/ja-jp/windows/wsl/disk-space#how-to-locate-the-vhdx-file-and-disk-path-for-your-linux-distribution

(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq '<distribution-name>' }).GetValue("BasePath") + "\ext4.vhdx"

<distribution-name>が必要になるので、WSLコマンドで名前を確認します。

>wsl -l -v
NAME STATE VERSION
* Ubuntu-22.04 Stopped 2

“Ubuntu-22.04” であることがわかったので、Microsoftドキュメントにある方法でファイルパスを検索します。

> (Get-ChildItem -Path HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Lxss | Where-Object { $_.GetValue("DistributionName") -eq 'Ubuntu-22.04' }).GetValue("BasePath") + "\\ext4.vhdx"
C:\\Users\\User\\AppData\\Local\\Packages\\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\\LocalState\\ext4.vhdx

“C:\Users\User\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\LocalState\ext4.vhdx” にWSLの仮想ディスクのファイルを見つけることができました。

それでは、仮想ディスクの最適化から完了まで一気にやっていきます。

DISKPART> select vdisk file="C:\\Users\\User\\AppData\\Local\\Packages\\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\\LocalState\\ext4.vhdx"

DiskPart により、仮想ディスク ファイルが選択されました。

DISKPART> attach vdisk readonly

100% 完了しました

DiskPart により、仮想ディスク ファイルがアタッチされました。

DISKPART> compact vdisk

100% 完了しました

DiskPart により、仮想ディスク ファイルは正常に圧縮されました。

DISKPART> detach vdisk

DiskPart により、仮想ディスク ファイルがデタッチされました。

DISKPART> exit

ファイルサイズが大きかったこともあり、compact vdiskの実行に30分ほどかかった気がします。

それでは、あらためてディスク容量を ”デバイスとドライブ” および ”インストールされているアプリケーション” から確認してみます。

852GBあったファイルサイズは254GBまで減らすことができました!👍

まとめ

WSL2の仮想ディスクのファイルサイズを削減してみたお話でした。

今回はDiskPartを使用してWSL2の仮想ディスクのファイルサイズを最適化することにより、ディスク容量の空きスペースを増やすことができました。

本記事に記載したIssuesは2019年11月20日から開いていることもあり、この問題はしばらく解決しないのだろうなと思っています。しかし、Issuesのコメントを追っていくと、.wslconfigに defaultVhdSizeを設定することで仮想ディスクのファイルサイズを制限することができるとの記載があります。

https://github.com/microsoft/WSL/issues/4699#issuecomment-2304879165

I figured out that you can restrict the size of a VHDX using defaultVhdSize parameter in .wslconfig :

ただ、defaultVhdSizeの効果が有効になるのはWSLを最初に作成したタイミングのみようです。そのため、今回の事象が頻発するようであれば.wslconfigにdefaultVhdSizeを設定して試して環境を再作成してみようと思います。

(WSLを使い始める前に知っておきたかった情報だったなぁ、という気持ちです…)

本日の記事はここまでとなります。

最後まで読んでいただきありがとうございました🙌