title: sg_write_buffer(8)

summary: send SCSI WRITE BUFFER commands

text:
# sg_write_buffer(8)

## NAME
sg_write_buffer - send SCSI WRITE BUFFER commands

## SYNOPSIS
sg_write_buffer [--bpw=CS] [--dry-run] [--help] [--id=ID] [--in=FILE] [--length=LEN] [--mode=MO] [--offset=OFF] [--read-stdin] [--skip=SKIP] [--specific=MS] [--timeout=TO] [--verbose] [--version] DEVICE

## DESCRIPTION
Sends one or more SCSI WRITE BUFFER commands to DEVICE, along with data provided by the user. In some cases no data is required, or data can be read from the file given in the --in=FILE option, or data is read from stdin when either --read-stdin or --in=- is given.

Some WRITE BUFFER command variants do not have associated data to send to the device. For example "activate_mc" activates deferred microcode that was sent via prior WRITE BUFFER commands. There is a different method used to download microcode to SES devices, see the sg_ses_microcode utility.

## OPTIONS
Arguments to long options are mandatory for short options as well. The options are arranged in alphabetical order based on the long option name.

-b, --bpw=CS

where CS is the chunk size in bytes. This will be the maximum number of bytes sent per WRITE BUFFER command. So if CS is less than the effective length then multiple WRITE BUFFER commands are sent, each taking the next chunk from the read data and increasing the buffer offset field in the WRITE BUFFER command by the appropriate amount. The default is a chunk size of 0 which is interpreted as a very large number hence only one WRITE BUFFER command will be sent. This option should only be used with modes that "download microcode, with offsets ..."; namely either mode 0x6, 0x7, 0xd or 0xe.

The number in CS can optionally be followed by ",act" or ",activate". In this case after WRITE BUFFER commands have been sent until the effective length is exhausted another WRITE BUFFER command with its mode set to "Activate deferred microcode mode" [mode 0xf] is sent.

-d, --dry-run

Do all the command line processing and sanity checks including reading the input file. However at the point where a WRITE BUFFER SCSI command(s) would be sent, step over that call and assume it completed without errors and continue. DEVICE is still opened but can be /dev/null (in Unix). It is recommended to use --verbose with this option to get an overview of what would have happened.

-h, --help

output the usage message then exit. If used multiple times also prints the mode names and their acronyms.

-i, --id=ID

this option sets the buffer id field in the cdb. ID is a value between 0 (default) and 255 inclusive.

-I, --in=FILE

read data from file FILE that will be sent with the WRITE BUFFER command. If FILE is '-' then stdin is read until an EOF is detected (this is the same action as --read-stdin). Data is read from the beginning of FILE except in the case when it is a regular file and the --skip=SKIP option is given.

-l, --length=LEN

where LEN is the length, in bytes, of data to be written to the device. If not given (and the length cannot be deduced from --in=FILE or --read-stdin) then defaults to zero. If the option is given and the length deduced from --in=FILE or --read-stdin is less (or no data is provided), then bytes of 0xff are used as fill bytes.

-m, --mode=MO

this option sets the MODE field in the cdb. MO is a value between 0 (default) and 31 inclusive. Alternatively an abbreviation can be given. See the MODES section below. To list the available mode abbreviations at run time give an invalid one (e.g. '--mode=xxx') or use the '-hh' option.

-o, --offset=OFF

this option sets the BUFFER OFFSET field in the cdb. OFF is a value between 0 (default) and 2**24-1 . It is a byte offset.

-r, --read-stdin

read data from stdin until an EOF is detected. This data is sent with the WRITE BUFFER command to DEVICE. The action of this option is the same as using '--in=-'. Previously this option's long name was --raw and it may still be used for backward compatibility.

-s, --skip=SKIP

this option is only active when --in=FILE is given and FILE is a regular file, rather than stdin. Data is read starting at byte offset SKIP to the end of file (or the amount given by --length=LEN). If not given the byte offset defaults to 0 (i.e. the start of the file).

-S, --specific=MS

MS is the MODE SPECIFIC field in the cdb. This is a 3-bit field so the values 0 to 7 are accepted. This field was introduced in SPC-4 revision 32 and can be used to specify additional events that activate deferred microcode (when MO is 0xD).

-t, --timeout=TO

TO is the command timeout (in seconds) for each WRITE BUFFER command issued by this utility. Its default value is 300 seconds (5 minutes) and should only be altered if this is not sufficient.

-v, --verbose

increase the level of verbosity, (i.e. debug output).

-V, --version

print the version string and then exit.

## MODES
Following is a list of WRITE BUFFER command settings for the MODE field. First is an acronym accepted by the MO argument of this utility. Following the acronym in square brackets are the corresponding decimal and hex values that may also be given for MO. The following are listed in numerical order.

hd [0, 0x0]

Combined header and data (obsolete in SPC-4).

vendor [1, 0x1]

Vendor specific.

data [2, 0x2]

Data (was called "Write Data" in SPC-3).

dmc [4, 0x4]

Download microcode and activate (was called "Download microcode" in SPC-3).

dmc_save [5, 0x5]

Download microcode, save, and activate (was called "Download microcode and save" in SPC-3).

dmc_offs [6, 0x6]

Download microcode with offsets and activate (was called "Download microcode with offsets" in SPC-3).

dmc_offs_save [7, 0x7]

Download microcode with offsets, save, and activate (was called "Download microcode with offsets and save" in SPC-3).

echo [10, 0xa]

Write data to echo buffer (was called "Echo buffer" in SPC-3).

dmc_offs_ev_defer [13, 0xd]

Download microcode with offsets, select activation events, save, and defer activate (introduced in SPC-4).

dmc_offs_defer [14, 0xe]

Download microcode with offsets, save, and defer activate (introduced in SPC-4).

activate_mc [15, 0xf]

Activate deferred microcode (introduced in SPC-4).

en_ex [26, 0x1A]

Enable expander communications protocol and Echo buffer (obsolete in SPC-4).

dis_ex [27, 0x1B]

Disable expander communications protocol (obsolete in SPC-4).

deh [28, 0x1C]

Download application client error history (was called "Download application log" in SPC-3).

## NOTES
If no --length=LEN is given this utility reads up to 8 MiB of data from the given file FILE (or stdin). If a larger amount of data is required then the --length=LEN option should be given.

The user should be aware that most operating systems have limits on the amount of data that can be sent with one SCSI command. In Linux this depends on the pass through mechanism used (e.g. block SG_IO or the sg driver) and various setting in sysfs in the Linux lk 2.6/3 series (e.g. /sys/block/sda/queue/max_sectors_kb). Devices (i.e. logical units) also typically have limits on the maximum amount of data they can handle in one command. These two limitations suggest that modes containing the word "offset" together with the --bpw=CS option are required as firmware files get larger and larger. And CS can be quite small, for example 4096 bytes, resulting in many WRITE BUFFER commands being sent.

Attempting to download a microcode/firmware file that is too large may cause an error to occur in the pass-through layer (i.e. before the SCSI command is issued). In Linux such error reports can be obscure as in "pass through os error invalid argument". FreeBSD reports such errors well to the machine's console but returns a cryptic error message to this utility.

Downloading incorrect microcode into a device has the ability to render that device inoperable. One would hope that the device vendor verifies the data before activating it. If the SCSI WRITE BUFFER command is given values in its cdb (e.g. LEN) that are inappropriate (e.g. too large) then the device should respond with a sense key of ILLEGAL REQUEST and an additional sense code of INVALID FIELD in CDB. If a WRITE BUFFER command (or a sequence of them) fails due to device vendor verification checks then it should respond with a sense key of ILLEGAL REQUEST and an additional sense code of COMMAND SEQUENCE ERROR.

All numbers given with options are assumed to be decimal. Alternatively numerical values can be given in hexadecimal preceded by either "0x" or "0X" (or has a trailing "h" or "H").

## EXAMPLES
The following sends new firmware to an enclosure. Sending a 1.5 MB file in one WRITE BUFFER command caused the enclosure to lock up temporarily and did not update the firmware. Breaking the firmware file into 4 KB chunks (an educated guess) was more successful:

sg_write_buffer -b 4k -m dmc_offs_save -I firmware.bin /dev/sg4

The firmware update occurred in the following enclosure power cycle. With a modern enclosure the Extended Inquiry VPD page gives indications in which situations a firmware upgrade will take place.

## EXIT STATUS
The exit status of sg_write_buffer is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

## AUTHORS
Written by Luben Tuikov and Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2006-2018 Luben Tuikov and Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
sg_read_buffer, sg_ses_microcode(sg3_utils)


title: sg_write_long(8)

summary: send SCSI WRITE LONG command

text:
# sg_write_long(8)

## 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
Send the SCSI WRITE LONG (10 or 16 byte) command to DEVICE. The buffer to be written to the DEVICE is filled with 0xff bytes or read from the IF file. This buffer includes the logical data (e.g. 512 bytes) and the ECC bytes.

This utility can be used to generate a MEDIUM ERROR at a specific logical block address. This can be useful for testing error handling. Prior to such a test, the sg_dd utility could be used to copy the original contents of the logical block address to some safe location. After the test the sg_dd utility could be used to write back the original contents of the logical block address. An alternate strategy would be to read the "long" contents of the logical block address with sg_read_long utility prior to testing and restore it with this utility after testing.

Take care: If recoverable errors are being injected (e.g. only one or a few bits changed so that the ECC is able to correct the data) then care should be taken with the settings in the "read write error recovery" mode page. Specifically if the ARRE (for reads) and/or AWRE (for writes) are set then recovered errors will cause the lba to be reassigned (and the old location to be added to the grown defect list (PLIST)). This is not easily reversed and uses (one of the finite number of) the spare sectors set aside for this purpose. If in doubt it is probably safest to clear the ARRE and AWRE bits. These bits can be checked and modified 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 apart from the case in which the WR_UNCOR bit is set. The SCSI READ LONG (10 and 16 byte) commands were made obsolete in the same revision.

## OPTIONS
Arguments to long options are mandatory for short options as well.

-S, --16

send a SCSI WRITE LONG (16) command to DEVICE. The default action (in the absence of this option) is to send a SCSI WRITE LONG (10) command.

-c, --cor_dis

sets the correction disabled (i.e 'COR_DIS') bit. This inhibits various other mechanisms such as automatic block reallocation, error recovery and various informational exception conditions being triggered. This bit is relatively new in SBC-3 .

-h, --help

output the usage message then exit.

-i, --in=IF

read data (binary) from file named IF and use it for the SCSI WRITE LONG command. If IF is "-" then stdin is read. If this option is not given then 0xff bytes are used as fill.

