基本概念
sg_write_same
是sg3_utils
软件包中的一个实用工具,用于向 SCSI 设备发送WRITE SAME
命令。这个命令用于将相同的数据块写入到多个连续的逻辑块地址(LBA)中,从而提高磁盘写入性能。这对于初始化新磁盘、擦除旧数据或写入大量重复数据非常有用。
sg_write_same 的用途
- 快速初始化:当你需要快速初始化一个新磁盘或分区时,可以使用
sg_write_same
命令写入整个区域的全零或其他数据。这比单独写入每个块要快得多。 - 擦除旧数据:如果你想删除磁盘上的所有数据,并且不关心数据的内容,可以使用
sg_write_same
命令来写入全零或其他已知的数据模式。这比传统的逐块擦除更快。 - 重复数据写入:当你需要将相同的数据块写入到磁盘上的多个位置时,
sg_write_same
可以大大提高效率。例如,当你复制一个大型文件到磁盘的多个位置时,你可以使用sg_write_same
来减少写操作的次数。
- OPERATION CODE (41h): 这是命令的操作码,标识这是一个
WRITE SAME(10)
命令。41h
是其在十六进制下的表示。 - WRPROTECT: 这个字段可能与写保护有关,它可能指示是否允许写入操作。但具体的行为可能取决于该字段的具体值和存储设备的实现。
- ANCHOR: 这个字段可能用于标识数据块写入的起始位置。在一些上下文中,它可能是一个逻辑块地址(LBA)或类似的引用。
- UNMAP: 这个字段可能指示在写入操作后是否应该解除映射某些未使用的数据块,以便回收存储空间。这在某些存储技术中(如SSD)可能是有用的。
- Obsolete: 这个字段可能指示某些旧的或不再使用的功能或选项。如果设置为有效,它可能意味着与该字段关联的功能或选项已过时或不再受支持。
- LOGICAL BLOCK ADDRESS (LSB/MSB): 这些字段用于指定要写入的逻辑块地址的起始和结束位置。LSB(最低有效位)和MSB(最高有效位)一起提供了完整的地址范围。
- GROUP NUMBER: 这个字段可能用于分组多个写入操作或请求,以便更有效地管理它们。
- NUMBER OF LOGICAL BLOCKS: 这个字段指定要写入的逻辑块的数量。
- CONTROL: 这个字段可能包含控制或校验位,用于确保命令的完整性和准确性。
使用方法
sg_write_same
命令接受多个参数来指定要写入的设备、起始 LBA、要写入的块数以及包含要写入数据的文件
示例 1:
使用 WRITE SAME(10) 命令,从文件 pattern.bin
读取一个数据块,并写入到设备的 LBA 0 开始的 1000 个块。
sg_write_same --10 --in=pattern.bin --lba=0 --num=1000 /dev/sdX |
这条命令 sg_write_same --10 --in=pattern.bin --lba=0 --num=1000 /dev/sdX
使用 sg3_utils
工具集中的 sg_write_same
命令向一个SCSI设备(在这里是 /dev/sdX
)发送一个WRITE SAME (10)命令。下面是对这条命令各部分的详细解释:
-
sg_write_same:这是
sg3_utils
工具集中的一个命令,用于向SCSI设备发送WRITE SAME命令。 -
--10:指定使用WRITE SAME (10)命令。WRITE SAME (10)是SCSI WRITE SAME命令的一个较旧的版本,与WRITE SAME (16)和WRITE SAME (32)相比,它有一些限制,比如它支持的逻辑块地址(LBA)范围和块数量较少。
-
--in=pattern.bin:指定一个包含要写入的数据的文件。在这个例子中,
pattern.bin
文件中的数据将被用作写入数据的模式或块。这个文件的内容将被复制到设备的连续逻辑块中。 -
--lba=0:指定从哪个逻辑块地址(LBA)开始写入。在这里,写入将从LBA 0开始,也就是设备的开始位置。
-
--num=1000:指定要写入的逻辑块数量。在这个例子中,将写入1000个逻辑块。
-
/dev/sdX:这是你要执行命令的SCSI设备的设备文件。在这个例子中,
/dev/sdX
是一个占位符,你应该将其替换为你的实际设备名称,如/dev/sda
、/dev/sdb
等。
综上所述,这条命令将从pattern.bin
文件中读取数据,并将这些数据写入到/dev/sdX
设备的从LBA 0开始的1000个逻辑块中。如果pattern.bin
文件中的数据不足以填充这1000个逻辑块,那么通常会使用文件中的数据来重复填充这些块,直到所有块都被填满。
示例 2:
使用 WRITE SAME(16) 命令,并且不发送任何数据(即,用零),从 LBA 100000 开始写入 10000 个块。
sg_write_same --16 --ndob --lba=100000 --num=10000 /dev/sdX |
这条命令 sg_write_same --16 --ndob --lba=100000 --num=10000 /dev/sdX
使用了 sg3_utils
工具集中的 sg_write_same
命令来向一个SCSI设备(在这个例子中是 /dev/sdX
)发送一个WRITE SAME命令。以下是对这个命令的详细解释:
-
sg_write_same:这是
sg3_utils
工具集中的命令,用于向SCSI设备发送WRITE SAME命令。WRITE SAME命令用于在连续的逻辑块地址(LBA)范围内写入相同的数据块。 -
--16:指定使用WRITE SAME (16)命令。WRITE SAME (16)是SCSI标准中的一个命令,允许指定一个最多16位的LBA范围和块数量。与WRITE SAME (32)相比,它支持的LBA范围和块数量较小。
-
--ndob:这个选项(No Data-Out Buffer)告诉设备不需要从主机接收任何数据。当使用WRITE SAME命令时,如果只是想告诉设备在指定的LBA范围内填充某个特定的模式(例如,全零),而不是从主机接收实际的数据块,就可以使用这个选项。如果没有使用
--in
选项来指定一个输入文件,则--ndob
通常会被使用。 -
--lba=100000:指定从哪个逻辑块地址(LBA)开始写入。在这个例子中,写入将从LBA 100000开始。
-
--num=10000:指定要写入的逻辑块数量。在这个例子中,将写入10000个逻辑块。
-
/dev/sdX:指定要执行命令的SCSI设备的设备文件。在这个例子中,
/dev/sdX
是目标设备,其中X
是一个占位符,代表具体的设备号(如a
、b
、c
等)。
综上所述,这条命令告诉 /dev/sdX
设备从LBA 100000开始,连续写入10000个逻辑块,并且不需要从主机接收任何实际的数据(因为使用了 --ndob
选项)。这通常用于快速初始化存储设备的一个区域,将其填充为某个特定的模式(例如,全零或全一),而不需要从主机传输大量的数据。
其中200表示512字节,400表示1024字节
注意事项
- 在使用
sg_write_same
命令之前,请确保你了解它的作用,并已经备份了重要数据。错误的WRITE SAME
命令可能会导致数据丢失。 - 不是所有的 SCSI 设备都支持
WRITE SAME
命令。在尝试使用sg_write_same
之前,请检查你的设备是否支持该命令。 sg_write_same
命令可能需要适当的权限才能运行。在某些系统上,你可能需要使用sudo
或其他方法来获得必要的权限。
参数解释:
-
--10|-R
发送WRITE SAME(10)
命令,即使指定了--unmap
。这表示使用 10 字节的 CDB(命令描述符块)来发送WRITE SAME
命令。 -
--16|-S
发送WRITE SAME(16)
命令。默认情况下,当未指定--unmap
,LBA+NUM 不超过 32 位,且 NUM 不大于 65535 时,会使用WRITE SAME(10)
。否则,默认使用WRITE SAME(16)
。 -
--32|-T
(
发送WRITE SAME(32)
命令。不过,在大多数情况下,WRITE SAME(32)
并不常见,因为WRITE SAME(16)
已经可以处理大量的 LBA 和块数了。--10|-R
发送WRITE SAME(10)命令(即使给出了--unmap
)--16|-S
发送WRITE SAME(16)命令(默认是10,除非给出了--unmap
,或者LBA+NUM超 过32位,或者NUM大于65535;则默认为16)--32|-T
发送WRITE SAME(32)命令(默认是10或16)) -
--anchor|-a
在 CDB 中设置 ANCHOR 字段。这通常用于某些特定的设备或高级用例。 -
--grpnum=GN|-g GN
设置组号字段(Group Number),默认为 0。这也是一个较高级别的选项,通常用于某些特定的设备或配置。 -
--help|-h
打印出使用信息。 -
--in=IF|-i IF
指定一个文件(IF),该文件包含要写入的一个数据块。你可以使用--xferlen
参数来指定从文件中读取的字节数,否则将使用整个文件。 -
--lba=LBA|-l LBA
指定开始写入的逻辑块地址(LBA),默认为 0。 -
--lbdata|-L
设置 LBDATA 位(已废弃)。在当前的 SCSI 标准中,这个位不再使用。 -
--ndob|-N
设置 NDOB(无数据输出缓冲区)位在 CDB 中。这通常用于某些特定的设备或高级用例。 -
--num=NUM|-n NUM
指定要写入的逻辑块数量(NUM),默认为 1。请注意,NUM 为 0 时在某些设备或驱动程序中可能有特殊含义(如“剩余的设备”)。 -
--pbdata|-P
设置 PBDATA 位(已废弃)。在当前的 SCSI 标准中,这个位不再使用。 -
--timeout=TO|-t TO
设置命令超时时间(单位:秒),默认为 60 秒。 -
--unmap|-U
设置 UNMAP 位。然而,需要注意的是,sg_write_same
命令本身并不执行 UNMAP 操作。这个参数主要用于选择发送WRITE SAME(16)
命令(如果--10
或--16
没有被明确指定),因为WRITE SAME(16)
允许 UNMAP 位的设置。但是,设置这个位并不意味着执行 UNMAP 操作;它只是将这个位设置为允许设备在写操作后释放未使用的块(如果设备支持并配置为这样做)。 -
--verbose|-v
增加输出信息的详细程度。 -
--version|-V
打印版本字符串然后退出。 -
--wrprotect=WPR|-w WPR
设置 WRPROTECT 字段的值,默认为 0。这通常用于某些特定的设备或配置。 -
--xferlen=LEN|-x LEN
从输入文件(由--in
或-i
指定)中读取并发送到设备的字节数。如果没有指定,则使用输入文件的整个长度。
示例
假设你有一个名为 data_block.bin
的文件,它包含一个 512 字节的数据块,并且你想将这个数据块写入到 /dev/sda
的 LBA 1000 开始的 100 个块中:
bash复制代码
sg_write_same --lba=1000 --num=100 --in=data_block.bin /dev/sda |
如果你想在写入后允许设备释放未使用的块(如果设备支持并配置为这样做),并且你的设备或驱动程序支持 WRITE SAME(16)
,你可以使用:
bash复制代码
sg_write_same --lba=1000 --num=100 --in=data_block.bin --unmap /dev/sda |