Merge pull request #30255 from wxy/20230512-Make-use-of-Btrfs-snapshots-to-upgrade-Fedora-Linux-with-easy-fallback

ATRP:20230512 make use of btrfs snapshots to upgrade fedora linux with easy fallback
This commit is contained in:
Xingyu.Wang 2023-10-09 11:42:17 +08:00 committed by GitHub
commit a0a88ae318
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 150 additions and 160 deletions

View File

@ -0,0 +1,150 @@
[#]: subject: "Make use of Btrfs snapshots to upgrade Fedora Linux with easy fallback"
[#]: via: "https://fedoramagazine.org/make-use-of-btrfs-snapshots-to-upgrade-fedora-linux-with-easy-fallback/"
[#]: author: "Stuart D Gathman https://fedoramagazine.org/author/sdgathman/"
[#]: collector: "lujun9972"
[#]: translator: "ChatGPT"
[#]: reviewer: "wxy"
[#]: publisher: "wxy"
[#]: url: "https://linux.cn/article-16267-1.html"
使用 Btrfs 快照方便升级 Fedora Linux 且易于回退
======
![][0]
在 2018 年的一篇 [早前的文章][3] 中,我们介绍了在升级 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 文件系统,并在其上分别挂载两个子卷,`root` 和 `home` ,挂载路径分别为 `/``/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` 子卷,以及两个只读快照 `home``f36`。要添加和删除这些快照,最简单的方法就是挂载 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][4] 或在 `/boot/loader/entries` 中编辑一项来将 `subvol=root` 替换为 `subvol=f36`。然而,为了初学者的安全起见,我们更建议你在启动时编辑 GRUB 进行操作。你可以参考 [关于 GRUB 的这篇文章][5] 了解如何进入 GRUB 菜单。在你到达那里后,按下 `e` 键编辑默认的内核启动项。放心 —— 你所做的更改都只存在于内存中,如果你弄错了,重启电脑即可重新开始。就像编辑 `fstab` 文件一样,找到 `subvol=root` 并将其更改为 `subvol=f36`。然后,按 `F10``Ctrl + X` 来引导你修改过的项目。通过这些更改,你的系统应该能够引导进入你的新快照。你可以查看 `/etc/fstab` 确保你正在引导至正确的子卷,或键入 `mount | grep subvol` 查看此时在 `/` 上挂载的子卷。
### 进行 Fedora Linux 的系统升级
如果你的回退功能没问题,重启并返回你的正常根文件系统(并像上面所述,进行确认)。然后,按照 [维基页面][6] 上的指南进行标准的系统升级。提示:在运行 `dnf system-upgrade reboot` 之前,给 `root` 子卷创建另一个快照,你可以给它命名为 `root.dl`。这样,如果你发现硬盘空间不够,你不必再下载五个 GB 的文件包。因为除了下载的包以外,所有的内容都将与 `root``f36` 共享,因此它不会占用任何额外的空间。然后说到磁盘块的共享问题……
因为在 `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 快照备份][7] 的文章。
*题图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][a]
选题:[lujun9972][b]
译者:[ChatGPT](https://linux.cn/lctt/ChatGPT)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/sdgathman/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2023/04/forkedtree-816x345.jpg
[2]: https://www.flickr.com/photos/brenejohn/20155029206/
[3]: https://fedoramagazine.org/use-lvm-upgrade-fedora/
[4]: https://fedoramagazine.org/setting-kernel-command-line-arguments-with-fedora-30/
[5]: https://fedoramagazine.org/boot-earlier-kernel/
[6]: https://docs.fedoraproject.org/en-US/quick-docs/dnf-system-upgrade/
[7]: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/
[0]: https://img.linux.net.cn/data/attachment/album/202310/09/113654ba1kp126nzn6tpjv.jpg

View File

@ -1,160 +0,0 @@
[#]: subject: "Make use of Btrfs snapshots to upgrade Fedora Linux with easy fallback"
[#]: via: "https://fedoramagazine.org/make-use-of-btrfs-snapshots-to-upgrade-fedora-linux-with-easy-fallback/"
[#]: author: "Stuart D Gathman https://fedoramagazine.org/author/sdgathman/"
[#]: collector: "lujun9972"
[#]: translator: " "
[#]: reviewer: " "
[#]: publisher: " "
[#]: url: " "
Make use of Btrfs snapshots to upgrade Fedora Linux with easy fallback
======
![][1]
A fork in a tree, [Photo by Brendan Johnson][2] (cropped).
Back in 2018, a [previous article][3] demonstrated how to use LVM to clone the root filesystem before upgrading Fedora Linux so as to have a fallback in the unlikely event that something goes wrong. Today, the default Fedora Workstation install uses Btrfs. Now you can use a Btrfs snapshot to make creating a bootable fallback much easier. Note that converting or migrating a system to Btrfs from another filesystem is outside the scope of this article.
### Check that root filesystem is Btrfs
This example uses a Pinebook aarch64 laptop. Before proceeding, first make sure that Btrfs is being used for the root (system) filesystem. Not every spin or image uses Btrfs by default.
```
$ 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
```
### List the existing Btrfs subvolumes
The above example output shows that the file system mounted on “root” (“/”) is type Btrfs. Notice that three mountpoints show the same backing device and the same _Used_ and _Available_ blocks. This is because they are parts (subvolumes) mounted from a single Btrfs filesystem. The _/f34_ subvolume is my bootable snapshot from last year.
A default Fedora Btrfs install creates one Btrfs filesystem with two subvolumes — _root_ and _home_ — mounted on / and /home respectively. Lets see what other subvolumes Ive added:
```
$ 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
```
There is an _f34_ subvol from the last system-upgrade and two readonly snapshots of _home_ and _f36_. The easiest way to add and delete snapshots is to mount the Btrfs root. I will update the system and create a new snapshot of the current f36 _root_ subvolume. If you have renamed your _root_ subvolume, then you presumably know enough to adjust the following example accordingly for your system.
### Create the Btrfs fallback snapshot
```
$ sudo dnf update --refresh
... lots of stuff updated (reboot if kernel updated)
$ 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'
```
Because Btrfs snapshots are filesystem based, it is not necessary to “sync” before the snapshot, as I recommended for LVM. To boot from the new subvol as a fallback, you will need to edit /mnt/root/f36/etc/fstab with your favorite editor. If you are a beginner, nano is a dirt simple text editor with minimal features. Here are some lines from my _fstab_ file:
```
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
```
Change _subvol=root_ to _subvol=f36_. This change is to the file in the snapshot, not your production _fstab_. You can compare them with diff /etc/fstab /mnt/root/f36/etc/fstab. In my case, I also deleted my _f34_ snapshot from last year with sudo btrfs subvol delete f34.
### Test the Btrfs fallback snapshot
Now you are ready to test the fallback. You could use [grubby][4] or edit an entry in /boot/loader/entries to change _subvol=root_ to _subvol=f36_. But in the interest of safety for beginners, I will have you edit the GRUB entry at boot time instead. Checkout [this article on GRUB][5] for tips on getting to the GRUB menu. Once you are there, press the **e** key to edit the default kernel entry. Dont worry — your changes are in volatile memory only. If you mess up, reboot to start over. Just like with fstab, find _subvol=root_ and change it to _subvol=f36_. Press **F10** or **Ctrl** + **X** to boot your modified entry. With these changes, the system should boot into your new snapshot. Look at /etc/fstab to make sure you are booting from the right subvol, or enter mount | grep subvol to see what subvolume is mounted on “/”.
### Do the Fedora Linux system upgrade
If your fallback is working, reboot back to your normal root filesystem (and confirm as above). Then proceed with the standard system-upgrade outlined on the [wiki page][6]. TIP: Before running dnf system-upgrade reboot, make another snapshot of root. Call it something like _root.dl_. That way, you dont have to download five gigabytes of packages again should you discover that there wasnt enough free space. The snapshot will not take up any additional space because all but the downloaded packages are shared with _root_ and _f36_. About that sharing of disk blocks …
dnf system-upgrade gets confused about free space as reported by Btrfs because the f36 files in the _root_ subvolume use the same disk locations as the same files in the _f36_ subvolume. So removing them from the _root_ subvolume during the upgrade process doesnt actually free up any space. If you run out of space, and you reboot — the graphical user interface (GUI) wont start. Use **Ctrl** + **Alt** + **F2** to login on a text console and practice your command line interface skills. Figuring out what to remove to free up space or how to expand the root filesystem is beyond the scope of this article (mine is often on an LVM volume and can be expanded). Having more than 50% free for the upgrade is a safe bet.
### Recovery
Should something go wrong, you can reboot and edit the GRUB entry to boot the fallback. If you are a beginner, youll want some hand holding if you do end up needing to change the GRUB entry on disk (so you dont have to edit at each boot). It is straight forward to delete or rename the broken _root_ subvol. Snapshot the _f36_ subvol (or the _root.dl_ snapshot) to try the system-upgrade process again. Here is an example of starting over after booting into the fallback system on subvol 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".
```
As it turns out, the new kernel-6.2.11 for f38 did not boot on my Pinebook after the system-upgrade! (Dont worry, ARM is an alternative CPU architecture for Fedora Linux — this is very unlikely to happen to you on a mainstream device.) I was indeed able to boot back to f36 by editing the GRUB entry for kernel-6.2.10 at boot time as described above. I am now using f38 again — but with kernel-6.2.10 from f36.
**Update** : _kernel-6.2.12 is out and it works on the Pinebook._
### Expiration
As you update the f38 system, it will eventually want to delete the last f36 kernel from /boot. That is normally not a problem, as by that time you have settled into f38, and the f36 snapshot is just an archive. If you want to keep your fork (f36 snapshot) bootable indefinitely, you should preserve a working f36 kernel under /boot. The simplest way to do so is to set _installonly_limit=0_ in /etc/dnf/dnf.conf and manually remove old kernels. It is simple and safe (but annoying).
Outline of a more complex solution (not for beginners): Run find /boot -name "*fc36*" to list all the kernel and GRUB files for your f36 subvolume snapshot that are under /boot (which is not in the snapshot). Copy them to a backup location (I would mount the f36 subvolume and copy to a backup directory there). While booted from f38, for each f36 kernel version, use dnf to remove that specific kernel version (for example, dnf remove kernel-core-5.19.11-200.fc36). Do not remove the f38 kernels! Now restore the f36 kernels you saved to /boot. The f38 system doesnt know about f36 kernels anymore, and it will not remove them from /boot.
The problem with that method is the danger of accidentally removing the running f38 kernel. If anyone has a better method, let me know in the comments.
### Future directions
Those comfortable with modifying GRUB entries might consider creating a snapshot subvolume named _f38_ , modifying the current GRUB entry to boot into that, rebooting, and running the system-upgrade in that subvolume. Then always name the subvol for the root filesystem after the Fedora Linux release it contains. I did not do that for this article for two reasons.
1. Naming the current active subvolume _root_ matches the Fedora Linux default.
2. Sticking with _root_ for the current subvol does not require any permanent changes outside of the normal system-upgrade procedure.
As this article has demonstrated, readonly snapsnots are useful as local restore points in case things go wrong when making significant system changes (such as a system release upgrade). These snapshots can also be sent to a remote backup using Btrfs _send_ subcommand. (And if the remote backup device already contains previous backups, Btrfs can do an incremental send that only transmits changed files to save time and space.) If you intend to archive these snapshots long term, the key to not getting confused about which ones are which and what order to restore them is to use a consistent naming convention. See the article on [Btrfs snapshots for backup][7] for more information about using Btrfs _send_ command to create backups.
--------------------------------------------------------------------------------
via: https://fedoramagazine.org/make-use-of-btrfs-snapshots-to-upgrade-fedora-linux-with-easy-fallback/
作者:[Stuart D Gathman][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://fedoramagazine.org/author/sdgathman/
[b]: https://github.com/lujun9972
[1]: https://fedoramagazine.org/wp-content/uploads/2023/04/forkedtree-816x345.jpg
[2]: https://www.flickr.com/photos/brenejohn/20155029206/
[3]: https://fedoramagazine.org/use-lvm-upgrade-fedora/
[4]: https://fedoramagazine.org/setting-kernel-command-line-arguments-with-fedora-30/
[5]: https://fedoramagazine.org/boot-earlier-kernel/
[6]: https://docs.fedoraproject.org/en-US/quick-docs/dnf-system-upgrade/
[7]: https://fedoramagazine.org/btrfs-snapshots-backup-incremental/