-l, --lba=LBA

where LBA is the logical block address of the sector to overwrite. Defaults to lba 0 which is a dangerous block to overwrite on a disk that is in use. Assumed to be in decimal unless prefixed with '0x' or has a trailing 'h'. If LBA is larger than can fit in 32 bits then the --16 option should be used.

-p, --pblock

sets the physical block (i.e 'PBLOCK') bit. This instructs DEVICE to use the given data (unless --wr_uncor is also given) to write to the physical block specified by LBA. The default action is to write to the logical block corresponding to the given lba. This bit is relatively new in SBC-3 .

-v, --verbose

increase the degree of verbosity (debug messages).

-V, --version

output version string then exit.

-w, --wr_uncor

sets the "write uncorrected" (i.e 'WR_UNCOR') bit. This instructs the DEVICE to flag the given lba (or the physical block that contains it if --pblock is also given) as having an unrecoverable error associated with it. Note: no data is transferred to DEVICE, other than the command (i.e. the cdb). In the absence of this option, the default action is to use the provided data or 0xff bytes (--xfer_len=BTL in length) and write it to DEVICE. This bit is relatively new in SBC-3 .

-x, --xfer_len=BTL

where BTL is the byte transfer length (default to 520). If the given value (or the default) does not match the "long" block size of the device, nothing is written to DEVICE and the appropriate xfer_len value may be deduced from the error response which is printed (to stderr).

## NOTES
Various numeric arguments (e.g. LBA) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page.

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 outlines setting up a block with corrupted data, checking the error condition, then restoring useful contents to that sector.

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

This utility may need to be executed several time in order to determine what the correct value for BTL is. Next use this utility to "corrupt" that sector. That might be done with:

sg_write_long --lba=0x1234 -x BTL /dev/sda

This will write a sector (and ECC data) of 0xff bytes. Some disks may 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) and change some values with a hex editor. Then write the changed image with:

sg_write_long --lba=0x1234 --in=0x1234_2.img -x BTL /dev/sda

Yet another approach is to use the --wr_uncor option, if supported:

sg_write_long --lba=0x1234 --wr_uncor /dev/sda

Next we use the sg_dd utility to check that the sector is corrupted. Here is 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 is to make sure that the sector is read (and no others) and the error is fully reported. The "blk_sgio=1" option causes the SG_IO ioctl to be used by sg_dd rather than the block subsystem.

Finally we should restore sector 0x1234 to a non-corrupted state. A sector full of zeros could be written with:

sg_dd if=/dev/zero of=/dev/sda blk_sgio=1 seek=0x1234 bs=512 count=1

This will result in a sector (block) with 512 bytes of 0x0 without a MEDIUM ERROR since the ECC and associated data will be regenerated and thus well formed. The 'blk_sgio=1' option is even more important in this case as it may stop the block subsystem doing a read before write (since the 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 is successful. Otherwise see 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)

branch: sisyphus


title: sg_write_same(8)

summary: send SCSI WRITE SAME command

text:
# sg_write_same(8)

## NAME
sg_write_same - send SCSI WRITE SAME command

## SYNOPSIS
sg_write_same [--10] [--16] [--32] [--anchor] [--ff] [--grpnum=GN] [--help] [--in=IF] [--lba=LBA] [--lbdata] [--num=NUM] [--ndob] [--pbdata] [--timeout=TO] [--unmap] [--verbose] [--version] [--wrprotect=WPR] [--xferlen=LEN] DEVICE

## DESCRIPTION
Send the SCSI WRITE SAME (10, 16 or 32 byte) command to DEVICE. This command writes the given block NUM times to consecutive blocks on the DEVICE starting at logical block address LBA.

The length of the block to be written multiple times is obtained from either the LEN argument, or the length of the given input file IF, or by calling READ CAPACITY(16) on DEVICE. The contents of the block to be written are obtained from the input file IF or zeros are used. If READ CAPACITY(16) is called (which implies IF was not given) and the PROT_EN bit is set then an extra 8 bytes (i.e. more than the logical block size) of 0xff are sent. If READ CAPACITY(16) fails then READ CAPACITY(10) is used to determine the block size.

If neither --10, --16 nor --32 is given then WRITE SAME(10) is sent unless one of the following conditions is met. If LBA (plus NUM) exceeds 32 bits, NUM exceeds 65535, or the --unmap option is given then WRITE SAME(16) is sent. The --10, --16 and --32 options are mutually exclusive.

SBC-3 revision 35d introduced a "No Data-Out Buffer" (NDOB) bit which, if set, bypasses the requirement to send a single block of data to the DEVICE together with the command. Only WRITE SAME (16 and 32 byte) support the NDOB bit. If given, a user block of zeros is assumed; if required, protection information of 0xffs is assumed.

In SBC-3 revision 26 the UNMAP and ANCHOR bits were added to the WRITE SAME (10) command. Since the UNMAP bit has been in WRITE SAME (16) and WRITE SAME (32) since SBC-3 revision 18, the lower of the two (i.e. WRITE SAME (16)) is the default when the --unmap option is given. To send WRITE SAME (10) use the --10 option.

Take care: The WRITE SAME(10, 16 and 32) commands may interpret a NUM of zero as write to the end of DEVICE. This utility defaults NUM to 1 . The WRITE SAME commands have no IMMED bit so if NUM is large (or zero) then an invocation of this utility could take a long time, potentially as long as a FORMAT UNIT command. In such situations the command timeout value TO may need to be increased from its default value of 60 seconds. In SBC-3 revision 26 the WSNZ (write same no zero) bit was added to the Block Limits VPD page [0xB0]. If set the WRITE SAME commands will not accept a NUM of zero. The same SBC-3 revision added the "Maximum Write Same Length" field to the Block Limits VPD page.

The Logical Block Provisioning VPD page [0xB2] contains the LBPWS and LBPWS10 bits. If LBPWS is set then WRITE SAME (16) supports the UNMAP bit. If LBPWS10 is set then WRITE SAME (10) supports the UNMAP bit. If either LBPWS or LBPWS10 is set and the WRITE SAME (32) is supported then WRITE SAME (32) supports the UNMAP bit.

As a precaution against an accidental 'sg_write_same /dev/sda' (for example) overwriting LBA 0 on /dev/sda with zeros, at least one of the --in=IF, --lba=LBA or --num=NUM options must be given. Obviously this utility can destroy a lot of user data so check the options carefully.

## OPTIONS
Arguments to long options are mandatory for short options as well. The options are arranged in alphabetical order based on the long option name.

-R, --10

send a SCSI WRITE SAME (10) command to DEVICE. The ability to set the --unmap (and --anchor) options to this command was added in SBC-3 revision 26.

-S, --16

send a SCSI WRITE SAME (16) command to DEVICE.

-T, --32

send a SCSI WRITE SAME (32) command to DEVICE.

-a, --anchor

sets the ANCHOR bit in the cdb. Introduced in SBC-3 revision 22. That draft requires the --unmap option to also be specified.

-f, --ff

the data-out buffer sent with this command is initialized with 0xff bytes when this option is given.

-g, --grpnum=GN

sets the 'Group number' field to GN. Defaults to a value of zero. GN should be a value between 0 and 63.

-h, --help

output the usage message then exit.

-i, --in=IF

read data (binary) from file named IF and use it as the data-out buffer for the SCSI WRITE SAME command. The length of the data-out buffer is --xferlen=LEN or, if that is not given, the length of the IF file. If IF is "-" then stdin is read. If this option and the --ff are not given then 0x00 bytes are used as fill with the length of the data-out buffer obtained from --xferlen=LEN or by calling READ CAPACITY(16 or 10). If the response to READ CAPACITY(16) has the PROT_EN bit set then data- out buffer size is modified accordingly with the last 8 bytes set to 0xff.

-l, --lba=LBA

where LBA is the logical block address to start the WRITE SAME command. Defaults to lba 0 which is a dangerous block to overwrite on a disk that is in use. Assumed to be in decimal unless prefixed with '0x' or has a trailing 'h'.

-L, --lbdata

sets the LBDATA bit in the WRITE SAME cdb. This bit was made obsolete in sbc3r32 in September 2012.

-N, --ndob

sets the NDOB bit in the WRITE SAME (16 and 32 byte) commands. NDOB stands for No Data-Out Buffer. Default is to clear this bit. When this option is given then --in=IF is not allowed and --xferlen=LEN can only be given if LEN is 0 .

By default zeros are written in each block, but it is possible that the "provisioning initialization pattern" is written depending on other settings.

-n, --num=NUM

where NUM is the number of blocks, starting at LBA, to write the data-out buffer to. The default value for NUM is 1. The value corresponds to the 'Number of logical blocks' field in the WRITE SAME cdb.

Note that a value of 0 in NUM may be interpreted as write the data-out buffer on every block starting at LBA to the end of the DEVICE. If the WSNZ bit (introduced in sbc3r26, January 2011) in the Block Limits VPD page is set then the value of 0 is disallowed, yielding an Invalid request sense key.

-P, --pbdata

sets the PBDATA bit in the WRITE SAME cdb. This bit was made obsolete in sbc3r32 in September 2012.

-t, --timeout=TO

where TO is the command timeout value in seconds. The default value is 60 seconds. If NUM is large (or zero) a WRITE SAME command may require considerably more time than 60 seconds to complete.

-U, --unmap

sets the UNMAP bit in the WRITE SAME(10, 16 and 32) cdb. See UNMAP section below.

-v, --verbose

increase the degree of verbosity (debug messages).

-V, --version

output version string then exit.

-w, --wrprotect=WPR

sets the "Write protect" field in the WRITE SAME cdb to WPR. The default value is zero. WPR should be a value between 0 and 7. When WPR is 1 or greater, and the disk's protection type is 1 or greater, then 8 extra bytes of protection information are expected or generated (to place in the command's data-out buffer).

-x, --xferlen=LEN

where LEN is the data-out buffer length. Defaults to the length of the IF file or, if that is not given, then the READ CAPACITY(16 or 10) command is used to find the 'Logical block length in bytes'. That figure may be increased by 8 bytes if the DEVICE's protection type is 1 or greater and the WRPROTECT field (see --wrprotect=WPR) is 1 or greater. If both this option and the IF option are given and LEN exceeds the length of the IF file then LEN is the data-out buffer length with zeros used as pad bytes.

## UNMAP
Logical block provisioning is a new term introduced in SBC-3 revision 25 for the ability to mark blocks as unused. For large storage arrays, it is a way to provision less physical storage than the READ CAPACITY command reports is available, potentially allocating more physical storage when WRITE commands require it. For flash memory (e.g. SSD drives) it is a way of potentially saving power (and perhaps access time) when it is known large sections (or almost all) of the flash memory is not in use. SSDs need wear levelling algorithms to have acceptable endurance and typically over provision to simplify those algorithms; hence they typically contain more physical flash storage than their logical size would dictate.

