dd中ibs / obs / bs的用途

时间:2009-08-30 21:24:00

标签: linux file-io filesystems

我有一个脚本,可以在linux机器上的文件中创建文件系统。我看到要创建文件系统,它使用'dd'和bs = x选项,从/ dev / zero读取并写入文件。我认为通常指定ibs / obs / bs对于从真实硬件设备读取是有用的,因为具有特定的块大小限制。但是,在这种情况下,当它从虚拟设备读取并写入文件时,我看不到使用'bs = x bytes'选项背后的任何意义。我的理解在这里错了吗? (以防如果有帮助,此文件系统稍后用于启动qemu vm)

4 个答案:

答案 0 :(得分:10)

要了解块大小,您必须熟悉磁带驱动器。如果您对磁带驱动器不感兴趣 - 例如,您认为自己不会使用磁带驱动器 - 那么您现在可以重新入睡。

还记得60年代,70年代甚至80年代的电影中的磁带驱动器吗?卷轴旋转的那些,依此类推?不是你的Exabyte甚至是QIC - 四分之一英寸盒式磁带;你老式的卷轴式半英寸磁带机?在那些方面,块大小很重要。

磁带上的数据是以块的形式写的。通过记录间的差距将每个块与下一个块分开。

----+-------+-----+-------+-----+----
... | block | IRG | block | IRG | ...
----+-------+-----+-------+-----+----

根据磁带机硬件和软件的不同,可能会出现各种问题。例如,如果磁带写入块大小为5120字节并且您读取块大小为512字节的磁带,则磁带驱动器可能会读取第一个块,返回512字节,然后丢弃剩余的磁带数据;下一个读取将从下一个块开始。相反,如果磁带写入的块大小为512字节,并且您请求的块为5120字节,那么您将获得短读取;每次读取只返回512个字节,如果你的软件没有注意,你就会读垃圾。还有一个问题是磁带驱动器必须加快读取块的速度,然后放慢速度。 ASCII艺术表明IRG小于数据块;不一定是这种情况。并且花了一些时间来读取一个块,超过IRG,向后倒退到达下一个块,然后再次向前开始。如果磁带机没有内存来缓冲数据 - 便宜的那些没有 - 那么你可能会严重影响你的磁带机性能。

战争故事:使用稍微更现代的磁带机在新机器上准备工作。我使用tar编写了一个没有合理块大小的磁带(所以默认为512字节)。这是一个很大的软件 - 一定是哦,总共不到100 MB(很久以前,换句话说)。磁带写得很好,因为机器足够现代,只需几秒钟就可以完成。但是,我必须在带有旧磁带驱动器的机器上从胶带上取下材料,这个磁带驱动器没有任何板载缓冲器。因此,它一次读取材料,512字节,卷轴向前摇动,读取一个块,然后向后摇动所有半英寸,然后向前读取到下一个块,然后摇回来,并且......好吧,你可以看到它这样做,并且因为它花费了相当多的时间来读取每个512字节块,所以花费的总时间是可怕的。我的航班准备离开......我也需要获取这些数据。 (它已经足够久了,而且在一片足够远的地方,最后一刻改变飞行也不是一个选择。)长话短说,它确实被读了 - 但是如果我用了一个合理的块大小(例如5120字节而不是默认值512),我会做得更多,更快,并且失去飞机的危险要小得多(但我确实赶上飞机,可能需要20分钟,尽管在高峰时间乘坐出租车穿过巴黎。)

使用更现代化的磁带驱动器,驱动器上有足够的内存来进行缓冲并使磁带驱动器流式传输 - 连续写入而不会反转 - 这是可行的。过去,我会使用256 KB的块大小来获取流式传输QIC磁带。我最近没有对磁带驱动器做过多少工作 - 让我们看看,不是这个千年,而是在此之前几年也没有多少;当然CD和DVD成为首选的软件分发机制(当没有使用电子下载时)并不多。

但是在过去,块大小确实很重要。而且dd为它提供了很好的支持。您甚至可以通过单独指定ibs(输入块大小)将数据从使用4 KB块写入的磁带驱动器传输到另一个要写入的磁带驱动器,例如16 KB块。 obs(输出块大小)。 Darned很有用!

此外,count参数是根据(输入)块大小而定的。说'dd bs=1024 count=1024 if=/dev/zero of=/my/file/of/zeroes'复制1 MB的零是很有用的。或者复制1 MB的文件。

dd的重要性大大减弱;对于任何十年或更久以前使用磁带机的人来说,它是军械库的重要组成部分。

答案 1 :(得分:3)

块大小是一次读取和写入的字节数。据推测,有一个count=选项,它以块大小为单位指定。如果有skip=seek=选项,则这些选项也将采用块大小单位。但是,如果您正在读取和编写常规文件,并且没有磁盘错误,那么只要您可以相应地缩放这些参数并且它们仍然是整数,则块大小并不重要。然而,某些尺寸可能比其他尺寸更有效。

答案 2 :(得分:2)

从/ dev / zero读取,没关系。 ibs / obs / bs指定一次读取多少字节。根据操作系统中读/写字节的方式选择一个数字是有帮助的。例如,Linux通常以4096字节的块从硬盘驱动器中读取。如果您至少对底层硬件的读/写方式有所了解,那么指定ibs / obs / bs可能是个好主意。顺便说一句,如果你指定bs,它将覆盖你为ibs和obs指定的任何内容。

答案 3 :(得分:0)

除了Jonathan Leffler的精彩答案之外,请注意bs=选项并不总是替代同时使用ibs=obs=,特别是旧版{1}} [丑陋的]磁带驱动器的日子。

bs=选项保留dd在读取数据后立即写入数据的权利。这可能导致您不再在输出上具有相同大小的块。这是GNU对此的看法,但这种行为可以追溯到我记忆中(80年代):

  

(bs =)将输入和输出块大小设置为字节。这使得每个块的dd读取和写入字节,覆盖任何“ibs”和“obs”设置。 此外,如果未指定数据转换conv选项,则输入会在读取后立即复制到输出,即使它小于块大小。

例如,回到旧版Sun系统的QIC日期,如果你这样做了:

tar cvf /dev/rst0c /bla

它可以工作,但是当驱动器写了一个小块时会导致大量的来回抖动,并试图备份和读取以便为下一次写入正确地重新定位。

如果您将其换成:

tar cvf - /bla | dd ibs=16K obs=16K of=/dev/rst0c

你会让QIC驱动器写出更大的块,而不是那么多。

但是,如果你弄错了这个:

tar cvf - /bla | dd bs=16K of=/dev/rst0c

根据每次阅读时可用的数据量,您可能会遇到与之前完全相同的颠簸风险。

同时指定ibs=obs=会阻止这种情况发生。