aboutsummaryrefslogtreecommitdiff
path: root/doc/sg_compare_and_write.8
blob: 83ea2ba51a4d09043216bbaa0522855f657705b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
.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)