Linux中國

使用 Btrfs 快照方便升級 Fedora Linux 且易於回退

在 2018 年的一篇 早前的文章 中,我們介紹了在升級 Fedora Linux 前如何利用 LVM 複製根文件系統,以便在可能出現錯誤的情況下能有一個回退機制。然而如今,Fedora 工作站的默認安裝已經是 Btrfs 文件系統了。現在,你可以利用 Btrfs 快照來更簡便地創建一個可引導的回退系統。注意,本文不涉及會如何從其它文件系統轉換或遷移到 Btrfs 上。

確認根文件系統是否為 Btrfs

本示例採用的是 Pinebook aarch64 筆記本電腦。在開始前,務必確認你的根文件系統是否採用 Btrfs。要明確,不是所有的定製版或者鏡像文件默認都使用 Btrfs。

$ df -T
Filesystem     Type     1K-blocks     Used Available Use% Mounted on
devtmpfs       devtmpfs      4096        0      4096   0% /dev
tmpfs          tmpfs       998992        0    998992   0% /dev/shm
tmpfs          tmpfs       399600     6360    393240   2% /run
/dev/mmcblk2p3 btrfs     56929280 39796116  15058348  73% /
tmpfs          tmpfs       998996       24    998972   1% /tmp
tmpfs          tmpfs      5242880        0   5242880   0% /var/lib/mock
/dev/mmcblk2p3 btrfs     56929280 39796116  15058348  73% /f34
/dev/mmcblk2p3 btrfs     56929280 39796116  15058348  73% /home
/dev/mmcblk2p2 ext4        996780   551888    376080  60% /boot
/dev/mmcblk2p1 vfat        194348    31648    162700  17% /boot/efi
tmpfs          tmpfs       199796      100    199696   1% /run/user/1000
tmpfs          tmpfs       199796       84    199712   1% /run/user/0

列出當前的 Btrfs 子卷

以上的示例輸出顯示掛載在 「根」(/)的文件系統類型是 Btrfs。你會注意到,有三個掛載點顯示了相同的備份設備以及 已用可用 的塊數。這是因為它們是從同一 Btrfs 文件系統掛載的不同部分(子卷)。比如,/f34 子卷是我去年創建的那個可引導快照。

默認的 Fedora Btrfs 安裝會創建一個 Btrfs 文件系統,並在其上分別掛載兩個子卷,roothome ,掛載路徑分別為 //home。讓我們一起來看看我還添加了哪些其它的子卷:

$ sudo btrfs subvol list /
ID 272 gen 110428 top level 5 path root
ID 273 gen 110426 top level 5 path home
ID 300 gen 109923 top level 5 path f34
ID 301 gen 95852 top level 5 path home.22Jul26
ID 302 gen 95854 top level 5 path f36.22Jul26

在這裡,我們有一個來自最近一次系統升級的 f34 子卷,以及兩個只讀快照 homef36。要添加和刪除這些快照,最簡單的方法就是掛載 Btrfs 的根目錄。我會更新系統並創建當前 f36 root 子卷的新快照。如果你已經重命名了你的 root 子卷,我相信你知道該如何調整以下的示例以適應你的系統。

創建 Btrfs 的回退快照

$ sudo dnf update --refresh
...更新了很多部分(如果升級了內核還需要重啟)
$ sudo mkdir -p /mnt/root
$ sudo mount /dev/mmcblk2p3 /mnt/root
$ cd /mnt/root
$ ls
f34  f36.22Jul26  home  home.22Jul26  root
$ sudo btrfs subvol snapshot root f36
Create a snapshot of 'root' in './f36'

因為 Btrfs 快照是以文件系統為基礎的,所以並不需要在創建快照之前進行 「同步」,正如我在 LVM 中建議的。要從新的子卷引導為回退,你需要使用你喜歡的編輯器編輯 /mnt/root/f36/etc/fstab。如果你是剛入門的話,nano 就是一款十分簡單的文本編輯器,功能基本夠用。以下是我 fstab 文件中的一些行:

