为什么 dd 从输出设备读取?

为什么 dd 从输出设备读取?

在将 CentOS 7 x86_64 DVD 映像复制到 USB 驱动器 (sdb)时dd,我使用iostat.

它一直在主要写入 USB 驱动器之间交替:

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              18,00       380,00        28,00        380         28
sdb              79,00        16,00      9000,00         16       9000

并同时从硬盘和 USB 驱动器读取:

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              53,00      5180,00         0,00       5180          0
sdb            1329,00      5316,00         0,00       5316          0

机器中没有其他任何事情发生,当dd停止时,磁盘变得空闲。

这是某种内部校验和过程吗dd

Linux 3.16.0 中 USB 驱动器的驱动程序有什么固有的吗?

答案1

在安全擦除外部 (USB 2.0) 硬盘时,我遇到了类似的情况:长时间读取,然后是几秒钟的高吞吐量写入,而我预计 100% 写入。我使用 pv 来显示整体写入速度(请参阅下面的命令),平均写入速度为 10MB/s,突发为 14MB/s,持续约 10 秒,然后是几 kB/s。我的 iostat 输出看起来非常像你的。

原来是我的问题dd 块大小太小(512 字节)。我怀疑正在发生的事情是内核将块读入其每块 1k 的缓冲区中,以便 dd 可以一次覆盖 512 个字节,然后将其刷新。我不是内核专家,所以这只是一个猜测。

我可以这么说将我的 dd 块大小提高到 72K 产生了巨大的变化。我现在看到 >40MB/s 的持续写入。这非常接近 USB 2.0 可以提供的理论最大值(480Kb/s,不包括 USB 开销),也非常接近这个 10 年前的磁盘可以达到的最大持续写入速度(大约 55MB/s),所以我很满意这或多或少是裸机速度。

这是我用来擦除驱动器的命令:

openssl enc -aes-256-ctr -pass \
pass:"$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64)" \
-nosalt </dev/zero \
| pv -bartpes 160041885696 -B 128K \
| dd bs=72K count=2170707 of=/dev/sdf iflag=fullblock

第 1-3 行使用从 /dev/urandom 生成的密码通过 AES-256-CTR 加密传输 /dev/zero。所以它是一个加密随机垃圾流。

第 4 行显示了进度,考虑到 160GB 驱动器的字节数并使用 pv 为 128KiB 的传输缓冲区大小。

第 5 行使用我使用计算器选择的块大小,试图找到 512 的最大倍数,该倍数是驱动器总字节数的一个因素。 iflag=fullblock 使 dd 重复读入其缓冲区,直到在写入之前有 1 个完整块。

相关内容