[ Content contribution] [btrfs正当时] 如何将系统正确安装到btrfs子卷并捏一个恢复环境
Tofloor
poster avatar
Ziggy
deepin
2024-03-24 22:16
Author

前期准备

安装准备

  1. 准备一个系统安装镜像并刻录到移动存储设备,最好是5.10+内核,对btrfs支持会更好
  2. 提前分两个区:
  • 一个btrfs分区作为母卷rootfs
  • 一个可以作为完整系统运行的live盘
  • 一个独立分区用于安装初始系统,可以安装到btrfs分区以外的独立硬盘中,当btrfs所在硬盘损坏时可以作为rootb备份进行还原。(建议)使用非btrfs格式用于区分

btrfs分区划分子卷

  1. 将btrfs分区挂载到/mnt中,开始创建所需的子卷
ziggy@ziggy-PC:~$ lsblk -f
NAME   FSTYPE FSVER LABEL     UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sdb                                                     
├─sdb1 vfat   FAT32           DCF5-3A2C                                           /boot/efi
├─sdb2 swap   1     swap      e2a198a1-6e12-4248-bca8-b5cfbf4ce723                [SWAP]
├─sdb3 btrfs        deepin    68e253cf-9282-47b3-b087-9c5910950c88   89.9G    32% /

根据lsblk得出btrfs分区为/dev/sdb3,挂载

root@ziggy-PC:~# mount /dev/sdb3 /mnt/
  1. 当btrfs分区被挂载到/mnt后,此时/mnt为btrfs母卷,本身不具备任何子卷功能。并且btrfs目前仍处于发展阶段和取决于btrfs+grub引导顺序,建议在系统子卷以外单独设置一个根子卷充当引导中转的作用。
  2. 以下示例依次设置子卷"@main(btrfs根卷),@home(用户主目录),@opt(应用目录),@root(root主目录,可选)"
root@ziggy-PC:/mnt# btrfs subvolume create /mnt/@main
root@ziggy-PC:/mnt# btrfs subvolume create /mnt/@home
root@ziggy-PC:/mnt# btrfs subvolume create /mnt/@opt
root@ziggy-PC:/mnt# btrfs subvolume create /mnt/@root

系统部署

初始系统安装

  1. 引导进入安装介质,选择非btrfs格式的卷作为"/"挂载点进行安装,安装时尽量选择仅"/"挂载点进行安装,方便后续进行数据迁移,建议的挂载方案:"/"根目录(必须),交换文件swap files(可选),efi(如果是UEFI引导的话)

乾坤大挪移

处于总所周知的两个原因,在安装完初始系统后,如果我们想要让系统正常在btrfs卷上运行并使能快照功能,就需要手动将已经安装好的系统迁移到btrfs子卷中

  1. 目前安装器暂不支持直接将系统安装到btrfs子卷中
  2. deepin安装器目前策略导致安装完系统但并未进入用户配置阶段时,此时的系统拥有相对最干净的环境
  3. 通过查看lsblk,记录/dev/sda1为初始系统的安装目录,/dev/sdb3/@main则为btrfs分区中的根卷
sda                                                     
├─sda1 ext4   1.0   Roota     a7f4b3d4-5d3d-45a1-a27b-798aa6fbae48   30.7G    26% /media/ziggy/Roota
sdb                                                     
├─sdb1 vfat   FAT32           DCF5-3A2C                                           /boot/efi
├─sdb2 swap   1     swap      e2a198a1-6e12-4248-bca8-b5cfbf4ce723                [SWAP]
├─sdb3 btrfs        deepin    68e253cf-9282-47b3-b087-9c5910950c88   89.9G    32% /mnt
  1. 确认后通过rsync来进行数据迁移,由于本示例中还单独划分了"@home,@opt,@root",因此还需要将初始系统中对应目录的数据迁移到子卷中。
root@ziggy-PC:/mnt# rsync -avrP /media/ziggy/Roota /mnt/@main
root@ziggy-PC:/mnt# rsync -avrP /media/ziggy/Roota/opt /mnt/@opt
root@ziggy-PC:/mnt# rsync -avrP /media/ziggy/Roota/home /mnt/@home
root@ziggy-PC:/mnt# rsync -avrP /media/ziggy/Roota/root /mnt/@root

文件配置

数据迁移完成后,由于btrfs卷与系统原安装路径不一致以及系统安装到btrfs子卷后的引导顺序,需要对数个配置文件进行重新配置

