Repeat a Block Write Safely with sg_write_same
sg_write_same writes one block pattern across a run of logical blocks, or asks the device to unmap that range instead. It can destroy data in seconds, so treat every example here as a template, not a command to paste. Allow about 15 minutes for a prepared test device, plus time to confirm the target LBA range from your storage documentation.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Confirm the executable and its version
- 2. Inspect the target without writing
- 3. Write a bounded range of zeros
- 4. Choose the command size deliberately
- 5. Repeat a supplied binary block
- 6. Treat zero as a special count
- 7. Use UNMAP only when provisioning support is confirmed
- 8. Recover from a mistaken test
- Package. You need
sg3-utils; here that issg3-utils 1.46-3ubuntu4. - Device. A SCSI device that supports the WRITE SAME variant you plan to send, and permission to open its device node.
- Versions. The binary here reports
sg_write_same version: 1.31 20200430; the installed manual page is labelledsg3_utils-1.45. Distributions package these with different version labels, so check your own.
Warning
Every write example below changes storage. Do not substitute a production disk until you have verified the device, starting LBA, block count, and intended pattern. The examples use an obvious placeholder device that must be replaced deliberately.
1. Confirm the executable and its version
Start with commands that do not touch a device:
$ command -v sg_write_same
/usr/bin/sg_write_same
$ sg_write_same --version
sg_write_same: version: 1.31 20200430
That output is from this machine; yours may report a different version. Read the local manual page too, because the command's defaults and safety checks are the contract you are about to use.
Checkpoint
If command -v prints nothing, install or repair sg3-utils through your normal package-management process before continuing. Installation is an administrative action, not part of the write procedure.
2. Inspect the target without writing
Set the device name only after checking it against your SCSI topology and change records. sg_readcap reports the logical block size and capacity; sg_vpd shows the block limits and provisioning pages that affect WRITE SAME.
$ DEVICE=/dev/sgX
$ sg_readcap "$DEVICE"
$ sg_vpd --page=0xb0 "$DEVICE"
$ sg_vpd --page=0xb2 "$DEVICE"
- Use the real device node. These commands are read-only, but a wrong device name still gives you information about the wrong target.
- Watch the Block Limits page. It may report a maximum WRITE SAME length and the WSNZ bit, meaning a number-of-blocks value of zero is not accepted.
- Watch the Logical Block Provisioning page. It indicates whether the device can use WRITE SAME with UNMAP.
- Never guess the block size. Do not infer it from a filesystem mount point; record the value
sg_readcapreturns and use it when constructing an input block.
3. Write a bounded range of zeros
With a verified test device, choose a starting LBA and a positive count. This command writes one zero-filled logical block repeatedly to 63 consecutive blocks:
$ sudo sg_write_same --lba=0x1234 --num=63 "$DEVICE"
--lbaaccepts decimal or hexadecimal values such as0x1234.--numcounts logical blocks, not bytes.- No
--inor--ff? The data block is filled with zeros. - No
--xferlen? The utility asks READ CAPACITY for the logical block length and sends one repeated block in the data-out buffer.
The default count is 1, but the default LBA is 0: a dangerous combination on an in-use disk. The utility therefore requires at least one of --in, --lba, or --num; keep both --lba and --num explicit in scripts.
Expected success is a zero exit status and usually no output:
$ status=$?
$ printf 'sg_write_same exit status: %s\n' "$status"
sg_write_same exit status: 0
That status confirms command completion, not that you selected the right disk. Verify the target and range in your change record before treating it as a successful storage operation.
4. Choose the command size deliberately
By default the utility selects WRITE SAME(10). It switches to WRITE SAME(16) when the LBA range needs more than 32 bits, the count exceeds 65535, or --unmap is used. Force one of the three sizes with exactly one of --10, --16, or --32:
$ sudo sg_write_same --16 --lba=0x1234 --num=63 "$DEVICE"
Do not add a force option merely to make an error disappear; the device must support the selected SCSI command. WRITE SAME(32) also needs a transport path that accepts a 32-byte CDB. Old Linux SCSI generic support did not accept CDBs larger than 16 bytes.
5. Repeat a supplied binary block
To write a pattern other than zeros, make a binary file exactly the size of one logical block, then pass it with --in. For a device whose logical block size is 512 bytes:
$ dd if=/dev/zero of=pattern.bin bs=512 count=1 status=none
$ sudo sg_write_same --in=pattern.bin --lba=0x1234 --num=63 "$DEVICE"
- The first command is safe. It only creates a zero block in the current directory; it is not a substitute for checking the target.
- Short files get padded. If the input file is shorter than an explicitly supplied
--xferlen, the utility pads with zeros. With no transfer length supplied, the file length determines the data-out buffer length. - Match the block size. Keep the file length equal to the device's logical block size unless you have a specific protection-information layout to apply.
- Stdin works too. Pass
--in=-to read from standard input, but avoid interactive pipelines for destructive operations: a delayed or truncated stream is hard to review. --fffills the data-out buffer with0xffbytes when no input file is supplied.
6. Treat zero as a special count
Do not use --num=0 as a shorthand for an unknown length. SCSI devices may interpret zero as every block from the starting LBA to the end of the device, which can take a long time and clear an entire disk. Devices with WSNZ set reject zero instead.
If a full-device operation is genuinely intended, stop and calculate the range from the device capacity, confirm an approved maintenance window, and check the device name a second time. A large positive count can also exceed the default 60-second timeout. Raise it only after estimating the operation:
$ sudo sg_write_same --lba=0x1234 --num=100000 --timeout=1800 "$DEVICE"
The WRITE SAME command has no IMMED bit, so the utility waits for the device. A timeout is not proof that the device stopped changing data; check the target's documentation and logs before retrying.
7. Use UNMAP only when provisioning support is confirmed
--unmap requests logical block provisioning rather than writing an ordinary pattern. The utility selects WRITE SAME(16) by default for this option:
$ sudo sg_write_same --unmap --lba=0x1234 --num=63 "$DEVICE"
Confirm the device's provisioning support first. The effect is device-dependent: an unmapped read may return zeros when the device reports LBPRZ, but that is not the same guarantee as writing a durable zero pattern. If the device lacks the required capability, expect an error or an operation that does not provide the semantics your application needs.
8. Recover from a mistaken test
- There is no universal undo for overwritten blocks. If the range mattered, restore it from a verified backup or a copy made before the write.
- For a test device, recovery is normally to recreate its filesystem or restore its test image, according to the device's role.
- Do not improvise a repair with another WRITE SAME command: it can overwrite more blocks and does not recover the old contents.
- If the command fails, save its exit status and diagnostic output, then inspect the device logs and SCSI sense data.
- Check everything before retrying: device path, LBA range, count, logical block size, command variant, protection-information settings, and timeout. Do not repeatedly retry after a timeout until you know whether the target completed it.
Done means
- Version checked.
sg_write_sameand its installed version were verified. - Target confirmed. The device, logical block size, LBA, count, and intended data pattern were checked before any write.
- Range was explicit. The write used an explicit positive range, unless a separately approved end-of-device operation was required.
- UNMAP was deliberate. It was used only after checking the device's provisioning capabilities.
- Recovery path exists. The exit status and change record were retained, and a backup or recovery path exists for data that matters.