LABEL=PINE      /    btrfs   subvol=root,compress=zstd:1        1 1
UUID=e31667fb-5b6f-48d9-aa90-f2fd6aa5f005 /boot ext4    defaults        1 2
UUID=75DB-5832          /boot/efi               vfat    umask=0077,shortname=winnt 0 2
LABEL=PINE      /home    btrfs   subvol=home,compress=zstd:1    1 1
LABEL=SWAP swap         swap    discard=once    0 0

subvol=root 更改為 subvol=f36。這個改動是作用在快照中的文件,而並非你實際運行中的 fstab 文件。你可以通過 diff /etc/fstab /mnt/root/f36/etc/fstab 對比它們的區別。在我的情況下,我還使用了 sudo btrfs subvol delete f34 來刪除我去年的 f34 快照。

測試 Btrfs 的回退快照

你現在可以進行回退的測試了。你可以使用 grubby 或在 /boot/loader/entries 中編輯一項來將 subvol=root 替換為 subvol=f36。然而,為了初學者的安全起見,我們更建議你在啟動時編輯 GRUB 進行操作。你可以參考 關於 GRUB 的這篇文章 了解如何進入 GRUB 菜單。在你到達那裡後,按下 e 鍵編輯默認的內核啟動項。放心 —— 你所做的更改都只存在於內存中,如果你弄錯了,重啟電腦即可重新開始。就像編輯 fstab 文件一樣,找到 subvol=root 並將其更改為 subvol=f36。然後,按 F10Ctrl + X 來引導你修改過的項目。通過這些更改,你的系統應該能夠引導進入你的新快照。你可以查看 /etc/fstab 確保你正在引導至正確的子卷,或鍵入 mount | grep subvol 查看此時在 / 上掛載的子卷。

進行 Fedora Linux 的系統升級

如果你的回退功能沒問題,重啟並返回你的正常根文件系統(並像上面所述,進行確認)。然後,按照 維基頁面 上的指南進行標準的系統升級。提示:在運行 dnf system-upgrade reboot 之前,給 root 子卷創建另一個快照,你可以給它命名為 root.dl。這樣,如果你發現硬碟空間不夠,你不必再下載五個 GB 的文件包。因為除了下載的包以外,所有的內容都將與 rootf36 共享,因此它不會佔用任何額外的空間。然後說到磁碟塊的共享問題……

因為在 root 子卷中的 f36 文件和 f36 子卷中的相同文件都使用的是相同的磁碟位置,所以在處理 Btrfs 報告的可用空間時,dnf system-upgrade 會感到困惑。因此在升級過程中從 root 子卷中刪除它們並不會真正釋放任何空間。如果你耗盡了所有空間,並且決定重啟電腦,那麼圖形用戶界面(GUI)將無法啟動。此時,你需要使用 Ctrl + Alt + F2 進入文本控制台並登錄,這將是你磨練命令行技能的好機會。如何清空空間或擴展根文件系統在這裡先不做討論(我的文件系統經常在一個 LVM 的卷上,可以被擴展)。通常,為升級保留超過 50% 的空閑空間是比較保險的。

恢復環節

如果不幸出現問題,你可以重啟電腦,並編輯 GRUB 條目以引導啟動回退快照。如果你是新手,一旦需要在磁碟上修改 GRUB 條目(這樣你就不需要每次啟動時都進行編輯),可能需要一些指導。刪除或重命名損壞的 root 子卷是非常直接的。你可以為 f36 子卷(或 root.dl 快照)創建一個快照,然後嘗試再一次進行系統升級。以下是在子卷 f36 上啟動到回退系統後重新開始的示例:

$ mount | grep subvol
$ sudo mount /dev/mmcblk2p3 /mnt/root
$ cd /mnt/root
$ sudo mv root root.failed
$ sudo btrfs subvol snapshot f36 root
Create a snapshot of 'f36' in './root'

