やること
- 実データ量に近いサイズまで安全に縮小する
- WSL2 の
ext4.vhdxが肥大化する問題への対処
- Linux 側で「不要ブロック」を通知(fstrim)
- Windows 側で「物理サイズを詰める」(compact)
前提条件
対象環境
- Windows 11 Home
- 別にproでも問題無いかも
- WSL2
- Linux kernel 5.15 以降(推奨:6.x)
- ファイルシステム:ext4
- Hyper-V 管理ツールなし(Home 想定)
-
Optimize-VHDを使えない環境
-
必須条件
- WSL 内で不要なファイルを消しとく
- WSL 内 root ファイルシステムが
discard対応であること
確認コマンド:
uname -a
mount | grep " / "
期待される例:
Linux ... microsoft-standard-WSL2
/dev/sdX on / type ext4 (rw,relatime,discard,...)
※ discard が無い場合は fstrim の効果が限定的、というかほぼ意味ないかも
※ 恐らく、ddコマンドとかで、(Windows側から見えるvhdxの容量 - WSL内の実容量)分ゼロ埋めしてあげればdiskpart効くんじゃないかな
実施手順
Step 1. WSL 内で trim 実行
sudo fstrim -av
出力例:
/: 976.6 GiB trimmed on /dev/sdd
※ WSLデフォルトのディスクサイズが1TB(確か)なので、今回対象にした実体30GBぐらいのディストロだとこんな感じのトリム結果になる
Step 2. WSL を完全停止(必須)
Windows 側 PowerShell:
wsl --shutdown
Step 3. diskpart で vhdx を compact
vhdxファイルのPath確認
WSLに入っている全てのディストリを対象に、ディストリ名・vhdxパス・vhdxパスの存在チェック結果を出力するPowerShellスクリプト
Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss |
ForEach-Object {
$distro = Get-ItemProperty $_.PSPath
$vhdxPath = Join-Path $distro.BasePath "ext4.vhdx"
[PSCustomObject]@{
Name = $distro.DistributionName
VhdxPath = $vhdxPath
Exists = Test-Path $vhdxPath
}
} | Format-List
※ MS公式のパス確認方法
<distribution-name>をwsl -l -vで出てくるディストロ名に変更する。
(Get-ChildItem -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | Where-Object { $_.GetValue("DistributionName") -eq '<distribution-name>' }).GetValue("BasePath") + "\ext4.vhdx"
diskpartで圧縮
powershellなどで実施
diskpart
diskpartで、以下を順に実行
<distribution-path>を先ほど取得したパスに変更
select vdisk file="<distribution-path>"
attach vdisk readonly
compact vdisk
detach vdisk
exit
Tips
.wslconfigに容量制限の設定を入れとくと良い (今後のディストロの初回インストール時のみ効くようになるけど...)
WSLディストロのディスクサイズを 50GB に設定する例
[wsl2]
defaultVhdSize=52428800000