Commit d9654a58576dae982458bdb1eb565c9876c24c22
Committed by
Anthony Liguori
1 parent
9dd986cc
qemu-io: Optionally verify only part of read data
There are reasonable test cases where a read must span areas that are not uniformly filled with one pattern but contains several parts. This makes -P useless for them currently. Introducing additional options which determine the part of the read data that should be verified with the given pattern allows to check such reads. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
1 changed file
with
41 additions
and
10 deletions
qemu-io.c
... | ... | @@ -191,11 +191,13 @@ read_help(void) |
191 | 191 | "\n" |
192 | 192 | " Reads a segment of the currently open file, optionally dumping it to the\n" |
193 | 193 | " standard output stream (with -v option) for subsequent inspection.\n" |
194 | +" -C, -- report statistics in a machine parsable format\n" | |
195 | +" -l, -- length for pattern verification (only with -P)\n" | |
194 | 196 | " -p, -- use bdrv_pread to read the file\n" |
195 | 197 | " -P, -- use a pattern to verify read data\n" |
196 | -" -C, -- report statistics in a machine parsable format\n" | |
197 | -" -v, -- dump buffer to standard output\n" | |
198 | 198 | " -q, -- quite mode, do not show I/O statistics\n" |
199 | +" -s, -- start offset for pattern verification (only with -P)\n" | |
200 | +" -v, -- dump buffer to standard output\n" | |
199 | 201 | "\n"); |
200 | 202 | } |
201 | 203 | |
... | ... | @@ -204,18 +206,26 @@ read_f(int argc, char **argv) |
204 | 206 | { |
205 | 207 | struct timeval t1, t2; |
206 | 208 | int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; |
209 | + int Pflag = 0, sflag = 0, lflag = 0; | |
207 | 210 | int c, cnt; |
208 | 211 | char *buf; |
209 | 212 | int64_t offset; |
210 | 213 | int count, total; |
211 | - int pattern = 0; | |
212 | - int Pflag = 0; | |
214 | + int pattern = 0, pattern_offset = 0, pattern_count = 0; | |
213 | 215 | |
214 | - while ((c = getopt(argc, argv, "CpP:qv")) != EOF) { | |
216 | + while ((c = getopt(argc, argv, "Cl:pP:qs:v")) != EOF) { | |
215 | 217 | switch (c) { |
216 | 218 | case 'C': |
217 | 219 | Cflag = 1; |
218 | 220 | break; |
221 | + case 'l': | |
222 | + lflag = 1; | |
223 | + pattern_count = cvtnum(optarg); | |
224 | + if (pattern_count < 0) { | |
225 | + printf("non-numeric length argument -- %s\n", optarg); | |
226 | + return 0; | |
227 | + } | |
228 | + break; | |
219 | 229 | case 'p': |
220 | 230 | pflag = 1; |
221 | 231 | break; |
... | ... | @@ -226,6 +236,14 @@ read_f(int argc, char **argv) |
226 | 236 | case 'q': |
227 | 237 | qflag = 1; |
228 | 238 | break; |
239 | + case 's': | |
240 | + sflag = 1; | |
241 | + pattern_offset = cvtnum(optarg); | |
242 | + if (pattern_offset < 0) { | |
243 | + printf("non-numeric length argument -- %s\n", optarg); | |
244 | + return 0; | |
245 | + } | |
246 | + break; | |
229 | 247 | case 'v': |
230 | 248 | vflag = 1; |
231 | 249 | break; |
... | ... | @@ -250,6 +268,19 @@ read_f(int argc, char **argv) |
250 | 268 | return 0; |
251 | 269 | } |
252 | 270 | |
271 | + if (!Pflag && (lflag || sflag)) { | |
272 | + return command_usage(&read_cmd); | |
273 | + } | |
274 | + | |
275 | + if (!lflag) { | |
276 | + pattern_count = count - pattern_offset; | |
277 | + } | |
278 | + | |
279 | + if ((pattern_count < 0) || (pattern_count + pattern_offset > count)) { | |
280 | + printf("pattern verfication range exceeds end of read data\n"); | |
281 | + return 0; | |
282 | + } | |
283 | + | |
253 | 284 | if (!pflag) |
254 | 285 | if (offset & 0x1ff) { |
255 | 286 | printf("offset %lld is not sector aligned\n", |
... | ... | @@ -278,12 +309,12 @@ read_f(int argc, char **argv) |
278 | 309 | } |
279 | 310 | |
280 | 311 | if (Pflag) { |
281 | - void* cmp_buf = malloc(count); | |
282 | - memset(cmp_buf, pattern, count); | |
283 | - if (memcmp(buf, cmp_buf, count)) { | |
312 | + void* cmp_buf = malloc(pattern_count); | |
313 | + memset(cmp_buf, pattern, pattern_count); | |
314 | + if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) { | |
284 | 315 | printf("Pattern verification failed at offset %lld, " |
285 | 316 | "%d bytes\n", |
286 | - (long long) offset, count); | |
317 | + (long long) offset + pattern_offset, pattern_count); | |
287 | 318 | } |
288 | 319 | free(cmp_buf); |
289 | 320 | } |
... | ... | @@ -309,7 +340,7 @@ static const cmdinfo_t read_cmd = { |
309 | 340 | .cfunc = read_f, |
310 | 341 | .argmin = 2, |
311 | 342 | .argmax = -1, |
312 | - .args = "[-aCpqv] [-P pattern ] off len", | |
343 | + .args = "[-aCpqv] [-P pattern [-s off] [-l len]] off len", | |
313 | 344 | .oneline = "reads a number of bytes at a specified offset", |
314 | 345 | .help = read_help, |
315 | 346 | }; | ... | ... |