我有一台三星 XE303C12,我一直在 SD 卡上运行 Arch Linux ARM。SD 卡的分区表如下:
- vboot 包装的 ALARM 内核占用的 Chrome OS 内核分区。
- 每当将 U-Boot 安装到分区 1 而不是 Arch Linux 内核时,我都会使用它来配置 U-Boot 的 ext2 分区。
- 我安装 Arch Linux 的根文件系统。
最近尝试一次性更新所有软件包,结果却损坏了根文件系统。我看到一些消息,说将内核刷新到 SD 卡上的某个分区,文件系统无法以只读或读写方式挂载。我尝试用 修复它,它多次fsck
提示我如何处理 inode,但我意识到它可能会针对分区上的每个 inode 询问我这个问题,于是我运行了fsck -y /dev/mmcblk1p3
。这可能运行了几百个 inode 直到停止。我不记得错误消息了。
为了保存数据以供将来恢复,我/dev/mmcblk1p3
使用 将其备份到 USB 驱动器上的 FAT32 文件系统dd
。由于 FAT32 无法容纳大于 4 GiB 的文件,我决定使用一些 shell 代码和循环将其分成几段。
跳过一些事情,我意识到dd
在过程开始时速度更快(我将其bs
设置为 512 的更大倍数以使其更快),因此第一个 64 MiB 段将在 3 秒内写入 USB 文件系统,并且每次迭代都会逐渐变慢。我发现这是因为磁盘缓存已满。
我寻找一种方法来清除缓存,dd
然后我偶然发现了这个帖子在 Unix Stack Exchange 网站上。顶部答案说要执行sync; echo 3 > /proc/sys/vm/drop_caches
。该答案下的评论指出该设置不是固定的,并且该评论中的链接让我想到echo 3 > /proc/sys/vm/drop_caches
在每次迭代之前执行dd
。我尝试过,但dd
复制速度仍然下降。
第一篇文章的答案中提到的第二个解决方案是使用 来dd
绕过iflag=direct
缓存。我这样做了,但我也使用了,oflag=direct
因为我认为缓存将同时适用于从 SD 卡复制和写入 USB。这评论说应该nocache
使用 而不是direct
,所以我也尝试了。两种方法都经历了从 ~17 MB/s 到 ~1-3 MB/s 的下降。
我猜我可能没有正确使用这些方法,那么有没有办法在每次迭代时可靠地刷新缓存以加快dd
速度,或者根本不使用缓存?
答案1
只要bs
使用的块大小 ( )dd
足够大,它实际上只受硬件速度的限制。我猜你只需要等待。
现在我需要一个计算器...找不到,只有bc
。所以你使用bs=
2 的 25 次方...所以大约 3300 万,这足够大了(仅供参考,使用bs
像 1 或 512 这样的小数通常会使 dd 变得很慢)。
有可能,甚至很有可能,SD 卡和/或 USB 驱动器读写速度不会更快。初始“快速”写入可能只是填充写入缓存,而实际写入速度始终相同缓慢。先刷新缓存只会给人一种写入速度更快的假象,但这种假象会持续更长时间。
因此,您在 SD 卡上安装的 Arch 已完全损坏,并且文件系统严重受损,并且您已经在其上运行了几次 fsck...我猜现在修复安装几乎毫无希望,而全新安装会快 1000 倍且更容易。
如果你可以安装它并复制任何值得保留的数据,为什么不现在就这么做,而忘记进一步的恢复呢?重要数据应该始终有备份无论如何,真的没有什么事情可做。
仅供参考,您还可以dd
在写入之前压缩图像,gz 管道很好,可以节省大量空间如果可用空间中有很多零,但这会使以后安装映像变得更加困难。Squashfs 也可以对整个驱动器进行映像,以便以后进行可安装的只读访问。
[不妨把这个放在“答案”中]
答案2
我猜我可能没有正确使用这些方法,那么有没有办法在每次迭代时可靠地刷新缓存以使 dd 更快,或者根本不使用缓存?
如果您使用 ddrescue,您可以使用 -d 选项至少在输入端避免使用缓存。
-d, --direct 使用直接磁盘访问输入文件