xref: /openbmc/qemu/qemu-io-cmds.c (revision 5df022cf)
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     if (bytes > INT_MAX) {
545         return -ERANGE;
546     }
547 
548     *total = blk_pread(blk, offset, (uint8_t *)buf, bytes);
549     if (*total < 0) {
550         return *total;
551     }
552     return 1;
553 }
554 
555 static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
556                      int64_t bytes, int flags, int64_t *total)
557 {
558     if (bytes > INT_MAX) {
559         return -ERANGE;
560     }
561 
562     *total = blk_pwrite(blk, offset, (uint8_t *)buf, bytes, flags);
563     if (*total < 0) {
564         return *total;
565     }
566     return 1;
567 }
568 
569 typedef struct {
570     BlockBackend *blk;
571     int64_t offset;
572     int64_t bytes;
573     int64_t *total;
574     int flags;
575     int ret;
576     bool done;
577 } CoWriteZeroes;
578 
579 static void coroutine_fn co_pwrite_zeroes_entry(void *opaque)
580 {
581     CoWriteZeroes *data = opaque;
582 
583     data->ret = blk_co_pwrite_zeroes(data->blk, data->offset, data->bytes,
584                                      data->flags);
585     data->done = true;
586     if (data->ret < 0) {
587         *data->total = data->ret;
588         return;
589     }
590 
591     *data->total = data->bytes;
592 }
593 
594 static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
595                                int64_t bytes, int flags, int64_t *total)
596 {
597     Coroutine *co;
598     CoWriteZeroes data = {
599         .blk    = blk,
600         .offset = offset,
601         .bytes  = bytes,
602         .total  = total,
603         .flags  = flags,
604         .done   = false,
605     };
606 
607     if (bytes > INT_MAX) {
608         return -ERANGE;
609     }
610 
611     co = qemu_coroutine_create(co_pwrite_zeroes_entry, &data);
612     bdrv_coroutine_enter(blk_bs(blk), co);
613     while (!data.done) {
614         aio_poll(blk_get_aio_context(blk), true);
615     }
616     if (data.ret < 0) {
617         return data.ret;
618     } else {
619         return 1;
620     }
621 }
622 
623 static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
624                                int64_t bytes, int64_t *total)
625 {
626     int ret;
627 
628     if (bytes > BDRV_REQUEST_MAX_BYTES) {
629         return -ERANGE;
630     }
631 
632     ret = blk_pwrite_compressed(blk, offset, buf, bytes);
633     if (ret < 0) {
634         return ret;
635     }
636     *total = bytes;
637     return 1;
638 }
639 
640 static int do_load_vmstate(BlockBackend *blk, char *buf, int64_t offset,
641                            int64_t count, int64_t *total)
642 {
643     if (count > INT_MAX) {
644         return -ERANGE;
645     }
646 
647     *total = blk_load_vmstate(blk, (uint8_t *)buf, offset, count);
648     if (*total < 0) {
649         return *total;
650     }
651     return 1;
652 }
653 
654 static int do_save_vmstate(BlockBackend *blk, char *buf, int64_t offset,
655                            int64_t count, int64_t *total)
656 {
657     if (count > INT_MAX) {
658         return -ERANGE;
659     }
660 
661     *total = blk_save_vmstate(blk, (uint8_t *)buf, offset, count);
662     if (*total < 0) {
663         return *total;
664     }
665     return 1;
666 }
667 
668 #define NOT_DONE 0x7fffffff
669 static void aio_rw_done(void *opaque, int ret)
670 {
671     *(int *)opaque = ret;
672 }
673 
674 static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
675                         int64_t offset, int *total)
676 {
677     int async_ret = NOT_DONE;
678 
679     blk_aio_preadv(blk, offset, qiov, 0, aio_rw_done, &async_ret);
680     while (async_ret == NOT_DONE) {
681         main_loop_wait(false);
682     }
683 
684     *total = qiov->size;
685     return async_ret < 0 ? async_ret : 1;
686 }
687 
688 static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
689                          int64_t offset, int flags, int *total)
690 {
691     int async_ret = NOT_DONE;
692 
693     blk_aio_pwritev(blk, offset, qiov, flags, aio_rw_done, &async_ret);
694     while (async_ret == NOT_DONE) {
695         main_loop_wait(false);
696     }
697 
698     *total = qiov->size;
699     return async_ret < 0 ? async_ret : 1;
700 }
701 
702 static void read_help(void)
703 {
704     printf(
705 "\n"
706 " reads a range of bytes from the given offset\n"
707 "\n"
708 " Example:\n"
709 " 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
710 "\n"
711 " Reads a segment of the currently open file, optionally dumping it to the\n"
712 " standard output stream (with -v option) for subsequent inspection.\n"
713 " -b, -- read from the VM state rather than the virtual disk\n"
714 " -C, -- report statistics in a machine parsable format\n"
715 " -l, -- length for pattern verification (only with -P)\n"
716 " -p, -- ignored for backwards compatibility\n"
717 " -P, -- use a pattern to verify read data\n"
718 " -q, -- quiet mode, do not show I/O statistics\n"
719 " -s, -- start offset for pattern verification (only with -P)\n"
720 " -v, -- dump buffer to standard output\n"
721 "\n");
722 }
723 
724 static int read_f(BlockBackend *blk, int argc, char **argv);
725 
726 static const cmdinfo_t read_cmd = {
727     .name       = "read",
728     .altname    = "r",
729     .cfunc      = read_f,
730     .argmin     = 2,
731     .argmax     = -1,
732     .args       = "[-abCqv] [-P pattern [-s off] [-l len]] off len",
733     .oneline    = "reads a number of bytes at a specified offset",
734     .help       = read_help,
735 };
736 
737 static int read_f(BlockBackend *blk, int argc, char **argv)
738 {
739     struct timespec t1, t2;
740     bool Cflag = false, qflag = false, vflag = false;
741     bool Pflag = false, sflag = false, lflag = false, bflag = false;
742     int c, cnt, ret;
743     char *buf;
744     int64_t offset;
745     int64_t count;
746     /* Some compilers get confused and warn if this is not initialized.  */
747     int64_t total = 0;
748     int pattern = 0;
749     int64_t pattern_offset = 0, pattern_count = 0;
750 
751     while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) {
752         switch (c) {
753         case 'b':
754             bflag = true;
755             break;
756         case 'C':
757             Cflag = true;
758             break;
759         case 'l':
760             lflag = true;
761             pattern_count = cvtnum(optarg);
762             if (pattern_count < 0) {
763                 print_cvtnum_err(pattern_count, optarg);
764                 return pattern_count;
765             }
766             break;
767         case 'p':
768             /* Ignored for backwards compatibility */
769             break;
770         case 'P':
771             Pflag = true;
772             pattern = parse_pattern(optarg);
773             if (pattern < 0) {
774                 return -EINVAL;
775             }
776             break;
777         case 'q':
778             qflag = true;
779             break;
780         case 's':
781             sflag = true;
782             pattern_offset = cvtnum(optarg);
783             if (pattern_offset < 0) {
784                 print_cvtnum_err(pattern_offset, optarg);
785                 return pattern_offset;
786             }
787             break;
788         case 'v':
789             vflag = true;
790             break;
791         default:
792             qemuio_command_usage(&read_cmd);
793             return -EINVAL;
794         }
795     }
796 
797     if (optind != argc - 2) {
798         qemuio_command_usage(&read_cmd);
799         return -EINVAL;
800     }
801 
802     offset = cvtnum(argv[optind]);
803     if (offset < 0) {
804         print_cvtnum_err(offset, argv[optind]);
805         return offset;
806     }
807 
808     optind++;
809     count = cvtnum(argv[optind]);
810     if (count < 0) {
811         print_cvtnum_err(count, argv[optind]);
812         return count;
813     } else if (count > BDRV_REQUEST_MAX_BYTES) {
814         printf("length cannot exceed %" PRIu64 ", given %s\n",
815                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
816         return -EINVAL;
817     }
818 
819     if (!Pflag && (lflag || sflag)) {
820         qemuio_command_usage(&read_cmd);
821         return -EINVAL;
822     }
823 
824     if (!lflag) {
825         pattern_count = count - pattern_offset;
826     }
827 
828     if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
829         printf("pattern verification range exceeds end of read data\n");
830         return -EINVAL;
831     }
832 
833     if (bflag) {
834         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
835             printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
836                    offset);
837             return -EINVAL;
838         }
839         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
840             printf("%"PRId64" is not a sector-aligned value for 'count'\n",
841                    count);
842             return -EINVAL;
843         }
844     }
845 
846     buf = qemu_io_alloc(blk, count, 0xab);
847 
848     clock_gettime(CLOCK_MONOTONIC, &t1);
849     if (bflag) {
850         ret = do_load_vmstate(blk, buf, offset, count, &total);
851     } else {
852         ret = do_pread(blk, buf, offset, count, &total);
853     }
854     clock_gettime(CLOCK_MONOTONIC, &t2);
855 
856     if (ret < 0) {
857         printf("read failed: %s\n", strerror(-ret));
858         goto out;
859     }
860     cnt = ret;
861 
862     ret = 0;
863 
864     if (Pflag) {
865         void *cmp_buf = g_malloc(pattern_count);
866         memset(cmp_buf, pattern, pattern_count);
867         if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
868             printf("Pattern verification failed at offset %"
869                    PRId64 ", %"PRId64" bytes\n",
870                    offset + pattern_offset, pattern_count);
871             ret = -EINVAL;
872         }
873         g_free(cmp_buf);
874     }
875 
876     if (qflag) {
877         goto out;
878     }
879 
880     if (vflag) {
881         dump_buffer(buf, offset, count);
882     }
883 
884     /* Finally, report back -- -C gives a parsable format */
885     t2 = tsub(t2, t1);
886     print_report("read", &t2, offset, count, total, cnt, Cflag);
887 
888 out:
889     qemu_io_free(buf);
890     return ret;
891 }
892 
893 static void readv_help(void)
894 {
895     printf(
896 "\n"
897 " reads a range of bytes from the given offset into multiple buffers\n"
898 "\n"
899 " Example:\n"
900 " 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
901 "\n"
902 " Reads a segment of the currently open file, optionally dumping it to the\n"
903 " standard output stream (with -v option) for subsequent inspection.\n"
904 " Uses multiple iovec buffers if more than one byte range is specified.\n"
905 " -C, -- report statistics in a machine parsable format\n"
906 " -P, -- use a pattern to verify read data\n"
907 " -v, -- dump buffer to standard output\n"
908 " -q, -- quiet mode, do not show I/O statistics\n"
909 "\n");
910 }
911 
912 static int readv_f(BlockBackend *blk, int argc, char **argv);
913 
914 static const cmdinfo_t readv_cmd = {
915     .name       = "readv",
916     .cfunc      = readv_f,
917     .argmin     = 2,
918     .argmax     = -1,
919     .args       = "[-Cqv] [-P pattern] off len [len..]",
920     .oneline    = "reads a number of bytes at a specified offset",
921     .help       = readv_help,
922 };
923 
924 static int readv_f(BlockBackend *blk, int argc, char **argv)
925 {
926     struct timespec t1, t2;
927     bool Cflag = false, qflag = false, vflag = false;
928     int c, cnt, ret;
929     char *buf;
930     int64_t offset;
931     /* Some compilers get confused and warn if this is not initialized.  */
932     int total = 0;
933     int nr_iov;
934     QEMUIOVector qiov;
935     int pattern = 0;
936     bool Pflag = false;
937 
938     while ((c = getopt(argc, argv, "CP:qv")) != -1) {
939         switch (c) {
940         case 'C':
941             Cflag = true;
942             break;
943         case 'P':
944             Pflag = true;
945             pattern = parse_pattern(optarg);
946             if (pattern < 0) {
947                 return -EINVAL;
948             }
949             break;
950         case 'q':
951             qflag = true;
952             break;
953         case 'v':
954             vflag = true;
955             break;
956         default:
957             qemuio_command_usage(&readv_cmd);
958             return -EINVAL;
959         }
960     }
961 
962     if (optind > argc - 2) {
963         qemuio_command_usage(&readv_cmd);
964         return -EINVAL;
965     }
966 
967 
968     offset = cvtnum(argv[optind]);
969     if (offset < 0) {
970         print_cvtnum_err(offset, argv[optind]);
971         return offset;
972     }
973     optind++;
974 
975     nr_iov = argc - optind;
976     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
977     if (buf == NULL) {
978         return -EINVAL;
979     }
980 
981     clock_gettime(CLOCK_MONOTONIC, &t1);
982     ret = do_aio_readv(blk, &qiov, offset, &total);
983     clock_gettime(CLOCK_MONOTONIC, &t2);
984 
985     if (ret < 0) {
986         printf("readv failed: %s\n", strerror(-ret));
987         goto out;
988     }
989     cnt = ret;
990 
991     ret = 0;
992 
993     if (Pflag) {
994         void *cmp_buf = g_malloc(qiov.size);
995         memset(cmp_buf, pattern, qiov.size);
996         if (memcmp(buf, cmp_buf, qiov.size)) {
997             printf("Pattern verification failed at offset %"
998                    PRId64 ", %zu bytes\n", offset, qiov.size);
999             ret = -EINVAL;
1000         }
1001         g_free(cmp_buf);
1002     }
1003 
1004     if (qflag) {
1005         goto out;
1006     }
1007 
1008     if (vflag) {
1009         dump_buffer(buf, offset, qiov.size);
1010     }
1011 
1012     /* Finally, report back -- -C gives a parsable format */
1013     t2 = tsub(t2, t1);
1014     print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
1015 
1016 out:
1017     qemu_iovec_destroy(&qiov);
1018     qemu_io_free(buf);
1019     return ret;
1020 }
1021 
1022 static void write_help(void)
1023 {
1024     printf(
1025 "\n"
1026 " writes a range of bytes from the given offset\n"
1027 "\n"
1028 " Example:\n"
1029 " 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
1030 "\n"
1031 " Writes into a segment of the currently open file, using a buffer\n"
1032 " filled with a set pattern (0xcdcdcdcd).\n"
1033 " -b, -- write to the VM state rather than the virtual disk\n"
1034 " -c, -- write compressed data with blk_write_compressed\n"
1035 " -f, -- use Force Unit Access semantics\n"
1036 " -n, -- with -z, don't allow slow fallback\n"
1037 " -p, -- ignored for backwards compatibility\n"
1038 " -P, -- use different pattern to fill file\n"
1039 " -s, -- use a pattern file to fill the write buffer\n"
1040 " -C, -- report statistics in a machine parsable format\n"
1041 " -q, -- quiet mode, do not show I/O statistics\n"
1042 " -u, -- with -z, allow unmapping\n"
1043 " -z, -- write zeroes using blk_co_pwrite_zeroes\n"
1044 "\n");
1045 }
1046 
1047 static int write_f(BlockBackend *blk, int argc, char **argv);
1048 
1049 static const cmdinfo_t write_cmd = {
1050     .name       = "write",
1051     .altname    = "w",
1052     .cfunc      = write_f,
1053     .perm       = BLK_PERM_WRITE,
1054     .argmin     = 2,
1055     .argmax     = -1,
1056     .args       = "[-bcCfnquz] [-P pattern | -s source_file] off len",
1057     .oneline    = "writes a number of bytes at a specified offset",
1058     .help       = write_help,
1059 };
1060 
1061 static int write_f(BlockBackend *blk, int argc, char **argv)
1062 {
1063     struct timespec t1, t2;
1064     bool Cflag = false, qflag = false, bflag = false;
1065     bool Pflag = false, zflag = false, cflag = false, sflag = false;
1066     int flags = 0;
1067     int c, cnt, ret;
1068     char *buf = NULL;
1069     int64_t offset;
1070     int64_t count;
1071     /* Some compilers get confused and warn if this is not initialized.  */
1072     int64_t total = 0;
1073     int pattern = 0xcd;
1074     const char *file_name = NULL;
1075 
1076     while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
1077         switch (c) {
1078         case 'b':
1079             bflag = true;
1080             break;
1081         case 'c':
1082             cflag = true;
1083             break;
1084         case 'C':
1085             Cflag = true;
1086             break;
1087         case 'f':
1088             flags |= BDRV_REQ_FUA;
1089             break;
1090         case 'n':
1091             flags |= BDRV_REQ_NO_FALLBACK;
1092             break;
1093         case 'p':
1094             /* Ignored for backwards compatibility */
1095             break;
1096         case 'P':
1097             Pflag = true;
1098             pattern = parse_pattern(optarg);
1099             if (pattern < 0) {
1100                 return -EINVAL;
1101             }
1102             break;
1103         case 'q':
1104             qflag = true;
1105             break;
1106         case 's':
1107             sflag = true;
1108             file_name = optarg;
1109             break;
1110         case 'u':
1111             flags |= BDRV_REQ_MAY_UNMAP;
1112             break;
1113         case 'z':
1114             zflag = true;
1115             break;
1116         default:
1117             qemuio_command_usage(&write_cmd);
1118             return -EINVAL;
1119         }
1120     }
1121 
1122     if (optind != argc - 2) {
1123         qemuio_command_usage(&write_cmd);
1124         return -EINVAL;
1125     }
1126 
1127     if (bflag && zflag) {
1128         printf("-b and -z cannot be specified at the same time\n");
1129         return -EINVAL;
1130     }
1131 
1132     if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
1133         printf("-f and -b or -c cannot be specified at the same time\n");
1134         return -EINVAL;
1135     }
1136 
1137     if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
1138         printf("-n requires -z to be specified\n");
1139         return -EINVAL;
1140     }
1141 
1142     if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
1143         printf("-u requires -z to be specified\n");
1144         return -EINVAL;
1145     }
1146 
1147     if (zflag + Pflag + sflag > 1) {
1148         printf("Only one of -z, -P, and -s "
1149                "can be specified at the same time\n");
1150         return -EINVAL;
1151     }
1152 
1153     offset = cvtnum(argv[optind]);
1154     if (offset < 0) {
1155         print_cvtnum_err(offset, argv[optind]);
1156         return offset;
1157     }
1158 
1159     optind++;
1160     count = cvtnum(argv[optind]);
1161     if (count < 0) {
1162         print_cvtnum_err(count, argv[optind]);
1163         return count;
1164     } else if (count > BDRV_REQUEST_MAX_BYTES) {
1165         printf("length cannot exceed %" PRIu64 ", given %s\n",
1166                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1167         return -EINVAL;
1168     }
1169 
1170     if (bflag || cflag) {
1171         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
1172             printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
1173                    offset);
1174             return -EINVAL;
1175         }
1176 
1177         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
1178             printf("%"PRId64" is not a sector-aligned value for 'count'\n",
1179                    count);
1180             return -EINVAL;
1181         }
1182     }
1183 
1184     if (!zflag) {
1185         if (sflag) {
1186             buf = qemu_io_alloc_from_file(blk, count, file_name);
1187             if (!buf) {
1188                 return -EINVAL;
1189             }
1190         } else {
1191             buf = qemu_io_alloc(blk, count, pattern);
1192         }
1193     }
1194 
1195     clock_gettime(CLOCK_MONOTONIC, &t1);
1196     if (bflag) {
1197         ret = do_save_vmstate(blk, buf, offset, count, &total);
1198     } else if (zflag) {
1199         ret = do_co_pwrite_zeroes(blk, offset, count, flags, &total);
1200     } else if (cflag) {
1201         ret = do_write_compressed(blk, buf, offset, count, &total);
1202     } else {
1203         ret = do_pwrite(blk, buf, offset, count, flags, &total);
1204     }
1205     clock_gettime(CLOCK_MONOTONIC, &t2);
1206 
1207     if (ret < 0) {
1208         printf("write failed: %s\n", strerror(-ret));
1209         goto out;
1210     }
1211     cnt = ret;
1212 
1213     ret = 0;
1214 
1215     if (qflag) {
1216         goto out;
1217     }
1218 
1219     /* Finally, report back -- -C gives a parsable format */
1220     t2 = tsub(t2, t1);
1221     print_report("wrote", &t2, offset, count, total, cnt, Cflag);
1222 
1223 out:
1224     if (!zflag) {
1225         qemu_io_free(buf);
1226     }
1227     return ret;
1228 }
1229 
1230 static void
1231 writev_help(void)
1232 {
1233     printf(
1234 "\n"
1235 " writes a range of bytes from the given offset source from multiple buffers\n"
1236 "\n"
1237 " Example:\n"
1238 " 'writev 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1239 "\n"
1240 " Writes into a segment of the currently open file, using a buffer\n"
1241 " filled with a set pattern (0xcdcdcdcd).\n"
1242 " -P, -- use different pattern to fill file\n"
1243 " -C, -- report statistics in a machine parsable format\n"
1244 " -f, -- use Force Unit Access semantics\n"
1245 " -q, -- quiet mode, do not show I/O statistics\n"
1246 "\n");
1247 }
1248 
1249 static int writev_f(BlockBackend *blk, int argc, char **argv);
1250 
1251 static const cmdinfo_t writev_cmd = {
1252     .name       = "writev",
1253     .cfunc      = writev_f,
1254     .perm       = BLK_PERM_WRITE,
1255     .argmin     = 2,
1256     .argmax     = -1,
1257     .args       = "[-Cfq] [-P pattern] off len [len..]",
1258     .oneline    = "writes a number of bytes at a specified offset",
1259     .help       = writev_help,
1260 };
1261 
1262 static int writev_f(BlockBackend *blk, int argc, char **argv)
1263 {
1264     struct timespec t1, t2;
1265     bool Cflag = false, qflag = false;
1266     int flags = 0;
1267     int c, cnt, ret;
1268     char *buf;
1269     int64_t offset;
1270     /* Some compilers get confused and warn if this is not initialized.  */
1271     int total = 0;
1272     int nr_iov;
1273     int pattern = 0xcd;
1274     QEMUIOVector qiov;
1275 
1276     while ((c = getopt(argc, argv, "CfqP:")) != -1) {
1277         switch (c) {
1278         case 'C':
1279             Cflag = true;
1280             break;
1281         case 'f':
1282             flags |= BDRV_REQ_FUA;
1283             break;
1284         case 'q':
1285             qflag = true;
1286             break;
1287         case 'P':
1288             pattern = parse_pattern(optarg);
1289             if (pattern < 0) {
1290                 return -EINVAL;
1291             }
1292             break;
1293         default:
1294             qemuio_command_usage(&writev_cmd);
1295             return -EINVAL;
1296         }
1297     }
1298 
1299     if (optind > argc - 2) {
1300         qemuio_command_usage(&writev_cmd);
1301         return -EINVAL;
1302     }
1303 
1304     offset = cvtnum(argv[optind]);
1305     if (offset < 0) {
1306         print_cvtnum_err(offset, argv[optind]);
1307         return offset;
1308     }
1309     optind++;
1310 
1311     nr_iov = argc - optind;
1312     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
1313     if (buf == NULL) {
1314         return -EINVAL;
1315     }
1316 
1317     clock_gettime(CLOCK_MONOTONIC, &t1);
1318     ret = do_aio_writev(blk, &qiov, offset, flags, &total);
1319     clock_gettime(CLOCK_MONOTONIC, &t2);
1320 
1321     if (ret < 0) {
1322         printf("writev failed: %s\n", strerror(-ret));
1323         goto out;
1324     }
1325     cnt = ret;
1326 
1327     ret = 0;
1328 
1329     if (qflag) {
1330         goto out;
1331     }
1332 
1333     /* Finally, report back -- -C gives a parsable format */
1334     t2 = tsub(t2, t1);
1335     print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
1336 out:
1337     qemu_iovec_destroy(&qiov);
1338     qemu_io_free(buf);
1339     return ret;
1340 }
1341 
1342 struct aio_ctx {
1343     BlockBackend *blk;
1344     QEMUIOVector qiov;
1345     int64_t offset;
1346     char *buf;
1347     bool qflag;
1348     bool vflag;
1349     bool Cflag;
1350     bool Pflag;
1351     bool zflag;
1352     BlockAcctCookie acct;
1353     int pattern;
1354     struct timespec t1;
1355 };
1356 
1357 static void aio_write_done(void *opaque, int ret)
1358 {
1359     struct aio_ctx *ctx = opaque;
1360     struct timespec t2;
1361 
1362     clock_gettime(CLOCK_MONOTONIC, &t2);
1363 
1364 
1365     if (ret < 0) {
1366         printf("aio_write failed: %s\n", strerror(-ret));
1367         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1368         goto out;
1369     }
1370 
1371     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1372 
1373     if (ctx->qflag) {
1374         goto out;
1375     }
1376 
1377     /* Finally, report back -- -C gives a parsable format */
1378     t2 = tsub(t2, ctx->t1);
1379     print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
1380                  ctx->qiov.size, 1, ctx->Cflag);
1381 out:
1382     if (!ctx->zflag) {
1383         qemu_io_free(ctx->buf);
1384         qemu_iovec_destroy(&ctx->qiov);
1385     }
1386     g_free(ctx);
1387 }
1388 
1389 static void aio_read_done(void *opaque, int ret)
1390 {
1391     struct aio_ctx *ctx = opaque;
1392     struct timespec t2;
1393 
1394     clock_gettime(CLOCK_MONOTONIC, &t2);
1395 
1396     if (ret < 0) {
1397         printf("readv failed: %s\n", strerror(-ret));
1398         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1399         goto out;
1400     }
1401 
1402     if (ctx->Pflag) {
1403         void *cmp_buf = g_malloc(ctx->qiov.size);
1404 
1405         memset(cmp_buf, ctx->pattern, ctx->qiov.size);
1406         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
1407             printf("Pattern verification failed at offset %"
1408                    PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
1409         }
1410         g_free(cmp_buf);
1411     }
1412 
1413     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1414 
1415     if (ctx->qflag) {
1416         goto out;
1417     }
1418 
1419     if (ctx->vflag) {
1420         dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
1421     }
1422 
1423     /* Finally, report back -- -C gives a parsable format */
1424     t2 = tsub(t2, ctx->t1);
1425     print_report("read", &t2, ctx->offset, ctx->qiov.size,
1426                  ctx->qiov.size, 1, ctx->Cflag);
1427 out:
1428     qemu_io_free(ctx->buf);
1429     qemu_iovec_destroy(&ctx->qiov);
1430     g_free(ctx);
1431 }
1432 
1433 static void aio_read_help(void)
1434 {
1435     printf(
1436 "\n"
1437 " asynchronously reads a range of bytes from the given offset\n"
1438 "\n"
1439 " Example:\n"
1440 " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
1441 "\n"
1442 " Reads a segment of the currently open file, optionally dumping it to the\n"
1443 " standard output stream (with -v option) for subsequent inspection.\n"
1444 " The read is performed asynchronously and the aio_flush command must be\n"
1445 " used to ensure all outstanding aio requests have been completed.\n"
1446 " Note that due to its asynchronous nature, this command will be\n"
1447 " considered successful once the request is submitted, independently\n"
1448 " of potential I/O errors or pattern mismatches.\n"
1449 " -C, -- report statistics in a machine parsable format\n"
1450 " -P, -- use a pattern to verify read data\n"
1451 " -i, -- treat request as invalid, for exercising stats\n"
1452 " -v, -- dump buffer to standard output\n"
1453 " -q, -- quiet mode, do not show I/O statistics\n"
1454 "\n");
1455 }
1456 
1457 static int aio_read_f(BlockBackend *blk, int argc, char **argv);
1458 
1459 static const cmdinfo_t aio_read_cmd = {
1460     .name       = "aio_read",
1461     .cfunc      = aio_read_f,
1462     .argmin     = 2,
1463     .argmax     = -1,
1464     .args       = "[-Ciqv] [-P pattern] off len [len..]",
1465     .oneline    = "asynchronously reads a number of bytes",
1466     .help       = aio_read_help,
1467 };
1468 
1469 static int aio_read_f(BlockBackend *blk, int argc, char **argv)
1470 {
1471     int nr_iov, c;
1472     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1473 
1474     ctx->blk = blk;
1475     while ((c = getopt(argc, argv, "CP:iqv")) != -1) {
1476         switch (c) {
1477         case 'C':
1478             ctx->Cflag = true;
1479             break;
1480         case 'P':
1481             ctx->Pflag = true;
1482             ctx->pattern = parse_pattern(optarg);
1483             if (ctx->pattern < 0) {
1484                 g_free(ctx);
1485                 return -EINVAL;
1486             }
1487             break;
1488         case 'i':
1489             printf("injecting invalid read request\n");
1490             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1491             g_free(ctx);
1492             return 0;
1493         case 'q':
1494             ctx->qflag = true;
1495             break;
1496         case 'v':
1497             ctx->vflag = true;
1498             break;
1499         default:
1500             g_free(ctx);
1501             qemuio_command_usage(&aio_read_cmd);
1502             return -EINVAL;
1503         }
1504     }
1505 
1506     if (optind > argc - 2) {
1507         g_free(ctx);
1508         qemuio_command_usage(&aio_read_cmd);
1509         return -EINVAL;
1510     }
1511 
1512     ctx->offset = cvtnum(argv[optind]);
1513     if (ctx->offset < 0) {
1514         int ret = ctx->offset;
1515         print_cvtnum_err(ret, argv[optind]);
1516         g_free(ctx);
1517         return ret;
1518     }
1519     optind++;
1520 
1521     nr_iov = argc - optind;
1522     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
1523     if (ctx->buf == NULL) {
1524         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1525         g_free(ctx);
1526         return -EINVAL;
1527     }
1528 
1529     clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
1530     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1531                      BLOCK_ACCT_READ);
1532     blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
1533     return 0;
1534 }
1535 
1536 static void aio_write_help(void)
1537 {
1538     printf(
1539 "\n"
1540 " asynchronously writes a range of bytes from the given offset source\n"
1541 " from multiple buffers\n"
1542 "\n"
1543 " Example:\n"
1544 " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1545 "\n"
1546 " Writes into a segment of the currently open file, using a buffer\n"
1547 " filled with a set pattern (0xcdcdcdcd).\n"
1548 " The write is performed asynchronously and the aio_flush command must be\n"
1549 " used to ensure all outstanding aio requests have been completed.\n"
1550 " Note that due to its asynchronous nature, this command will be\n"
1551 " considered successful once the request is submitted, independently\n"
1552 " of potential I/O errors or pattern mismatches.\n"
1553 " -P, -- use different pattern to fill file\n"
1554 " -C, -- report statistics in a machine parsable format\n"
1555 " -f, -- use Force Unit Access semantics\n"
1556 " -i, -- treat request as invalid, for exercising stats\n"
1557 " -q, -- quiet mode, do not show I/O statistics\n"
1558 " -u, -- with -z, allow unmapping\n"
1559 " -z, -- write zeroes using blk_aio_pwrite_zeroes\n"
1560 "\n");
1561 }
1562 
1563 static int aio_write_f(BlockBackend *blk, int argc, char **argv);
1564 
1565 static const cmdinfo_t aio_write_cmd = {
1566     .name       = "aio_write",
1567     .cfunc      = aio_write_f,
1568     .perm       = BLK_PERM_WRITE,
1569     .argmin     = 2,
1570     .argmax     = -1,
1571     .args       = "[-Cfiquz] [-P pattern] off len [len..]",
1572     .oneline    = "asynchronously writes a number of bytes",
1573     .help       = aio_write_help,
1574 };
1575 
1576 static int aio_write_f(BlockBackend *blk, int argc, char **argv)
1577 {
1578     int nr_iov, c;
1579     int pattern = 0xcd;
1580     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1581     int flags = 0;
1582 
1583     ctx->blk = blk;
1584     while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
1585         switch (c) {
1586         case 'C':
1587             ctx->Cflag = true;
1588             break;
1589         case 'f':
1590             flags |= BDRV_REQ_FUA;
1591             break;
1592         case 'q':
1593             ctx->qflag = true;
1594             break;
1595         case 'u':
1596             flags |= BDRV_REQ_MAY_UNMAP;
1597             break;
1598         case 'P':
1599             pattern = parse_pattern(optarg);
1600             if (pattern < 0) {
1601                 g_free(ctx);
1602                 return -EINVAL;
1603             }
1604             break;
1605         case 'i':
1606             printf("injecting invalid write request\n");
1607             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1608             g_free(ctx);
1609             return 0;
1610         case 'z':
1611             ctx->zflag = true;
1612             break;
1613         default:
1614             g_free(ctx);
1615             qemuio_command_usage(&aio_write_cmd);
1616             return -EINVAL;
1617         }
1618     }
1619 
1620     if (optind > argc - 2) {
1621         g_free(ctx);
1622         qemuio_command_usage(&aio_write_cmd);
1623         return -EINVAL;
1624     }
1625 
1626     if (ctx->zflag && optind != argc - 2) {
1627         printf("-z supports only a single length parameter\n");
1628         g_free(ctx);
1629         return -EINVAL;
1630     }
1631 
1632     if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
1633         printf("-u requires -z to be specified\n");
1634         g_free(ctx);
1635         return -EINVAL;
1636     }
1637 
1638     if (ctx->zflag && ctx->Pflag) {
1639         printf("-z and -P cannot be specified at the same time\n");
1640         g_free(ctx);
1641         return -EINVAL;
1642     }
1643 
1644     ctx->offset = cvtnum(argv[optind]);
1645     if (ctx->offset < 0) {
1646         int ret = ctx->offset;
1647         print_cvtnum_err(ret, argv[optind]);
1648         g_free(ctx);
1649         return ret;
1650     }
1651     optind++;
1652 
1653     if (ctx->zflag) {
1654         int64_t count = cvtnum(argv[optind]);
1655         if (count < 0) {
1656             print_cvtnum_err(count, argv[optind]);
1657             g_free(ctx);
1658             return count;
1659         }
1660 
1661         ctx->qiov.size = count;
1662         blk_aio_pwrite_zeroes(blk, ctx->offset, count, flags, aio_write_done,
1663                               ctx);
1664     } else {
1665         nr_iov = argc - optind;
1666         ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
1667                                 pattern);
1668         if (ctx->buf == NULL) {
1669             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1670             g_free(ctx);
1671             return -EINVAL;
1672         }
1673 
1674         clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
1675         block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1676                          BLOCK_ACCT_WRITE);
1677 
1678         blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done,
1679                         ctx);
1680     }
1681 
1682     return 0;
1683 }
1684 
1685 static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
1686 {
1687     BlockAcctCookie cookie;
1688     block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
1689     blk_drain_all();
1690     block_acct_done(blk_get_stats(blk), &cookie);
1691     return 0;
1692 }
1693 
1694 static const cmdinfo_t aio_flush_cmd = {
1695     .name       = "aio_flush",
1696     .cfunc      = aio_flush_f,
1697     .oneline    = "completes all outstanding aio requests"
1698 };
1699 
1700 static int flush_f(BlockBackend *blk, int argc, char **argv)
1701 {
1702     return blk_flush(blk);
1703 }
1704 
1705 static const cmdinfo_t flush_cmd = {
1706     .name       = "flush",
1707     .altname    = "f",
1708     .cfunc      = flush_f,
1709     .oneline    = "flush all in-core file state to disk",
1710 };
1711 
1712 static int truncate_f(BlockBackend *blk, int argc, char **argv);
1713 static const cmdinfo_t truncate_cmd = {
1714     .name       = "truncate",
1715     .altname    = "t",
1716     .cfunc      = truncate_f,
1717     .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
1718     .argmin     = 1,
1719     .argmax     = 3,
1720     .args       = "[-m prealloc_mode] off",
1721     .oneline    = "truncates the current file at the given offset",
1722 };
1723 
1724 static int truncate_f(BlockBackend *blk, int argc, char **argv)
1725 {
1726     Error *local_err = NULL;
1727     int64_t offset;
1728     int c, ret;
1729     PreallocMode prealloc = PREALLOC_MODE_OFF;
1730 
1731     while ((c = getopt(argc, argv, "m:")) != -1) {
1732         switch (c) {
1733         case 'm':
1734             prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
1735                                        PREALLOC_MODE__MAX, NULL);
1736             if (prealloc == PREALLOC_MODE__MAX) {
1737                 error_report("Invalid preallocation mode '%s'", optarg);
1738                 return -EINVAL;
1739             }
1740             break;
1741         default:
1742             qemuio_command_usage(&truncate_cmd);
1743             return -EINVAL;
1744         }
1745     }
1746 
1747     offset = cvtnum(argv[optind]);
1748     if (offset < 0) {
1749         print_cvtnum_err(offset, argv[1]);
1750         return offset;
1751     }
1752 
1753     /*
1754      * qemu-io is a debugging tool, so let us be strict here and pass
1755      * exact=true.  It is better to err on the "emit more errors" side
1756      * than to be overly permissive.
1757      */
1758     ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
1759     if (ret < 0) {
1760         error_report_err(local_err);
1761         return ret;
1762     }
1763 
1764     return 0;
1765 }
1766 
1767 static int length_f(BlockBackend *blk, int argc, char **argv)
1768 {
1769     int64_t size;
1770     char s1[64];
1771 
1772     size = blk_getlength(blk);
1773     if (size < 0) {
1774         printf("getlength: %s\n", strerror(-size));
1775         return size;
1776     }
1777 
1778     cvtstr(size, s1, sizeof(s1));
1779     printf("%s\n", s1);
1780     return 0;
1781 }
1782 
1783 
1784 static const cmdinfo_t length_cmd = {
1785     .name   = "length",
1786     .altname    = "l",
1787     .cfunc      = length_f,
1788     .oneline    = "gets the length of the current file",
1789 };
1790 
1791 
1792 static int info_f(BlockBackend *blk, int argc, char **argv)
1793 {
1794     BlockDriverState *bs = blk_bs(blk);
1795     BlockDriverInfo bdi;
1796     ImageInfoSpecific *spec_info;
1797     Error *local_err = NULL;
1798     char s1[64], s2[64];
1799     int ret;
1800 
1801     if (bs->drv && bs->drv->format_name) {
1802         printf("format name: %s\n", bs->drv->format_name);
1803     }
1804     if (bs->drv && bs->drv->protocol_name) {
1805         printf("format name: %s\n", bs->drv->protocol_name);
1806     }
1807 
1808     ret = bdrv_get_info(bs, &bdi);
1809     if (ret) {
1810         return ret;
1811     }
1812 
1813     cvtstr(bdi.cluster_size, s1, sizeof(s1));
1814     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1815 
1816     printf("cluster size: %s\n", s1);
1817     printf("vm state offset: %s\n", s2);
1818 
1819     spec_info = bdrv_get_specific_info(bs, &local_err);
1820     if (local_err) {
1821         error_report_err(local_err);
1822         return -EIO;
1823     }
1824     if (spec_info) {
1825         printf("Format specific information:\n");
1826         bdrv_image_info_specific_dump(spec_info);
1827         qapi_free_ImageInfoSpecific(spec_info);
1828     }
1829 
1830     return 0;
1831 }
1832 
1833 
1834 
1835 static const cmdinfo_t info_cmd = {
1836     .name       = "info",
1837     .altname    = "i",
1838     .cfunc      = info_f,
1839     .oneline    = "prints information about the current file",
1840 };
1841 
1842 static void discard_help(void)
1843 {
1844     printf(
1845 "\n"
1846 " discards a range of bytes from the given offset\n"
1847 "\n"
1848 " Example:\n"
1849 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1850 "\n"
1851 " Discards a segment of the currently open file.\n"
1852 " -C, -- report statistics in a machine parsable format\n"
1853 " -q, -- quiet mode, do not show I/O statistics\n"
1854 "\n");
1855 }
1856 
1857 static int discard_f(BlockBackend *blk, int argc, char **argv);
1858 
1859 static const cmdinfo_t discard_cmd = {
1860     .name       = "discard",
1861     .altname    = "d",
1862     .cfunc      = discard_f,
1863     .perm       = BLK_PERM_WRITE,
1864     .argmin     = 2,
1865     .argmax     = -1,
1866     .args       = "[-Cq] off len",
1867     .oneline    = "discards a number of bytes at a specified offset",
1868     .help       = discard_help,
1869 };
1870 
1871 static int discard_f(BlockBackend *blk, int argc, char **argv)
1872 {
1873     struct timespec t1, t2;
1874     bool Cflag = false, qflag = false;
1875     int c, ret;
1876     int64_t offset, bytes;
1877 
1878     while ((c = getopt(argc, argv, "Cq")) != -1) {
1879         switch (c) {
1880         case 'C':
1881             Cflag = true;
1882             break;
1883         case 'q':
1884             qflag = true;
1885             break;
1886         default:
1887             qemuio_command_usage(&discard_cmd);
1888             return -EINVAL;
1889         }
1890     }
1891 
1892     if (optind != argc - 2) {
1893         qemuio_command_usage(&discard_cmd);
1894         return -EINVAL;
1895     }
1896 
1897     offset = cvtnum(argv[optind]);
1898     if (offset < 0) {
1899         print_cvtnum_err(offset, argv[optind]);
1900         return offset;
1901     }
1902 
1903     optind++;
1904     bytes = cvtnum(argv[optind]);
1905     if (bytes < 0) {
1906         print_cvtnum_err(bytes, argv[optind]);
1907         return bytes;
1908     } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
1909         printf("length cannot exceed %"PRIu64", given %s\n",
1910                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1911         return -EINVAL;
1912     }
1913 
1914     clock_gettime(CLOCK_MONOTONIC, &t1);
1915     ret = blk_pdiscard(blk, offset, bytes);
1916     clock_gettime(CLOCK_MONOTONIC, &t2);
1917 
1918     if (ret < 0) {
1919         printf("discard failed: %s\n", strerror(-ret));
1920         return ret;
1921     }
1922 
1923     /* Finally, report back -- -C gives a parsable format */
1924     if (!qflag) {
1925         t2 = tsub(t2, t1);
1926         print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
1927     }
1928 
1929     return 0;
1930 }
1931 
1932 static int alloc_f(BlockBackend *blk, int argc, char **argv)
1933 {
1934     BlockDriverState *bs = blk_bs(blk);
1935     int64_t offset, start, remaining, count;
1936     char s1[64];
1937     int ret;
1938     int64_t num, sum_alloc;
1939 
1940     start = offset = cvtnum(argv[1]);
1941     if (offset < 0) {
1942         print_cvtnum_err(offset, argv[1]);
1943         return offset;
1944     }
1945 
1946     if (argc == 3) {
1947         count = cvtnum(argv[2]);
1948         if (count < 0) {
1949             print_cvtnum_err(count, argv[2]);
1950             return count;
1951         }
1952     } else {
1953         count = BDRV_SECTOR_SIZE;
1954     }
1955 
1956     remaining = count;
1957     sum_alloc = 0;
1958     while (remaining) {
1959         ret = bdrv_is_allocated(bs, offset, remaining, &num);
1960         if (ret < 0) {
1961             printf("is_allocated failed: %s\n", strerror(-ret));
1962             return ret;
1963         }
1964         offset += num;
1965         remaining -= num;
1966         if (ret) {
1967             sum_alloc += num;
1968         }
1969         if (num == 0) {
1970             count -= remaining;
1971             remaining = 0;
1972         }
1973     }
1974 
1975     cvtstr(start, s1, sizeof(s1));
1976 
1977     printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
1978            sum_alloc, count, s1);
1979     return 0;
1980 }
1981 
1982 static const cmdinfo_t alloc_cmd = {
1983     .name       = "alloc",
1984     .altname    = "a",
1985     .argmin     = 1,
1986     .argmax     = 2,
1987     .cfunc      = alloc_f,
1988     .args       = "offset [count]",
1989     .oneline    = "checks if offset is allocated in the file",
1990 };
1991 
1992 
1993 static int map_is_allocated(BlockDriverState *bs, int64_t offset,
1994                             int64_t bytes, int64_t *pnum)
1995 {
1996     int64_t num;
1997     int num_checked;
1998     int ret, firstret;
1999 
2000     num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
2001     ret = bdrv_is_allocated(bs, offset, num_checked, &num);
2002     if (ret < 0) {
2003         return ret;
2004     }
2005 
2006     firstret = ret;
2007     *pnum = num;
2008 
2009     while (bytes > 0 && ret == firstret) {
2010         offset += num;
2011         bytes -= num;
2012 
2013         num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
2014         ret = bdrv_is_allocated(bs, offset, num_checked, &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