Featured image of post 如何修復 WSL 錯誤: read-only file system

如何修復 WSL 錯誤: read-only file system

故障原因推測

這個狀況出現不少次,但只出現在一台電腦上,而且是在我執行這兩種動作時:

  1. 啟動 VScode 連線到 WSL 環境 (IDE 初始化時會掃描程式碼)
  2. 使用 NPM build assets

這兩個動作的共同點在於執行時會有大量的 I/O 動作,最後造成 WSL 檔案系統進入唯讀狀態

1
Error: read-only file system

但是這種狀況沒有發生在其他設備上,而跟其他設備的儲存體不同的是,只有這台的 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 就可以看到了:

1
2
3
4
5
/dev/sdd: UUID="4825c63e-64b4-4bdf-a2d2-5810d052c462" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sdb: UUID="f3dfd593-63b2-45c3-a96c-83cda120004b" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sde: UUID="c4eb02d2-9723-4437-af08-ba92cd8b6385" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sdc: UUID="44199e16-30c9-411c-b823-370b1e33107e" BLOCK_SIZE="4096" TYPE="ext4"
/dev/sda: BLOCK_SIZE="4096" TYPE="ext4"

這一步,要確認故障的 WSL distro 是使用哪一個 VHD,在故障的 WSL distro 內執行指令: mount | grep ext4

1
2
3
mount | grep ext4
/dev/sdb on / type ext4 (rw,relatime,discard,errors=remount-ro,data=ordered)
/dev/sdb on /snap type ext4 (rw,relatime,discard,errors=remount-ro,data=ordered)

這邊得知故障的 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:

1
su

然後先把這個指令打好,先不要按下執行:

1
e2fsck -y /dev/sdb

接著以系統管理員權限開啟 CMD 或 PowerShell,執行 wsl -l -v,確認 WSL Distro 的名稱,然後使用 wsl -t 名稱 停止執行個體。

1
2
3
4
5
6
7
8
9
C:\Users\calos>wsl -l -v
  NAME                   STATE           VERSION
* Ubuntu                 Running         2
  docker-desktop-data    Stopped         2
  Alpine                 Running         2
  docker-desktop         Stopped         2

C:\Users\calos>wsl -t Ubuntu
操作順利完成。

接著馬上在 Alpine 內送出剛剛打好的指令,就會開始修復。

如果速度不夠快的話就會出現裝置使用中,停止修復的錯誤:

1
2
3
e2fsck 1.46.6 (1-Feb-2023)
/dev/sdb is in use.
e2fsck: Cannot continue, aborting.

這種情況,就再次停止 WSL 執行個體並馬上執行 e2fsck 即可,手速要快一點,多試幾次一定可以成功。

Step 4: 確認修復結果

啟動修復後的 WSL distro,確認一下受損狀況。

會使檔案系統進入 read-only 狀態的觸發條件大多數情況如同實體儲存體,與磁區錯誤有關,有可能在修復後會發現某些東西還是壞的。

我自己有檢查到的情況只有 ~/.zsh_history 有部分的錯誤,裡面有一行紀錄是亂碼,刪掉就可以了,算是滿幸運。

如果是重要的東西,平日請勤做備份。


References

comments powered by Disqus