"Firmware固件==>efi引导文件==>Grub==>Btrfs母卷==>Btrfs子卷Grub==>Btrfs子卷rootfs"

/boot目录

/boot目录中需要对grub.cfg引导文件进行修改,这里可以分为几步

  1. 通过搜索将初始系统的UUID批量替换为btrfs母卷的UUID

    截图_选择区域_20240324215338.png

  2. 观察grub.cfg文件中对系统绝对路径的引用,在"/"前加上"/@main",表明该路径修改后为子卷中的路径

    截图_选择区域_20240324215426.png

  3. 在linux行内核启动参数中添加"rootflags=subvol=@main"指示grub引导btrfs母卷中的@main子卷

        linux   /@main/boot/vmlinuz-6.1.32-amd64-desktop-hwe root=UUID=68e253cf-9282-47b3-b087-9c5910950c88 ro splash quiet rootflags=subvol=@main DEEPIN_GFXMODE=$DEEPIN_GFXMODE
        initrd  /@main/boot/initrd.img-6.1.32-amd64-desktop-hwe

/etc目录

  1. 修改fstab文件,根据实际的子卷和需求情况来修改挂载信息,此处核心的为根目录挂载点设置,其他挂载点可以参考根目录挂载点来进行修改,仅需修改subvol指向子卷
#                
# /dev/sdb1 LABEL=Roota
UUID=68e253cf-9282-47b3-b087-9c5910950c88       /               btrfs           rw,relatime,ssd,compress=zstd,subvol=@main     0 1

UUID=68e253cf-9282-47b3-b087-9c5910950c88       /home           btrfs           rw,relatime,ssd,subvol=@home 0 1

UUID=68e253cf-9282-47b3-b087-9c5910950c88       /opt            btrfs           rw,relatime,ssd,subvol=@opt  0 1
  1. 修改/etc/default/grub文件,在"GRUB_CMDLINE_LINUX_DEFAULT"字段中添加“rootflags=subvol=@main”,这样在grub update后才会自动在新的grub文件中自动添加该启动命令
root@ziggy-PC:/boot/grub# cat /etc/default/grub
# Written by org.deepin.dde.Grub2
GRUB_CMDLINE_LINUX_DEFAULT="splash quiet rootflags=subvol=@main"

EFI目录(如果是UEFI引导的话)

  1. 通过lsblk查看得知/boot/efi挂载点所在分区的UUID并挂载到/mnt中
root@ziggy-PC:/boot/grub#mount /dev/sdb1 /mnt
  1. 进入/mnt目录,找到boot和deepin目录,修改grub.cfg文件.将"search.fs_uuid"修改为btrfs母卷对应的UUID信息,"set prefix"中加入子卷对应的路径"
root@ziggy-PC:/boot/efi/EFI/deepin# cat grub.cfg 
search.fs_uuid 68e253cf-9282-47b3-b087-9c5910950c88 root hd0,gpt2
set prefix=($root)'/@main/boot/grub'
configfile $prefix/grub.cfg

快照部署

由于前文提及@main子卷用于根卷不打算作为常用系统子卷使用,因此在该基础上创建一个@sys快照子卷来作为日用环境

root@ziggy-PC:/# btrfs subvolume snapshot /mnt/@main /mnt/@sys

快照创建完成后,由于子卷发生改变,因此需要重复"### 文件配置"步骤来调整新子卷的内容,但通用文件不需要改动

/boot目录

  1. 修改@sys子卷中的grub.cfg文件,在linux行内核启动参数中添加"rootflags=subvol=@sys"指示grub引导btrfs母卷中的@sys子卷,并且该引导项中的initrd和linux路径均需要修改为当前系统@sys子卷

/etc目录

  1. 修改@sys子卷中的fstab文件,根据实际的子卷和需求情况来修改挂载信息,此处核心的为根目录挂载点设置,其他挂载点可以参考根目录挂载点来进行修改,仅需修改subvol指向子卷
  2. 修改@sys子卷中的/etc/default/grub文件,在"GRUB_CMDLINE_LINUX_DEFAULT"字段中添加“rootflags=subvol=@sys”,这样在grub update后才会自动在新的grub文件中自动添加该启动命令

初始化部署

