每次在 update-grub 运行后有新的 linux-image 时,它apt upgrade
都会扫描整个驱动器以查找 Linux 映像。它还会扫描所有 ZFS 快照。一段时间后,它会在升级过程中产生巨大的控制台输出,其中包含如下日志:
[...]
cannot open 'bpool/BOOT/ubuntu@install': dataset does not exist
Found linux image: vmlinuz-4.15.0-23-generic in rpool/ROOT/ubuntu@install
Found initrd image: initrd.img-4.15.0-23-generic in rpool/ROOT/ubuntu@install
cannot open 'bpool/BOOT/ubuntu@otherSnapshot': dataset does not exist
Found linux image: vmlinuz-4.15.0-23-generic in rpool/ROOT/ubuntu@otherSnapshot
Found initrd image: initrd.img-4.15.0-23-generic in rpool/ROOT/ubuntu@otherSnapshot
cannot open 'bpool/BOOT/ubuntu@anotherSnapshot': dataset does not exist
Found linux image: vmlinuz-4.15.0-23-generic in rpool/ROOT/ubuntu@anotherSnapshot
Found initrd image: initrd.img-4.15.0-23-generic in rpool/ROOT/ubuntu@anotherSnapshot
[...]
有没有办法告诉 update-grub.zfs
在扫描期间跳过目录?
GRUB_DISABLE_OS_PROBER=true
通过输入禁用 os-prober\etc\default\grub
对我来说不起作用。据我所知,os-prober 用于扫描除可启动驱动器之外的所有其他驱动器,并且 ZFS 快照位于可启动分区上。
答案1
我也为此烦恼不已。我每 5 分钟制作一次快照,这意味着update-grub
通常需要半个小时才能完成,没有必要扫描所有快照。
因此,我进行了一些挖掘,添加了set -x
各种脚本,update-grub
最后缩小了此行为的定位范围(至少在 Ubuntu 20.04 上)。以下是如何禁用快照扫描:
/etc/grub.d/10_linux_zfs
使用文本编辑器打开文件- 找到该函数
bootlist()
。 - 注释掉(在前面加上
#
)以下几行(对我来说,它们位于第 543 行至 545 行):
for snapshot_dataset in $(zfs list -H -o name -t snapshot "${dataset}"); do
boot_list="${boot_list}$(get_dataset_info ${snapshot_dataset} ${mntdir})\n"
done
- 利润。
编辑:我验证了此更改之后update-grub
仍然会为我的系统上已安装的内核添加所需的启动菜单项。
从粗略的调查来看,此代码路径似乎仅用于为快照中的内核映像添加启动菜单条目(如果它们包含不同的条目)。如果您不关心这些(例如,我不关心),则此更改应该是安全的。
答案2
改编自@tlanger的回答。这个答案的优点是它仍然应该考虑每个数据集的最新十个快照。只是没有你所做的一切。
sudo vim /etc/grub.d/10_linux_zfs
输入
/get information from snapshots of
后按 Enter,跳转到正确的位置用这个替换嵌套循环:
for dataset in $(get_root_datasets); do
# get information from current root dataset
boot_list="${boot_list}$(get_dataset_info ${dataset} ${mntdir})\n"
# get information from snapshots of this root dataset
# LB: change on 2022-04-25 to speed up update-grub
##for snapshot_dataset in $(zfs list -r -H -o name -t snapshot "${dataset}" | grep "${dataset}"@); do
for snapshot_dataset in $(zfs list -r -H -o name -S creation -t snapshot "${dataset}" | head -n 10 | grep "${dataset}"@); do
boot_list="${boot_list}$(get_dataset_info ${snapshot_dataset} ${mntdir})\n"
done
done
- 根据您的使用情况调整
head -n 10
为您认为合理的任何数字。 - 为了您自己的方便,如果发生故障,请更改评论中的日期。
- 测试一下
update-grub
,发现现在速度快多了。