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