由于"初始化"环境本质上还是以快照子卷的形式存在,因此仅需要参考前面快照部署内容即可完成部署。即对@sys子卷做只读快照操作为同btrfs母卷下的"@snaps/@restore子卷"(支持个人习惯的自定义)以及修改/etc对应文件即可完成.snapshots的"-r" 参数为只读快照

root@ziggy-PC:/# btrfs subvolume snapshot -r /mnt/@sys /mnt/@snaps/@restore

由于通过安装器安装的系统一般还会附属"高级菜单",个人建议直接利用高级菜单,将其描述修改为Restore,initrd和linux路径修改为自己的初始化环境子卷。这样就可以在选Restore菜单引导时进入初始化环境了。
但值得注意的是,建议恢复时是以快照的形式先将"@restore子卷"恢复到一个新子卷中再进行用户配置环节操作,这样就可以极大程度避免初始化环境被破坏了.

参考文献: @AMZ 将uos/deepin运行在btrfs文件系统,并启用快照功能

Reply Favorite View the author
All Replies
jjcui8595
Moderator
2024-03-24 22:43
#1

感谢分享

Reply View the author
HualetWang
deepin
2024-03-24 23:22
#2
like
Reply View the author
阿尼樱奈奈
Moderator
2024-03-25 01:19
#3

这个要支持下like

Reply View the author
乾豫恒益
deepin
2024-03-25 08:38
#4

yeah yeah

Reply View the author
jjcui8595
Moderator
2024-03-25 09:26
#5

V23系统只要创建单独的boot分区,是可以把'/"安装在btrfs分区上的。这样是不是更简便一些呢?

Reply View the author
Ziggy
deepin
2024-03-25 09:48
#6
jjcui8595

V23系统只要创建单独的boot分区,是可以把'/"安装在btrfs分区上的。这样是不是更简便一些呢?

/安装到btrfs后,btrfs只是一个和ext4无异的普通文件系统,只有安装到子卷里才可以进行快照操作。至于boot如果是使用子卷的话就很不建议单独挂载了,不跟随系统一起的话,升级内核容易爆炸,我上回就翻车了sweat

Reply View the author
jjcui8595
Moderator
2024-03-25 10:07
#7
Ziggy

/安装到btrfs后,btrfs只是一个和ext4无异的普通文件系统,只有安装到子卷里才可以进行快照操作。至于boot如果是使用子卷的话就很不建议单独挂载了,不跟随系统一起的话,升级内核容易爆炸,我上回就翻车了sweat

I see

Reply View the author
磨剪子戗菜刀
deepin
2024-03-25 13:52
#8

条理清楚,逻辑清晰

参照贵帖,成功把系统迁移到了btrfs子卷中kissing_heart

Reply View the author
流浪的加菲
deepin
2024-03-25 17:15
#9

技术活,当赏like

Reply View the author
buyike
Moderator
2024-03-25 19:43
#10

这个图可以换一下吗?我滚轮了都要滚坏了。

或者,换成横式的?

202403241422487574_boot.png

Reply View the author
Ziggy
deepin
2024-03-26 09:45
#11
buyike

这个图可以换一下吗?我滚轮了都要滚坏了。

或者,换成横式的?

202403241422487574_boot.png

ok已经换成更直白可视的text

Reply View the author
buyike
Moderator
2024-03-26 13:20
#12
Ziggy

ok已经换成更直白可视的text

👍

Reply View the author
Tent
deepin
2024-03-27 13:42
#13

另外是不是可以参考下已有的全盘安装的方案,把“系统关键文件”(Roota含boot使用btrfs)和“个人数据、系统日志、已安装软件、临时文件”(_dde_data使用ext4)分开存放。

这样应该有3个好处吧:

1、节省系统盘的磁盘空间:系统盘只放系统关键文件和一部分安装到/usr下的软件文件。并且这样相当于只对这些文件做快照;

2、方便异常情况下恢复数据:系统盘可以整个格式化掉重装,因为不含个人数据。并且ext4的数据比btrfs好恢复;

3、文件系统性能方面:ext4总体上优于btrfs,所以还是让ext4来当主力。

我现在的分区方式是这样的:

