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,11 +191,13 @@ read_help(void) | ||
| 191 | "\n" | 191 | "\n" |
| 192 | " Reads a segment of the currently open file, optionally dumping it to the\n" | 192 | " Reads a segment of the currently open file, optionally dumping it to the\n" |
| 193 | " standard output stream (with -v option) for subsequent inspection.\n" | 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 | " -p, -- use bdrv_pread to read the file\n" | 196 | " -p, -- use bdrv_pread to read the file\n" |
| 195 | " -P, -- use a pattern to verify read data\n" | 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 | " -q, -- quite mode, do not show I/O statistics\n" | 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 | "\n"); | 201 | "\n"); |
| 200 | } | 202 | } |
| 201 | 203 | ||
| @@ -204,18 +206,26 @@ read_f(int argc, char **argv) | @@ -204,18 +206,26 @@ read_f(int argc, char **argv) | ||
| 204 | { | 206 | { |
| 205 | struct timeval t1, t2; | 207 | struct timeval t1, t2; |
| 206 | int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; | 208 | int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; |
| 209 | + int Pflag = 0, sflag = 0, lflag = 0; | ||
| 207 | int c, cnt; | 210 | int c, cnt; |
| 208 | char *buf; | 211 | char *buf; |
| 209 | int64_t offset; | 212 | int64_t offset; |
| 210 | int count, total; | 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 | switch (c) { | 217 | switch (c) { |
| 216 | case 'C': | 218 | case 'C': |
| 217 | Cflag = 1; | 219 | Cflag = 1; |
| 218 | break; | 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 | case 'p': | 229 | case 'p': |
| 220 | pflag = 1; | 230 | pflag = 1; |
| 221 | break; | 231 | break; |
| @@ -226,6 +236,14 @@ read_f(int argc, char **argv) | @@ -226,6 +236,14 @@ read_f(int argc, char **argv) | ||
| 226 | case 'q': | 236 | case 'q': |
| 227 | qflag = 1; | 237 | qflag = 1; |
| 228 | break; | 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 | case 'v': | 247 | case 'v': |
| 230 | vflag = 1; | 248 | vflag = 1; |
| 231 | break; | 249 | break; |
| @@ -250,6 +268,19 @@ read_f(int argc, char **argv) | @@ -250,6 +268,19 @@ read_f(int argc, char **argv) | ||
| 250 | return 0; | 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 | if (!pflag) | 284 | if (!pflag) |
| 254 | if (offset & 0x1ff) { | 285 | if (offset & 0x1ff) { |
| 255 | printf("offset %lld is not sector aligned\n", | 286 | printf("offset %lld is not sector aligned\n", |
| @@ -278,12 +309,12 @@ read_f(int argc, char **argv) | @@ -278,12 +309,12 @@ read_f(int argc, char **argv) | ||
| 278 | } | 309 | } |
| 279 | 310 | ||
| 280 | if (Pflag) { | 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 | printf("Pattern verification failed at offset %lld, " | 315 | printf("Pattern verification failed at offset %lld, " |
| 285 | "%d bytes\n", | 316 | "%d bytes\n", |
| 286 | - (long long) offset, count); | 317 | + (long long) offset + pattern_offset, pattern_count); |
| 287 | } | 318 | } |
| 288 | free(cmp_buf); | 319 | free(cmp_buf); |
| 289 | } | 320 | } |
| @@ -309,7 +340,7 @@ static const cmdinfo_t read_cmd = { | @@ -309,7 +340,7 @@ static const cmdinfo_t read_cmd = { | ||
| 309 | .cfunc = read_f, | 340 | .cfunc = read_f, |
| 310 | .argmin = 2, | 341 | .argmin = 2, |
| 311 | .argmax = -1, | 342 | .argmax = -1, |
| 312 | - .args = "[-aCpqv] [-P pattern ] off len", | 343 | + .args = "[-aCpqv] [-P pattern [-s off] [-l len]] off len", |
| 313 | .oneline = "reads a number of bytes at a specified offset", | 344 | .oneline = "reads a number of bytes at a specified offset", |
| 314 | .help = read_help, | 345 | .help = read_help, |
| 315 | }; | 346 | }; |