Don't forget to edit /mnt/root/root/etc/fstab to change the subvol mounted on "/" to "root".

事實證明,新的 f38 版本的 kernel-6.2.11 在我的 Pinebook 上進行系統升級後並未成功啟動!(不過請不要擔心,ARM 只是 Fedora Linux 的可選 CPU 架構——在主流設備上,你很少會遭遇此類問題。)的確,我成功地按照前文所述,在啟動時編輯了 GRUB 條目並恢復到了 f36 的 kernel-6.2.10。現在,我繼續使用著 f38,但同時搭載了 f36 的 kernel-6.2.10。

更新:kernel-6.2.12 已經發布,且我已確認它在 Pinebook 上運行正常。

過期問題

隨著你不斷更新 f38 系統,它最終可能會希望刪除 /boot 下的最後一個 f36 內核。通常來說,這並不是問題,因為到那個時候,你已經完全熟悉 f38,而 f36 快照只是一個存檔。然而,如果你希望你的復刻版本(即 f36 的快照)能無限期地啟動,那麼你應當在 /boot 下保存一個能正常工作的 f36 內核。最簡單的方法是在 /etc/dnf/dnf.conf 文件中設置 installonly_limit=0 並手動移除舊的內核,這種方法既簡單又安全(儘管可能稍顯繁瑣)。

這裡還有一個更複雜的解決方案(不適合新手):運行 find /boot -name "*fc36*" 指令,列舉出所有在 f36 子卷快照中的內核及 GRUB 文件(這些文件並未包含在快照之內)。將這些文件備份至安全位置(例如我會掛載 f36 子卷,並將文件備份至其下的一個目錄)。當 f38 系統啟動後,對於每一個 f36 內核版本,都需使用 dnf 刪除特定版本的內核(例如,使用 dnf remove kernel-core-5.19.11-200.fc36)。千萬不要刪除 f38 的內核!然後將你先前備份的 f36 內核恢復至 /boot 下。此時,f38 系統已經無法再識別 f36 的內核,因此也不會將其從 /boot 中刪除。

然而,使用此方法有一個缺點,那就是你可能會不小心刪除正在運行的 f38 內核。如果大家有更佳的解決辦法,歡迎在評論區分享。

展望未來

對於習慣於修改 GRUB 條目的用戶,他們可能會考慮創建一個命名為 f38 的快照子卷。將當前的 GRUB 條目進行修改,以便啟動到這個子卷,重啟後,在這個子卷中進行系統升級。此後,總是根據它所包含的 Fedora Linux 版本來命名根文件系統的子卷。但在本文中,我沒有採用這種作法,原因有兩點:

  1. 將當前活動的子卷命名為 root,這是遵循 Fedora Linux 的默認設置。
  2. 堅持使用 root 作為當前子卷,這樣在進行正常的系統升級操作之外,並不需要任何永久性的更改。

正如本文所展示的,針對重大系統更改(如系統版本升級)可能引發問題時,只讀快照作為本地恢復點,非常有用。這些快照還可以通過 Btrfs 的 send 子命令,發送至遠程備份。(如果遠程備份設備已經包含了先前的備份數據,Btrfs 可以進行增量發送,僅傳輸發生變更的文件,這樣就能節省時間和空間。)如果你打算長期存檔這些快照,保持清晰不混淆且能明確恢復順序的關鍵,就是要使用一套一致的命名規則。關於如何使用 Btrfs 的 send 命令來創建備份的更多信息,你可以參考關於 Btrfs 快照備份 的文章。

(題圖:MJ/6aed1d19-f1dd-4935-ad6f-61f6a868f150)

via: https://fedoramagazine.org/make-use-of-btrfs-snapshots-to-upgrade-fedora-linux-with-easy-fallback/

作者:Stuart D Gathman 選題:lujun9972 譯者:ChatGPT 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國