# /dev/nvme0n1p2 LABEL=Roota
UUID=XXXXXXXXXXXXXX       /               btrfs           rw,relatime,ssd,space_cache,subvolid=5,subvol=/ 0 0
# /dev/nvme0n1p1 LABEL=EFI
UUID=XXXX-XXXX          /boot/efi       vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro     0 2
# /dev/nvme0n1p3 数据盘
UUID="XXXXXXXXXXXXX" /data ext4 rw,relatime 0 2
/data/home /home none defaults,bind 0 0
/data/opt /opt none defaults,bind 0 0
/data/var /var none defaults,bind 0 0
/data/root /root none defaults,bind 0 0
# tmpfs,放临时文件
tmpfs /tmp tmpfs size=8g,mode=1777 0 0

然后如果仅还原根分区快照的话,会有一个dpkg已安装软件信息不匹配的情况,现在我是通过手工备份/var/lib/dpkg/info/和/var/lib/dpkg/status这两个来解决的,这么做是否可行,或者是否有更优的方案?

Reply View the author
Ziggy
deepin
2024-03-27 13:54
#14
Tent

另外是不是可以参考下已有的全盘安装的方案,把“系统关键文件”(Roota含boot使用btrfs)和“个人数据、系统日志、已安装软件、临时文件”(_dde_data使用ext4)分开存放。

这样应该有3个好处吧:

1、节省系统盘的磁盘空间:系统盘只放系统关键文件和一部分安装到/usr下的软件文件。并且这样相当于只对这些文件做快照;

2、方便异常情况下恢复数据:系统盘可以整个格式化掉重装,因为不含个人数据。并且ext4的数据比btrfs好恢复;

3、文件系统性能方面:ext4总体上优于btrfs,所以还是让ext4来当主力。

我现在的分区方式是这样的:

# /dev/nvme0n1p2 LABEL=Roota
UUID=XXXXXXXXXXXXXX       /               btrfs           rw,relatime,ssd,space_cache,subvolid=5,subvol=/ 0 0
# /dev/nvme0n1p1 LABEL=EFI
UUID=XXXX-XXXX          /boot/efi       vfat            rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro     0 2
# /dev/nvme0n1p3 数据盘
UUID="XXXXXXXXXXXXX" /data ext4 rw,relatime 0 2
/data/home /home none defaults,bind 0 0
/data/opt /opt none defaults,bind 0 0
/data/var /var none defaults,bind 0 0
/data/root /root none defaults,bind 0 0
# tmpfs,放临时文件
tmpfs /tmp tmpfs size=8g,mode=1777 0 0

然后如果仅还原根分区快照的话,会有一个dpkg已安装软件信息不匹配的情况,现在我是通过手工备份/var/lib/dpkg/info/和/var/lib/dpkg/status这两个来解决的,这么做是否可行,或者是否有更优的方案?

当然是支持自定义部署策略的,我这个只是一个example~如果是个人观点来看,var这种最好是跟着系统来滚动,就不需要担心数据匹配问题,而且假设这么一个场景:系统出问题之后回退到历史快照,但是log还是最新的并没有跟随系统回退,如果是想要分析debug信息还是会有点影响的。

Reply View the author
Tent
deepin
2024-03-27 14:07
#15
Ziggy

当然是支持自定义部署策略的,我这个只是一个example~如果是个人观点来看,var这种最好是跟着系统来滚动,就不需要担心数据匹配问题,而且假设这么一个场景:系统出问题之后回退到历史快照,但是log还是最新的并没有跟随系统回退,如果是想要分析debug信息还是会有点影响的。

日志这个确实容易混乱,那这种把日志单独拿出来的方案,就还是自己用吧。要是给别人用还是要严谨些😂。

Reply View the author
Amz
deepin
2024-04-01 18:40
#16

哈哈借楼在安利一下效率为上的鼠标主题

https://bbs.deepin.org/post/270008

Reply View the author
Amz
deepin
2024-04-01 18:48
#17

截图_gpartedbin_20240401184403.png

截图_timeshift-gtk_20240401184450.png

目前也就这样用用,完整方案的btrfs应当体验一下suse你会得到更多启发,子卷方案 支持子卷的安装器 快照管理工具 apt钩子 grub钩子 update-grub脚本 等等的全套工具配合

Reply View the author
程序猿MT
deepin
2024-04-16 16:13
#18

nice, 手贱, 成功按照楼主的方法把系统搞挂了。

Reply View the author
哈萨雅琪
deepin
2024-04-24 20:05
#19
程序猿MT

nice, 手贱, 成功按照楼主的方法把系统搞挂了。

为什么要用brtfs ,比ext4和xfs好么?

Reply View the author