在早些时间,我的系统提示我系统的根目录空间不足。当时我并没有在意,但是难过的是在第二天我打开电脑,输入登录密码时竟然登录失败了,而且没有任何提示。
排查过程
因为我使用了 systemd-homed 并且开启了加密,我当时以为是滚动更新或者关机异常导致脏数据1 /home 挂掉了。
我当时悲痛欲绝😢,不过好在我机敏异常,想到去登录 root因为 root 用户没有使用 homed,或许 root 用户也无法使用。。 但是绝望的是我禁用了 root 登录。我紧接着想到使用 LiveOS 来启用 root。更绝望的是我之前的 LiveOS U 盘因为临时传输文件让我格式化了!谁能懂我的痛苦啊。不过好在我手头刚好有另一台电脑,我下载了镜像进入了 LiveOS 启用了 root 用户。
之后我尝试使用 root 登录,果然登录进去了。因为怀疑是滚动更新导致挂掉,所以我使用 Timeshift 回滚Timeshift 救我狗命!,
可惜并没有效果。之后我尝试使用 homectl authenticate xxx 来进入,结果提示空间不足无法挂载。原谅我当时没有截图或者记录下来。
这是一个相当好的提示,这意味着我的 /home 目录也许没有损坏。
我立刻删了点 Timeshift 的快照,然后将家目录的空间降到 240G之前 350G。。之后就可以正常登录了。
解决方案选择
既然直到了问题的原因就是没有空间了,多给弄点空间就好了。正好我的电脑里还有一块闲置硬盘 512 G没错,我电脑里面两块硬盘,一块是之前的电脑上拔下来的。好奇的人可以看看之前的记录闲鱼卖货经历。另一块是买电脑时给的。。
那么问题就来到了如何添加。已知我目前的架构是 LUKS 全盘加密根目录参见:全盘加密教程,
在加密块上使用 btrfs 作为文件系统。而我的家目录是使用 sytemd-homed 管理的。
我想到的几种方案是
- 利用 LVM 直接将两块硬盘混合起来,变成一个虚拟池。然而我开始安装的时候就没有使用 LVM,这条路基本就堵死了。
- 直接使用 btrfs 的
btrfs derive add来直接实时给存储池添加空间。btrfs 提供一部分 LVM 的功能。 - 将额外的硬盘直接挂载给
/home目录。
我开始的考虑是第三种方案。我当时想到的好处是下次重装系统可以保留 /home 分区。但是我转念一想,我每次重装系统几乎都是「干净」重装,也就是完全从 0 开始。没必要单独分区。而且我日常也有随缘备份的习惯,也不至于丢掉重要文件。
这让我选择了方案 2。说实话,我当时并不了解如何操作这个流程,我在网上找了好多资料。基本上能看的教程和问题解答都看了,始终没有我想要的内容。这就是我写这篇文章的动机。在这里特别感谢 archlinux-cn-offtopic 和 archlinux-cn 群中友好群友对我的帮助。这几乎是我近些年在网上体验最好的社区关系了。也推荐使用 arch 的小伙伴加入这两个群,里面的人都非常友善。
添加新硬盘
考虑好添加方案后就开始实操。
先展示一下我当时的硬盘分区。其中 loop0 是 sytemd-homed 提供的本地回环挂载的加密家目录。nvme0n1 是要添加的新硬盘。
NAME TYPE SIZE PTTYPE FSTYPE MOUNTPOINTS
loop0 loop 300G crypto_LUKS
└─home-xxx crypt 300G btrfs /home/xxx
zram0 disk 4G swap [SWAP]
nvme0n1 disk 476.9G gpt
├─nvme0n1p1 part 1G gpt vfat /efi
└─nvme0n1p2 part 475.9G gpt crypto_LUKS
└─linuxroot crypt 475.9G btrfs /home
/root
/var/log
/var/cache
/tmp
/usr-local
/var/lib/docker
/var/tmp
/var/lib/libvirt
/var/lib/containers
/srv
/
nvme1n1 disk 476.9G crypto_LUKS分区
既然目前我们的硬盘已经加密了,我们当然希望加入进来的新盘也要加密。依照这个想法,我们先将新硬盘格式化。
wipefs -af /dev/nvme1n1并写入分区表。
partprobe /dev/nvme1n1之后提供一个占据全盘的分区。
sgdisk -n 0:0:0 -t 0:8309 -c 0:luks /dev/nvme1n1加密
之后对 /nvme0n1p1 进行加密。
cryptsetup luksFormat /dev/nvme1n1p1较为重要的点来了。虽然我们现在对硬盘进行了加密,并假设我们已经正确将两块硬盘混合到一起了。这就万事大吉了么?很可惜的是,并不是,因为系统无法自动将 /nvme0n1p1 进行挂载,而 btrfs 找不到这个硬盘就会报错并导致无法开机。
所以我们需要让引导知道这个硬盘在哪里,并且需要解密。
我们使用 blkid 来获取分区 UUID。
blkid/dev/mapper/linuxroot: LABEL="linuxroot" UUID="2d160a68-3525-4d3e-a536-6d5ba958b768" UUID_SUB="fc945959-b8c7-41b8-9fe1-aea5642d6275" BLOCK_SIZE="4096" TYPE="btrfs"
/dev/nvme0n1p1: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="169B-94E9" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="esp" PARTUUID="fbfee40e-e0cd-47a4-a2e7-6649abdce0be"
/dev/nvme0n1p2: UUID="149d82cd-e65e-46a3-8182-e60a30a77cba" TYPE="crypto_LUKS" PARTLABEL="luks" PARTUUID="f13bf7af-7b8d-40c7-963f-d3761d36268e"
/dev/mapper/home-xxx: LABEL="xxx" UUID="a007119c-2334-4bd9-a5e8-023e0aa24a81" UUID_SUB="10c4fc22-f75f-4343-ba06-27b010d4f6d7" BLOCK_SIZE="4096" TYPE="btrfs"
/dev/loop0: UUID="d19148f0-419c-4cbe-b5bb-679447f3e227" LABEL="lyle" SUBSYSTEM="systemd-home" TYPE="crypto_LUKS"
/dev/mapper/linuxroot2: LABEL="linuxroot" UUID="2d160a68-3525-4d3e-a536-6d5ba958b768" UUID_SUB="05b643c3-54f7-4e04-b317-586f0928ec51" BLOCK_SIZE="4096" TYPE="btrfs"
/dev/nvme1n1p1: UUID="70b0a7d3-9968-4a63-b244-884ca28f85ad" TYPE="crypto_LUKS" PARTLABEL="luks" PARTUUID="8f33a848-8590-4d41-ac68-3ff541051730"
/dev/zram0: LABEL="zram0" UUID="f574f838-3ff9-40c1-8e09-97742b8757a0" TYPE="swap"找到对应的 /dev/nvme1n1p1 的 UUID。输入 rd.luks.name=70b0a7d3-9968-4a63-b244-884ca28f85ad=linuxroot2 到 /etc/cmdline.d/root.conf 中添加对应的引导。
rd.luks.name=149d82cd-e65e-46a3-8182-e60a30a77cba=linuxroot rd.luks.name=70b0a7d3-9968-4a63-b244-884ca28f85ad=linuxroot2 root=/dev/mapper/linuxroot rootfstype=btrfs rootflags=subvol=/@ rw这样,我们就可以正确的引导。不要忘了重建引导。
mkinitcpio -P接下来你可以选择使用 TPM 来自动解密。你可以参考 配置 TPM 自动解锁 你只需要注意每次都要同时对两个硬盘都操作一遍即可。
还需要打开加密盘才能添加。
cryptsetup open /dev/nvme1n1p1 linuxroot2btrfs 添加新盘
这一步挺简单的,只需要执行:
btrfs device add /dev/mapper/linuxroot2 /需要注意的是 btrfs device add [你要添加的盘] [当前主盘挂载点] 中不要写错位置。最好使用 /dev/mapper/linuxroot2 来作为路径,而不使用 /dev/nemve1n1p1。这是因为这个路径很容易变化,例如从 nvme1n1p1 变成 nvme01n1p1,这可能导致错误。而映射地址 /dev/mapper/linuxroot2 是引导中写的地址,不会发生变化。而且需要注意不要对 /dev/nvme1n1p1 创建文件系统,只需要保持原样即可。也就是说不要使用 mkfs.btrfs!
添加进去之后你可以检查一下,使用:
btrfs filesystem show /Label: 'linuxroot' uuid: 2d160a68-3525-4d3e-a536-6d5ba958b768
Total devices 2 FS bytes used 392.91GiB
devid 1 size 475.92GiB used 392.91GiB path /dev/mapper/linuxroot
devid 2 size 476.92GiB used 000.00GiB path /dev/mapper/linuxroot2你可以看到已经添加成功,你还可以通过下方命令来检查。
btrfs filesystem usage -T /至此就完成了添加硬盘,欢呼!