Support for logical block provisioning is indicated by the LBPME bit being set in the READ CAPACITY(16) command response (see the sg_readcap utility). That implies at least one of the UNMAP or WRITE SAME(16) commands is implemented. If the UNMAP command is implemented then the "Maximum unmap LBA count" and "Maximum unmap block descriptor count" fields in the Block Limits VPD page should both be greater than zero. The READ CAPACITY(16) command response also contains a LBPRZ bit which if set means that if unmapped blocks are read then zeros will be returned for the data (and if protection information is active, 0xff bytes are returned for that). In SBC-3 revision 27 the same LBPRZ bit was added to the Logical Block Provisioning VPD page.

In SBC-3 revision 25 the LBPU and ANC_SUP bits where added to the Logical Block Provisioning VPD page. When LBPU is set it indicates that the device supports the UNMAP command (see the sg_unmap utility). When the ANC_SUP bit is set it indicates the device supports anchored LBAs.

When the UNMAP bit is set in the cdb then the data-out buffer is also sent. Additionally the data section of that data-out buffer should be full of 0x0 bytes while the data protection block, 8 bytes at the end if present, should be set to 0xff bytes. If these conditions are not met and the LBPRZ bit is set then the UNMAP bit is ignored and the data-out buffer is written to the DEVICE as if the UNMAP bit was zero. In the absence of the --in=IF option, this utility will attempt build a data-out buffer that meets the requirements for the UNMAP bit in the cdb to be acted on by the DEVICE.

Logical blocks may also be unmapped by the SCSI UNMAP and FORMAT UNIT commands (see the sg_unmap and sg_format utilities).

The unmap capability in SCSI is closely related to the ATA DATA SET MANAGEMENT command with the "Trim" bit set. That ATA trim capability does not interact well with SATA command queueing known as NCQ. T13 have introduced a new command called the SFQ DATA SET MANAGEMENT command also with a the "Trim" bit to address that problem. The SCSI WRITE SAME with the UNMAP bit set and the UNMAP commands do not have any problems with SCSI queueing.

## NOTES
Various numeric arguments (e.g. LBA) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page.

In Linux, prior to lk 3.17, the sg driver did not support cdb sizes greater than 16 bytes. Hence a device node like /dev/sg1 which is associated with the sg driver would fail with this utility if the --32 option was given (or implied by other options). The bsg driver with device nodes like /dev/bsg/6:0:0:1 does support cdb sizes greater than 16 bytes since its introduction in lk 2.6.28 .

## EXIT STATUS
The exit status of sg_write_same is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

## EXAMPLES
BEWARE: all these examples will overwrite the data on one or more blocks, potentially CLEARING the WHOLE DISK.

One simple usage is to write blocks of zero from (and including) a given LBA for 63 blocks:

sg_write_same --lba=0x1234 --num=63 /dev/sdc

Since --xferlen=LEN has not been given, then this utility will call the READ CAPACITY command on /dev/sdc to determine the number of bytes in a logical block. Let us assume that is 512 bytes. Since --in=IF is not given a block of zeros is assumed. So 63 blocks of zeros (each block containing 512 bytes) will be written from (and including) LBA 0x1234 . Note that only one block of zeros is passed to the SCSI WRITE SAME command in the data-out buffer (as required by SBC-3). Using the WRITE SAME SCSI command to write one or more blocks blocks of zeros is equivalent to the NVMe command: Write Zeroes.

Now we will write zero blocks to the WHOLE disk. [Note sanitize type commands will also clear blocks and metadata that are not directly visible]:

sg_write_same --lba=0x0 --num=0 /dev/sdc

Yes, in this context --num=0 means the rest of the disk. The above invocation may give an error due to the WSNZ bit in the Block Limits VPD page being set. To get around that try:

sg_write_same --lba=0x0 --ndob /dev/sdc

this invocation, if supported, has the added benefit of not sending a data out buffer of zeros. Notes that it is possible that the "provisioning initialization pattern" is written to each block instead of zeros.

A similar example follows but in this case the blocks are "unmapped" ("trimmed" in ATA speak) rather than zeroed:

sg_write_same --unmap -L 0x1234 -n 63 /dev/sdc

Note that if the LBPRZ bit in the READ CAPACITY(16) response is set (i.e. LPPRZ is an acronym for logical block provisioning read zeros) then these two examples do the same thing, at least seen from the point of view of subsequent reads.

This utility can also be used to write protection information (PI) on disks formatted with a protection type greater than zero. PI is 8 bytes of extra data appended to the user data of a logical block: the first two bytes are a CRC (the "guard"), the next two bytes are the "application tag" and the last four bytes are the "reference tag". With protection types 1 and 2 if the application tag is 0xffff then the guard should not be checked (against the user data).

In this example we assume the logical block size (of the user data) is 512 bytes and the disk has been formatted with protection type 1. Since we are going to modify LBA 2468 then we take a copy of it first:

dd if=/dev/sdb skip=2468 bs=512 of=2468.bin count=1

The following command line sets the user data to zeros and the PI to 8 0xFF bytes on LBA 2468:

sg_write_same --lba=2468 /dev/sdb

Reading back that block should be successful because the application tag is 0xffff which suppresses the guard (CRC) check (which would otherwise be wrong):

dd if=/dev/sdb skip=2468 bs=512 of=/dev/null count=1

Now an attempt is made to create a binary file with zeros in the user data, 0x0000 in the application tag and 0xff bytes in the other two PI fields. It is awkward to create 0xff bytes in a file (in Unix) as the "tr" command below shows:

dd if=/dev/zero bs=1 count=512 of=ud.bin

tr "\000" "\377" < /dev/zero | dd bs=1 of=ff_s.bin count=8

cat ud.bin ff_s.bin > lb.bin

dd if=/dev/zero bs=1 count=2 seek=514 conv=notrunc of=lb.bin

The resulting file can be viewed with 'hexdump -C lb.bin' and should contain 520 bytes. Now that file can be written to LBA 2468 as follows:

sg_write_same --lba=2468 wrprotect=3 --in=lb.bin /dev/sdb

Note the --wrprotect=3 rather than being set to 1, since we want the WRITE SAME command to succeed even though the PI data now indicates the user data is corrupted. When an attempt is made to read the LBA, an error should occur:

dd if=/dev/sdb skip=2468 bs=512 of=/dev/null count=1

dd errors are not very expressive, if dmesg is checked there should be a line something like this: "[sdb] Add. Sense: Logical block guard check failed". The block can be corrected by doing a "sg_write_same --lba=1234 /dev/sdb" again or restoring the original contents of that LBA:

dd if=2468.bin bs=512 seek=2468 of=/dev/sdb conv=notrunc count=1

Hopefully the dd command would never try to truncate the output file when it is a block device.

## AUTHORS
Written by Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2009-2020 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
sg_format,sg_get_lba_status,sg_readcap,sg_vpd,sg_unmap, sg_write_x(sg3_utils)


title: sg_write_verify(8)

summary: send the SCSI WRITE AND VERIFY command

text:
# sg_write_verify(8)

## NAME
sg_write_and_verify - send the SCSI WRITE AND VERIFY command

## SYNOPSIS
sg_write_verify [--16] [--bytchk=BC] [--dpo] [--group=GN] [--help] [--ilen=ILEN] [--in=IF] --lba=LBA [--num=NUM] [--repeat] [--timeout=TO] [--verbose] [--version] [--wrprotect=WP] DEVICE

## DESCRIPTION
Send a SCSI WRITE AND VERIFY (10) or (16) command to DEVICE. The data to be written is read from the IF file or, in its absence, a buffer full of 0xff bytes is used. The length of the data-out buffer sent with the command is ILEN bytes or, if that is not given, then it is the length of the IF file.

The write operation is to the DEVICE's medium (optionally to its cache) starting at logical block address LBA for NUM logical blocks. After the write to medium is performed a verify operation takes place which may viewed as a medium read (with appropriate checks) but without the data being returned. Additionally, if BS is set to one, the data read back from the medium in the verify operation is compared to the original data-out buffer.

The relationship between the number of logical blocks to be written (i.e. NUM) and the length (in bytes) of the data-out buffer (i.e. ILEN) may be simply found by multiplying the former by the logical block size. However if the DEVICE has protection information (PI) then it becomes a bit more complicated. Hence the calculation is left to the user with the default ILEN, in the absence of the IF file, being set to NUM * 512.

For sending large amounts of data to contiguous logical blocks, a single WRITE AND VERIFY command may not be appropriate (e.g. due to operating system limitations). In such cases see the REPEAT section below.

## OPTIONS
Arguments to long options are mandatory for short options as well. The options are arranged in alphabetical order based on the long option name.

-S, --16

Send a WRITE AND VERIFY(16) command. The default is to send a WRITE AND VERIFY(10) command unless LBA or NUM are too large for the 10 byte variant.

-b, --bytchk=BC

where BC is the value to place in the command's BYTCHK field. Values between 0 and 3 (inclusive) are accepted. The default is value is 0 which implies only a write to the medium then a verify operation are performed. The only other value T10 defines currently is 1 which does performs an additional comparison between the data-out buffer that was used by the write operation and the contents of the logical blocks read back from the medium.

-d, --dpo

Set the DPO (disable page out) bit in the command. The default is to leave it clear.

-g, --group=GN

where GN is the value to place in the command's GROUP NUMBER field. Values between 0 and 63 (inclusive) are accepted. The default is value is 0.

-h, --help

output the usage message then exit.

-I, --ilen=ILEN

where ILEN is the number of bytes that will be placed in the data-out buffer. If the IF file is given then no more than ILEN bytes are read from that file. If the IF file does not contain ILEN bytes then an error is reported. If the IF file is not given then a data-out buffer with ILEN bytes of 0xff is sent.

-i, --in=IF

read data (binary) from file named IF. If IF is "-" then stdin is used. This data will become the data-out buffer and will be written to the DEVICE's medium. If BC is 1 then that data-out buffer will be held until after the verify operation and compared to the data read back from the medium.

-l, --lba=LBA

where LBA is the logical block address to start the write to medium. Assumed to be in decimal unless prefixed with '0x' or has a trailing 'h'. Must be provided.

-n, --num=NUM

where NUM is the number of blocks, starting at LBA, to write to the medium. The default value for NUM is 1.

-R, --repeat

this option will continue to do WRITE AND VERIFY commands until the IF file is exhausted. This option requires both the --ilen=ILEN and --in=IF options to be given. Each command starts at the next logical block address and is for no more than NUM blocks. The last command may be shorter with the number of blocks scaled as required. If there are residue bytes a warning is sent to stderr. See the REPEAT section.

-t, --timeout=TO

where TO is the command timeout value in seconds. The default value is 60 seconds. If NUM is large then command may require considerably more time than 60 seconds to complete.

-v, --verbose

increase the degree of verbosity (debug messages).

-V, --version

output version string then exit.

-w, --wrprotect=WP

set the WRPROTECT field in the cdb to WP. The default value is 0 which implies no protection information is sent (along with the user data) in the data-out buffer.

## REPEAT
For data sizes around a megabyte and larger, it may be appropriate to send multiple SCSI WRITE AND VERIFY commands due to operating system limitations (e.g. pass-through SCSI interfaces often limit the amount of data that can be passed with a SCSI command). With this utility the mechanism for doing that is the --repeat option.

In this mode the --ilen=ILEN and --in=IF options must be given. The ILEN and NUM values are treated as a per SCSI command parameters. Up to ILEN bytes will be read from the IF file continually until it is exhausted. If the IF file is stdin, reading continues until an EOF is detected. The data read from each iteration becomes the data-out buffer for a new WRITE AND VERIFY command.

The last read from the file (or stdin) may read less than ILEN bytes in which case the number of logical blocks sent to the last WRITE AND VERIFY is scaled back accordingly. If there is a residual number of bytes left after that scaling then that is reported to stderr.

If an error occurs then that is reported to stderr and via the exit status and the utility stops at that point.

## NOTES
Other SCSI WRITE commands have a Force Unit Access (FUA) bit but that is set (implicitly) by WRITE AND VERIFY commands hence there is no option to set it. The data-out buffer may still additionally be placed in the DEVICE's cache and setting the DPO bit is a hint not to do that.

Normal SCSI WRITEs can be done with the ddpt and the sg_dd utilities. The SCSI WRITE SAME command can be done with the sg_write_same utility while the SCSI COMPARE AND WRITE command (sg_compare_and_write utility) offers a "test and set" facility.

Various numeric arguments (e.g. LBA) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page.

## EXIT STATUS
The exit status of sg_write_verify is 0 when it is successful. If the verify operation fails that is typically indicated with a medium error which leads to an exit status of 3.

If BC is set to 1 and the comparison it causes fails this utility will indicate the miscompare with an exit status of 14. For other exit status values see the EXIT STATUS section in the sg3_utils(8) man page.

## EXAMPLES
To start with, a simple example: write 1 block of data held in file t.bin that is 512 bytes long then write that block to LBA 0x1234 on /dev/sg4 .

\# sg_write_verify --lba=0x1234 --in=t.bin /dev/sg4

Since '--num=' is not given then it defaults to 1. Further the ILEN value is obtained from the file size of t.bin . To additionally do a data-out comparison to the read back data:

\# sg_write_verify -l 0x1234 -i t.bin --bytchk=1 /dev/sg4

The ddpt command can do copies between SCSI devices using READ and WRITE commands. However, currently it has no facility to promote those WRITES to WRITE AND VERIFY commands. Using a pipe, that could be done like this:

\# ddpt if=/dev/sg2 bs=512 bpt=8 count=11 of=- |

sg_write_verify --in=- -l 0x567 -n 8 --ilen=4096 --repeat /dev/sg4

Both ddpt and sg_write_verify are configured for segments of 8 512 byte logical blocks. Since 11 logical blocks are read then first 8 logical blocks are copied followed by a copy of the remaining 3 blocks. Since it is assumed that there is no protection information then the data-in and data-out buffers will be 4096 bytes each. For sg_write_verify this needs to be stated explicitly with the --ilen=4096 option.

## AUTHORS
Bruno Goncalves and Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2014-2018 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
ddpt(in a package of that name), sg_compare_and_write(8), sg_dd(8), sg_write_same(8)


title: sg_write_x(8)

text:
# sg_write_x(8)

## NAME
sg_write_x - SCSI WRITE normal/ATOMIC/SAME/SCATTERED/STREAM, ORWRITE commands

## SYNOPSIS
sg_write_x [--16] [--32] [--app-tag=AT] [--atomic=AB] [--bmop=OP,PGP] [--bs=BS] [--combined=DOF] [--dld=DLD] [--dpo] [--dry-run] [--fua] [--generation=EOG,NOG] [--grpnum=GN] [--help] --in=IF [--lba=LBA[,LBA...]] [--normal] [--num=NUM[,NUM...]] [--offset=OFF[,DLEN]] [--or] [--quiet] [--ref-tag=RT] [--same=NDOB] [--scat-file=SF] [--scat-raw] [--scattered=RD] [--stream=ID] [--strict] [--tag-mask=TM] [--timeout=TO] [--unmap=U_A] [--verbose] [--version] [--wrprotect=WPR] DEVICE

Synopsis per supported command:

sg_write_x --normal --in=IF [--16] [--32] [--app-tag=AT] [--bs=BS] [--dld=DLD] [--dpo] [--fua] [--grpnum=GN] [--lba=LBA] [--num=NUM] [--offset=OFF[,DLEN]] [--ref-tag=RT] [--strict] [--tag-mask=TM] [--timeout=TO] [--wrprotect=WPR] DEVICE

sg_write_x --or --in=IF [--16] [--32] [--bmop=OP,PGP] [--bs=BS] [--dpo] [--fua] [--generation=EOG,NOG] [--grpnum=GN] [--lba=LBA] [--num=NUM] [--offset=OFF[,DLEN]] [--strict] [--timeout=TO] [--wrprotect=OPR] DEVICE

sg_write_x --atomic=AB --in=IF [--16] [--32] [--app-tag=AT] [--bs=BS] [--dpo] [--fua] [--grpnum=GN] [--lba=LBA] [--num=NUM] [--offset=OFF[,DLEN]] [--ref-tag=RT] [--strict] [--timeout=TO] [--wrprotect=WPR] DEVICE

sg_write_x --same=NDOB [--16] [--32] [--app-tag=AT] [--bs=BS] [--dpo] [--fua] [--grpnum=GN] [--in=IF] [--lba=LBA] [--num=NUM] [--offset=OFF[,DLEN]] [--ref-tag=RT] [--strict] [--timeout=TO] [--unmap=U_A] [--wrprotect=WPR] DEVICE

sg_write_x --scattered=RD --in=IF [--16] [--32] [--app-tag=AT] [--bs=BS] [--dld=DLD] [--dpo] [--fua] [--grpnum=GN] [--lba=LBA[,LBA...]] [--num=NUM[,NUM...]] [--offset=OFF[,DLEN]] [--ref-tag=RT] [--scat-file=SF] [--scat-raw] [--strict] [--tag-mask=TM] [--timeout=TO] [--wrprotect=WPR] DEVICE

sg_write_x --stream=ID --in=IF [--16] [--32] [--app-tag=AT] [--bs=BS] [--dpo] [--fua] [--grpnum=GN] [--lba=LBA] [--num=NUM] [--offset=OFF[,DLEN]] [--ref-tag=RT] [--strict] [--tag-mask=TM] [--timeout=TO] [--wrprotect=WPR] DEVICE

## DESCRIPTION
This utility will send one of six SCSI commands, all associated with writing data to the given DEVICE. They are a "normal" WRITE, ORWRITE, WRITE ATOMIC, WRITE SAME, WRITE SCATTERED or WRITE STREAM. This utility supports the 16 and 32 byte variants of all six commands. Hence some closely related commands are not supported (e.g. WRITE(10)). All 32 byte variants, apart from ORWRITE(32), require the DEVICE to be formatted with type 1, 2 or 3 Protection Information (PI), making all logical blocks 8 bytes (or a multiple of 8 bytes) longer on the media.

The command line interface is a little crowded with over thirty options. Hence the SYNOPSIS, after listing all the (long) options, lists those applicable to each supported command. For each command synopsis, the option that selects the SCSI command is shown first followed by any required options. If no command option is given then a "normal" WRITE is assumed. Even though the --scat-file=SF option can be given for every command, it is only shown for WRITE SCATTERED where it is most useful. If the --scat-file=SF option is given then neither the --lba=LBA[,LBA...] nor the --num=NUM[,NUM...] options should be given. Only the first item of the --lba=LBA[,LBA...] and the --num=NUM[,NUM...] options (or first pair (or quintet) from the --scat-file=SF option) is used for all but the WRITE SCATTERED command. All commands can take --dry-run and --verbose in addition to those shown in the SYNOPSIS.

The logical block size in bytes can be given explicitly with the --bs=BS option, as long as BS is greater than zero. It is typically a power of two, 512 or greater. If the --bs=BS option is not given or BS is zero then the SCSI READ CAPACITY command is used to find the logical block size. First the READ CAPACITY(16) command is tried and if successful the logical block size in the response is typically used as the actual block size for this utility. The exception is when PROT_EN is set in the response and the --wrprotect=WPR option is given and non-zero; in which case 8 (bytes) is added to the logical block size to yield the actual block size used by this utility. If READ CAPACITY(16) fails then READ CAPACITY(10) is tried and if that works then the logical block size in the response is used as the actual block size.

The number of bytes this utility will attempt to read from the file named by IF is the product of the actual block size and the number_of_blocks (NUM or the sum of NUM arguments). If less bytes are read from the file IF and the --strict option is given then this utility exits with an exit status of SG_LIB_FILE_ERROR. If less bytes are read from the file IF and the --strict option is not given then bytes of zero are substituted for the "missing" bytes and this utility continues.

Attempts to write multi megabyte data with a single command are likely to fail for one of several reasons. First the operating system might object to allocating a buffer that large. Next the SCSI pass-through usually limits data blocks to a few megabytes or less. Finally the storage device might have a limited amount of RAM to support a write operation such as atomic (as it may need to roll back). The storage device can inform the application client of its limitations via the block limits VPD page (0xb0), with the maximum atomic transfer length field amongst others.

A degenerate LBA (Logical Block Address) range descriptor with no PI has an LBA and NUM of zero. A degenerate LBA range descriptor with PI additionally has its RT, AT and TM fields set to zero (note: that is not the default values for RT, AT and TM). They are degenerate in the sense that they are indistinguishable from a pad of zeros that follow the scatter list in the data-out buffer. SBC-4 makes clear that a degenerate LBA range descriptor is valid. This may become an issue if RD given in the --scattered=RD option has the value 0. In this case the logic may need to scan the user provided data to calculate the number of LBA range descriptors which is required by the WRITE SCATTERED cdb. In the absence of other information the logic will take a degenerate LBA range descriptor as a terminator of the scatter list.

