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