SG_WRITE_LONG(8)
๐ SG_WRITE_LONG(8) ๐
sg3_utils manual, the cute edition ๐
โจ NAME โจ
sg_write_long - send SCSI WRITE LONG command ๐
๐ฆ SYNOPSIS ๐ฆ
sg_write_long [--16] [--cor_dis] [--help] [--in=IF] [--lba=LBA]
[--pblock] [--verbose] [--version] [--wr_uncor] [--xfer_len=BTL] DEVICE
๐ธ DESCRIPTION ๐ธ
okay so bestie, sg_write_long sends the SCSI WRITE LONG command (10 or 16 byte version) to DEVICE ๐ The buffer it writes is either filled with 0xff bytes or read from the IF file. That buffer holds the logical data (like 512 bytes) and the ECC bytes, so it's literally the whole sector including the error-correction stuff ๐ง
This utility can be used to generate a MEDIUM ERROR at a specific logical block address, which is super useful for testing error handling ๐ Before you do that, you can use the sg_dd utility to copy the original contents of that LBA somewhere safe. After the test, use sg_dd again to write the original contents back. An alternate strategy is to read the "long" contents of the LBA with the sg_read_long utility before testing, then restore it with this utility after testing ๐
โ ๏ธ Take care, bestie! If you're injecting recoverable errors (like flipping only one or a few bits so the ECC can fix the data), you need to watch the settings in the "read write error recovery" mode page ๐ฅบ Specifically, if ARRE (for reads) and/or AWRE (for writes) are set, recovered errors will cause the LBA to get reassigned, and the old location gets added to the grown defect list (PLIST). That's not easily reversed and it uses up one of the finite spare sectors set aside for this purpose ๐ If you're not sure, it's probably safest to clear the ARRE and AWRE bits. You can check and change these bits with the sdparm utility. For example: "sdparm -c AWRE,ARRE /dev/sda" will clear the bits until the disk is power cycled โจ
In SBC-4 revision 7, all uses of SCSI WRITE LONG (10 and 16 byte) commands were made obsolete, except for the case where the WR_UNCOR bit is set ๐ญ The SCSI READ LONG (10 and 16 byte) commands were made obsolete in that same revision too, so it's a whole era shift ๐
๐ OPTIONS ๐
Arguments to long options are mandatory for short options as well, no exceptions, periodt ๐
-S,--16โ sends a SCSI WRITE LONG (16) command to DEVICE. If you don't include this one, the default is a SCSI WRITE LONG (10) command, so you're good ๐-c,--cor_disโ sets the correction disabled (akaCOR_DIS) bit ๐ซถ This stops a bunch of other mechanisms from kicking in, like automatic block reallocation, error recovery, and various informational exception conditions. Fair warning: this bit is relatively new in SBC-3 .-h,--helpโ outputs the usage message, then exits ๐ง-i,--in=IFโ reads binary data from the file named IF and uses it for the SCSI WRITE LONG command ๐ If IF is-, stdin gets read instead. If you don't give this option,0xffbytes are used as the fill ๐ธ-l,--lba=LBAโ LBA is the logical block address of the sector you want to overwrite ๐ฏ It defaults to LBA 0, which is a dangerous block to overwrite on a disk that's in use ๐ฑ LBA is assumed to be decimal unless you prefix it with0xor add a trailingh. If your LBA is bigger than 32 bits can hold, use the--16option instead.-p,--pblockโ sets the physical block (akaPBLOCK) bit ๐ This tells DEVICE to use the given data (unless--wr_uncoris also given) to write to the physical block specified by LBA. By default it writes to the logical block that matches the given LBA. Also relatively new in SBC-3 .-v,--verboseโ cranks up the verbosity, so you get more debug messages ๐-V,--versionโ outputs the version string, then exits ๐ท๏ธ-w,--wr_uncorโ sets the "write uncorrected" (akaWR_UNCOR) bit โญ This tells DEVICE to flag the given LBA (or the physical block containing it, if--pblockis also given) as having an unrecoverable error attached to it ๐ฅ Note: no data gets transferred to DEVICE, just the command (the cdb). Without this option, the default is to use your provided data (or0xffbytes,--xfer_len=BTLin length) and write it to DEVICE. This bit is also relatively new in SBC-3 .-x,--xfer_len=BTLโ BTL is the byte transfer length, defaulting to 520 ๐ If the value you give (or the default) doesn't match the "long" block size of the device, nothing gets written to DEVICE ๐ โโ๏ธ Instead, the right xfer_len value can be figured out from the error response that gets printed to stderr.
๐ NOTES ๐
Various numeric arguments (like LBA) can include multiplicative suffixes or be given in hexadecimal. Check out the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page for the deets ๐ค
The 10 byte SCSI WRITE LONG command limits the logical block address to a 32 bit quantity. For larger LBAs, use the --16 option for the SCSI WRITE LONG (16) command ๐ฆ
๐ง EXAMPLES ๐ง
This section walks through setting up a block with corrupted data, checking the error condition, and then restoring useful contents to that sector. It's giving full science experiment vibes ๐งช
First, if the data in a sector is important, save it with the sg_read_long utility:
sg_read_long --lba=0x1234 --out=0x1234_1.img -x BTL /dev/sda
You might need to run this a few times to figure out the correct value for BTL ๐ฅน Next, use this utility to "corrupt" that sector. You can do that with:
sg_write_long --lba=0x1234 -x BTL /dev/sda
This writes a sector (and its ECC data) full of 0xff bytes. Some disks might reject this (at least one of the author's does ๐). Another approach is to copy the 0x1234_1.img file (to 0x1234_2.img in this example), change some values with a hex editor, and then write the changed image with:
sg_write_long --lba=0x1234 --in=0x1234_2.img -x BTL /dev/sda
Yet another approach, if it's supported, is to use the --wr_uncor option:
sg_write_long --lba=0x1234 --wr_uncor /dev/sda
Next, we use the sg_dd utility to check that the sector is corrupted. Here's an example:
sg_dd if=/dev/sda blk_sgio=1 skip=0x1234 of=. bs=512 count=1 verbose=4
Notice that the blk_sgio=1 option is given. This makes sure that only that sector gets read and the error is fully reported ๐ The blk_sgio=1 option makes sg_dd use the SG_IO ioctl instead of the block subsystem.
Finally, we should restore sector 0x1234 to a non-corrupted state ๐ซถ A sector full of zeros can be written with:
sg_dd if=/dev/zero of=/dev/sda blk_sgio=1 seek=0x1234 bs=512 count=1
This results in a sector (block) with 512 bytes of 0x0 and no MEDIUM ERROR, since the ECC and associated data get regenerated and are thus well formed โจ The blk_sgio=1 option is even more important in this case, because it may stop the block subsystem from doing a read before the write (since that read will most likely fail) ๐ฌ Another approach is to write back the original contents:
sg_write_long --lba=0x1234 --in=0x1234_1.img -x BTL /dev/sda
๐ท EXIT STATUS ๐ท
The exit status of sg_write_long is 0 when it's successful ๐ Otherwise, check out the sg3_utils(8) man page.
๐ AUTHORS ๐
Written by Saeed Bishara. Further work by Douglas Gilbert ๐ซถ
๐ REPORTING BUGS ๐
Report bugs to <dgilbert at interlog dot com> ๐ฎ
๐ COPYRIGHT ๐
Copyright ยฉ 2004-2016 Douglas Gilbert This software is distributed under the GPL version 2. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE ๐
๐ SEE ALSO ๐
sg_read_long, sg_dd (both in sg3_utils), sdparm(sdparm) ๐
Thanks for hanging with me, bestie! ๐ That's the whole tea from sg3_utils 1.42, January 2016 โจ๐
๐ฆ where this page comes from
- alpine 3.24: sg3_utils-doc 1.48-r0 ยท BSD-2-Clause AND GPL-2.0-or-later
- arch rolling: sg3_utils 1.49-1 ยท GPL-2.0-or-later AND BSD-2-Clause
- centos-stream 10: sg3_utils 1.48-11.el10 ยท GPL-2.0-or-later AND BSD-2-Clause
- debian trixie: sg3-utils 1.48-3~deb13u1
- fedora 43: sg3_utils 1.48-10.fc43 ยท GPL-2.0-or-later AND BSD-2-Clause
- fedora 43: sg3_utils 1.48-6.fc43 ยท GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-10.fc44 ยท GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-8.fc44 ยท GPL-2.0-or-later AND BSD-2-Clause
- nixos 26.05: sg3_utils 1.48
- nixpkgs unstable: sg3_utils 1.49
- ubuntu questing: sg3-utils 1.48-2ubuntu1
- ubuntu resolute: sg3-utils 1.48-3ubuntu3
- ubuntu resolute: sg3-utils 1.48-3ubuntu3.2
- ubuntu stonking: sg3-utils 1.48-3ubuntu5
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms