离开Grub菜单时,在Ubuntu启动屏幕之前,会出现此消息。
如何解决问题以清除消息?
那是什么意思?
error: Diskfilter writes are not supported
系统启动,并且看起来工作正常。
离开Grub菜单时,在Ubuntu启动屏幕之前,会出现此消息。
如何解决问题以清除消息?
那是什么意思?
error: Diskfilter writes are not supported
系统启动,并且看起来工作正常。
Answers:
在最新版本的Ubuntu Server LTS(Ubuntu Server 14.04 LTS)中,当您在LVM或RAID分区内创建启动分区(或根分区,如果启动分区不存在)时,会发生此错误。 。
您可以在Ubuntu Launchpad中获得有关此错误的更多信息:错误#1274320“错误:不支持diskfilter写入”。
更新:此错误已在Ubuntu Server 14.04和某些较新的Ubuntu版本中修复。可能只需要运行即可apt-get upgrade
。
系统启动时,GRUB读取中的load_env
数据/boot/grub/grubenv
。该文件称为GRUB环境块。
从GRUB手册中:
能够记住从一次引导到下一次引导的少量信息通常很有用。
[...]
在引导时,load_env命令(请参见load_env)从中加载环境变量,而save_env(请参见save_env)命令将环境变量保存到其中。
[...]
grub-mkconfig
使用此工具来实施GRUB_SAVEDEFAULT
可以在以下行为中建立此行为/etc/grub.d/00_header
(update-grub
使用此文件生成/boot/grub/grub.cfg
文件):
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
问题在于该save_env
语句仅在简单的安装中有效(您不能save_env
在RAID或LVM磁盘中运行)。从GRUB手册中:
出于安全原因,仅当安装在普通磁盘(无LVM或RAID),使用非校验和文件系统(无ZFS)以及使用BIOS或EFI功能(无ATA,USB或IEEE1275)时,此存储才可用。
GRUB recordfail功能使用该save_env
语句来更新recordfail状态(请参见Ubuntu帮助 -Grub 2中的“上次引导失败或引导进入恢复模式”部分)。但是,在Ubuntu 14.04(和最新的Debian版本)中,save_env
即使GRUB安装在LVM或RAID中,也会使用该语句(recordfail功能内)。
让我们看一下从104到124的行/etc/grub.d/00_header
:
if [ "$quick_boot" = 1 ]; then
[...]
case "$FS" in
btrfs | cpiofs | newc | odc | romfs | squash4 | tarfs | zfs)
cat <<EOF
# GRUB lacks write support for $FS, so recordfail support is disabled.
[...]
if [ -n "\${have_grubenv}" ]; then if [ -z "\${boot_once}" ]; then save_env recordfail; fi; fi
当使用不受支持的文件系统(btrfs,zfs等)时,GRUB会正确跳过recordfail功能,但是它不会随时跳过LVM和RAID。
为了在文件系统中正确读取/写入,GRUB会加载适当的模块。
GRUB 在RAID分区中使用diskfilter模块(insmod diskfilter
),在LVM分区中使用lvm模块。
让我们看一下diskfilter模块的读/写实现:
apt-get source grub2
vim grub2-2.02~beta2/grub-core/disk/diskfilter.c
我在这里粘贴代码(从808到823行)。此问题中显示的警告出现在第821行:
static grub_err_t
grub_diskfilter_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf)
{
return read_lv (disk->data, sector, size, buf);
}
static grub_err_t
grub_diskfilter_write (grub_disk_t disk __attribute ((unused)),
grub_disk_addr_t sector __attribute ((unused)),
grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"diskfilter writes are not supported");
}
该grub_diskfilter_read
功能已实现(GRUB可以读取RAID文件系统)。但是,该grub_diskfilter_write
函数会引发GRUB_ERR_NOT_IMPLEMENTED_YET
错误。
quick_boot=0
解决问题?为什么这是错误的解决方案?如果您在/etc/grub.d/00_header
代码中再看一遍,将会看到仅在时使用了recordfail功能quick_boot=1
。因此,quick_boot
从1 更改为0将禁用recordfail功能,并禁用RAID / LVM分区中的写操作。
但是,它也会禁用许多其他功能(运行grep \$quick_boot /etc/grub.d/*
,您会看到)。更重要的是,如果有一天您将/boot/grub
目录更改为RAID / LVM之外,那么recordfail功能仍将禁用。
综上所述,此解决方案不必要地禁用了功能,并且不是通用的。
save_env
当GRUB位于LVM或RAID分区内时,正确的解决方案应考虑禁用该语句。
在Debian Bug Tracker系统中提出了一个补丁来实施该解决方案。可以在以下位置找到它:https : //bugs.debian.org/cgi-bin/bugreport.cgi?bug=754921
该补丁背后的想法是:
grub-probe --target=abstraction "${grubdir}"
命令以获取GRUB用于读取/写入目录中文件的抽象模块类型/boot/grub
;diskfilter
or lvm
模块,则跳过recordfail save_env
语句,并在/boot/grub/grub.cfg
文件中写一个适当的注释;
# GRUB lacks write support for /dev/md0, so recordfail support is disabled.
如果您不想等待Ubuntu / Debian家伙在官方代码中应用此补丁,可以使用我的补丁00_header
:
# Download
wget https://gist.githubusercontent.com/rarylson/da6b77ad6edde25529b2/raw/99f266a10e663e1829efc25eca6eddb9412c6fdc/00_header_patched
# Apply
mv /etc/grub.d/00_header /etc/grub.d/00_header.orig
mv 00_header_patched /etc/grub.d/00_header
# Disable the old script and enable the new one
chmod -x /etc/grub.d/00_header.orig
chmod +x /etc/grub.d/00_header
# Update Grub
update-grub
00_header
文件中的所有修复均无效。我不会禁用quick_boot
使其消失。
00_header
文件(按这里的建议)不起作用。我知道,仅因为它对我(以及对Rarylson Freitas)有用,并不意味着它一定对所有人都有效。但是,您确定对新旧事物给予正确的权限00_header
并可以运行update-grub
吗?(如果您只是00_header
就地编辑 ,chmod
则不需要,但update-grub
仍然是必需的。)
我认为此错误是由于RAID或LVM分区而发生的。
对于此问题的临时解决方案:
编辑:/etc/grub.d/10_linux
更换 'quick_boot="1"' with 'quick_boot="0"'
然后 :
sudo update-grub