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