The reference for these commands is SBC-4 (T10/BSR INCITS 506-2021) and draft SBC-5 INCITS 571 revision 1 dated 21 May 2021. All six SCSI commands are described in those documents. WRITE ATOMIC was added in SBC-4 revision 3; WRITE STREAM was added in SBC-4 revision 7; WRITE SCATTERED was added in SBC-4 revision 11 while the others are in the previous SBC-3 standard.

## OPTIONS
Arguments to long options are mandatory for short options as well. The options are arranged in alphabetical order based on the long option name.

-6, --16

send the 16 byte cdb variant of the selected SCSI command. If no command is selected then the (normal) SCSI WRITE(16) command is sent. If neither this option nor the --32 option is given then this option is assumed.

-3, --32

send the 32 byte cdb variant of the selected SCSI command. If no command is selected then the (normal) SCSI WRITE(32) command is sent. If neither this option nor the --16 option is given then then the --16 option is assumed. If both this option and the --16 option are given then this option takes precedence. Note that apart from ORWRITE(32) all other 32 byte cdb variants require a DEVICE formatted with type 1, 2 or 3 protection information.

-a, --app-tag=AT

where AT is the "expected logical block application tag" field found in most of the 32 byte cdb variants (the exception is ORWRITE(32)). AT is a 16 bit field which means the maximum value is 0xffff. The default value is 0xffff .

-A, --atomic=AB

selects the WRITE ATOMIC command and AB is placed in the Atomic Boundary field of its cdb. It is a 16 bit field so the maximum value is 0xffff. If unsure what value to set, try 0 which will attempt to write the whole data-out buffer in a single atomic operation.

-B, --bmop=OP,PGP

where OP and PGP are the values to be placed in ORWRITE(32)'s BMOP and 'Previous Generation Processing' fields respectively. BMOP is a 3 bit field (ranges from 0 to 7) and PGP is a 4 bit field (ranges from 0 to 15). Both fields default to 0.

-b, --bs=BS

where BS is the logical block size or the actual block size which will be slightly bigger. The default value is zero. If this option is not given or is given with a BS of zero then the SCSI READ CAPACITY(16) command is sent to DEVICE. If that fails then the READ CAPACITY(10) command is sent. The logical and actual block size will be derived from the response of the READ CAPACITY command.

This section assumes BS is greater than zero. If BS is less than 512 (bytes) or not a multiple of 8, a warning is issued and the utility continues unless the --strict option is also given. If BS is a power of two (e.g. 512) then the logical and actual block size is set to BS (e.g. 512). If BS is not a power of two (e.g. 520) then the logical block size is set to the closest power of two less than BS (e.g. 512) and the actual block size is set to BS (e.g. 520).

If the logical and actual block size are different then a later check will reduce the actual block size back to the logical block size unless --wrprotect=WPR is greater than zero.

-c, --combined=DOF

This option only applies to WRITE SCATTERED and assumes the whole data-out buffer can be read from IF given by the --in=IF option. The whole data-out buffer is the parameter list header, followed by zero or more LBA range descriptors, optionally followed by some pad bytes and then the data to be written to the media. If the --lba=LBA[,LBA...], --num=NUM[,NUM...] or --scat-file=SF options are also given then an error is generated. The DOF argument should be the value suitable for the 'Logical Block Data Offset' field in the WRITE SCATTERED cdb. This is the offset in the data-out buffer where the data to write to the media commences. The unit of that field is the actual block size which is the logical block size plus a multiple of 8, if protection information (PI) is being sent. When WPR (from --wrprotect=WPR) is greater than zero then PI is expected. SBC-4 revision 15 does not state it but it would appear that a DOF value of 0 is invalid. It is suggested that this option be used with the --strict option while experimenting as random or incorrect data fed in via the --in=IF option could write a lot of "interesting" data all over the DEVICE. If DOF is given as 0 the utility will scan the data in IF until RD LBA range descriptors are found; or if RD is also 0 until a degenerate LBA range descriptor is found.

-D, --dld=DLD

where DLD is the duration limits descriptor spread across 3 bits in the SCSI WRITE(16) and the WRITE SCATTERED(16) cdbs. DLD is between 0 to 7 inclusive with a default of zero. The DLD0 field in WRITE(16) and WRITE SCATTERED(16) is set if (0x1 & DLD) is non-zero. The DLD1 field in both cdbs is set if (0x2 & DLD) is non-zero. The DLD2 field in both cdbs is set if (0x4 & DLD) is non-zero.

-d, --dpo

if this option is given then the DPO (disable page out) bit field in the cdb is set. The default is to clear this bit field. Applies to all commands supported by thus utility except WRITE SAME.

-x, --dry-run

this option exits (with a status of 0) just before it would otherwise send the selected SCSI write command. It may still send a SCSI READ CAPACITY command (16 byte variant and perhaps 10 byte variant as well) so the DEVICE is still required. It reads the data in and processes it if the --in=IF and/or the --scat-file=SF options are given. All command line processing and sanity checks (e.g. if the --strict option is given) will be performed and if there is an error then there will be a non zero exit status value.

If this option is given twice (e.g. -xx) then instead of performing the selected write SCSI command, the data-out buffer is written to a file called sg_write_x.bin . If it doesn't exist then that file is created in the current directory and is truncated if it previously did exist with longer contents. The data-out buffer is written in binary with some information about it written to stdout. For writes other than scattered the filename and its length in bytes is output to stdout. For write scattered additionally its number of LBA range descriptors and its logical block data offset written to stdout.

-f, --fua

if this option is given then the FUA (force unit access) bit field in the cdb is set. The default is to clear this bit field. Applies to all commands supported by thus utility except WRITE SAME.

-G, --generation=EOG,NOG

the arguments for this option are used by the ORWITE(32) command only. EOG is placed in the "Expected ORWgeneration" field while NOG is placed in the "New ORWgeneration" field. Both are 32 bits long and default to zero.

-g, --grpnum=GN

sets the 'Group number' field to GN. Defaults to a value of zero. GN should be a value between 0 and 63.

-h, --help

output the usage message then exit. Use multiple times for more help. Currently '-h' to '-hhhh' provide different output.

-i, --in=IF

read data (in binary) from a file named IF in a single OS system call (in Unix: read(2)). That data is placed in a continuous buffer and then used as the data-out buffer for all SCSI write commands apart from WRITE SCATTERED(16 or 32) which may include other data in the data-out buffer. For WRITE SCATTERED (16 or 32) the data-out buffer is made up of 3 or 4 components in this order: a parameter list header (32 zero bytes); zero or more LBA range descriptors, optionally some pad bytes (zeros) and then data to write to the media. For WRITE SCATTERED IF only provides the data to write to the media unless --combined=DOF is given. When the --combined=DOF option is given IF contains all components of the WRITE SCATTERED data-out buffer in binary. The data read from IF starts from byte offset OFF which defaults to zero and no more than DLEN bytes are read from that point (i.e. from the file byte offset OFF). If DLEN is zero or not given the rest of the file IF is read. This option is mandatory apart from when --same=1 is given (that sets the NDOB bit which stands for "No Data Out Buffer"). In Unix based OSes, any number of zeros can be produced by using the /dev/zero device file.

IF may be "-" which is taken as stdin. In this case the --offset=OFF,DLEN can be given with OFF set to 0 and LEN set to a non-zero value, preferably a multiple of the actual block size. The utility can also deduce how long the IF should be from NUM (or the sum of them in the case of a scatter list).

-l, --lba=LBA[,LBA...]

where the argument is a single Logical Block Address (LBA) or a comma separated list of LBAs each of which is the address of the first block written by the selected write command. Only the WRITE SCATTERED command can usefully take more than one LBA. Whatever number of LBAs is given, there needs to be an equal number of NUMs given to the --num=NUM[,NUM...] option. The first given LBA joins with the first given NUM to form the first LBA range descriptor (which T10 number from zero in SBC-4). The second LBA joins with the second LBA to form the second LBA range descriptor, etc. A more convenient way to define a large number of LBA range descriptors is with the --scat-file=SF option. Defaults to logical block 0 (which could be dangerous) while NUM defaults to 0 which makes the combination harmless. LBA is assumed to be in decimal unless prefixed with '0x' or has a trailing 'h'.

-N, --normal

the choice of a "normal" WRITE (16 or 32) command can be made explicitly with this option. In the absence of selecting any other command (e.g. --atomic=AB ), the choice of a "normal" WRITE is the default.

-n, --num=NUM[,NUM...]

where the argument is a single NUMber of blocks (NUM) or a comma separated list of NUMs that pair with the corresponding entries in the --lba=LBA[,LBA...] option. If a NUM is given and is not provided by another method (e.g. by using the --scat-file=SF option) then it defaults to the number of blocks derived from the size of the file named by IF (starting at byte offset OFF to the end or the file or DLEN). Apart from the --combined=DOF option, an LBA must be explicitly given (either with I--lba=LBA or via --scat-file=SF), if not NUM defaults to 0 as a safety measure.

-o, --offset=OFF[,DLEN]

where OFF is the byte offset within the file named IF to start reading from. The default value of OFF is zero which is the beginning of file named IF. DLEN is the maximum number of bytes to read, starting at byte offset OFF, from the file named IF. Less bytes will be read if an end of file occurs before DLEN is exhausted. If DLEN is zero or not given then reading from byte offset OFF to the end of the file named IF is assumed.

-O, --or

selects the ORWRITE command. ORWRITE(16) has similar fields to WRITE(16) apart from the WRPROTECT field being named ORPROTECT with slightly different semantics and the absence of the 3 DLD bit fields. ORWRITE(32) has four extra fields that are set with the --bmop=OP,PGP and --generation=EOG,NOG options. ORWRITE(32) is the only 32 byte cdb command in this utility that does not require a DEVICE formatted with type 1, 2 or 3 PI (although it will still work if it is formatted with PI).

-Q, --quiet

suppress some informational messages such as the ones associated with detected errors when this utility is about to exit. The exit status value is still returned to the operating system when this utility exits.

-r, --ref-tag=RT

where RT is the "expected initial logical block reference tag" field found in the 32 byte cdb variants of WRITE, WRITE ATOMIC, WRITE SAME and WRITE STREAM. The field is also found in the WRITE SCATTERED(32) LBA range descriptors. It is a 32 bit field which means the maximum value is 0xffffffff. The default value is 0xffffffff.

-S, --same=NDOB

selects the WRITE SAME command with the NDOB field set to NDOB which stands for No Data-Out Buffer. NDOB can take values 0 or 1 (i.e. it is a single bit field). When --same=1 all options associated with the data-out buffer are ignored.

