245 lines
11 KiB
Groff
245 lines
11 KiB
Groff
.TH "COMPARE AND WRITE" "8" "April 2021" "sg3_utils\-1.47" SG3_UTILS
|
|
.SH NAME
|
|
sg_compare_and_write \- send the SCSI COMPARE AND WRITE command
|
|
.SH SYNOPSIS
|
|
.B sg_compare_and_write
|
|
[\fI\-\-dpo\fR] [\fI\-\-fua\fR] [\fI\-\-fua_nv\fR] [\fI\-\-grpnum=GN\fR]
|
|
[\fI\-\-help\fR] \fI\-\-in=IF\fR [\fI\-\-inw=WF\fR] \fI\-\-lba=LBA\fR
|
|
[\fI\-\-num=NUM\fR] [\fI\-\-quiet\fR] [\fI\-\-timeout=TO\fR]
|
|
[\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fI\-\-wrprotect=WP\fR]
|
|
[\fI\-\-xferlen=LEN\fR] \fIDEVICE\fR
|
|
.SH DESCRIPTION
|
|
.\" Add any additional description here
|
|
Send the SCSI COMPARE AND WRITE command to \fIDEVICE\fR. This utility fetches
|
|
a compare buffer and a write buffer from either one or two files. If the
|
|
\fI\-\-inw=WF\fR option is given then the compare buffer is fetched from the
|
|
file indicated by the \fI\-\-in=IF\fR while the write buffer is fetched from
|
|
the file indicated by the \fI\-\-inw=WF\fR. If the \fI\-\-inw=WF\fR option is
|
|
not given then the concatenated compare and write buffers are fetched from the
|
|
file indicated by the \fI\-\-in=IF\fR option.
|
|
.PP
|
|
Those buffers are expected to each contain \fINUM\fR blocks of data. The
|
|
compare starts at logical block address \fILBA\fR on the \fIDEVICE\fR and if
|
|
the comparison fails (i.e. the provided compare buffer does not equal the data
|
|
at \fILBA\fR on the \fIDEVICE\fR) then the COMPARE AND WRITE command finishes
|
|
with a sense key of MISCOMPARE. In this case this utility will complete and
|
|
set an exit status of 14 (which happens to be the sense key value of
|
|
MISCOMPARE).
|
|
.PP
|
|
If the comparison succeeds then the provided write buffer is stored starting
|
|
at \fILBA\fR for \fINUM\fR blocks on the \fIDEVICE\fR.
|
|
.PP
|
|
The actual number of bytes transferred in the data\-out buffer of the COMPARE
|
|
AND WRITE command may need to be given by the user with the
|
|
\fI\-\-xferlen=LEN\fR option. \fILEN\fR defaults to (2 * \fINUM\fR * 512)
|
|
which is 1024 for the default \fINUM\fR of 1. If the block size is other than
|
|
512 then the user will need to use \fI\-\-xferlen=LEN\fR option. If
|
|
protection information is given (indicated by a value of \fIWP\fR other than
|
|
0 (the default)) then for a \fINUM\fR of 1 \fILEN\fR should be 1040 . Note
|
|
that the SCSI READ CAPACITY command is not performed by this utility (e.g.
|
|
to find the block size).
|
|
.PP
|
|
The T10 definition of the SCSI COMPARE AND WRITE command requires that the
|
|
\fIDEVICE\fR implement the compare and optional write as an uninterrupted
|
|
series of actions. Depending on some other \fIDEVICE\fR settings a
|
|
verify operation may occur prior to the compare.
|
|
.PP
|
|
When a mismatch occurs between the compare buffer and the blocks starting
|
|
at \fILBA\fR read from the \fIDEVICE\fR the sense buffer containing the
|
|
MISCOMPARE sense key causes several messages to be sent to stderr (including
|
|
the offset of the first byte mismatch). To suppress these messages use the
|
|
\fI\-\-quiet\fR option. With or without the \fI\-\-quiet\fR option the exit
|
|
status will be set to 14.
|
|
.PP
|
|
This command is defined in SBC\-3 whose most recent revision is 36. SBC\-3
|
|
and other SCSI documents can be found at https://www.t10.org .
|
|
.SH 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.
|
|
.TP
|
|
\fB\-d\fR, \fB\-\-dpo\fR
|
|
Set the DPO bit in the COMPARE AND WRITE CDB
|
|
.TP
|
|
\fB\-f\fR, \fB\-\-fua\fR
|
|
Set the FUA bit in the COMPARE AND WRITE CDB
|
|
.TP
|
|
\fB\-F\fR, \fB\-\-fua_nv\fR
|
|
Set the FUA_NV bit in the COMPARE AND WRITE CDB. This bit was removed in
|
|
SBC\-3 revision 35d and its position marked as "reserved".
|
|
.TP
|
|
\fB\-g\fR, \fB\-\-grpnum\fR=\fIGN\fR
|
|
where \fIGN\fR is the value to be placed in the group number field in the
|
|
COMPARE AND WRITE CDB.
|
|
.TP
|
|
\fB\-h\fR, \fB\-\-help\fR
|
|
output the usage message then exit.
|
|
.TP
|
|
\fB\-i\fR, \fB\-\-in\fR=\fIIF\fR
|
|
read data (binary) from file named \fIIF\fR. This will either be the combined
|
|
compare and write buffers (when the \fI\-\-inw=WF\fR option is not given) or
|
|
just the compare buffer (when the \fI\-\-inw=WF\fR option is given). If
|
|
\fIIF\fR is '\-' then stdin (e.g. a pipe) is read.
|
|
.TP
|
|
\fB\-C\fR, \fB\-\-inc\fR=\fIIF\fR
|
|
The same as the \fB\-\-in\fR option.
|
|
.TP
|
|
\fB\-D\fR, \fB\-\-inw\fR=\fIWF\fR
|
|
read data (binary) from file named \fIWF\fR. This will the write buffer
|
|
that will become the second half of the data\-out buffer sent to the
|
|
\fIDEVICE\fR associated with the COMPARE AND WRITE command. Note that
|
|
when this option is given then the \fI\-\-in=IF\fR is expected to hold
|
|
the associated compare buffer.
|
|
.TP
|
|
\fB\-l\fR, \fB\-\-lba\fR=\fILBA\fR
|
|
where \fILBA\fR is the logical block address to start the COMPARE AND WRITE
|
|
command. Assumed to be in decimal unless prefixed with '0x' or has a
|
|
trailing 'h'.
|
|
.TP
|
|
\fB\-n\fR, \fB\-\-num\fR=\fINUM\fR
|
|
where \fINUM\fR is the number of blocks, starting at \fILBA\fR, to read
|
|
and compare with the verify instance. And given a match, the \fINUM\fR of
|
|
blocks to write starting \fILBA\fR. The default value for \fINUM\fR is 1.
|
|
.TP
|
|
\fB\-q\fR, \fB\-\-quiet\fR
|
|
suppress the sense buffer messages associated with a MISCOMPARE sense key
|
|
that would otherwise be sent to stderr. Still set the exit status to 14
|
|
which is the sense key value indicating a MISCOMPARE.
|
|
.TP
|
|
\fB\-t\fR, \fB\-\-timeout\fR=\fITO\fR
|
|
where \fITO\fR is the command timeout value in seconds. The default value is
|
|
60 seconds. If \fINUM\fR is large (or zero) a WRITE SAME command may require
|
|
considerably more time than 60 seconds to complete.
|
|
.TP
|
|
\fB\-v\fR, \fB\-\-verbose\fR
|
|
increase the degree of verbosity (debug messages).
|
|
.TP
|
|
\fB\-V\fR, \fB\-\-version\fR
|
|
output version string then exit.
|
|
.TP
|
|
\fB\-w\fR, \fB\-\-wrprotect\fR=\fIWP\fR
|
|
set the WRPROTECT field in the cdb to \fIWP\fR. The default value is 0 which
|
|
implies no protection information is sent (along with the user data) by this
|
|
utility.
|
|
.TP
|
|
\fB\-x\fR, \fB\-\-xferlen\fR=\fILEN\fR
|
|
where \fILEN\fR is the data out buffer length in byte. It defaults to (2 *
|
|
\fINUM\fR * 512) bytes. If the \fIDEVICE\fR block size is other than 512
|
|
bytes or \fIWP\fR is non\-zero (implying additional protection information)
|
|
then this default will be incorrect; the use must supply the correct value
|
|
for \fILEN\fR
|
|
.SH NOTES
|
|
Various numeric arguments (e.g. \fILBA\fR) may include multiplicative
|
|
suffixes or be given in hexadecimal. See the "NUMERIC ARGUMENTS" section
|
|
in the sg3_utils(8) man page.
|
|
.SH EXAMPLES
|
|
Before overwriting the first two blocks of whatever (SCSI) storage device
|
|
that is chosen, take a small backup. The logical block size is assumed to
|
|
be 512 bytes. Take a copy (in backup01.bin) of the first two blocks::
|
|
.PP
|
|
# sg_dd if=/dev/sg1 bs=512 of=backup01.bin count=2
|
|
2+0 records in
|
|
2+0 records out
|
|
.PP
|
|
.B WARNING:
|
|
if /dev/sg1 corresponds to a disk on your system that contains currently
|
|
mounted file systems, do _not_ continue. If you can, unmount all file
|
|
systems on that disk. If that is not possible, use another disk with no
|
|
mounted file systems on it. In Linux the scsi_debug driver is a good
|
|
candidate for experimentation.
|
|
.PP
|
|
Now fill the first block with 0xff bytes:
|
|
.PP
|
|
# sg_dd iflag=ff bs=512 of=/dev/sg1 count=1
|
|
1+0 records in
|
|
1+0 records out
|
|
.PP
|
|
and the second block with 0x0 bytes:
|
|
.PP
|
|
# sg_dd iflag=00 bs=512 seek=1 of=/dev/sg1 count=1
|
|
1+0 records in
|
|
1+0 records out
|
|
.PP
|
|
Now copy those two blocks into a file:
|
|
.PP
|
|
# sg_dd if=/dev/sg1 bs=512 of=ff00.bin count=2
|
|
2+0 records in
|
|
2+0 records out
|
|
.PP
|
|
Now we can do a compare and write command. It is told to compare the first
|
|
block (i.e. LBA 0) with the first block in the given file (i.e. ff00.bin).
|
|
If they are equal (they should be both full of 0xff bytes). Since the
|
|
compare succeeds, it will write the second block in ff00.bin over LBA 0:
|
|
.PP
|
|
# sg_compare_and_write \-\-in=ff00.bin \-\-lba=0 \-\-num=1 /dev/sg1
|
|
|
|
.PP
|
|
No news is good news. Now if we do that command again:
|
|
.PP
|
|
# sg_compare_and_write \-\-in=ff00.bin \-\-lba=0 \-\-num=1 /dev/sg1
|
|
Miscompare at byte offset: 0 [0x0]
|
|
sg_compare_and_write failed: Miscompare
|
|
.PP
|
|
This is expected. The first sg_compare_and_write ended up writing 0x0 bytes
|
|
over LBA 0x0. The second sg_compare_and_write command compares LBA 0x0 with
|
|
0xff bytes and fails immediately (i.e. at byte offset: 0). Now we will
|
|
overwrite the first 3 bytes of ff00.bin with 0x0:
|
|
.PP
|
|
# sg_dd bs=1 iflag=00 of=ff00.bin count=3
|
|
3+0 records in
|
|
3+0 records out
|
|
.PP
|
|
Notice the 'bs=1' operand. The dd utility (and thus sg_dd) is very useful for
|
|
doing small binary edits on a file. Now if we do that sg_compare_and_write
|
|
again, it still fails but with a small difference:
|
|
.PP
|
|
# sg_compare_and_write \-\-in=ff00.bin \-\-lba=0 \-\-num=1 /dev/sg1
|
|
Miscompare at byte offset: 3 [0x3]
|
|
sg_compare_and_write failed: Miscompare
|
|
.PP
|
|
So the bytes at offset 0, 1, and 2 compared equal but not the byte at
|
|
offset 3. The SCSI COMPARE AND WRITE will stop on the first micompared
|
|
byte.
|
|
.SH EXIT STATUS
|
|
The exit status of sg_compare_and_write is 0 when it is successful. If the
|
|
compare step fails then the exit status is 14. For other exit status values
|
|
see the EXIT STATUS section in the sg3_utils(8) man page.
|
|
.PP
|
|
Earlier versions of this utility set an exit status of 98 when there was a
|
|
MISCOMPARE.
|
|
.SH AUTHORS
|
|
Written by Shahar Salzman. Maintained by Douglas Gilbert. Additions by
|
|
Eric Seppanen.
|
|
.SH "REPORTING BUGS"
|
|
Report bugs to shahar.salzman@kaminario.com or dgilbert@interlog.com
|
|
.SH COPYRIGHT
|
|
Copyright \(co 2012\-2020 Kaminario Technologies LTD
|
|
.br
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
.br
|
|
* Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
.br
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
.br
|
|
* Neither the name of the <organization> nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without
|
|
specific prior written permission.
|
|
|
|
.br
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL Kaminario Technologies LTD BE LIABLE FOR ANY
|
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
.SH "SEE ALSO"
|
|
.B sg_xcopy, sg_receive_copy_results(sg3_utils)
|