sg_write_verify writes selected logical blocks to a SCSI device, then asks the device to verify them immediately. The examples use sg_write_verify from sg3-utils 1.46-3ubuntu4, whose utility reports version 1.18 (20200430) on this machine.
/dev/sg4, a known logical block size, and data that can be overwritten. Device access may need sudo.Warning: This is a write command. Do not experiment against a production disk, an array member, or a device whose contents you have not backed up.
Start with read-only checks. They need no elevated privileges and do not contact a SCSI device:
$ sg_write_verify --version
sg_write_verify: version: 1.18 20200430
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
--lba.--16 explicitly requests WRITE AND VERIFY(16).Checkpoint: Confirm that the binary is the one you expect and read its local usage text:
$ command -v sg_write_verify
/usr/bin/sg_write_verify
$ sg_write_verify --help
/dev/sg4 is only an example; SCSI generic numbering can change after a reboot or hardware change. Use your normal inventory process, such as lsscsi -g if it is installed, and match the vendor, model and serial number. Do not infer the target from its number alone.Checkpoint: Write down the exact device, starting LBA, block size and number of blocks. Stop if any of those values is uncertain. The next steps can overwrite medium data and are not reversible through sg_write_verify.
When an input file is supplied, its binary contents become the data written to the medium. This example creates a 512-byte file of zeroes in /tmp. It changes no device data, but check the path before running it if the file already matters to you:
$ truncate -s 512 /tmp/sg-write-verify-512.bin
$ wc -c /tmp/sg-write-verify-512.bin
512 /tmp/sg-write-verify-512.bin
--in, the utility uses the input file length as ILEN unless you provide --ilen. If the file is shorter than an explicit --ilen, the command reports an error.--in, it sends a buffer of 0xff bytes; without --ilen, that buffer defaults to NUM * 512. That default is convenient only when it matches the device's layout.Replace /dev/sg4 and 0x1234 with values you have already checked. This operation needs permission to issue a write to the device, so use sudo only if ordinary access fails:
$ sudo sg_write_verify --lba=0x1234 --in=/tmp/sg-write-verify-512.bin /dev/sg4
The hexadecimal LBA is equivalent to a decimal LBA. The command writes one block because --num was omitted. After the write, the device performs its verify operation. The default --bytchk=0 verifies the medium without returning data for a host-side comparison.
A successful command exits with status zero and normally produces no output. Check that directly:
$ printf 'exit status: %s\n' "$?"
exit status: 0
Do not treat a silent command as proof that you selected the right disk. It only describes this command's result. The write itself may already have changed the medium.
Set --bytchk=1 when you want the verify operation to compare the data read back with the original data-out buffer as well as checking the medium:
$ sudo sg_write_verify --lba=0x1234 --num=1 --in=/tmp/sg-write-verify-512.bin --bytchk=1 /dev/sg4
$ printf 'exit status: %s\n' "$?"
exit status: 0
sg3_utils(8) documentation and should be investigated rather than retried blindly.Pass-through interfaces can limit how much data fits in one SCSI command. For a larger file, --repeat reads successive chunks and issues multiple WRITE AND VERIFY commands. It requires both --in and --ilen. Here, each command handles up to eight 512-byte blocks:
$ truncate -s 45056 /tmp/sg-write-verify-image.bin
$ sudo sg_write_verify --lba=0x2000 --num=8 --ilen=4096 --in=/tmp/sg-write-verify-image.bin --repeat /dev/sg4
The file is read until it is exhausted, starting at the requested LBA and advancing after each command. The final command can contain fewer blocks. If the final read leaves a number of bytes that cannot form complete blocks, the utility warns on standard error and the layout needs correcting. A device error stops the sequence at that point, so record which range was completed before deciding whether to resume.
For a pipe, use standard input as the input file and keep the same explicit chunk size:
$ dd if=/path/to/source.bin bs=512 count=11 status=none | \
sudo sg_write_verify --in=- --lba=0x567 --num=8 --ilen=4096 --repeat /dev/sg4
The producer supplies eleven blocks, so the first command handles eight and the last handles three. The source and target block sizes must agree. A pipe ending unexpectedly is not a safe indication that the intended image was transferred; check the producer's status and the utility's status separately in a script.
The command timeout defaults to 60 seconds. A large count or a slow medium can need more time, so increase it deliberately when the device and operation justify that:
$ sudo sg_write_verify --lba=0x2000 --num=8 --ilen=4096 --in=/tmp/sg-write-verify-image.bin --repeat --timeout=300 /dev/sg4
A longer timeout does not make an unresponsive device safe; it can instead make a failed command take longer to return. Use --verbose for diagnostics, not as a substitute for confirming the target:
$ sudo sg_write_verify --verbose --lba=0x1234 --in=/tmp/sg-write-verify-512.bin /dev/sg4
--repeat with both --in and --ilen, and recorded where any interrupted run stopped.