Test Before You Write with sg_write_x

sg_write_x can dry-run a SCSI write, checking your input and block range before anything touches the disk. A successful dry-run does not write media, but the real write remains your responsibility. Allow about 20 minutes for a first test.

1. Check the installed command

Start with read-only commands. This host has package version 1.46-3ubuntu4, while the executable reports its own upstream version as 1.24 from 20200429. The installed manpage identifies itself as sg3_utils-1.45.

$ command -v sg_write_x
/usr/bin/sg_write_x
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
$ sg_write_x --version
sg_write_x version: 1.24 20200429

That mismatch is a reason to trust the local help and manpage together, not to copy an option from a different release without checking it. --help is also worth reading: it confirms that this build accepts long options such as --atomic, --same, --scattered and --stream, and it shows a few short-option spellings that differ from the long option's first letter, so prefer the long form in scripts and runbooks.

Checkpoint: Record the device path, package version and executable version before changing anything.

2. Decide exactly what will be written

sg_write_x sends one of six SCSI commands: normal WRITE, ORWRITE, WRITE ATOMIC, WRITE SAME, WRITE SCATTERED or WRITE STREAM. If no variant is selected, normal WRITE is assumed unless --strict requires an explicit choice. The default CDB is the 16-byte form; --32 selects the 32-byte form, but all 32-byte variants except ORWRITE(32) require suitable type 1, 2 or 3 protection information formatting on the device.

For a first test, choose normal WRITE or WRITE ATOMIC deliberately. Atomic writing is not a generic safety switch: it asks the device to provide the atomic behaviour described by its SCSI implementation. This is a representative four-block WRITE ATOMIC request, not a command to paste against an unknown disk:

sudo sg_write_x --atomic=0 --bs=512 --in=/dev/zero \
  --lba=0x1234 --num=4 /dev/sgX

Replace /dev/sgX with the correct device, and verify the LBA independently. The hexadecimal LBA is accepted by the utility. With a 512-byte block size, this command supplies 2048 bytes of zeroes, targeting blocks 0x1234 through 0x1237 inclusive.

Do not leave out --lba while experimenting. The manpage says its default is logical block 0. The default block count is zero, which is harmless, but adding a real input file and forgetting the intended LBA is not a useful safety strategy.

3. Make the block calculation explicit

sudo sg_write_x --normal --strict --bs=512 \
  --in=/path/to/payload.bin --lba=0x1234 --num=4 /dev/sgX

Here payload.bin must provide at least 2048 bytes. The command still writes only after all checks pass, so --strict is a guard against accidental padding, not a preview.

4. Run a dry-run against the real device

--dry-run exits immediately before sending the selected write CDB. It may still issue READ CAPACITY and it still reads and processes the input file. It also performs command-line and sanity checks. This makes it the right checkpoint before a real write, but it is not a virtual device and it does not prove that the target would accept the write.

sudo sg_write_x --atomic=0 --strict --dry-run --bs=512 \
  --in=/dev/zero --lba=0x1234 --num=4 /dev/sgX
$ printf 'dry-run status: %s\n' "$?"
dry-run status: 0

A zero status means the command reached the point immediately before the write. It does not confirm the target's atomic support, protection information, write permissions or final media result. If the device cannot answer capacity commands, try an explicit correct --bs, but do not use that to conceal an unknown device format.

Checkpoint: Stop here and compare the device path, variant, CDB size, block size, LBA, count and input length with your change record.

5. Use WRITE SAME and the other variants carefully

For any of these variants, add --strict while testing, and --verbose when diagnostics matter. Keep --timeout in mind: the default is 120 seconds, and a large request on slow media may need longer. A longer timeout does not make a write safer.

6. Perform the real write only after the checkpoint

Warning: The next command changes the contents of the target. It can overwrite useful data, trigger device-specific protection behaviour, or disrupt a service using the logical unit. Unmount filesystems and stop dependent services only when that is part of your storage procedure. Keep a recovery plan; there is no general undo command for a SCSI block write.

Once the dry-run and review agree, remove only --dry-run from the exact command you tested. Keep --strict and the explicit block size:

sudo sg_write_x --atomic=0 --strict --bs=512 \
  --in=/path/to/payload.bin --lba=0x1234 --num=4 /dev/sgX
$ printf 'write status: %s\n' "$?"
write status: 0

Zero is the utility's successful exit status. It means the command completed successfully according to the device and operating system, not that your higher-level data or application has been validated. A non-zero result needs the diagnostic on standard error, the SCSI sense information and the device documentation. Do not rerun a failed write blindly: a timeout can leave the device in an uncertain state.

Done means