不支持Diskfilter写入>是什么导致此错误?


88

离开Grub菜单时,在Ubuntu启动屏幕之前,会出现此消息。

如何解决问题以清除消息?

那是什么意思?

error:  Diskfilter writes are not supported

系统启动,并且看起来工作正常。


1
在Ubuntu Desktop 15.04中仍未修复...
ThePiercingPrince

1
仍未在16.04中修复。如此难以解决的错误修复步伐很难跟上。
Paul Tomblin

Answers:


145

这是一个错误!

在最新版本的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_headerupdate-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如何保护自己免受RAID和LVM内部写入的影响?

为了在文件系统中正确读取/写入,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
  • 如果GRUB使用diskfilteror 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

特别感谢您提供的错误参考。我希望您能理解,但我发现nux的解决方案更具吸引力。;)
运行CMD

6
嗨@ClassStacker,我总结了答案!它很大,很多人都很难理解:p它仍然很大,但至少我按节进行了组织。因此,现在您只能查看感兴趣的部分。
罗里森·弗雷塔斯

8
哇。谢谢。如果有“本月答案”功能,我将为您投票。此外,您应获得“无BS”奖。这种文章确实具有价值,并且与论坛相比,该站点网络之间存在巨大差异。
运行CMD

1
遗憾的是,我受到了该错误的影响,并且错误报告或此处的编辑00_header文件中的所有修复均无效。我不会禁用quick_boot使其消失。
douggro

@douggro我不确定为什么编辑后的00_header文件(按这里的建议)不起作用。我知道,仅因为它对我(以及对Rarylson Freitas)有用,并不意味着它一定对所有人都有效。但是,您确定对新旧事物给予正确的权限00_header并可以运行update-grub吗?(如果您只是00_header就地编辑 ,chmod则不需要,但update-grub仍然是必需的。)
Eliah Kagan 2014年

33

我认为此错误是由于RAIDLVM分区而发生的。

对于此问题的临时解决方案:

编辑:/etc/grub.d/10_linux

更换 'quick_boot="1"' with 'quick_boot="0"'

然后 :

sudo update-grub

谢谢,它运行良好。是的,我对所有卷都使用LVM。
RCF 2014年

谢谢您的解决方案。它节省了我很多工作。您还有一些背景资料吗?
运行CMD

@ClassStacker如果您要从nux寻求更多信息,则需要编辑注释以(@nux)开头。如果您问我,您正在寻找哪种背景?
RCF

2
@ RCF-U14.04 1)不,我不必。只需单击“添加评论”->“帮助”即可了解“将始终将您的评论通知发表者”。2)我想(从nux)知道为什么这可以解决问题,特别是考虑到Rarylson Freitas的广泛回答。但是,如果您可以回答,请随时这样做。
在2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.