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