故障原因推測
這個狀況出現不少次,但只出現在一台電腦上,而且是在我執行這兩種動作時:
- 啟動 VScode 連線到 WSL 環境 (IDE 初始化時會掃描程式碼)
- 使用 NPM build assets
這兩個動作的共同點在於執行時會有大量的 I/O 動作,最後造成 WSL 檔案系統進入唯讀狀態
|
|
但是這種狀況沒有發生在其他設備上,而跟其他設備的儲存體不同的是,只有這台的 SSD 是 QLC + Dramless 的組合。
個人感覺問題是出在這邊,打算要把這條 SSD 換掉再觀察看看,無奈還有東西需要跑在上面,所以才有了這篇。
修復方式
由於 WSL 2 是使用 VHD (虛擬硬碟) 檔案,不同於 VM 的部分,VM 啟動時可以選擇進入修復模式執行 e2fsck 就完事,但是 WSL 無法這樣做,而 e2fsck 無法對已掛載 / 使用中的磁區進行修復。
爬了一下文,也測試過幾種方法,只有將 VHD 掛到其他 WSL 進行修復這個方式才有效。
Step 1: 安裝修復用的 WSL Distro
目前故障的 WSL distro 是 Ubuntu,由於只是要執行 e2fsck,因此只需要有基本功能的 distro 即可,這邊推薦輕量好用的 Alpine Linux。
至 Alpine Linux 的 MS Store 頁面進行安裝,照著畫面導引完成即可。
Step 2: 確認故障的 WSL Distro 使用的 VHD 代號
WSL 所有執行個體彼此互相看的到各自的虛擬硬碟,也可以互相掛載,在任意 WSL 執行 blkid 就可以看到了:
|
|
這一步,要確認故障的 WSL distro 是使用哪一個 VHD,在故障的 WSL distro 內執行指令: mount | grep ext4
|
|
這邊得知故障的 WSL distro 使用的是 /dev/sdb。
Step 3: 停止故障的 WSL Distro 執行個體,並執行修復
這邊要注意的是,因為 Windows 的 LXSS Manager service 會把預設的 WSL Distro 掛到 Windows 檔案總管,而本篇故障的 WSL Distro 為預設值,所以將 WSL 執行個體停止後,LXSS 會馬上重新啟動 WSL Distro。
不過在啟動前會有幾秒的等待時間,只要搶在 LXSS 把 WSL 啟動前執行 e2fsck 即可。
首先,先在 Alpine 內切換為 root:
|
|
然後先把這個指令打好,先不要按下執行:
|
|
接著以系統管理員權限開啟 CMD 或 PowerShell,執行 wsl -l -v,確認 WSL Distro 的名稱,然後使用 wsl -t 名稱 停止執行個體。
|
|
接著馬上在 Alpine 內送出剛剛打好的指令,就會開始修復。
如果速度不夠快的話就會出現裝置使用中,停止修復的錯誤:
|
|
這種情況,就再次停止 WSL 執行個體並馬上執行 e2fsck 即可,手速要快一點,多試幾次一定可以成功。
Step 4: 確認修復結果
啟動修復後的 WSL distro,確認一下受損狀況。
會使檔案系統進入 read-only 狀態的觸發條件大多數情況如同實體儲存體,與磁區錯誤有關,有可能在修復後會發現某些東西還是壞的。
我自己有檢查到的情況只有 ~/.zsh_history 有部分的錯誤,裡面有一行紀錄是亂碼,刪掉就可以了,算是滿幸運。
如果是重要的東西,平日請勤做備份。
References