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