问题描述
我想故意损坏文件以测试the claims that btrfs can heal itself。文章讨论了关闭文件系统,”flipping”损坏了一张照片然后重新安装它。在较旧的文件系统中,这只会被破坏,但它应该在btrfs中自行修复。理论上,这是有道理的,但我真的想测试它。
问题是文章没有解释如何做到这一点。我如何在文件系统的一个非常特定的部分更改一个位?
我还应该指出,这必须在脱机文件系统上完成,以便btrfs不会将我的写入视为故意。
编辑:虽然问题(和讨论)谈论了很多关于btrfs的问题,但我想知道是否存在实现这种损坏的文件系统独立方法(以便可以在不同的RAID类型/控制器/等之间进行比较)。
最佳解决方案
我不是专家,但btrfs-progs
软件包实际上包含一个专门用于执行此操作的工具,尽管您可能需要从源代码构建。在任何情况下,一旦安装或构建了btrfs-progs
,您就应该能够使用工具btrfs-corrupt-block
,btrfs开发人员使用该工具来测试文件系统。
现在,就像我说的,我没有太多时间玩btrfs,所以我不知道这个工具的确切用法。但有了它,你应该能够破坏一个脱机文件系统,当读取损坏的文件时它将被修复(假设你已经设置了RAID或某些东西,以便有另一个副本可供使用)。
次佳解决方案
-
获取块设备上单个扇区的值(例如
/dev/sda1
),偏移量为100万个扇区偏移量(仅举例):sudo dd if=/dev/sda1 of=/root/mysector bs=512 count=1 skip=1M
这个任意选择的1M * 512字节偏移量只是为了确保您不在文件系统的元数据部分中,实际上在包含数据的扇区上。
-
通过使用十六进制编辑器更改内容来编辑原始扇区数据。参见例如Need a good hex editor for Linux。
-
将扇区放回驱动器上,
if
和of
参数反转:sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
第三种解决方案
@Oli – 嗨,我是吉姆·萨尔特,那个写这篇文章的人。我正在使用虚拟机,这使事情变得更简单。我所做的是从JPEG文件开始,并在十六进制编辑器中打开它。我使用的特别之一是Bless,你可以在Ubuntu中安装一个简单的apt-get安装祝福。
在Bless中打开JPEG后,我点击了几次页面以进入JPEG的”meat”,然后突出显示了大约50个字节的数据,并将其复制并粘贴到文本编辑器中(在我的情况下, gedit中)。这给了我一些搜索。
现在我将JPEG保存到VM上的每个阵列中。阵列后面的存储是一系列.qcow2文件。一旦我将JPEG保存到数组中,我就可以将与每个数组相关联的.qcow2文件加载到Bless中,并搜索它们 – 它们不是很大,只是JPEG和一些元数据 – 对于那个50字节模式我突出显示并复制了JPEG。瞧,我有块腐败!此时,我可以使用Bless手动编辑存储在VM虚拟磁盘上的JPEG的单个字节 – 重要的是,在每个阵列上以完全相同的方式这样做。
唯一的缺点是,在本文中测试的RAID5阵列的情况下,我必须确保我编辑条带中的数据的实际副本,而不是条带本身的奇偶校验 – 它是一个小图像否则为空数组,因此条带中的FOLLOWING块中没有任何数据,使得奇偶校验块包含数据块中未更改的数据。如果我不小心编辑了奇偶校验块而不是数据块,则图像将显示为未更改。
最后一点 – 您不需要虚拟机来执行此操作 – 您可以使用裸机以相同的方式执行相同的操作;因为你需要使用整个原始驱动器而不是使用漂亮的小.qcow2文件,所以它只需要更多的痛苦了,你要么必须拉动驱动器并将它们放在不同的机器中,或者启动到一个实时(或只是替代)环境来搞乱它们。 (我用这种方式测试了ZFS的数据修复,但是真正的裸机,7年前我第一次对next-gen文件系统感兴趣。)
希望这可以帮助!
第四种方案
您可以尝试在打开的文件上执行FIBMAP
ioctl(2)
的小程序。
通过快速网络搜索,我发现这篇博客文章http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html详细说明了如何执行此操作 – 它甚至会为您提供一个示例程序的链接,您可以自己编译和运行该示例程序。
$ git clone git://kernel.ubuntu.com/cking/debug-code
$ cd debug-code/block-mapper-fibmap
$ make
$ sudo ./fibmap /path/to/your/image-file.jpg
这正是hdparm --fibmap
(由@falconer提到)的实现方式。
找到块编号后,您可以使用dd
功夫来修改文件,如@gertvdijk勾勒出的那样。或者你可以修改上面的fibmap.c
程序为你做翻转,直接写入绕过文件系统层的设备文件(程序的三个参数:1。文件的路径,2。包含的文件的设备文件文件系统,3.要修改的偏移量和位数)。
(免责声明:我没有测试过,也不能保证FIBMAP
ioctl(2)
可以用于环回设备或btrfs文件系统中的文件,但我强烈期望它。我猜hdparm
会在执行ioctl(2)
之前检查设备类型文件,因此失败。)
第五种方案
sudo hdparm --fibmap /PATH/TO/FILE
将为您提供文件所在的LBA。在此之后你可以使用@gertvdijk的答案。