Commit d9654a58576dae982458bdb1eb565c9876c24c22

Authored by Kevin Wolf
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 };
... ...