這個實作的緣分來自某天遠端ssh連到樹莓派中做例行性的更新時,出現30: Read-only file system檔案系統唯讀的畫面,根據以往的經驗,若重開機,大概率需要手動執行fsck /dev/mmcblk0p2進行修復作業,若運氣不好,即使完成fsck並重新開機後,也無法順利進到Ubuntu desktop作業系統。經與Gemini討論後,大致流程如下,同時一併了解fsck的工作機制。
- 趁尚可在終端命令列操作時,利用dd(Data Duplicator)將樹莓派的映像檔以網路備份到TrueNAS。
- 完成備份後,讓樹莓派重新開機並執行fsck /dev/mmcblk0p2,看是否能順利進到Ubuntu desktop作業系統
- 若無法進到作業系統,將該SD卡重新燒錄一個乾淨的作業系統,再利用NFS(Net File System)、debugfs和rdump到已備份在TrueNAS中的映像檔撈資料。
fsck(File System Consistency Check)是什麼
在樹莓派的Linux作業系統中,路徑 /dev/mmcblk0 代表整張SD卡,而 /dev/mmcblk0p2 則是儲存Ubuntu作業系統主要核心資料、個人帳號家目錄(Home Directory)及應用程式的第二個分區(通常為 ext4 檔案系統)。當 ext4 檔案系統的元資料(Metadata)、超級區塊(Superblock)或目錄樹結構(Directory Tree)發生不一致時,Linux 核心(Kernel)為了保護剩餘資料不被進一步損壞,會啟動保護機制,強制將掛載的根檔案系統由可讀寫(Read-Write)狀態切換為唯讀(Read-Only)狀態。當系統在開機檢查中便無法將其正常掛載,即呼叫fsck(File System Consistency Check)工具。
而fsck的核心任務是維持檔案系統結構的一致性和完整性,確保作業系統底層看得懂這個磁區,但其不保證實體檔案資料內容的正確性。因此透過手動執行 sudo fsck /dev/mmcblk0p2 ,其工作過程包含掃描該分區的inode節點、修復錯誤的孤立節點(Orphaned Inodes)、更正區塊點陣圖(Block Bitmaps)的不一致,並強制清理已損壞的日誌。修復過程中,若發現某個關鍵系統檔案(如 Xorg 顯示伺服器元件、GDM3 桌面管理器組態、或是 libc 核心動態連結庫)所在的區塊已損壞,其會為了讓檔案系統順利掛載,粗暴地將這些不完整的檔案刪除或移至恰當路徑,檔案系統雖然在結構上呈現一致性,但可能導致作業系統的重要系統組件發生缺損,而當引導程序在呼叫桌面作業系統時,會因為找不到對應的相依性二進位檔案,而無法順利進入桌面作業系統。
當SD卡在唯讀狀態下,如何將映像檔備份到TrueNAS
然而,須注意的是當樹莓派系統檔案損壞呈現唯讀狀態時,任何要寫入SD卡的操作都會遭到拒絕。很不巧的是這張SD卡連線過與目前TrueNAS相同IP address的其他主機,需要將舊的公鑰刪除,明顯是遭拒的寫入動作,如同下圖。Gemini提及tmpfs(Temporary File System)方案,簡單說就是利用記憶體仍是可讀寫的狀態,將需要存取的設定參數暫放在記憶體中,繞過SD卡的唯讀限制,相當巧妙也容易理解。(OS: 跟AI討論解決方案時,這種腦力激盪下的啊哈時刻,最讓人為之振奮~~)
樹莓派端設定:
a.利用下列指令在記憶體中,掛載一個10MB的記憶體虛擬硬碟。
sudo mount -t tmpfs -o size=10M tmpfs /mnt
b.為了避免因密碼認證逾時或頻繁跳出輸入提示,而導致備份中斷,直接使用ssh認證金鑰方式,並將產生的私鑰與公鑰儲存在路徑 /mnt/id_ed25519。
ssh-keygen -t ed25519 -N "" -f /mnt/id_ed25519
c.利用下列指令將公鑰(類似ssh-ed25519 AA)印出,並複製該公鑰內容並註冊至TrueNAS中
cat /mnt/id_ed25519.pub
TrueNAS端設定
a.進到Credentials -> Users,選擇你要ssh連線到TrueNAS的帳號。
b.點選Edit,並將上述公鑰複製到Public SSH Key的欄位中,同時須注意要開啟SSH Access訪問權限和關閉Allow SSH login with Password選項,並點擊Save,如下圖。
執行下列指令,進行樹莓派備份到TureNAS的作業
sudo dd if=/dev/mmcblk0 bs=4M status=progress | ssh -i /mnt/id_ed25519 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no you_truenas_account@you_truenas_ip "sudo dd of=/mnt/main_pool/ubuntu_22.04_desktop_rpi4_backup/raspberrypi_backup.img bs=4M"
幾個重要指令段說明
-o UserKnownHostsFile=/dev/null : 將已確認的TrueNAS主機名單暫時指向 Linux 的/dev/null路徑。由於樹莓派此時實體磁碟唯讀,當 SSH 首次連線想要將 TrueNAS 的主機特徵碼寫入實體硬碟的 ~/.ssh/known_hosts 時會因為唯讀而報錯卡死。將其扔進垃圾桶可以強制讓此記錄只留在記憶體中,繞過磁碟寫入限制。
-o StrictHostKeyChecking=no : 關閉樹莓派金鑰檢查,自動跳過第一次連線到TrueNAS主機時彈出的 Are you sure you want to continue connecting (yes/no)? 互動提問,防止管線自動化腳本陷入停滯。
利用NFS為樹莓派掛載TrueNAS的映像檔
當完成備份後,索性就直接將SD卡重新燒錄Ubuntu 24.04 desktop LTS,一併升級到新版作業系統。接著,利用NFS讓已備份在TrueNAS的raspberrypi_backupup.img作為樹莓派的網路硬碟,以接續稍後的資料撈取作業。配置NFS的工作同樣分為TrueNAS端和樹莓派端,步驟如下。
TrueNAS端設定:
a. 進到Shares,並點擊UNIX(NFS) Shares右上角的Add。
b. 在Path欄位,選定上述備份映像檔的路徑 /mnt/main_pool/ubuntu_22.04_desktop_rpi4_backup,並記得勾選Enable和點擊Save,如下兩圖。
樹莓派端設定:
a. 安裝NFS用戶端套件
sudo apt update
sudo apt install nfs-common -y
b. 建立一個樹莓派端的臨時網路掛載點
c. 將TureNAS中的資料集路徑掛載到樹莓派上
sudo mount -t nfs your_TrueNAS_ip_address:/mnt/main_pool/ubuntu_22.04_desktop_rpi4_backup /mnt/truenas_net
d. 檢查是否可在樹莓派中看到掛載進來的映像檔(raspberrypi_backup.img),如下圖所示。
ls /mnt/truenas_net/
利用losetup(Loop Device Setup)將映像檔掛載為虛擬硬碟
雖然已可在樹莓派的路徑看到映像檔,但現階段屬於看得到卻無法讀取的狀態,原因是其目前屬於一個多個磁碟分區的單一區塊檔案(Block),因此需要透過losetup將其掛載成虛擬硬碟才能被讀取或修改。另外,Ubuntu Desktop 系統在開機時,後台的一些服務(snapd 軟體包管理器或系統的虛擬記憶體機制)會自動佔用了 /dev/loop0 到 /dev/loop7 等前幾個預設的虛擬插槽,所以避免猜測和插槽衝突,可直接利用下列指令使其自動分配並取得分配後的結果,執行自動分配的前後的差異如下圖,紅色框處為映像檔被掛載在/dev/loop7。
sudo losetup -Pf /mnt/truenas_net/raspberrypi_backup.img
losetup -a
其中Gemini提供P和f參數說明如下:
- f:代表 Find First Unused,這行命令是告訴 Ubuntu:「請自動幫我去底層翻箱倒櫃,尋找一個目前完全空白、沒有被任何 Snapd 或系統程式佔用的虛擬插槽(可能是 loop8, loop16 等),並把映像檔掛載上去。」這能徹底根除資源忙碌的衝突。
利用debugfs進入掛載虛擬硬碟中查找資料
當映像檔已被掛載成虛擬硬碟後,同時也取得路徑(/dev/loop7),即可進入這個有缺陷的備份映像檔查找資料,利用下列指令進入debugfs模式,其中/dev/loop7p2是備份映像檔的Ubuntu作業系統主分區,也是存放核心資料的區域。
sudo debugfs /dev/loop7p2
接著在debugfs模式中,用cd指令進到個人帳戶的家目錄,並用ls -l指令將資料列出,同時可利用help指令查看debugfs的內建指令列表,操作方式類似ubuntu終端命令,如下三圖所示。
利用debugfs的內建指令rdump撈取資料
debugfs的內建指令列表中,rdump(Recursively dump)可將整個資料夾內容儲存到樹莓派本地端中,如下圖所示。例如若要將Downloads資料夾撈取到樹莓派本地端的/home/user/backup_for_rpi4_22.04資料夾,可在debugfs模式中輸入下列指令,即開始傳輸資料。
rdump Downloads /home/user/backup_for_rpi4_22.04/
安全卸載和資源釋放
完成資料救援後,在debugfs模式中輸入q,即可跳出並回到ubuntu的終端命令列。另外,考量資源釋放和網路安全,建議釋放虛擬硬碟(/dev/loop7),同時卸除Truenas的NFS,指令如下。
sudo losetup -d /dev/loop7
sudo umount /mnt/truenas_net
或許對於Linux大神來說,這個資料救援流程只是吃一塊蛋糕的時間,再熟悉不過。真沒想到與AI的來回問答,除了可大致了解一個未知主題的結構性和前因後果,同時還可以將事務實作完成,讚嘆啊~~
沒有留言:
張貼留言