-q, --scat-file=SF

where SF is the name of an auxiliary file containing the scatter list for the WRITE SCATTERED command. If the --scat-raw option is also given then SF is assumed to contain both the parameter list header (32 bytes of zeros) followed by zero or more LBA range descriptors which are also 32 bytes long each. These components are as defined by SBC-4 (i.e. in binary with integers in big endian format). If the --scat-raw option is not given then a file of ACSII hexadecimal is expected as described in the SCATTERED FILE ASCII FORMAT section below.

If this option is given with the --combined=DOF option then this utility will exit with a syntax error. SF must not be "-", a way of stopping the user trying to redirect stdin.

-R, --scat-raw

this option only effects the way that the file named SF from the --scat-file=SF option for WRITE SCATTERED is interpreted. By default (i.e. without this option), SF is parsed as ASCII hexadecimal with blank lines and line contents from and including '#' to the end of line ignored. Hence it can contain comments and other indications. When this option is given, the file named SF is interpreted as binary. As binary it is assumed to contain 32 bytes of zeros (the WRITE SCATTERED parameter list header) followed by zero or more LBA range descriptors (which are 32 bytes each). If the --strict option is given the reserved field in those two items are checked with any non zero bytes causing an error.

-S, --scattered=RD

selects the WRITE SCATTERED command with RD being the number of LBA range descriptors that will be placed in the data-out buffer. If RD is zero then the logic will try and determine the number of range descriptors by other means (e.g. by parsing the file named by SF, if there is one). The LBA range descriptors differ between the 16 and 32 byte cdb variants of WRITE SCATTERED. In the 16 byte cdb variant the 32 byte LBA range descriptor is made up of an 8 byte LBA, followed by a 4 byte number_of_blocks followed by 20 bytes of zeros. In the 32 byte variant the LBA and number_of_blocks are followed by a RT (4 bytes), an AT (2 bytes) and a TM (2 bytes) then 12 bytes of zeros.

This paragraph applies when RD is greater than zero. If RD is less than the number of LBA range descriptors built from command line options, from the --scat-file=SF option or decoded from IF (when the --combined=DOF option is given) then RD takes precedence; so RD is placed in the "Number of LBA Range Descriptors" field in the cdb. If RD is greater than the number of LBA range descriptors found from the provided data and options, then an error is generated.

-T, --stream=ID

selects the WRITE STREAM command with the STR_ID field set to ID. ID can take values from 0 to 0xffff (i.e. it is a 16 bit field).

-s, --strict

when this option is present, more things (e.g. that reserved fields contain zeros) and any irregularities will terminate the utility with a message to stderr and an indicative exit status. While experimenting with these commands, especially WRITE SCATTERED, it is recommended to use this option.

-t, --tag-mask=TM

where TM is the "logical block application tag mask" field found in the 32 byte cdb variants of WRITE, WRITE ATOMIC, WRITE SAME and WRITE STREAM. The field is also found in the WRITE SCATTERED(32) LBA range descriptors. It is a 16 bit field which means the maximum value is 0xffff. The default value is 0xffff.

-I, --timeout=TO

where TO is the command timeout value in seconds. The default value is 120 seconds. If NUM is large on slow media then these WRITE commands may require considerably more time than 120 seconds to complete. An alternate long option form is --tmo=TO .

-u, --unmap=U_A

where U_A is OR-ed bit values used to set the UNMAP and ANCHOR bit fields in the WRITE SAME (16 or 32) cdb. If U_A is 1 then the UNMAP bit field is set; if U_A is 2 then the ANCHOR bit field is set; if U_A is 3 then both the UNMAP and ANCHOR bit fields are set. The default value for both bit fields is clear (0); setting U_A to 0 will also clear both bit fields.

-v, --verbose

increase the degree of verbosity (debug messages). These messages are usually written to stderr.

-V, --version

output version string then exit.

-w, --wrprotect=WPR

sets the WRPROTECT field (3 bits) in all sg_write_x commands apart from ORWRITE which has a 3 bit ORPROTECT field (and the synopsis shows OPR to highlight the difference). In all cases WPR is placed in that 3 bit field. The default value is zero which does not send any PI in the data-out buffer. WPR should be a value between 0 and 7.

## SCATTERED FILE ASCII FORMAT
All commands in this utility can take a --scat-file=SF and that option can be seen as a replacement for the --lba=LBA[,LBA...] and --num=NUM[,NUM...] options. if both the --scat-file=SF and --scat-raw options are given then the file named SF is expected to be binary and contain the parameter list header (32 bytes of zeros for both the 16 and 32 byte variants) followed by zero or more LBA range descriptors, each of 32 bytes each. This section describes what is expected in SF when the --scat-raw option is not given.

The ASCII hexadecimal "scatter file" (named by SF) can contain comments, empty lines and numbers. If multiple numbers appear on one line they can be separated by spaces, tabs or a single comma. Numbers are parsed as decimal unless prefixed by "0x" (or "0X") or have a suffix of "h". Ox is the prefix of hexadecimal number is the C language while T10 uses the "h" suffix for the same purpose. Anything from and including a "#" character to the end-of-line is ignored, so comments can be placed there.

For the WRITE SCATTERED (16) command, its LBA range descriptors contain two items per descriptor: an 8 byte LBA followed by a 4 byte number_of_blocks. The remaining 20 bytes of the descriptor are zeros. The format accepted is relatively loose with each decoded value being placed in an LBA and then a number_of_blocks until the end-of-file is reached. The pattern starts with a LBA and if it doesn't finish with a number_of_blocks (i.e. an odd number of values are parsed) an error occurs. So the number of LBA range descriptors generated will be half the number of values parsed in SF.

For the WRITE SCATTERED (32) command, its LBA range descriptors contain five items per descriptor: an 8 byte LBA followed by a 4 byte number_of_blocks, then a 4 byte RT, a 2 byte AT, and a 2 byte TM. The last three items are associated with protection information (PI). The accepted format in the SF file is more constrained than the 16 byte cdb variant. The items for each LBA range descriptor must be found on one line with adjacent items being comma separated. The first two items (LBA and number_of_blocks) must be given, and if no more items are on the line then RT, AT and TM are given their default values (all "ff" bytes). Spaces and tabs may appear between items but commas are the separators. Two commas with no value between them will cause the "missing" item to receive its default value.

## NOTES
Various numeric arguments (e.g. LBA) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page.

In Linux, prior to lk 3.17, the sg driver did not support cdb sizes greater than 16 bytes. Hence a device node like /dev/sg1 which is associated with the sg driver would fail with this utility if the --32 option was given (or implied by other options). The bsg driver with device nodes like /dev/bsg/6:0:0:1 does support cdb sizes greater than 16 bytes since its introduction in lk 2.6.28 .

## EXIT STATUS
The exit status of sg_write_x is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

## EXAMPLES
One simple usage is to write 4 blocks of zeros from (and including) a given LBA according to the rules of WRITE ATOMIC with an atomic boundary of 0. Since no cdb size option is given, the 16 byte cdb will be assumed (i.e. WRITE ATOMIC(16)):

sg_write_x --atomic=0 --in=/dev/zero --lba=0x1234 --num=4 /dev/sdc

Since --bs=BS has not been given, then this utility will call the READ CAPACITY(16) command on /dev/sdc to determine the number of bytes in a logical block. If the READ CAPACITY(16) command fails then the READ CAPACITY(10) command is tried. Let us assume one of them works and that the number of bytes in each logical block is 512 bytes. So 4 blocks of zeros (each block containing 512 bytes) will be written from (and including) LBA 0x1234 . Now to bypass the need for the READ CAPACITY command(s) the --bs=BS option can be used:

sg_write_x --atomic=0 --bs=512 --in=/dev/zero --lba=0x1234 --num=4 /dev/sdc

Since --bs= is given and its value (512) is a power of 2, then the actual block size is also 512. If instead 520 was given then the logical block size would be 512 (the highest power of 2 less than 520) and the actual block size would be 520 bytes. To send the 32 byte variant add --32 as in:

sg_write_x --atomic=0 --32 --bs=512 --in=/dev/zero --lba=0x1234 --num=4 /dev/sdc

For examples using 'sg_write_x --same=NDOB' see the manpage for sg_write_same(8). The syntax is a little different but the semantics are the same.

To send a WRITE STREAM(32) with a STR_ID of 1 use the following:

sg_write_x --stream=1 --32 --bs=512 --in=/dev/zero --lba=0x1234 --num=4 /dev/sdc

Next is a WRITE SCATTERED(16) command with the scatter list, split between the --lba= and --num= options, on the command line:

sg_write_x --scattered=2 --lba=2,0x33 --num=4,1 -i /dev/zero /dev/sg1

Example of a WRITE SCATTERED(16) command with a degenerate LBA range descriptor (first element to --lba= and --num=):

sg_write_x --scattered=2 --lba=0,0x33 --num=0,1 -i /dev/zero /dev/sg1

Example of a WRITE SCATTERED(16) command with the scatter list in scat_file.txt

sg_write_x --scattered=3 -q scat_file.txt -i /dev/zero /dev/sg1

Next a WRITE SCATTERED(16) command with its scatter list and data in a single file. Note that the argument to --scattered= is 0 so the number of LBA range descriptors is calculated by analyzing the first two blocks of scat_data.bin (because the argument to --combined= is 2) :

sg_write_x --scattered=0 --combined=2 -i scat_data.bin /dev/sg1

When the -xx option is used, a WRITE SCATTERED command is not executed but instead the contents of the data-out buffer are written to a file called sg_write_x.bin . In the case of WRITE SCATTERED that binary file is suitable for supplying to a later invocation to do the actual write to media. For example:

$ sg_write_x --scattered=3 -q scat_file.txt -xx -i /dev/zero /dev/sg1

Wrote 8192 bytes to sg_write_x.bin, LB data offset: 1

Number of LBA range descriptors: 3

sg_write_x --scattered=0 --combined=1 -i sg_write_x.bin /dev/sg1

Notice when the sg_write_x.bin is written (and nothing is written to the media), a summary of what has happened is sent to stdout. The value shown for "LB data offset:" (1) should be given to the --combined= option when the write to media actually occurs (i.e. the second invocation shown directly above).

## AUTHORS
Written by Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2017-2023 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
sg_readcap,sg_vpd,sg_write_same,sg_stream_ctl(sg3_utils)


title: sg_xcopy(8)

text:
# sg_xcopy(8)

## NAME
sg_xcopy - copy data to and from files and devices using SCSI EXTENDED COPY (XCOPY)

