xref: /qemu/qemu-io-cmds.c (revision f2ad72b3)
1 /*
2  * Command line utility to exercise the QEMU I/O path.
3  *
4  * Copyright (C) 2009 Red Hat, Inc.
5  * Copyright (c) 2003-2005 Silicon Graphics, Inc.
6  *
7  * This work is licensed under the terms of the GNU GPL, version 2 or later.
8  * See the COPYING file in the top-level directory.
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qemu-io.h"
13 #include "sysemu/block-backend.h"
14 #include "block/block.h"
15 #include "block/block_int.h" /* for info_f() */
16 #include "block/qapi.h"
17 #include "qemu/error-report.h"
18 #include "qemu/main-loop.h"
19 #include "qemu/timer.h"
20 #include "sysemu/block-backend.h"
21 
22 #define CMD_NOFILE_OK   0x01
23 
24 bool qemuio_misalign;
25 
26 static cmdinfo_t *cmdtab;
27 static int ncmds;
28 
29 static int compare_cmdname(const void *a, const void *b)
30 {
31     return strcmp(((const cmdinfo_t *)a)->name,
32                   ((const cmdinfo_t *)b)->name);
33 }
34 
35 void qemuio_add_command(const cmdinfo_t *ci)
36 {
37     cmdtab = g_renew(cmdinfo_t, cmdtab, ++ncmds);
38     cmdtab[ncmds - 1] = *ci;
39     qsort(cmdtab, ncmds, sizeof(*cmdtab), compare_cmdname);
40 }
41 
42 int qemuio_command_usage(const cmdinfo_t *ci)
43 {
44     printf("%s %s -- %s\n", ci->name, ci->args, ci->oneline);
45     return 0;
46 }
47 
48 static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct)
49 {
50     if (ct->flags & CMD_FLAG_GLOBAL) {
51         return 1;
52     }
53     if (!(ct->flags & CMD_NOFILE_OK) && !blk) {
54         fprintf(stderr, "no file open, try 'help open'\n");
55         return 0;
56     }
57     return 1;
58 }
59 
60 static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
61                    char **argv)
62 {
63     char *cmd = argv[0];
64 
65     if (!init_check_command(blk, ct)) {
66         return 0;
67     }
68 
69     if (argc - 1 < ct->argmin || (ct->argmax != -1 && argc - 1 > ct->argmax)) {
70         if (ct->argmax == -1) {
71             fprintf(stderr,
72                     "bad argument count %d to %s, expected at least %d arguments\n",
73                     argc-1, cmd, ct->argmin);
74         } else if (ct->argmin == ct->argmax) {
75             fprintf(stderr,
76                     "bad argument count %d to %s, expected %d arguments\n",
77                     argc-1, cmd, ct->argmin);
78         } else {
79             fprintf(stderr,
80                     "bad argument count %d to %s, expected between %d and %d arguments\n",
81                     argc-1, cmd, ct->argmin, ct->argmax);
82         }
83         return 0;
84     }
85     optind = 0;
86     return ct->cfunc(blk, argc, argv);
87 }
88 
89 static const cmdinfo_t *find_command(const char *cmd)
90 {
91     cmdinfo_t *ct;
92 
93     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
94         if (strcmp(ct->name, cmd) == 0 ||
95             (ct->altname && strcmp(ct->altname, cmd) == 0))
96         {
97             return (const cmdinfo_t *)ct;
98         }
99     }
100     return NULL;
101 }
102 
103 /* Invoke fn() for commands with a matching prefix */
104 void qemuio_complete_command(const char *input,
105                              void (*fn)(const char *cmd, void *opaque),
106                              void *opaque)
107 {
108     cmdinfo_t *ct;
109     size_t input_len = strlen(input);
110 
111     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
112         if (strncmp(input, ct->name, input_len) == 0) {
113             fn(ct->name, opaque);
114         }
115     }
116 }
117 
118 static char **breakline(char *input, int *count)
119 {
120     int c = 0;
121     char *p;
122     char **rval = g_new0(char *, 1);
123 
124     while (rval && (p = qemu_strsep(&input, " ")) != NULL) {
125         if (!*p) {
126             continue;
127         }
128         c++;
129         rval = g_renew(char *, rval, (c + 1));
130         rval[c - 1] = p;
131         rval[c] = NULL;
132     }
133     *count = c;
134     return rval;
135 }
136 
137 static int64_t cvtnum(const char *s)
138 {
139     char *end;
140     int64_t ret;
141 
142     ret = qemu_strtosz_suffix(s, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
143     if (*end != '\0') {
144         /* Detritus at the end of the string */
145         return -EINVAL;
146     }
147     return ret;
148 }
149 
150 static void print_cvtnum_err(int64_t rc, const char *arg)
151 {
152     switch (rc) {
153     case -EINVAL:
154         printf("Parsing error: non-numeric argument,"
155                " or extraneous/unrecognized suffix -- %s\n", arg);
156         break;
157     case -ERANGE:
158         printf("Parsing error: argument too large -- %s\n", arg);
159         break;
160     default:
161         printf("Parsing error: %s\n", arg);
162     }
163 }
164 
165 #define EXABYTES(x)     ((long long)(x) << 60)
166 #define PETABYTES(x)    ((long long)(x) << 50)
167 #define TERABYTES(x)    ((long long)(x) << 40)
168 #define GIGABYTES(x)    ((long long)(x) << 30)
169 #define MEGABYTES(x)    ((long long)(x) << 20)
170 #define KILOBYTES(x)    ((long long)(x) << 10)
171 
172 #define TO_EXABYTES(x)  ((x) / EXABYTES(1))
173 #define TO_PETABYTES(x) ((x) / PETABYTES(1))
174 #define TO_TERABYTES(x) ((x) / TERABYTES(1))
175 #define TO_GIGABYTES(x) ((x) / GIGABYTES(1))
176 #define TO_MEGABYTES(x) ((x) / MEGABYTES(1))
177 #define TO_KILOBYTES(x) ((x) / KILOBYTES(1))
178 
179 static void cvtstr(double value, char *str, size_t size)
180 {
181     char *trim;
182     const char *suffix;
183 
184     if (value >= EXABYTES(1)) {
185         suffix = " EiB";
186         snprintf(str, size - 4, "%.3f", TO_EXABYTES(value));
187     } else if (value >= PETABYTES(1)) {
188         suffix = " PiB";
189         snprintf(str, size - 4, "%.3f", TO_PETABYTES(value));
190     } else if (value >= TERABYTES(1)) {
191         suffix = " TiB";
192         snprintf(str, size - 4, "%.3f", TO_TERABYTES(value));
193     } else if (value >= GIGABYTES(1)) {
194         suffix = " GiB";
195         snprintf(str, size - 4, "%.3f", TO_GIGABYTES(value));
196     } else if (value >= MEGABYTES(1)) {
197         suffix = " MiB";
198         snprintf(str, size - 4, "%.3f", TO_MEGABYTES(value));
199     } else if (value >= KILOBYTES(1)) {
200         suffix = " KiB";
201         snprintf(str, size - 4, "%.3f", TO_KILOBYTES(value));
202     } else {
203         suffix = " bytes";
204         snprintf(str, size - 6, "%f", value);
205     }
206 
207     trim = strstr(str, ".000");
208     if (trim) {
209         strcpy(trim, suffix);
210     } else {
211         strcat(str, suffix);
212     }
213 }
214 
215 
216 
217 static struct timeval tsub(struct timeval t1, struct timeval t2)
218 {
219     t1.tv_usec -= t2.tv_usec;
220     if (t1.tv_usec < 0) {
221         t1.tv_usec += 1000000;
222         t1.tv_sec--;
223     }
224     t1.tv_sec -= t2.tv_sec;
225     return t1;
226 }
227 
228 static double tdiv(double value, struct timeval tv)
229 {
230     return value / ((double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0));
231 }
232 
233 #define HOURS(sec)      ((sec) / (60 * 60))
234 #define MINUTES(sec)    (((sec) % (60 * 60)) / 60)
235 #define SECONDS(sec)    ((sec) % 60)
236 
237 enum {
238     DEFAULT_TIME        = 0x0,
239     TERSE_FIXED_TIME    = 0x1,
240     VERBOSE_FIXED_TIME  = 0x2,
241 };
242 
243 static void timestr(struct timeval *tv, char *ts, size_t size, int format)
244 {
245     double usec = (double)tv->tv_usec / 1000000.0;
246 
247     if (format & TERSE_FIXED_TIME) {
248         if (!HOURS(tv->tv_sec)) {
249             snprintf(ts, size, "%u:%02u.%02u",
250                     (unsigned int) MINUTES(tv->tv_sec),
251                     (unsigned int) SECONDS(tv->tv_sec),
252                     (unsigned int) (usec * 100));
253             return;
254         }
255         format |= VERBOSE_FIXED_TIME; /* fallback if hours needed */
256     }
257 
258     if ((format & VERBOSE_FIXED_TIME) || tv->tv_sec) {
259         snprintf(ts, size, "%u:%02u:%02u.%02u",
260                 (unsigned int) HOURS(tv->tv_sec),
261                 (unsigned int) MINUTES(tv->tv_sec),
262                 (unsigned int) SECONDS(tv->tv_sec),
263                 (unsigned int) (usec * 100));
264     } else {
265         snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
266     }
267 }
268 
269 /*
270  * Parse the pattern argument to various sub-commands.
271  *
272  * Because the pattern is used as an argument to memset it must evaluate
273  * to an unsigned integer that fits into a single byte.
274  */
275 static int parse_pattern(const char *arg)
276 {
277     char *endptr = NULL;
278     long pattern;
279 
280     pattern = strtol(arg, &endptr, 0);
281     if (pattern < 0 || pattern > UCHAR_MAX || *endptr != '\0') {
282         printf("%s is not a valid pattern byte\n", arg);
283         return -1;
284     }
285 
286     return pattern;
287 }
288 
289 /*
290  * Memory allocation helpers.
291  *
292  * Make sure memory is aligned by default, or purposefully misaligned if
293  * that is specified on the command line.
294  */
295 
296 #define MISALIGN_OFFSET     16
297 static void *qemu_io_alloc(BlockBackend *blk, size_t len, int pattern)
298 {
299     void *buf;
300 
301     if (qemuio_misalign) {
302         len += MISALIGN_OFFSET;
303     }
304     buf = blk_blockalign(blk, len);
305     memset(buf, pattern, len);
306     if (qemuio_misalign) {
307         buf += MISALIGN_OFFSET;
308     }
309     return buf;
310 }
311 
312 static void qemu_io_free(void *p)
313 {
314     if (qemuio_misalign) {
315         p -= MISALIGN_OFFSET;
316     }
317     qemu_vfree(p);
318 }
319 
320 static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
321 {
322     uint64_t i;
323     int j;
324     const uint8_t *p;
325 
326     for (i = 0, p = buffer; i < len; i += 16) {
327         const uint8_t *s = p;
328 
329         printf("%08" PRIx64 ":  ", offset + i);
330         for (j = 0; j < 16 && i + j < len; j++, p++) {
331             printf("%02x ", *p);
332         }
333         printf(" ");
334         for (j = 0; j < 16 && i + j < len; j++, s++) {
335             if (isalnum(*s)) {
336                 printf("%c", *s);
337             } else {
338                 printf(".");
339             }
340         }
341         printf("\n");
342     }
343 }
344 
345 static void print_report(const char *op, struct timeval *t, int64_t offset,
346                          int64_t count, int64_t total, int cnt, int Cflag)
347 {
348     char s1[64], s2[64], ts[64];
349 
350     timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
351     if (!Cflag) {
352         cvtstr((double)total, s1, sizeof(s1));
353         cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
354         printf("%s %"PRId64"/%"PRId64" bytes at offset %" PRId64 "\n",
355                op, total, count, offset);
356         printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
357                s1, cnt, ts, s2, tdiv((double)cnt, *t));
358     } else {/* bytes,ops,time,bytes/sec,ops/sec */
359         printf("%"PRId64",%d,%s,%.3f,%.3f\n",
360             total, cnt, ts,
361             tdiv((double)total, *t),
362             tdiv((double)cnt, *t));
363     }
364 }
365 
366 /*
367  * Parse multiple length statements for vectored I/O, and construct an I/O
368  * vector matching it.
369  */
370 static void *
371 create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
372              int pattern)
373 {
374     size_t *sizes = g_new0(size_t, nr_iov);
375     size_t count = 0;
376     void *buf = NULL;
377     void *p;
378     int i;
379 
380     for (i = 0; i < nr_iov; i++) {
381         char *arg = argv[i];
382         int64_t len;
383 
384         len = cvtnum(arg);
385         if (len < 0) {
386             print_cvtnum_err(len, arg);
387             goto fail;
388         }
389 
390         /* should be SIZE_T_MAX, but that doesn't exist */
391         if (len > INT_MAX) {
392             printf("Argument '%s' exceeds maximum size %d\n", arg, INT_MAX);
393             goto fail;
394         }
395 
396         if (len & 0x1ff) {
397             printf("length argument %" PRId64
398                    " is not sector aligned\n", len);
399             goto fail;
400         }
401 
402         sizes[i] = len;
403         count += len;
404     }
405 
406     qemu_iovec_init(qiov, nr_iov);
407 
408     buf = p = qemu_io_alloc(blk, count, pattern);
409 
410     for (i = 0; i < nr_iov; i++) {
411         qemu_iovec_add(qiov, p, sizes[i]);
412         p += sizes[i];
413     }
414 
415 fail:
416     g_free(sizes);
417     return buf;
418 }
419 
420 static int do_read(BlockBackend *blk, char *buf, int64_t offset, int64_t count,
421                    int64_t *total)
422 {
423     int ret;
424 
425     if (count >> 9 > INT_MAX) {
426         return -ERANGE;
427     }
428 
429     ret = blk_read(blk, offset >> 9, (uint8_t *)buf, count >> 9);
430     if (ret < 0) {
431         return ret;
432     }
433     *total = count;
434     return 1;
435 }
436 
437 static int do_write(BlockBackend *blk, char *buf, int64_t offset, int64_t count,
438                     int64_t *total)
439 {
440     int ret;
441 
442     if (count >> 9 > INT_MAX) {
443         return -ERANGE;
444     }
445 
446     ret = blk_write(blk, offset >> 9, (uint8_t *)buf, count >> 9);
447     if (ret < 0) {
448         return ret;
449     }
450     *total = count;
451     return 1;
452 }
453 
454 static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
455                     int64_t count, int64_t *total)
456 {
457     if (count > INT_MAX) {
458         return -ERANGE;
459     }
460 
461     *total = blk_pread(blk, offset, (uint8_t *)buf, count);
462     if (*total < 0) {
463         return *total;
464     }
465     return 1;
466 }
467 
468 static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
469                      int64_t count, int64_t *total)
470 {
471     if (count > INT_MAX) {
472         return -ERANGE;
473     }
474 
475     *total = blk_pwrite(blk, offset, (uint8_t *)buf, count);
476     if (*total < 0) {
477         return *total;
478     }
479     return 1;
480 }
481 
482 typedef struct {
483     BlockBackend *blk;
484     int64_t offset;
485     int64_t count;
486     int64_t *total;
487     int ret;
488     bool done;
489 } CoWriteZeroes;
490 
491 static void coroutine_fn co_write_zeroes_entry(void *opaque)
492 {
493     CoWriteZeroes *data = opaque;
494 
495     data->ret = blk_co_write_zeroes(data->blk, data->offset / BDRV_SECTOR_SIZE,
496                                     data->count / BDRV_SECTOR_SIZE, 0);
497     data->done = true;
498     if (data->ret < 0) {
499         *data->total = data->ret;
500         return;
501     }
502 
503     *data->total = data->count;
504 }
505 
506 static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count,
507                               int64_t *total)
508 {
509     Coroutine *co;
510     CoWriteZeroes data = {
511         .blk    = blk,
512         .offset = offset,
513         .count  = count,
514         .total  = total,
515         .done   = false,
516     };
517 
518     if (count >> BDRV_SECTOR_BITS > INT_MAX) {
519         return -ERANGE;
520     }
521 
522     co = qemu_coroutine_create(co_write_zeroes_entry);
523     qemu_coroutine_enter(co, &data);
524     while (!data.done) {
525         aio_poll(blk_get_aio_context(blk), true);
526     }
527     if (data.ret < 0) {
528         return data.ret;
529     } else {
530         return 1;
531     }
532 }
533 
534 static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
535                                int64_t count, int64_t *total)
536 {
537     int ret;
538 
539     if (count >> 9 > INT_MAX) {
540         return -ERANGE;
541     }
542 
543     ret = blk_write_compressed(blk, offset >> 9, (uint8_t *)buf, count >> 9);
544     if (ret < 0) {
545         return ret;
546     }
547     *total = count;
548     return 1;
549 }
550 
551 static int do_load_vmstate(BlockBackend *blk, char *buf, int64_t offset,
552                            int64_t count, int64_t *total)
553 {
554     if (count > INT_MAX) {
555         return -ERANGE;
556     }
557 
558     *total = blk_load_vmstate(blk, (uint8_t *)buf, offset, count);
559     if (*total < 0) {
560         return *total;
561     }
562     return 1;
563 }
564 
565 static int do_save_vmstate(BlockBackend *blk, char *buf, int64_t offset,
566                            int64_t count, int64_t *total)
567 {
568     if (count > INT_MAX) {
569         return -ERANGE;
570     }
571 
572     *total = blk_save_vmstate(blk, (uint8_t *)buf, offset, count);
573     if (*total < 0) {
574         return *total;
575     }
576     return 1;
577 }
578 
579 #define NOT_DONE 0x7fffffff
580 static void aio_rw_done(void *opaque, int ret)
581 {
582     *(int *)opaque = ret;
583 }
584 
585 static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
586                         int64_t offset, int *total)
587 {
588     int async_ret = NOT_DONE;
589 
590     blk_aio_readv(blk, offset >> 9, qiov, qiov->size >> 9,
591                   aio_rw_done, &async_ret);
592     while (async_ret == NOT_DONE) {
593         main_loop_wait(false);
594     }
595 
596     *total = qiov->size;
597     return async_ret < 0 ? async_ret : 1;
598 }
599 
600 static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
601                          int64_t offset, int *total)
602 {
603     int async_ret = NOT_DONE;
604 
605     blk_aio_writev(blk, offset >> 9, qiov, qiov->size >> 9,
606                    aio_rw_done, &async_ret);
607     while (async_ret == NOT_DONE) {
608         main_loop_wait(false);
609     }
610 
611     *total = qiov->size;
612     return async_ret < 0 ? async_ret : 1;
613 }
614 
615 struct multiwrite_async_ret {
616     int num_done;
617     int error;
618 };
619 
620 static void multiwrite_cb(void *opaque, int ret)
621 {
622     struct multiwrite_async_ret *async_ret = opaque;
623 
624     async_ret->num_done++;
625     if (ret < 0) {
626         async_ret->error = ret;
627     }
628 }
629 
630 static int do_aio_multiwrite(BlockBackend *blk, BlockRequest* reqs,
631                              int num_reqs, int *total)
632 {
633     int i, ret;
634     struct multiwrite_async_ret async_ret = {
635         .num_done = 0,
636         .error = 0,
637     };
638 
639     *total = 0;
640     for (i = 0; i < num_reqs; i++) {
641         reqs[i].cb = multiwrite_cb;
642         reqs[i].opaque = &async_ret;
643         *total += reqs[i].qiov->size;
644     }
645 
646     ret = blk_aio_multiwrite(blk, reqs, num_reqs);
647     if (ret < 0) {
648         return ret;
649     }
650 
651     while (async_ret.num_done < num_reqs) {
652         main_loop_wait(false);
653     }
654 
655     return async_ret.error < 0 ? async_ret.error : 1;
656 }
657 
658 static void read_help(void)
659 {
660     printf(
661 "\n"
662 " reads a range of bytes from the given offset\n"
663 "\n"
664 " Example:\n"
665 " 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
666 "\n"
667 " Reads a segment of the currently open file, optionally dumping it to the\n"
668 " standard output stream (with -v option) for subsequent inspection.\n"
669 " -b, -- read from the VM state rather than the virtual disk\n"
670 " -C, -- report statistics in a machine parsable format\n"
671 " -l, -- length for pattern verification (only with -P)\n"
672 " -p, -- use blk_pread to read the file\n"
673 " -P, -- use a pattern to verify read data\n"
674 " -q, -- quiet mode, do not show I/O statistics\n"
675 " -s, -- start offset for pattern verification (only with -P)\n"
676 " -v, -- dump buffer to standard output\n"
677 "\n");
678 }
679 
680 static int read_f(BlockBackend *blk, int argc, char **argv);
681 
682 static const cmdinfo_t read_cmd = {
683     .name       = "read",
684     .altname    = "r",
685     .cfunc      = read_f,
686     .argmin     = 2,
687     .argmax     = -1,
688     .args       = "[-abCpqv] [-P pattern [-s off] [-l len]] off len",
689     .oneline    = "reads a number of bytes at a specified offset",
690     .help       = read_help,
691 };
692 
693 static int read_f(BlockBackend *blk, int argc, char **argv)
694 {
695     struct timeval t1, t2;
696     int Cflag = 0, pflag = 0, qflag = 0, vflag = 0;
697     int Pflag = 0, sflag = 0, lflag = 0, bflag = 0;
698     int c, cnt;
699     char *buf;
700     int64_t offset;
701     int64_t count;
702     /* Some compilers get confused and warn if this is not initialized.  */
703     int64_t total = 0;
704     int pattern = 0;
705     int64_t pattern_offset = 0, pattern_count = 0;
706 
707     while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) {
708         switch (c) {
709         case 'b':
710             bflag = 1;
711             break;
712         case 'C':
713             Cflag = 1;
714             break;
715         case 'l':
716             lflag = 1;
717             pattern_count = cvtnum(optarg);
718             if (pattern_count < 0) {
719                 print_cvtnum_err(pattern_count, optarg);
720                 return 0;
721             }
722             break;
723         case 'p':
724             pflag = 1;
725             break;
726         case 'P':
727             Pflag = 1;
728             pattern = parse_pattern(optarg);
729             if (pattern < 0) {
730                 return 0;
731             }
732             break;
733         case 'q':
734             qflag = 1;
735             break;
736         case 's':
737             sflag = 1;
738             pattern_offset = cvtnum(optarg);
739             if (pattern_offset < 0) {
740                 print_cvtnum_err(pattern_offset, optarg);
741                 return 0;
742             }
743             break;
744         case 'v':
745             vflag = 1;
746             break;
747         default:
748             return qemuio_command_usage(&read_cmd);
749         }
750     }
751 
752     if (optind != argc - 2) {
753         return qemuio_command_usage(&read_cmd);
754     }
755 
756     if (bflag && pflag) {
757         printf("-b and -p cannot be specified at the same time\n");
758         return 0;
759     }
760 
761     offset = cvtnum(argv[optind]);
762     if (offset < 0) {
763         print_cvtnum_err(offset, argv[optind]);
764         return 0;
765     }
766 
767     optind++;
768     count = cvtnum(argv[optind]);
769     if (count < 0) {
770         print_cvtnum_err(count, argv[optind]);
771         return 0;
772     } else if (count > SIZE_MAX) {
773         printf("length cannot exceed %" PRIu64 ", given %s\n",
774                (uint64_t) SIZE_MAX, argv[optind]);
775         return 0;
776     }
777 
778     if (!Pflag && (lflag || sflag)) {
779         return qemuio_command_usage(&read_cmd);
780     }
781 
782     if (!lflag) {
783         pattern_count = count - pattern_offset;
784     }
785 
786     if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
787         printf("pattern verification range exceeds end of read data\n");
788         return 0;
789     }
790 
791     if (!pflag) {
792         if (offset & 0x1ff) {
793             printf("offset %" PRId64 " is not sector aligned\n",
794                    offset);
795             return 0;
796         }
797         if (count & 0x1ff) {
798             printf("count %"PRId64" is not sector aligned\n",
799                    count);
800             return 0;
801         }
802     }
803 
804     buf = qemu_io_alloc(blk, count, 0xab);
805 
806     gettimeofday(&t1, NULL);
807     if (pflag) {
808         cnt = do_pread(blk, buf, offset, count, &total);
809     } else if (bflag) {
810         cnt = do_load_vmstate(blk, buf, offset, count, &total);
811     } else {
812         cnt = do_read(blk, buf, offset, count, &total);
813     }
814     gettimeofday(&t2, NULL);
815 
816     if (cnt < 0) {
817         printf("read failed: %s\n", strerror(-cnt));
818         goto out;
819     }
820 
821     if (Pflag) {
822         void *cmp_buf = g_malloc(pattern_count);
823         memset(cmp_buf, pattern, pattern_count);
824         if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
825             printf("Pattern verification failed at offset %"
826                    PRId64 ", %"PRId64" bytes\n",
827                    offset + pattern_offset, pattern_count);
828         }
829         g_free(cmp_buf);
830     }
831 
832     if (qflag) {
833         goto out;
834     }
835 
836     if (vflag) {
837         dump_buffer(buf, offset, count);
838     }
839 
840     /* Finally, report back -- -C gives a parsable format */
841     t2 = tsub(t2, t1);
842     print_report("read", &t2, offset, count, total, cnt, Cflag);
843 
844 out:
845     qemu_io_free(buf);
846 
847     return 0;
848 }
849 
850 static void readv_help(void)
851 {
852     printf(
853 "\n"
854 " reads a range of bytes from the given offset into multiple buffers\n"
855 "\n"
856 " Example:\n"
857 " 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
858 "\n"
859 " Reads a segment of the currently open file, optionally dumping it to the\n"
860 " standard output stream (with -v option) for subsequent inspection.\n"
861 " Uses multiple iovec buffers if more than one byte range is specified.\n"
862 " -C, -- report statistics in a machine parsable format\n"
863 " -P, -- use a pattern to verify read data\n"
864 " -v, -- dump buffer to standard output\n"
865 " -q, -- quiet mode, do not show I/O statistics\n"
866 "\n");
867 }
868 
869 static int readv_f(BlockBackend *blk, int argc, char **argv);
870 
871 static const cmdinfo_t readv_cmd = {
872     .name       = "readv",
873     .cfunc      = readv_f,
874     .argmin     = 2,
875     .argmax     = -1,
876     .args       = "[-Cqv] [-P pattern ] off len [len..]",
877     .oneline    = "reads a number of bytes at a specified offset",
878     .help       = readv_help,
879 };
880 
881 static int readv_f(BlockBackend *blk, int argc, char **argv)
882 {
883     struct timeval t1, t2;
884     int Cflag = 0, qflag = 0, vflag = 0;
885     int c, cnt;
886     char *buf;
887     int64_t offset;
888     /* Some compilers get confused and warn if this is not initialized.  */
889     int total = 0;
890     int nr_iov;
891     QEMUIOVector qiov;
892     int pattern = 0;
893     int Pflag = 0;
894 
895     while ((c = getopt(argc, argv, "CP:qv")) != -1) {
896         switch (c) {
897         case 'C':
898             Cflag = 1;
899             break;
900         case 'P':
901             Pflag = 1;
902             pattern = parse_pattern(optarg);
903             if (pattern < 0) {
904                 return 0;
905             }
906             break;
907         case 'q':
908             qflag = 1;
909             break;
910         case 'v':
911             vflag = 1;
912             break;
913         default:
914             return qemuio_command_usage(&readv_cmd);
915         }
916     }
917 
918     if (optind > argc - 2) {
919         return qemuio_command_usage(&readv_cmd);
920     }
921 
922 
923     offset = cvtnum(argv[optind]);
924     if (offset < 0) {
925         print_cvtnum_err(offset, argv[optind]);
926         return 0;
927     }
928     optind++;
929 
930     if (offset & 0x1ff) {
931         printf("offset %" PRId64 " is not sector aligned\n",
932                offset);
933         return 0;
934     }
935 
936     nr_iov = argc - optind;
937     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
938     if (buf == NULL) {
939         return 0;
940     }
941 
942     gettimeofday(&t1, NULL);
943     cnt = do_aio_readv(blk, &qiov, offset, &total);
944     gettimeofday(&t2, NULL);
945 
946     if (cnt < 0) {
947         printf("readv failed: %s\n", strerror(-cnt));
948         goto out;
949     }
950 
951     if (Pflag) {
952         void *cmp_buf = g_malloc(qiov.size);
953         memset(cmp_buf, pattern, qiov.size);
954         if (memcmp(buf, cmp_buf, qiov.size)) {
955             printf("Pattern verification failed at offset %"
956                    PRId64 ", %zd bytes\n", offset, qiov.size);
957         }
958         g_free(cmp_buf);
959     }
960 
961     if (qflag) {
962         goto out;
963     }
964 
965     if (vflag) {
966         dump_buffer(buf, offset, qiov.size);
967     }
968 
969     /* Finally, report back -- -C gives a parsable format */
970     t2 = tsub(t2, t1);
971     print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
972 
973 out:
974     qemu_iovec_destroy(&qiov);
975     qemu_io_free(buf);
976     return 0;
977 }
978 
979 static void write_help(void)
980 {
981     printf(
982 "\n"
983 " writes a range of bytes from the given offset\n"
984 "\n"
985 " Example:\n"
986 " 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
987 "\n"
988 " Writes into a segment of the currently open file, using a buffer\n"
989 " filled with a set pattern (0xcdcdcdcd).\n"
990 " -b, -- write to the VM state rather than the virtual disk\n"
991 " -c, -- write compressed data with blk_write_compressed\n"
992 " -p, -- use blk_pwrite to write the file\n"
993 " -P, -- use different pattern to fill file\n"
994 " -C, -- report statistics in a machine parsable format\n"
995 " -q, -- quiet mode, do not show I/O statistics\n"
996 " -z, -- write zeroes using blk_co_write_zeroes\n"
997 "\n");
998 }
999 
1000 static int write_f(BlockBackend *blk, int argc, char **argv);
1001 
1002 static const cmdinfo_t write_cmd = {
1003     .name       = "write",
1004     .altname    = "w",
1005     .cfunc      = write_f,
1006     .argmin     = 2,
1007     .argmax     = -1,
1008     .args       = "[-bcCpqz] [-P pattern ] off len",
1009     .oneline    = "writes a number of bytes at a specified offset",
1010     .help       = write_help,
1011 };
1012 
1013 static int write_f(BlockBackend *blk, int argc, char **argv)
1014 {
1015     struct timeval t1, t2;
1016     int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;
1017     int cflag = 0;
1018     int c, cnt;
1019     char *buf = NULL;
1020     int64_t offset;
1021     int64_t count;
1022     /* Some compilers get confused and warn if this is not initialized.  */
1023     int64_t total = 0;
1024     int pattern = 0xcd;
1025 
1026     while ((c = getopt(argc, argv, "bcCpP:qz")) != -1) {
1027         switch (c) {
1028         case 'b':
1029             bflag = 1;
1030             break;
1031         case 'c':
1032             cflag = 1;
1033             break;
1034         case 'C':
1035             Cflag = 1;
1036             break;
1037         case 'p':
1038             pflag = 1;
1039             break;
1040         case 'P':
1041             Pflag = 1;
1042             pattern = parse_pattern(optarg);
1043             if (pattern < 0) {
1044                 return 0;
1045             }
1046             break;
1047         case 'q':
1048             qflag = 1;
1049             break;
1050         case 'z':
1051             zflag = 1;
1052             break;
1053         default:
1054             return qemuio_command_usage(&write_cmd);
1055         }
1056     }
1057 
1058     if (optind != argc - 2) {
1059         return qemuio_command_usage(&write_cmd);
1060     }
1061 
1062     if (bflag + pflag + zflag > 1) {
1063         printf("-b, -p, or -z cannot be specified at the same time\n");
1064         return 0;
1065     }
1066 
1067     if (zflag && Pflag) {
1068         printf("-z and -P cannot be specified at the same time\n");
1069         return 0;
1070     }
1071 
1072     offset = cvtnum(argv[optind]);
1073     if (offset < 0) {
1074         print_cvtnum_err(offset, argv[optind]);
1075         return 0;
1076     }
1077 
1078     optind++;
1079     count = cvtnum(argv[optind]);
1080     if (count < 0) {
1081         print_cvtnum_err(count, argv[optind]);
1082         return 0;
1083     } else if (count > SIZE_MAX) {
1084         printf("length cannot exceed %" PRIu64 ", given %s\n",
1085                (uint64_t) SIZE_MAX, argv[optind]);
1086         return 0;
1087     }
1088 
1089     if (!pflag) {
1090         if (offset & 0x1ff) {
1091             printf("offset %" PRId64 " is not sector aligned\n",
1092                    offset);
1093             return 0;
1094         }
1095 
1096         if (count & 0x1ff) {
1097             printf("count %"PRId64" is not sector aligned\n",
1098                    count);
1099             return 0;
1100         }
1101     }
1102 
1103     if (!zflag) {
1104         buf = qemu_io_alloc(blk, count, pattern);
1105     }
1106 
1107     gettimeofday(&t1, NULL);
1108     if (pflag) {
1109         cnt = do_pwrite(blk, buf, offset, count, &total);
1110     } else if (bflag) {
1111         cnt = do_save_vmstate(blk, buf, offset, count, &total);
1112     } else if (zflag) {
1113         cnt = do_co_write_zeroes(blk, offset, count, &total);
1114     } else if (cflag) {
1115         cnt = do_write_compressed(blk, buf, offset, count, &total);
1116     } else {
1117         cnt = do_write(blk, buf, offset, count, &total);
1118     }
1119     gettimeofday(&t2, NULL);
1120 
1121     if (cnt < 0) {
1122         printf("write failed: %s\n", strerror(-cnt));
1123         goto out;
1124     }
1125 
1126     if (qflag) {
1127         goto out;
1128     }
1129 
1130     /* Finally, report back -- -C gives a parsable format */
1131     t2 = tsub(t2, t1);
1132     print_report("wrote", &t2, offset, count, total, cnt, Cflag);
1133 
1134 out:
1135     if (!zflag) {
1136         qemu_io_free(buf);
1137     }
1138 
1139     return 0;
1140 }
1141 
1142 static void
1143 writev_help(void)
1144 {
1145     printf(
1146 "\n"
1147 " writes a range of bytes from the given offset source from multiple buffers\n"
1148 "\n"
1149 " Example:\n"
1150 " 'writev 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1151 "\n"
1152 " Writes into a segment of the currently open file, using a buffer\n"
1153 " filled with a set pattern (0xcdcdcdcd).\n"
1154 " -P, -- use different pattern to fill file\n"
1155 " -C, -- report statistics in a machine parsable format\n"
1156 " -q, -- quiet mode, do not show I/O statistics\n"
1157 "\n");
1158 }
1159 
1160 static int writev_f(BlockBackend *blk, int argc, char **argv);
1161 
1162 static const cmdinfo_t writev_cmd = {
1163     .name       = "writev",
1164     .cfunc      = writev_f,
1165     .argmin     = 2,
1166     .argmax     = -1,
1167     .args       = "[-Cq] [-P pattern ] off len [len..]",
1168     .oneline    = "writes a number of bytes at a specified offset",
1169     .help       = writev_help,
1170 };
1171 
1172 static int writev_f(BlockBackend *blk, int argc, char **argv)
1173 {
1174     struct timeval t1, t2;
1175     int Cflag = 0, qflag = 0;
1176     int c, cnt;
1177     char *buf;
1178     int64_t offset;
1179     /* Some compilers get confused and warn if this is not initialized.  */
1180     int total = 0;
1181     int nr_iov;
1182     int pattern = 0xcd;
1183     QEMUIOVector qiov;
1184 
1185     while ((c = getopt(argc, argv, "CqP:")) != -1) {
1186         switch (c) {
1187         case 'C':
1188             Cflag = 1;
1189             break;
1190         case 'q':
1191             qflag = 1;
1192             break;
1193         case 'P':
1194             pattern = parse_pattern(optarg);
1195             if (pattern < 0) {
1196                 return 0;
1197             }
1198             break;
1199         default:
1200             return qemuio_command_usage(&writev_cmd);
1201         }
1202     }
1203 
1204     if (optind > argc - 2) {
1205         return qemuio_command_usage(&writev_cmd);
1206     }
1207 
1208     offset = cvtnum(argv[optind]);
1209     if (offset < 0) {
1210         print_cvtnum_err(offset, argv[optind]);
1211         return 0;
1212     }
1213     optind++;
1214 
1215     if (offset & 0x1ff) {
1216         printf("offset %" PRId64 " is not sector aligned\n",
1217                offset);
1218         return 0;
1219     }
1220 
1221     nr_iov = argc - optind;
1222     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
1223     if (buf == NULL) {
1224         return 0;
1225     }
1226 
1227     gettimeofday(&t1, NULL);
1228     cnt = do_aio_writev(blk, &qiov, offset, &total);
1229     gettimeofday(&t2, NULL);
1230 
1231     if (cnt < 0) {
1232         printf("writev failed: %s\n", strerror(-cnt));
1233         goto out;
1234     }
1235 
1236     if (qflag) {
1237         goto out;
1238     }
1239 
1240     /* Finally, report back -- -C gives a parsable format */
1241     t2 = tsub(t2, t1);
1242     print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
1243 out:
1244     qemu_iovec_destroy(&qiov);
1245     qemu_io_free(buf);
1246     return 0;
1247 }
1248 
1249 static void multiwrite_help(void)
1250 {
1251     printf(
1252 "\n"
1253 " writes a range of bytes from the given offset source from multiple buffers,\n"
1254 " in a batch of requests that may be merged by qemu\n"
1255 "\n"
1256 " Example:\n"
1257 " 'multiwrite 512 1k 1k ; 4k 1k'\n"
1258 "  writes 2 kB at 512 bytes and 1 kB at 4 kB into the open file\n"
1259 "\n"
1260 " Writes into a segment of the currently open file, using a buffer\n"
1261 " filled with a set pattern (0xcdcdcdcd). The pattern byte is increased\n"
1262 " by one for each request contained in the multiwrite command.\n"
1263 " -P, -- use different pattern to fill file\n"
1264 " -C, -- report statistics in a machine parsable format\n"
1265 " -q, -- quiet mode, do not show I/O statistics\n"
1266 "\n");
1267 }
1268 
1269 static int multiwrite_f(BlockBackend *blk, int argc, char **argv);
1270 
1271 static const cmdinfo_t multiwrite_cmd = {
1272     .name       = "multiwrite",
1273     .cfunc      = multiwrite_f,
1274     .argmin     = 2,
1275     .argmax     = -1,
1276     .args       = "[-Cq] [-P pattern ] off len [len..] [; off len [len..]..]",
1277     .oneline    = "issues multiple write requests at once",
1278     .help       = multiwrite_help,
1279 };
1280 
1281 static int multiwrite_f(BlockBackend *blk, int argc, char **argv)
1282 {
1283     struct timeval t1, t2;
1284     int Cflag = 0, qflag = 0;
1285     int c, cnt;
1286     char **buf;
1287     int64_t offset, first_offset = 0;
1288     /* Some compilers get confused and warn if this is not initialized.  */
1289     int total = 0;
1290     int nr_iov;
1291     int nr_reqs;
1292     int pattern = 0xcd;
1293     QEMUIOVector *qiovs;
1294     int i;
1295     BlockRequest *reqs;
1296 
1297     while ((c = getopt(argc, argv, "CqP:")) != -1) {
1298         switch (c) {
1299         case 'C':
1300             Cflag = 1;
1301             break;
1302         case 'q':
1303             qflag = 1;
1304             break;
1305         case 'P':
1306             pattern = parse_pattern(optarg);
1307             if (pattern < 0) {
1308                 return 0;
1309             }
1310             break;
1311         default:
1312             return qemuio_command_usage(&writev_cmd);
1313         }
1314     }
1315 
1316     if (optind > argc - 2) {
1317         return qemuio_command_usage(&writev_cmd);
1318     }
1319 
1320     nr_reqs = 1;
1321     for (i = optind; i < argc; i++) {
1322         if (!strcmp(argv[i], ";")) {
1323             nr_reqs++;
1324         }
1325     }
1326 
1327     reqs = g_new0(BlockRequest, nr_reqs);
1328     buf = g_new0(char *, nr_reqs);
1329     qiovs = g_new(QEMUIOVector, nr_reqs);
1330 
1331     for (i = 0; i < nr_reqs && optind < argc; i++) {
1332         int j;
1333 
1334         /* Read the offset of the request */
1335         offset = cvtnum(argv[optind]);
1336         if (offset < 0) {
1337             print_cvtnum_err(offset, argv[optind]);
1338             goto out;
1339         }
1340         optind++;
1341 
1342         if (offset & 0x1ff) {
1343             printf("offset %lld is not sector aligned\n",
1344                    (long long)offset);
1345             goto out;
1346         }
1347 
1348         if (i == 0) {
1349             first_offset = offset;
1350         }
1351 
1352         /* Read lengths for qiov entries */
1353         for (j = optind; j < argc; j++) {
1354             if (!strcmp(argv[j], ";")) {
1355                 break;
1356             }
1357         }
1358 
1359         nr_iov = j - optind;
1360 
1361         /* Build request */
1362         buf[i] = create_iovec(blk, &qiovs[i], &argv[optind], nr_iov, pattern);
1363         if (buf[i] == NULL) {
1364             goto out;
1365         }
1366 
1367         reqs[i].qiov = &qiovs[i];
1368         reqs[i].sector = offset >> 9;
1369         reqs[i].nb_sectors = reqs[i].qiov->size >> 9;
1370 
1371         optind = j + 1;
1372 
1373         pattern++;
1374     }
1375 
1376     /* If there were empty requests at the end, ignore them */
1377     nr_reqs = i;
1378 
1379     gettimeofday(&t1, NULL);
1380     cnt = do_aio_multiwrite(blk, reqs, nr_reqs, &total);
1381     gettimeofday(&t2, NULL);
1382 
1383     if (cnt < 0) {
1384         printf("aio_multiwrite failed: %s\n", strerror(-cnt));
1385         goto out;
1386     }
1387 
1388     if (qflag) {
1389         goto out;
1390     }
1391 
1392     /* Finally, report back -- -C gives a parsable format */
1393     t2 = tsub(t2, t1);
1394     print_report("wrote", &t2, first_offset, total, total, cnt, Cflag);
1395 out:
1396     for (i = 0; i < nr_reqs; i++) {
1397         qemu_io_free(buf[i]);
1398         if (reqs[i].qiov != NULL) {
1399             qemu_iovec_destroy(&qiovs[i]);
1400         }
1401     }
1402     g_free(buf);
1403     g_free(reqs);
1404     g_free(qiovs);
1405     return 0;
1406 }
1407 
1408 struct aio_ctx {
1409     BlockBackend *blk;
1410     QEMUIOVector qiov;
1411     int64_t offset;
1412     char *buf;
1413     int qflag;
1414     int vflag;
1415     int Cflag;
1416     int Pflag;
1417     BlockAcctCookie acct;
1418     int pattern;
1419     struct timeval t1;
1420 };
1421 
1422 static void aio_write_done(void *opaque, int ret)
1423 {
1424     struct aio_ctx *ctx = opaque;
1425     struct timeval t2;
1426 
1427     gettimeofday(&t2, NULL);
1428 
1429 
1430     if (ret < 0) {
1431         printf("aio_write failed: %s\n", strerror(-ret));
1432         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1433         goto out;
1434     }
1435 
1436     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1437 
1438     if (ctx->qflag) {
1439         goto out;
1440     }
1441 
1442     /* Finally, report back -- -C gives a parsable format */
1443     t2 = tsub(t2, ctx->t1);
1444     print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
1445                  ctx->qiov.size, 1, ctx->Cflag);
1446 out:
1447     qemu_io_free(ctx->buf);
1448     qemu_iovec_destroy(&ctx->qiov);
1449     g_free(ctx);
1450 }
1451 
1452 static void aio_read_done(void *opaque, int ret)
1453 {
1454     struct aio_ctx *ctx = opaque;
1455     struct timeval t2;
1456 
1457     gettimeofday(&t2, NULL);
1458 
1459     if (ret < 0) {
1460         printf("readv failed: %s\n", strerror(-ret));
1461         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1462         goto out;
1463     }
1464 
1465     if (ctx->Pflag) {
1466         void *cmp_buf = g_malloc(ctx->qiov.size);
1467 
1468         memset(cmp_buf, ctx->pattern, ctx->qiov.size);
1469         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
1470             printf("Pattern verification failed at offset %"
1471                    PRId64 ", %zd bytes\n", ctx->offset, ctx->qiov.size);
1472         }
1473         g_free(cmp_buf);
1474     }
1475 
1476     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1477 
1478     if (ctx->qflag) {
1479         goto out;
1480     }
1481 
1482     if (ctx->vflag) {
1483         dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
1484     }
1485 
1486     /* Finally, report back -- -C gives a parsable format */
1487     t2 = tsub(t2, ctx->t1);
1488     print_report("read", &t2, ctx->offset, ctx->qiov.size,
1489                  ctx->qiov.size, 1, ctx->Cflag);
1490 out:
1491     qemu_io_free(ctx->buf);
1492     qemu_iovec_destroy(&ctx->qiov);
1493     g_free(ctx);
1494 }
1495 
1496 static void aio_read_help(void)
1497 {
1498     printf(
1499 "\n"
1500 " asynchronously reads a range of bytes from the given offset\n"
1501 "\n"
1502 " Example:\n"
1503 " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
1504 "\n"
1505 " Reads a segment of the currently open file, optionally dumping it to the\n"
1506 " standard output stream (with -v option) for subsequent inspection.\n"
1507 " The read is performed asynchronously and the aio_flush command must be\n"
1508 " used to ensure all outstanding aio requests have been completed.\n"
1509 " -C, -- report statistics in a machine parsable format\n"
1510 " -P, -- use a pattern to verify read data\n"
1511 " -v, -- dump buffer to standard output\n"
1512 " -q, -- quiet mode, do not show I/O statistics\n"
1513 "\n");
1514 }
1515 
1516 static int aio_read_f(BlockBackend *blk, int argc, char **argv);
1517 
1518 static const cmdinfo_t aio_read_cmd = {
1519     .name       = "aio_read",
1520     .cfunc      = aio_read_f,
1521     .argmin     = 2,
1522     .argmax     = -1,
1523     .args       = "[-Cqv] [-P pattern ] off len [len..]",
1524     .oneline    = "asynchronously reads a number of bytes",
1525     .help       = aio_read_help,
1526 };
1527 
1528 static int aio_read_f(BlockBackend *blk, int argc, char **argv)
1529 {
1530     int nr_iov, c;
1531     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1532 
1533     ctx->blk = blk;
1534     while ((c = getopt(argc, argv, "CP:qv")) != -1) {
1535         switch (c) {
1536         case 'C':
1537             ctx->Cflag = 1;
1538             break;
1539         case 'P':
1540             ctx->Pflag = 1;
1541             ctx->pattern = parse_pattern(optarg);
1542             if (ctx->pattern < 0) {
1543                 g_free(ctx);
1544                 return 0;
1545             }
1546             break;
1547         case 'q':
1548             ctx->qflag = 1;
1549             break;
1550         case 'v':
1551             ctx->vflag = 1;
1552             break;
1553         default:
1554             g_free(ctx);
1555             return qemuio_command_usage(&aio_read_cmd);
1556         }
1557     }
1558 
1559     if (optind > argc - 2) {
1560         g_free(ctx);
1561         return qemuio_command_usage(&aio_read_cmd);
1562     }
1563 
1564     ctx->offset = cvtnum(argv[optind]);
1565     if (ctx->offset < 0) {
1566         print_cvtnum_err(ctx->offset, argv[optind]);
1567         g_free(ctx);
1568         return 0;
1569     }
1570     optind++;
1571 
1572     if (ctx->offset & 0x1ff) {
1573         printf("offset %" PRId64 " is not sector aligned\n",
1574                ctx->offset);
1575         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1576         g_free(ctx);
1577         return 0;
1578     }
1579 
1580     nr_iov = argc - optind;
1581     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
1582     if (ctx->buf == NULL) {
1583         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1584         g_free(ctx);
1585         return 0;
1586     }
1587 
1588     gettimeofday(&ctx->t1, NULL);
1589     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1590                      BLOCK_ACCT_READ);
1591     blk_aio_readv(blk, ctx->offset >> 9, &ctx->qiov,
1592                   ctx->qiov.size >> 9, aio_read_done, ctx);
1593     return 0;
1594 }
1595 
1596 static void aio_write_help(void)
1597 {
1598     printf(
1599 "\n"
1600 " asynchronously writes a range of bytes from the given offset source\n"
1601 " from multiple buffers\n"
1602 "\n"
1603 " Example:\n"
1604 " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1605 "\n"
1606 " Writes into a segment of the currently open file, using a buffer\n"
1607 " filled with a set pattern (0xcdcdcdcd).\n"
1608 " The write is performed asynchronously and the aio_flush command must be\n"
1609 " used to ensure all outstanding aio requests have been completed.\n"
1610 " -P, -- use different pattern to fill file\n"
1611 " -C, -- report statistics in a machine parsable format\n"
1612 " -q, -- quiet mode, do not show I/O statistics\n"
1613 "\n");
1614 }
1615 
1616 static int aio_write_f(BlockBackend *blk, int argc, char **argv);
1617 
1618 static const cmdinfo_t aio_write_cmd = {
1619     .name       = "aio_write",
1620     .cfunc      = aio_write_f,
1621     .argmin     = 2,
1622     .argmax     = -1,
1623     .args       = "[-Cq] [-P pattern ] off len [len..]",
1624     .oneline    = "asynchronously writes a number of bytes",
1625     .help       = aio_write_help,
1626 };
1627 
1628 static int aio_write_f(BlockBackend *blk, int argc, char **argv)
1629 {
1630     int nr_iov, c;
1631     int pattern = 0xcd;
1632     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1633 
1634     ctx->blk = blk;
1635     while ((c = getopt(argc, argv, "CqP:")) != -1) {
1636         switch (c) {
1637         case 'C':
1638             ctx->Cflag = 1;
1639             break;
1640         case 'q':
1641             ctx->qflag = 1;
1642             break;
1643         case 'P':
1644             pattern = parse_pattern(optarg);
1645             if (pattern < 0) {
1646                 g_free(ctx);
1647                 return 0;
1648             }
1649             break;
1650         default:
1651             g_free(ctx);
1652             return qemuio_command_usage(&aio_write_cmd);
1653         }
1654     }
1655 
1656     if (optind > argc - 2) {
1657         g_free(ctx);
1658         return qemuio_command_usage(&aio_write_cmd);
1659     }
1660 
1661     ctx->offset = cvtnum(argv[optind]);
1662     if (ctx->offset < 0) {
1663         print_cvtnum_err(ctx->offset, argv[optind]);
1664         g_free(ctx);
1665         return 0;
1666     }
1667     optind++;
1668 
1669     if (ctx->offset & 0x1ff) {
1670         printf("offset %" PRId64 " is not sector aligned\n",
1671                ctx->offset);
1672         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1673         g_free(ctx);
1674         return 0;
1675     }
1676 
1677     nr_iov = argc - optind;
1678     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, pattern);
1679     if (ctx->buf == NULL) {
1680         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1681         g_free(ctx);
1682         return 0;
1683     }
1684 
1685     gettimeofday(&ctx->t1, NULL);
1686     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1687                      BLOCK_ACCT_WRITE);
1688     blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov,
1689                    ctx->qiov.size >> 9, aio_write_done, ctx);
1690     return 0;
1691 }
1692 
1693 static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
1694 {
1695     BlockAcctCookie cookie;
1696     block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
1697     blk_drain_all();
1698     block_acct_done(blk_get_stats(blk), &cookie);
1699     return 0;
1700 }
1701 
1702 static const cmdinfo_t aio_flush_cmd = {
1703     .name       = "aio_flush",
1704     .cfunc      = aio_flush_f,
1705     .oneline    = "completes all outstanding aio requests"
1706 };
1707 
1708 static int flush_f(BlockBackend *blk, int argc, char **argv)
1709 {
1710     blk_flush(blk);
1711     return 0;
1712 }
1713 
1714 static const cmdinfo_t flush_cmd = {
1715     .name       = "flush",
1716     .altname    = "f",
1717     .cfunc      = flush_f,
1718     .oneline    = "flush all in-core file state to disk",
1719 };
1720 
1721 static int truncate_f(BlockBackend *blk, int argc, char **argv)
1722 {
1723     int64_t offset;
1724     int ret;
1725 
1726     offset = cvtnum(argv[1]);
1727     if (offset < 0) {
1728         print_cvtnum_err(offset, argv[1]);
1729         return 0;
1730     }
1731 
1732     ret = blk_truncate(blk, offset);
1733     if (ret < 0) {
1734         printf("truncate: %s\n", strerror(-ret));
1735         return 0;
1736     }
1737 
1738     return 0;
1739 }
1740 
1741 static const cmdinfo_t truncate_cmd = {
1742     .name       = "truncate",
1743     .altname    = "t",
1744     .cfunc      = truncate_f,
1745     .argmin     = 1,
1746     .argmax     = 1,
1747     .args       = "off",
1748     .oneline    = "truncates the current file at the given offset",
1749 };
1750 
1751 static int length_f(BlockBackend *blk, int argc, char **argv)
1752 {
1753     int64_t size;
1754     char s1[64];
1755 
1756     size = blk_getlength(blk);
1757     if (size < 0) {
1758         printf("getlength: %s\n", strerror(-size));
1759         return 0;
1760     }
1761 
1762     cvtstr(size, s1, sizeof(s1));
1763     printf("%s\n", s1);
1764     return 0;
1765 }
1766 
1767 
1768 static const cmdinfo_t length_cmd = {
1769     .name   = "length",
1770     .altname    = "l",
1771     .cfunc      = length_f,
1772     .oneline    = "gets the length of the current file",
1773 };
1774 
1775 
1776 static int info_f(BlockBackend *blk, int argc, char **argv)
1777 {
1778     BlockDriverState *bs = blk_bs(blk);
1779     BlockDriverInfo bdi;
1780     ImageInfoSpecific *spec_info;
1781     char s1[64], s2[64];
1782     int ret;
1783 
1784     if (bs->drv && bs->drv->format_name) {
1785         printf("format name: %s\n", bs->drv->format_name);
1786     }
1787     if (bs->drv && bs->drv->protocol_name) {
1788         printf("format name: %s\n", bs->drv->protocol_name);
1789     }
1790 
1791     ret = bdrv_get_info(bs, &bdi);
1792     if (ret) {
1793         return 0;
1794     }
1795 
1796     cvtstr(bdi.cluster_size, s1, sizeof(s1));
1797     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1798 
1799     printf("cluster size: %s\n", s1);
1800     printf("vm state offset: %s\n", s2);
1801 
1802     spec_info = bdrv_get_specific_info(bs);
1803     if (spec_info) {
1804         printf("Format specific information:\n");
1805         bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
1806         qapi_free_ImageInfoSpecific(spec_info);
1807     }
1808 
1809     return 0;
1810 }
1811 
1812 
1813 
1814 static const cmdinfo_t info_cmd = {
1815     .name       = "info",
1816     .altname    = "i",
1817     .cfunc      = info_f,
1818     .oneline    = "prints information about the current file",
1819 };
1820 
1821 static void discard_help(void)
1822 {
1823     printf(
1824 "\n"
1825 " discards a range of bytes from the given offset\n"
1826 "\n"
1827 " Example:\n"
1828 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1829 "\n"
1830 " Discards a segment of the currently open file.\n"
1831 " -C, -- report statistics in a machine parsable format\n"
1832 " -q, -- quiet mode, do not show I/O statistics\n"
1833 "\n");
1834 }
1835 
1836 static int discard_f(BlockBackend *blk, int argc, char **argv);
1837 
1838 static const cmdinfo_t discard_cmd = {
1839     .name       = "discard",
1840     .altname    = "d",
1841     .cfunc      = discard_f,
1842     .argmin     = 2,
1843     .argmax     = -1,
1844     .args       = "[-Cq] off len",
1845     .oneline    = "discards a number of bytes at a specified offset",
1846     .help       = discard_help,
1847 };
1848 
1849 static int discard_f(BlockBackend *blk, int argc, char **argv)
1850 {
1851     struct timeval t1, t2;
1852     int Cflag = 0, qflag = 0;
1853     int c, ret;
1854     int64_t offset, count;
1855 
1856     while ((c = getopt(argc, argv, "Cq")) != -1) {
1857         switch (c) {
1858         case 'C':
1859             Cflag = 1;
1860             break;
1861         case 'q':
1862             qflag = 1;
1863             break;
1864         default:
1865             return qemuio_command_usage(&discard_cmd);
1866         }
1867     }
1868 
1869     if (optind != argc - 2) {
1870         return qemuio_command_usage(&discard_cmd);
1871     }
1872 
1873     offset = cvtnum(argv[optind]);
1874     if (offset < 0) {
1875         print_cvtnum_err(offset, argv[optind]);
1876         return 0;
1877     }
1878 
1879     optind++;
1880     count = cvtnum(argv[optind]);
1881     if (count < 0) {
1882         print_cvtnum_err(count, argv[optind]);
1883         return 0;
1884     } else if (count >> BDRV_SECTOR_BITS > INT_MAX) {
1885         printf("length cannot exceed %"PRIu64", given %s\n",
1886                (uint64_t)INT_MAX << BDRV_SECTOR_BITS,
1887                argv[optind]);
1888         return 0;
1889     }
1890 
1891     gettimeofday(&t1, NULL);
1892     ret = blk_discard(blk, offset >> BDRV_SECTOR_BITS,
1893                       count >> BDRV_SECTOR_BITS);
1894     gettimeofday(&t2, NULL);
1895 
1896     if (ret < 0) {
1897         printf("discard failed: %s\n", strerror(-ret));
1898         goto out;
1899     }
1900 
1901     /* Finally, report back -- -C gives a parsable format */
1902     if (!qflag) {
1903         t2 = tsub(t2, t1);
1904         print_report("discard", &t2, offset, count, count, 1, Cflag);
1905     }
1906 
1907 out:
1908     return 0;
1909 }
1910 
1911 static int alloc_f(BlockBackend *blk, int argc, char **argv)
1912 {
1913     BlockDriverState *bs = blk_bs(blk);
1914     int64_t offset, sector_num, nb_sectors, remaining;
1915     char s1[64];
1916     int num, ret;
1917     int64_t sum_alloc;
1918 
1919     offset = cvtnum(argv[1]);
1920     if (offset < 0) {
1921         print_cvtnum_err(offset, argv[1]);
1922         return 0;
1923     } else if (offset & 0x1ff) {
1924         printf("offset %" PRId64 " is not sector aligned\n",
1925                offset);
1926         return 0;
1927     }
1928 
1929     if (argc == 3) {
1930         nb_sectors = cvtnum(argv[2]);
1931         if (nb_sectors < 0) {
1932             print_cvtnum_err(nb_sectors, argv[2]);
1933             return 0;
1934         } else if (nb_sectors > INT_MAX) {
1935             printf("length argument cannot exceed %d, given %s\n",
1936                    INT_MAX, argv[2]);
1937             return 0;
1938         }
1939     } else {
1940         nb_sectors = 1;
1941     }
1942 
1943     remaining = nb_sectors;
1944     sum_alloc = 0;
1945     sector_num = offset >> 9;
1946     while (remaining) {
1947         ret = bdrv_is_allocated(bs, sector_num, remaining, &num);
1948         if (ret < 0) {
1949             printf("is_allocated failed: %s\n", strerror(-ret));
1950             return 0;
1951         }
1952         sector_num += num;
1953         remaining -= num;
1954         if (ret) {
1955             sum_alloc += num;
1956         }
1957         if (num == 0) {
1958             nb_sectors -= remaining;
1959             remaining = 0;
1960         }
1961     }
1962 
1963     cvtstr(offset, s1, sizeof(s1));
1964 
1965     printf("%"PRId64"/%"PRId64" sectors allocated at offset %s\n",
1966            sum_alloc, nb_sectors, s1);
1967     return 0;
1968 }
1969 
1970 static const cmdinfo_t alloc_cmd = {
1971     .name       = "alloc",
1972     .altname    = "a",
1973     .argmin     = 1,
1974     .argmax     = 2,
1975     .cfunc      = alloc_f,
1976     .args       = "off [sectors]",
1977     .oneline    = "checks if a sector is present in the file",
1978 };
1979 
1980 
1981 static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
1982                             int64_t nb_sectors, int64_t *pnum)
1983 {
1984     int num, num_checked;
1985     int ret, firstret;
1986 
1987     num_checked = MIN(nb_sectors, INT_MAX);
1988     ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
1989     if (ret < 0) {
1990         return ret;
1991     }
1992 
1993     firstret = ret;
1994     *pnum = num;
1995 
1996     while (nb_sectors > 0 && ret == firstret) {
1997         sector_num += num;
1998         nb_sectors -= num;
1999 
2000         num_checked = MIN(nb_sectors, INT_MAX);
2001         ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
2002         if (ret == firstret && num) {
2003             *pnum += num;
2004         } else {
2005             break;
2006         }
2007     }
2008 
2009     return firstret;
2010 }
2011 
2012 static int map_f(BlockBackend *blk, int argc, char **argv)
2013 {
2014     int64_t offset;
2015     int64_t nb_sectors, total_sectors;
2016     char s1[64];
2017     int64_t num;
2018     int ret;
2019     const char *retstr;
2020 
2021     offset = 0;
2022     total_sectors = blk_nb_sectors(blk);
2023     if (total_sectors < 0) {
2024         error_report("Failed to query image length: %s",
2025                      strerror(-total_sectors));
2026         return 0;
2027     }
2028 
2029     nb_sectors = total_sectors;
2030 
2031     do {
2032         ret = map_is_allocated(blk_bs(blk), offset, nb_sectors, &num);
2033         if (ret < 0) {
2034             error_report("Failed to get allocation status: %s", strerror(-ret));
2035             return 0;
2036         } else if (!num) {
2037             error_report("Unexpected end of image");
2038             return 0;
2039         }
2040 
2041         retstr = ret ? "    allocated" : "not allocated";
2042         cvtstr(offset << 9ULL, s1, sizeof(s1));
2043         printf("[% 24" PRId64 "] % 8" PRId64 "/% 8" PRId64 " sectors %s "
2044                "at offset %s (%d)\n",
2045                offset << 9ULL, num, nb_sectors, retstr, s1, ret);
2046 
2047         offset += num;
2048         nb_sectors -= num;
2049     } while (offset < total_sectors);
2050 
2051     return 0;
2052 }
2053 
2054 static const cmdinfo_t map_cmd = {
2055        .name           = "map",
2056        .argmin         = 0,
2057        .argmax         = 0,
2058        .cfunc          = map_f,
2059        .args           = "",
2060        .oneline        = "prints the allocated areas of a file",
2061 };
2062 
2063 static void reopen_help(void)
2064 {
2065     printf(
2066 "\n"
2067 " Changes the open options of an already opened image\n"
2068 "\n"
2069 " Example:\n"
2070 " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
2071 "\n"
2072 " -r, -- Reopen the image read-only\n"
2073 " -c, -- Change the cache mode to the given value\n"
2074 " -o, -- Changes block driver options (cf. 'open' command)\n"
2075 "\n");
2076 }
2077 
2078 static int reopen_f(BlockBackend *blk, int argc, char **argv);
2079 
2080 static QemuOptsList reopen_opts = {
2081     .name = "reopen",
2082     .merge_lists = true,
2083     .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
2084     .desc = {
2085         /* no elements => accept any params */
2086         { /* end of list */ }
2087     },
2088 };
2089 
2090 static const cmdinfo_t reopen_cmd = {
2091        .name           = "reopen",
2092        .argmin         = 0,
2093        .argmax         = -1,
2094        .cfunc          = reopen_f,
2095        .args           = "[-r] [-c cache] [-o options]",
2096        .oneline        = "reopens an image with new options",
2097        .help           = reopen_help,
2098 };
2099 
2100 static int reopen_f(BlockBackend *blk, int argc, char **argv)
2101 {
2102     BlockDriverState *bs = blk_bs(blk);
2103     QemuOpts *qopts;
2104     QDict *opts;
2105     int c;
2106     int flags = bs->open_flags;
2107 
2108     BlockReopenQueue *brq;
2109     Error *local_err = NULL;
2110 
2111     while ((c = getopt(argc, argv, "c:o:r")) != -1) {
2112         switch (c) {
2113         case 'c':
2114             if (bdrv_parse_cache_flags(optarg, &flags) < 0) {
2115                 error_report("Invalid cache option: %s", optarg);
2116                 return 0;
2117             }
2118             break;
2119         case 'o':
2120             if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
2121                 qemu_opts_reset(&reopen_opts);
2122                 return 0;
2123             }
2124             break;
2125         case 'r':
2126             flags &= ~BDRV_O_RDWR;
2127             break;
2128         default:
2129             qemu_opts_reset(&reopen_opts);
2130             return qemuio_command_usage(&reopen_cmd);
2131         }
2132     }
2133 
2134     if (optind != argc) {
2135         qemu_opts_reset(&reopen_opts);
2136         return qemuio_command_usage(&reopen_cmd);
2137     }
2138 
2139     qopts = qemu_opts_find(&reopen_opts, NULL);
2140     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : NULL;
2141     qemu_opts_reset(&reopen_opts);
2142 
2143     brq = bdrv_reopen_queue(NULL, bs, opts, flags);
2144     bdrv_reopen_multiple(brq, &local_err);
2145     if (local_err) {
2146         error_report_err(local_err);
2147     }
2148 
2149     return 0;
2150 }
2151 
2152 static int break_f(BlockBackend *blk, int argc, char **argv)
2153 {
2154     int ret;
2155 
2156     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2157     if (ret < 0) {
2158         printf("Could not set breakpoint: %s\n", strerror(-ret));
2159     }
2160 
2161     return 0;
2162 }
2163 
2164 static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2165 {
2166     int ret;
2167 
2168     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2169     if (ret < 0) {
2170         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2171     }
2172 
2173     return 0;
2174 }
2175 
2176 static const cmdinfo_t break_cmd = {
2177        .name           = "break",
2178        .argmin         = 2,
2179        .argmax         = 2,
2180        .cfunc          = break_f,
2181        .args           = "event tag",
2182        .oneline        = "sets a breakpoint on event and tags the stopped "
2183                          "request as tag",
2184 };
2185 
2186 static const cmdinfo_t remove_break_cmd = {
2187        .name           = "remove_break",
2188        .argmin         = 1,
2189        .argmax         = 1,
2190        .cfunc          = remove_break_f,
2191        .args           = "tag",
2192        .oneline        = "remove a breakpoint by tag",
2193 };
2194 
2195 static int resume_f(BlockBackend *blk, int argc, char **argv)
2196 {
2197     int ret;
2198 
2199     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2200     if (ret < 0) {
2201         printf("Could not resume request: %s\n", strerror(-ret));
2202     }
2203 
2204     return 0;
2205 }
2206 
2207 static const cmdinfo_t resume_cmd = {
2208        .name           = "resume",
2209        .argmin         = 1,
2210        .argmax         = 1,
2211        .cfunc          = resume_f,
2212        .args           = "tag",
2213        .oneline        = "resumes the request tagged as tag",
2214 };
2215 
2216 static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2217 {
2218     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2219         aio_poll(blk_get_aio_context(blk), true);
2220     }
2221 
2222     return 0;
2223 }
2224 
2225 static const cmdinfo_t wait_break_cmd = {
2226        .name           = "wait_break",
2227        .argmin         = 1,
2228        .argmax         = 1,
2229        .cfunc          = wait_break_f,
2230        .args           = "tag",
2231        .oneline        = "waits for the suspension of a request",
2232 };
2233 
2234 static int abort_f(BlockBackend *blk, int argc, char **argv)
2235 {
2236     abort();
2237 }
2238 
2239 static const cmdinfo_t abort_cmd = {
2240        .name           = "abort",
2241        .cfunc          = abort_f,
2242        .flags          = CMD_NOFILE_OK,
2243        .oneline        = "simulate a program crash using abort(3)",
2244 };
2245 
2246 static void sigraise_help(void)
2247 {
2248     printf(
2249 "\n"
2250 " raises the given signal\n"
2251 "\n"
2252 " Example:\n"
2253 " 'sigraise %i' - raises SIGTERM\n"
2254 "\n"
2255 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2256 " given to sigraise.\n"
2257 "\n", SIGTERM);
2258 }
2259 
2260 static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2261 
2262 static const cmdinfo_t sigraise_cmd = {
2263     .name       = "sigraise",
2264     .cfunc      = sigraise_f,
2265     .argmin     = 1,
2266     .argmax     = 1,
2267     .flags      = CMD_NOFILE_OK,
2268     .args       = "signal",
2269     .oneline    = "raises a signal",
2270     .help       = sigraise_help,
2271 };
2272 
2273 static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2274 {
2275     int64_t sig = cvtnum(argv[1]);
2276     if (sig < 0) {
2277         print_cvtnum_err(sig, argv[1]);
2278         return 0;
2279     } else if (sig > NSIG) {
2280         printf("signal argument '%s' is too large to be a valid signal\n",
2281                argv[1]);
2282         return 0;
2283     }
2284 
2285     /* Using raise() to kill this process does not necessarily flush all open
2286      * streams. At least stdout and stderr (although the latter should be
2287      * non-buffered anyway) should be flushed, though. */
2288     fflush(stdout);
2289     fflush(stderr);
2290 
2291     raise(sig);
2292     return 0;
2293 }
2294 
2295 static void sleep_cb(void *opaque)
2296 {
2297     bool *expired = opaque;
2298     *expired = true;
2299 }
2300 
2301 static int sleep_f(BlockBackend *blk, int argc, char **argv)
2302 {
2303     char *endptr;
2304     long ms;
2305     struct QEMUTimer *timer;
2306     bool expired = false;
2307 
2308     ms = strtol(argv[1], &endptr, 0);
2309     if (ms < 0 || *endptr != '\0') {
2310         printf("%s is not a valid number\n", argv[1]);
2311         return 0;
2312     }
2313 
2314     timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2315     timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2316 
2317     while (!expired) {
2318         main_loop_wait(false);
2319     }
2320 
2321     timer_free(timer);
2322 
2323     return 0;
2324 }
2325 
2326 static const cmdinfo_t sleep_cmd = {
2327        .name           = "sleep",
2328        .argmin         = 1,
2329        .argmax         = 1,
2330        .cfunc          = sleep_f,
2331        .flags          = CMD_NOFILE_OK,
2332        .oneline        = "waits for the given value in milliseconds",
2333 };
2334 
2335 static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2336 {
2337     if (cmd) {
2338         printf("%s ", cmd);
2339     } else {
2340         printf("%s ", ct->name);
2341         if (ct->altname) {
2342             printf("(or %s) ", ct->altname);
2343         }
2344     }
2345 
2346     if (ct->args) {
2347         printf("%s ", ct->args);
2348     }
2349     printf("-- %s\n", ct->oneline);
2350 }
2351 
2352 static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2353 {
2354     help_oneline(cmd, ct);
2355     if (ct->help) {
2356         ct->help();
2357     }
2358 }
2359 
2360 static void help_all(void)
2361 {
2362     const cmdinfo_t *ct;
2363 
2364     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2365         help_oneline(ct->name, ct);
2366     }
2367     printf("\nUse 'help commandname' for extended help.\n");
2368 }
2369 
2370 static int help_f(BlockBackend *blk, int argc, char **argv)
2371 {
2372     const cmdinfo_t *ct;
2373 
2374     if (argc == 1) {
2375         help_all();
2376         return 0;
2377     }
2378 
2379     ct = find_command(argv[1]);
2380     if (ct == NULL) {
2381         printf("command %s not found\n", argv[1]);
2382         return 0;
2383     }
2384 
2385     help_onecmd(argv[1], ct);
2386     return 0;
2387 }
2388 
2389 static const cmdinfo_t help_cmd = {
2390     .name       = "help",
2391     .altname    = "?",
2392     .cfunc      = help_f,
2393     .argmin     = 0,
2394     .argmax     = 1,
2395     .flags      = CMD_FLAG_GLOBAL,
2396     .args       = "[command]",
2397     .oneline    = "help for one or all commands",
2398 };
2399 
2400 bool qemuio_command(BlockBackend *blk, const char *cmd)
2401 {
2402     char *input;
2403     const cmdinfo_t *ct;
2404     char **v;
2405     int c;
2406     bool done = false;
2407 
2408     input = g_strdup(cmd);
2409     v = breakline(input, &c);
2410     if (c) {
2411         ct = find_command(v[0]);
2412         if (ct) {
2413             done = command(blk, ct, c, v);
2414         } else {
2415             fprintf(stderr, "command \"%s\" not found\n", v[0]);
2416         }
2417     }
2418     g_free(input);
2419     g_free(v);
2420 
2421     return done;
2422 }
2423 
2424 static void __attribute((constructor)) init_qemuio_commands(void)
2425 {
2426     /* initialize commands */
2427     qemuio_add_command(&help_cmd);
2428     qemuio_add_command(&read_cmd);
2429     qemuio_add_command(&readv_cmd);
2430     qemuio_add_command(&write_cmd);
2431     qemuio_add_command(&writev_cmd);
2432     qemuio_add_command(&multiwrite_cmd);
2433     qemuio_add_command(&aio_read_cmd);
2434     qemuio_add_command(&aio_write_cmd);
2435     qemuio_add_command(&aio_flush_cmd);
2436     qemuio_add_command(&flush_cmd);
2437     qemuio_add_command(&truncate_cmd);
2438     qemuio_add_command(&length_cmd);
2439     qemuio_add_command(&info_cmd);
2440     qemuio_add_command(&discard_cmd);
2441     qemuio_add_command(&alloc_cmd);
2442     qemuio_add_command(&map_cmd);
2443     qemuio_add_command(&reopen_cmd);
2444     qemuio_add_command(&break_cmd);
2445     qemuio_add_command(&remove_break_cmd);
2446     qemuio_add_command(&resume_cmd);
2447     qemuio_add_command(&wait_break_cmd);
2448     qemuio_add_command(&abort_cmd);
2449     qemuio_add_command(&sleep_cmd);
2450     qemuio_add_command(&sigraise_cmd);
2451 }
2452