利用BTRFS快照实现快速Linux环境切换
对于喜欢折腾的人来说,经常会遇到环境玩崩的情况,在Linux下更是一件常事。而如果每次都要重装系统,其实又非常不方便,也没必要。
在BTRFS文件系统逐步稳定并可用的今天,如果我们将根文件系统迁移到了BTRFS,或许,我们可以借助BTRFS快照功能,实现Linux环境的无痛切换与还原?
思路
为了方便,我们假设一个非常无聊的例子:
- 希望在一个分区内,安装一个Debian系统
- 在Debian系统上,分别安装配置GNOME和KDE两个桌面环境
- 实现两个桌面环境的根文件系统互不干扰,可按需分别启动
需要说明的是,这套配置里,我们假设包括/usr
, /etc
等路径均没有分配独立的挂载点,否则那就太麻烦啦!/home
是否独立挂载取决于环境隔离的程度。
仔细一想,想要实现上述功能的思路是非常简单的:
- 在BTRFS文件系统上安装一个基础操作系统
- 对基础操作系统进行快照
- 根据基础快照,创建两组新的读写快照(子卷),在两个子卷内分别安装GNOME和KDE环境,并按需切换
其实,以Debian为例,如果在安装系统时指定了根文件系统为BTRFS文件系统,Debian安装程序会贴心地为我们创建一个@rootfs
子卷,而后每次启动电脑时,实际上都是将@rootfs
子卷挂载成/
节点。因此,以上步骤的前两步都已被自动完成。
似乎,我们只要解决第三步就行?但麻烦的也在这第三步。
GRUB的麻烦
回忆一下,Linux是如何确定自动挂载文件系统配置的?第一个想到的一定是/etc/fstab
文件。
还是以Debian的为例,默认情况下,如果设置根文件系统为BTRFS,在/etc/fstab
文件里面,我们可以找到类似于以下定义:
1 | # / was on /dev/sda1 during installation |
显然,这一句的意思是,将硬盘上的@rootfs
子卷,挂载到/
路径上。
那么接下来,我们似乎只要创建一个@rootfs
的快照子卷,然后修改上面的fstab
文件,把subvol=
后面替换成新子卷名称,就可以实现快速切换了?
一开始我也是这么认为的,直到我安装完KDE桌面重启后,对着仍然黑麻麻的屏幕两眼发黑,我才意识到不对劲。
让我们瞄一眼/boot/grub/grub.cfg
文件:
1 | menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-12345678-1234-1234-5678-123456789012' { |
好吧……事实上根文件系统的子卷名称,是写入到了GRUB配置文件里的。在GRUB引导时,会按照/boot/grub/grub.cfg
的配置查找子卷,然后加载该子卷中的系统。
而要修改GRUB配置,似乎就有点麻烦了。如果手动修改配置,需要在每次安装完驱动或更新内核后再手动调整一遍配置,极其麻烦且容易疏漏。而如果希望自动修改,又暂时没有好主意。
重命名子卷
修改GRUB配置的路子走不通,系统默认引导@rootfs
子卷的行为有点难修改。既然如此,为什么我们不通过替换@rootfs
子卷的方式,狸猫换太子呢!
安装基本系统
首先正常安装Debian基本系统,在配置分区的时候,为/
挂载点分配一个BTRFS文件系统。
进行基础配置
安装完系统后,重启进入基本系统,进行必要的配置,安装一些在不同环境下都用得上的包。也就是准备一个基本系统的过程啦!
拍摄基础快照
重启进LiveCD,挂载BTRFS分区整个卷:
1 | mount /dev/sda1 /mnt |
我们给系统子卷@rootfs
创建一个快照@sysbase
(名字可以随意起),用于记录此刻基本系统的状态:
1 | btrfs subvolume snapshot @rootfs @sysbase |
如果希望基本系统内容不变,可以增加一个选项-r
,以创建一个只读快照。
配置环境1
接着,重启电脑,按需要配置第一个环境,例如安装GNOME桌面等。
配置环境2
之后,如果我们想要从基本系统开始重新配置一个新环境,我们需要再次进入LiveCD,挂载BTRFS分区完整卷到/mnt
下。
这回,我们需要把环境1,也就是现在的@rootfs
先移到一边,也就是重命名一下。
1 | mv @rootfs @gnome-env |
现在,我们的硬盘上似乎只有两个子卷了:
1 | /mnt/ |
我们现在想让系统回到基本系统,也就是回到@sysbase
的状态。怎么做呢?我们可以,给@sysbase
再创建一个快照,让这个快照成为新的@rootfs
:
1 | btrfs subvolume snapshot @sysbase @rootfs |
接着重启电脑,我们就回到了基本系统状态,此时我们对系统的修改,就变成了我们的环境2。
还要更多环境!
如果还需要更多环境,只需要像配置环境2时一样,将当前@rootfs
重命名一下,再从基本系统,或者任何一个其他快照,创建一个新的@rootfs
快照,重启电脑,就可以创建新环境了。
而如果我们希望在环境之间切换,也非常简单,同样地,将当前@rootfs
重命名为其他名字,再将想要切换的快照重命名成@rootfs
,或者创建一个新@rootfs
快照都行。
如果我们玩坏了环境,也不用完全重装系统,只需要将不想要的环境子卷删除,btrfs subvolume delete @broken-env
,再选择一个好的环境为@rootfs
即可。非常灵活!