## SYNOPSIS
sg_xcopy [bs=BS] [conv=CONV] [count=COUNT] [ibs=BS] [if=IFILE] [iflag=FLAGS] [obs=BS] [of=OFILE] [oflag=FLAGS] [seek=SEEK] [skip=SKIP] [--help] [--version]

[app=0|1] [bpt=BPT] [cat=0|1] [dc=0|1] [fco=0|1] [id_usage={hold|discard|disable}] [list_id=ID] [prio=PRIO] [time=0|1] [verbose=VERB] [--on_dst|--on_src] [--verbose]

## DESCRIPTION
Copy data to and from any files. Specialized for "files" that are Linux SCSI devices that support the SCSI EXTENDED COPY (XCOPY) command.

This utility has similar syntax and semantics to dd(1) but with no "conversions" is supported.

The first group in the synopsis above are "standard" Unix dd(1) operands. The second group are extra options added by this utility. Both groups are defined below in combined, alphabetical order.

By default the XCOPY command is sent to OFILE. This can be changed with the --on_src or iflag=xflag options which cause the XCOPY command to be sent to IFILE instead. Also see the section on ENVIRONMENT VARIABLES.

In the SPC-4 standard the T10 committee has expanded the XCOPY command so that it now has two variants: "LID1" (for a List Identifier length of 1 byte) and "LID4" (for a List Identifier length of 4 bytes). This utility supports the older, LID1 variant which is also found in SPC-3 and earlier. While the LID1 variant in SPC-4 is command level (binary) compatible with XCOPY as defined in SPC-3, some of the command naming has changed. This utility uses the older, SPC-3 XCOPY names.

The ddpt utility supports the same xcopy(LID1) functionality as this utility with the same options and flags. Additionally ddpt supports a subset of xcopy(LID4) functionality variously called "xcopy version 2, lite" or ODX. ODX is a market name and stands for Offloaded Data Xfer (i.e. transfer).

## OPTIONS
app={0|1}

if 1 start the destination of the copy at the end of OFILE. This assumes that OFILE is a regular file. The default is 0 in which case the destination of the copy starts at the beginning of OFILE (possibly offset be SEEK). This option cannot be used with the seek=SEEK option.

bpt=BPT

each IO transaction will be made using BPT blocks (or less if near the end of the copy). Default is 128 for logical block sizes less that 2048 bytes, otherwise the default is 32. So for bs=512 the reads and writes will each convey 64 KiB of data by default (less if near the end of the transfer or memory restrictions). When cd/dvd drives are accessed, the logical block size is typically 2048 bytes and bpt defaults to 32 which again implies 64 KiB transfers.

bs=BS

where BS must be the logical block size of the physical device (if either the input or output files are accessed via SCSI commands). Note that this differs from dd(1) which permits BS to be an integral multiple. Defaults to the device logical block size.

cat={0|1}

sets the SCSI EXTENDED COPY command segment descriptor CAT bit to 0 or 1 (default: 0). The CAT bit (in conjunction with the PAD bit) controls the handling of residual data. See section HANDLING OF RESIDUAL DATA for details.

conv=CONV

all CONV arguments are ignored.

count=COUNT

copy COUNT blocks from IFILE to OFILE. Default is the minimum (IFILE if dc=0 or OFILE if dc=1) number of blocks that SCSI devices report from SCSI READ CAPACITY commands or that block devices (or their partitions) report. Normal files are not probed for their size. If skip=SKIP or seek=SEEK are given and the count is derived (i.e. not explicitly given) then the derived count is scaled back so that the copy will not overrun the device. If the file name is a block device partition and COUNT is not given then the size of the partition rather than the size of the whole device is used. If COUNT is not given (or count=-1) and cannot be derived then an error message is issued and no copy takes place.

dc={0|1}

sets the SCSI EXTENDED COPY command segment descriptor DC bit to 0 or 1 (default: 0). The DC bit controls whether COUNT refers to the source (dc=0) or the target (dc=1) descriptor.

fco={0|1}

sets the SCSI EXTENDED COPY command segment descriptor FCO bit to 0 or 1 (default: 0). The Fast Copy Only (FCO) bit set will result in the copy being done but a technique faster than SCSI READ and WRITE commands. If the copy cannot but done in a faster manner then a sense key of "Copy aborted" with and additional sense of "Fast copy not possible" is returned.

ibs=BS

if given must be the same as BS given to 'bs=' option.

id_usage={hold|discard|disable}

sets the SCSI EXTENDED COPY command parameter list field called LIST ID USAGE to 0 if the argument is 'hold', to 2 if the argument is 'discard', or to '3' if the argument is 'disable'.

If the device has the ability to hold data (as indicated by "held data limit" being greater than zero) then id_usage defaults to 'hold' otherwise it defaults to 'discard'.

if=IFILE

read from IFILE instead of stdin. If IFILE is '-' then stdin is read. Starts reading at the beginning of IFILE unless SKIP is given.

iflag=FLAGS

where FLAGS is a comma separated list of one or more flags outlined below. These flags are associated with IFILE and are ignored when IFILE is stdin.

list_id=ID

sets the SCSI EXTENDED COPY command parameter list field called LIST IDENTIFIER to ID. ID should be a value between 0 and 255 (inclusive). ID usually defaults to 1 unless id_usage=disable in which case it defaults to 0.

obs=BS

if given must be the same as BS given to 'bs=' option.

of=OFILE

write to OFILE instead of stdout. If OFILE is '-' then writes to stdout. If OFILE is /dev/null then no actual writes are performed. If OFILE is '.' (period) then it is treated the same way as /dev/null (this is a shorthand notation). If OFILE exists then it is _not_ truncated; it is overwritten from the start of OFILE unless 'oflag=append' or SEEK is given.

oflag=FLAGS

where FLAGS is a comma separated list of one or more flags outlined below. These flags are associated with OFILE and are ignored when OFILE is /dev/null, '.' (period), or stdout.

prio=PRIO

sets the SCSI EXTENDED COPY command parameter list field called PRIORITY to PRIO. The default value is 1.

seek=SEEK

start writing SEEK bs-sized blocks from the start of OFILE. Default is block 0 (i.e. start of file).

skip=SKIP

start reading SKIP bs-sized blocks from the start of IFILE. Default is block 0 (i.e. start of file).

time={0|1}

when 1, times transfer and does throughput calculation, outputting the results (to stderr) at completion. When 0 (default) doesn't perform timing.

verbose=VERB

as VERB increases so does the amount of debug output sent to stderr. Default value is zero which yields the minimum amount of debug output. A value of 1 reports extra information that is not repetitive. A value 2 reports cdbs and responses for SCSI commands that are not repetitive (i.e. other that READ and WRITE). Error processing is not considered repetitive. Values of 3 and 4 yield output for all SCSI commands (and Unix read() and write() calls) so there can be a lot of output.

-h, --help

outputs usage message and exits.

--on_dst

send the XCOPY command to the output file/device (i.e. OFILE). This is the default unless overridden by the --on_src or iflag=xflag options. Also see the section below on ENVIRONMENT VARIABLES.

--on_src

send the XCOPY command to the input file/device (i.e. IFILE).

-v, --verbose

equivalent to verbose=1. When used twice, equivalent to verbose=2, etc.

-V, --version

outputs version number information and exits.

## FLAGS
Here is a list of flags and their meanings:

append

causes the O_APPEND flag to be added to the open of OFILE. For regular files this will lead to data appended to the end of any existing data. Cannot be used together with the seek=SEEK option as they conflict. The default action of this utility is to overwrite any existing data from the beginning of the file or, if SEEK is given, starting at block SEEK. Note that attempting to 'append' to a device file (e.g. a disk) will usually be ignored or may cause an error to be reported.

excl

causes the O_EXCL flag to be added to the open of IFILE and/or OFILE.

flock

after opening the associated file (i.e. IFILE and/or OFILE) an attempt is made to get an advisory exclusive lock with the flock() system call. The flock arguments are "FLOCK_EX | FLOCK_NB" which will cause the lock to be taken if available else a "temporarily unavailable" error is generated. An exit status of 90 is produced in the latter case and no copy is done.

null

has no affect, just a placeholder.

pad

