我一直对验证备份到可移动媒体的数据有些偏执,因此在将内容复制到 USB 闪存驱动器或便携式硬盘后,我总是卸载该驱动器,重新安装它,然后将存储的文件与原始文件进行 diff -q 比较。
几年前我发现(至少用我拥有的设备),我可以看到大约 1bit/GByte 的位错误。不知怎么的(我忘了细节),我发现解决办法是在写入任何数据之前,
echo 64 > /sys/block/sda/device/max_sectors
(当然假设媒体显示为 sda)。只要我记得这样做,我就从来没有遇到过任何问题。(我相信默认值max_sectors
是 128)。
我的问题是:
只有我一个人有这种问题吗?我见过各种闪存驱动器、便携式硬盘、主板和笔记本电脑都存在这个问题(但从未对所有组合进行过详尽的测试,以查看是否有任何组合真正可靠)。用于 Windows 的介质和双启动 Windows 的机器似乎没有类似的问题,因此它似乎是 Linux 特有的。
问题究竟出在哪里?是不符合标准的介质、芯片组还是电缆?
我可以在我的系统 (Debian Lenny) 上配置什么来自动设置
max_sectors
?(一些 HAL 脚本或 sysctl 调整?更全局的 /sys 参数?)。大概默认的 128 在内核的某个地方,但自定义内核似乎有点过分。
谢谢你的建议
答案1
首先,当您获得一个新设备时,我建议您将数据写入其中,然后使用 md5sum/sha1sum/... 验证数据。特别是便宜的 USB 设备容易损坏。 :( USB 笔在前几 (几百) MB 上运行良好,但在最后几 MB 上容易丢失数据,这并不罕见。遗憾的是,许多用户并没有意识到这一点,并且太晚才注意到问题:当 USB 笔已满时。
您所说的问题通常位于 USB 芯片组(尽管有时只有在使用特殊硬件组合时才会出现)。如果它在 Windows 上工作正常,但在使用相同硬件的 Linux 上失败,这听起来像是 Windows 驱动程序中存在一种解决方法,而 Linux 内核中尚不存在这种解决方法。而 Linux 默认使用 max_sectors=240(即 120kB),根据http://www.linux-usb.org/FAQ.html#i5(其中也提到了 Genesys Logic 制造的适配器的一些问题)。
要自动设置 max_sectors:使用 udev 执行此任务。它允许您仅为要调整的设备配置 max_sectors。
您可以检索有关正在运行的 USB 设备的必要信息:
# udevadm info -a -p /sys/class/block/sda/
或者对于较旧的 udev 版本:
# udevinfo -a -p /sys/class/block/sda/
然后获取您想要用于规则的属性,并创建一个新文件,如 42-fix-max_sectors.rules,并将其放在 /lib/udev/rules.d(使用较新的 udev 版本时)或 /etc/udev/rules.d(对于较旧的 udev 版本)。要了解此配置文件的外观,请执行以下操作:
SUBSYSTEM=="block", ATTRS{model}=="Voyager Mini ", RUN+="/bin/sh -c '/bin/echo 64 > /sys/block/%k/device/max_sectors'"
确保在编写规则文件后重新加载 udev(通过运行 /etc/init.d/udev reload)。为了测试您的配置文件,我建议使用:
# udevadm test /sys/class/block/sda/
PS:如果我注意到任何问题,因为通常不值得付出努力去寻找任何解决方法(而且我确信你知道墨菲会在你认为你已经成功工作时抓住你 ;))。
答案2
根据文件的数量或文件的大小,我过去曾见过类似的事情。
在备份/复制超过 400 万个 .PDF 文件时,我们发现某些文件的 MD5 哈希值并不相同!
对我们有用的是 rsync。
我建议您尝试的一件事是 rsync 文件并查看是否仍然遇到数据丢失。
希望这可以帮助。
答案3
在我的 Ubuntu 9.04 系统上,/etc/udev/rules.d
和都/lib/udev/rules.d
使用。README
建议使用 来/etc/udev/rules.d
作为本地规则或覆盖 中包含的包提供的规则/lib/udev/rules.d
。此外,它还说:
udev 守护进程使用 inotify 监视此目录,以便自动获取对这些文件的更改,因此它们必须是文件而不是指向另一个位置的符号链接(如 Debian 中的情况)。
我在这里发布这些信息是因为 Ubuntu 是基于 Debian 的,这些差异对于那些认为行为相同的人来说可能很重要。
答案4
这太棒了!我预计所有硬件都会出现随机数据损坏,但我注意到 USB 设备太差了,这真是一场噩梦。显然,根本原因是糟糕的 USB 芯片组以及不关心数据完整性的协议和文件系统开发人员,但非常感激能够找到一种让 USB 设备可用的解决方法。
您仍应始终预期数据损坏,因为您不知道会遇到哪些导致数据损坏的新问题。在复制大型数据集之前,请保留所有文件的哈希值,并在之后进行验证。
cd /oldfs
find . -type f -exec md5sum {} \; >& /oldfs.md5
rsync -a . /newfs/
cd /newfs
md5sum -c /oldfs.md5 | grep -v OK$
既然已经发现 max_sectors 的默认设置会导致许多设备损坏,那么最好依靠发行版供应商和内核开发人员来分发默认设置,这些默认设置侧重于常见设备的数据完整性,而不是少数设备的性能。当数据损坏时,不合规的设备很难成为不使用它们期望的设置的理由。