sets the SCSI EXTENDED COPY command segment descriptor PAD bit. The PAD bit (in conjunction with the CAT bit) controls the handling of residual data.(See section HANDLING OF RESIDUAL DATA for details.

xcopy

has no affect; for compatibility with ddpt.

## HANDLING OF RESIDUAL DATA
The pad and cat bits control the handling of residual data. As the data can be specified either in terms of source or target logical block size and both might have different block sizes residual data is likely to happen in these cases. If both logical block sizes are identical these bits have no effect as residual data will not occur.

If none of these bits are set, the EXTENDED COPY command will be aborted with additional sense 'UNEXPECTED INEXACT SEGMENT'.

If only the cat bit is set the residual data will be retained and made available for subsequent segment descriptors. Residual data will be discarded for the last segment descriptor.

If the pad bit is set for the source descriptor only, any residual data for both source or destination will be discarded.

If the pad bit is set for the target descriptor only any residual source data will be handled as if the cat bit is set, but any residual destination data will be padded to make a whole block transfer.

If the pad bit is set for both source and target any residual source data will be discarded, and any residual destination data will be padded.

## ENVIRONMENT VARIABLES
If the command line invocation does not explicitly (and unambiguously) indicate whether the XCOPY SCSI command should be sent to IFILE (i.e. the source) or OFILE (i.e. the destination) then a check is made for the presence of the XCOPY_TO_SRC and XCOPY_TO_DST environment variables. If either one exists (but not both) then it indicates where the SCSI XCOPY command will be sent. By default the XCOPY command is sent to OFILE.

## RETIRED OPTIONS
Here are some retired options that are still present:

append=0 | 1

when set, equivalent to 'oflag=append'. When clear the action is to overwrite the existing file (if it exists); this is the default. See the 'append' flag.

## NOTES
Copying data behind an Operating System's back can cause problems. In the case of Linux, users should look at this link:

https://linux-mm.org/Drop_Caches

This command sequence may be useful:

sync; echo 3 > /proc/sys/vm/drop_caches

Various numeric arguments (e.g. SKIP) may include multiplicative suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section in the sg3_utils(8) man page.

The COUNT, SKIP and SEEK arguments can take 64 bit values (i.e. very big numbers). Other values are limited to what can fit in a signed 32 bit number.

All informative, warning and error output is sent to stderr so that dd's output file can be stdout and remain unpolluted. If no options are given, then the usage message is output and nothing else happens.

If a device supports xcopy operations then it should set the 3PC field (3PC stands for Third Party Copy) in its standard INQUIRY response. This utility will attempt a xcopy operation irrespective of the value in the 3PC field but if it is zero (cleared) one would expect the xcopy operation to fail.

The status of the SCSI EXTENDED COPY command can be queried with sg_copy_results(sg3_utils)

Currently only block-to-block transfers are implemented; IFILE and OFILE must refer to a SCSI block device.

No account is taken of partitions so, for example, /dev/sbc2, /dev/sdc, /dev/sg2, and /dev/bsg/3:0:0:1 would all refer to the same thing: the whole logical unit (i.e. the whole disk) starting at LBA 0. So any partition indication (e.g. /dev/sdc2) is ignored. The user should set SKIP, SEEK and COUNT with information obtained from a command like 'fdisk -l -u /dev/sdc' to account for partitions.

XCOPY (LID1) capability has been added to the ddpt utility which is in a package of the same name. The ddpt utility will run on other OSes (e.g. FreeBSD and Windows) while sg_xcopy only runs on Linux. Also ddpt permits the arguments to ibs= and ibs= to be different.

## EXAMPLES
Copy 2M of data from the start of one device to another:

\# sg_xcopy if=/dev/sdo of=/dev/sdp count=2048 list_id=2 dc=1

sg_xcopy: if=/dev/sdo skip=0 of=/dev/sdp seek=0 count=1024

Start of loop, count=1024, bpt=65535, lba_in=0, lba_out=0

sg_xcopy: 1024 blocks, 1 command

Check the status of the EXTENDED COPY command:

\# sg_copy_results --status --list_id=2 /dev/sdp

Receive copy results (copy status):

Held data discarded: Yes

Copy manager status: Operation completed without errors

Segments processed: 1

Transfer count units: 0

Transfer count: 0

## SIGNALS
The signal handling has been borrowed from dd: SIGINT, SIGQUIT and SIGPIPE output the number of remaining blocks to be transferred and the records in + out counts; then they have their default action. SIGUSR1 causes the same information to be output yet the copy continues. All output caused by signals is sent to stderr.

## EXIT STATUS
The exit status of sg_xcopy is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

An additional exit status of 90 is generated if the flock flag is given and some other process holds the advisory exclusive lock.

## AUTHORS
Written by Hannes Reinecke and Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2000-2021 Hannes Reinecke and 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
There is a web page discussing sg_dd at https://sg.danny.cz/sg/sg_dd.html

A POSIX threads version of this utility called sgp_dd is in the sg3_utils package. Another version from that package is called sgm_dd and it uses memory mapped IO to speed transfers from sg devices.

The lmbench package contains lmdd which is also interesting. For moving data to and from tapes see dt which is found at https://www.scsifaq.org/RMiller_Tools/index.html

To change mode parameters that effect a SCSI device's caching and error recovery see sdparm(sdparm)

See also dd(1), sg_copy_results(sg3_utils), ddrescue(GNU), ddpt,ddptctl(ddpt)


title: sg_z_act_query(8)

text:
# sg_z_act_query(8)

## NAME
sg_z_act_query - send a SCSI ZONE ACTIVATE or ZONE QUERY command

## SYNOPSIS
sg_z_act_query [--activate] [--all] [--force] [--help] [--hex] [--inhex=FN] [--maxlen=LEN] [--num=ZS] [--other=ZDID] [--query] [--raw] [--verbose] [--version] [--zone=ID] DEVICE

## DESCRIPTION
Sends a SCSI ZONE ACTIVATE or ZONE QUERY command to the DEVICE. If the --activate option is not given, then a ZONE QUERY command is sent. These commands were added in the ZBC-2 draft revision 4 (zbc2r04.pdf).

Both of these commands have similar cdb_s and responses hence they are both placed in this utility. The difference is that only the ZONE ACTIVATE command will potentially activate or deactivate zones. Both commands will perform a "Verify activations operation" as defined in ZBC-2 .

## OPTIONS
Arguments to long options are mandatory for short options as well.

-A, --activate

sends a ZONE ACTIVATE command to the DEVICE. The default (i.e. without this option) is to send a ZONE QUERY command.

-a, --all

sets the ALL field in the cdb.

-f, --force

when decoding the response to this command, certain sanity checks are done and if they fail a message is sent to stderr and a non-zero exit status is set. If this option is given those sanity checks are bypassed.

-h, --help

output the usage message then exit.

-H, --hex

output the response in hexadecimal to stdout. When used once the whole response is output in ASCII hexadecimal with a leading address (starting at 0) on each line. When used twice each zone activation descriptor in the response is output separately in hexadecimal. When used thrice the whole response is output in hexadecimal with no leading address (on each line).

The output format when this option is given thrice is suitable for a later invocation with the --inhex=FN option.

-i, --inhex=FN

where FN is a file name whose contents are assumed to be ASCII hexadecimal. If DEVICE is also given then DEVICE is ignored, a warning is issued and the utility continues, decoding the file named FN. See the "HEX, BINARY AND JSON FORMATS" section in the sg3_utils manpage for more information. If the --raw option is also given then the contents of FN are treated as binary.

By default it is assumed the response is from a ZONE QUERY command but that shouldn't matter because the response of the ZONE ACTIVATE and ZONE QUERY commands is of the same form.

-m, --maxlen=LEN

where LEN is the (maximum) response length in bytes. It is placed in the cdb's "allocation length" field. If not given (or LEN is zero) then 8192 is used. The maximum allowed value of LEN is 1048576.

The draft standard disallows allocation lengths less than 64.

-n, --num=ZS

where ZS is placed in the "Number of zones" field in the cdb. This option is usually ignored if the --all option is given. If the --all option is not given, the default value of this field is 1 .

-o, --other=ZDID

where the ZDID value will be placed in the "Other zone domain ID" field of the cdb to be sent to the DEVICE.

-q, --query

causes the ZONE QUERY command to be sent to the DEVICE. Since this is the default action, this option is typically not needed. If both this option and the --activate option are given, an error will be reported (and no command will be sent).

-r, --raw

output response in binary (to stdout) unless the --inhex=FN option is also given. In that case the input file name (FN) is decoded as binary (and the output is _not_ in binary (but may be hex)).

-v, --verbose

increase the level of verbosity, (i.e. debug output).

-V, --version

print the version string and then exit.

-z, --zone=ID

where ID is placed in the cdb's ZONE ID field. A zone id is a zone start logical block address (LBA). The default value is 0. ID is assumed to be in decimal unless prefixed with '0x' or has a trailing 'h' which indicate hexadecimal. The maximum value that can be given is 2^64 - 2. In the unlikely event of wanting to give 2^64 - 1, enter "-1".

## EXIT STATUS
The exit status of sg_z_act_query is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

## AUTHORS
Written by Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2021-2023 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
sg_zone,sg_rep_zones,sg_reset_wp(sg3_utils)


title: sg_zone(8)

summary: send a SCSI ZONE modifying command

text:
# sg_zone(8)

## NAME
sg_zone - send a SCSI ZONE modifying command

## SYNOPSIS
sg_zone [--all] [--close] [--count=ZC] [--element=EID] [--finish] [--help] [--open] [--remove] [--sequentialize] [--timeout=SE] [--verbose] [--version] [--zone=ID] DEVICE

## DESCRIPTION
Sends a SCSI OPEN ZONE, CLOSE ZONE, FINISH ZONE, REMOVE ELEMENT AND MODIFY ZONES or SEQUENTIALIZE ZONE command to the DEVICE. All but the last two are found in the ZBC standard (INCITS 536-2016). The REMOVE ELEMENT AND MODIFY ZONES command was added in zbc2r07 while the SEQUENTIALIZE ZONE command was added in zbc2r01b.

One and only one of the --open, --close, --finish, --remove and --sequentialize options can be chosen.

The REPORT ZONES, REPORT REALMS and REPORT ZONE DOMAINS commands may be accessed via the sg_rep_zones utility. The ZONE ACTIVATE and ZONE QUERY commands may be accessed via the sg_z_act_query utility. The RESET WRITE POINTER command may be accessed via the sg_reset_wp utility.

## OPTIONS
Arguments to long options are mandatory for short options as well.

-a, --all

sets the ALL field in the cdb.

-c, --close

causes the CLOSE ZONE command to be sent to the DEVICE.

-C, --count=ZC

ZC is placed in the Zone Count field in the cdb of all four commands supported by this utility. ZC should be a value from 0 to 65535 (0xffff) inclusive.

-e, --element=EID

where EID is an element identifier which is a 32 bit unsigned integer starting at one. This field is used by the REMOVE ELEMENT AND MODIFY ZONES command and its default value is zero (which is invalid). So the user needs to supply a valid element identifier when --remove is used.

-f, --finish

causes the FINISH ZONE command to be sent to the DEVICE.

-h, --help

output the usage message then exit.

-o, --open

causes the OPEN ZONE command to be sent to the DEVICE.

-r, --remove

causes the REMOVE ELEMENT AND MODIFY ZONES command to be sent to the DEVICE. In practice, --element=EID needs to be also given.

-S, --sequentialize

causes the SEQUENTIALIZE ZONE command to be sent to the DEVICE.

-t, --timeout=SE

where SE is the command timeout in seconds. The default is 60 seconds and if 0 is given, it is mapped to 60. An alternate form is --tmo=SE.

-v, --verbose

increase the level of verbosity, (i.e. debug output).

-V, --version

print the version string and then exit.

-z, --zone=ID

where ID is placed in the cdb's ZONE ID field. A zone id is a zone start logical block address (LBA). The default value is 0. ID is assumed to be in decimal unless prefixed with '0x' or has a trailing 'h' which indicate hexadecimal.

## NOTES
After a REMOVE ELEMENT AND MODIFY ZONES command has completed, the element in question is said to be depopulated and any affected zones are placed in the 'offline' zone condition.

SBC-4 has a similar command to REMOVE ELEMENT AND MODIFY ZONES called REMOVE ELEMENT AND TRUNCATE. The difference is that the latter "changes the association between LBAs and physical blocks" and the former does not change that association. In both cases, depopulated elements that have the 'Restoration Allowed' (RALWD) bit set (see sg_get_elem_status) may be restored with the RESTORE ELEMENTS AND REBUILD command (see sg_rem_rest_elem).

## EXIT STATUS
The exit status of sg_zone is 0 when it is successful. Otherwise see the sg3_utils(8) man page.

## AUTHORS
Written by Douglas Gilbert.

## REPORTING BUGS
Report bugs to <dgilbert at interlog dot com>.

## COPYRIGHT
Copyright © 2014-2023 Douglas Gilbert

This software is distributed under a BSD-2-Clause license. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

## SEE ALSO
sg_rem_rest_elem,sg_rep_zones,sg_reset_wp,sg_z_act_query(sg3_utils)