xref: /openbmc/qemu/qemu-io-cmds.c (revision 073d9f2c)
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     optind = 0;
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 " -p, -- ignored for backwards compatibility\n"
950 " -P, -- use different pattern to fill file\n"
951 " -C, -- report statistics in a machine parsable format\n"
952 " -q, -- quiet mode, do not show I/O statistics\n"
953 " -u, -- with -z, allow unmapping\n"
954 " -z, -- write zeroes using blk_co_pwrite_zeroes\n"
955 "\n");
956 }
957 
958 static int write_f(BlockBackend *blk, int argc, char **argv);
959 
960 static const cmdinfo_t write_cmd = {
961     .name       = "write",
962     .altname    = "w",
963     .cfunc      = write_f,
964     .perm       = BLK_PERM_WRITE,
965     .argmin     = 2,
966     .argmax     = -1,
967     .args       = "[-bcCfquz] [-P pattern] off len",
968     .oneline    = "writes a number of bytes at a specified offset",
969     .help       = write_help,
970 };
971 
972 static int write_f(BlockBackend *blk, int argc, char **argv)
973 {
974     struct timeval t1, t2;
975     bool Cflag = false, qflag = false, bflag = false;
976     bool Pflag = false, zflag = false, cflag = false;
977     int flags = 0;
978     int c, cnt, ret;
979     char *buf = NULL;
980     int64_t offset;
981     int64_t count;
982     /* Some compilers get confused and warn if this is not initialized.  */
983     int64_t total = 0;
984     int pattern = 0xcd;
985 
986     while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) {
987         switch (c) {
988         case 'b':
989             bflag = true;
990             break;
991         case 'c':
992             cflag = true;
993             break;
994         case 'C':
995             Cflag = true;
996             break;
997         case 'f':
998             flags |= BDRV_REQ_FUA;
999             break;
1000         case 'p':
1001             /* Ignored for backwards compatibility */
1002             break;
1003         case 'P':
1004             Pflag = true;
1005             pattern = parse_pattern(optarg);
1006             if (pattern < 0) {
1007                 return -EINVAL;
1008             }
1009             break;
1010         case 'q':
1011             qflag = true;
1012             break;
1013         case 'u':
1014             flags |= BDRV_REQ_MAY_UNMAP;
1015             break;
1016         case 'z':
1017             zflag = true;
1018             break;
1019         default:
1020             qemuio_command_usage(&write_cmd);
1021             return -EINVAL;
1022         }
1023     }
1024 
1025     if (optind != argc - 2) {
1026         qemuio_command_usage(&write_cmd);
1027         return -EINVAL;
1028     }
1029 
1030     if (bflag && zflag) {
1031         printf("-b and -z cannot be specified at the same time\n");
1032         return -EINVAL;
1033     }
1034 
1035     if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
1036         printf("-f and -b or -c cannot be specified at the same time\n");
1037         return -EINVAL;
1038     }
1039 
1040     if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
1041         printf("-u requires -z to be specified\n");
1042         return -EINVAL;
1043     }
1044 
1045     if (zflag && Pflag) {
1046         printf("-z and -P cannot be specified at the same time\n");
1047         return -EINVAL;
1048     }
1049 
1050     offset = cvtnum(argv[optind]);
1051     if (offset < 0) {
1052         print_cvtnum_err(offset, argv[optind]);
1053         return offset;
1054     }
1055 
1056     optind++;
1057     count = cvtnum(argv[optind]);
1058     if (count < 0) {
1059         print_cvtnum_err(count, argv[optind]);
1060         return count;
1061     } else if (count > BDRV_REQUEST_MAX_BYTES) {
1062         printf("length cannot exceed %" PRIu64 ", given %s\n",
1063                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1064         return -EINVAL;
1065     }
1066 
1067     if (bflag || cflag) {
1068         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
1069             printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
1070                    offset);
1071             return -EINVAL;
1072         }
1073 
1074         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
1075             printf("%"PRId64" is not a sector-aligned value for 'count'\n",
1076                    count);
1077             return -EINVAL;
1078         }
1079     }
1080 
1081     if (!zflag) {
1082         buf = qemu_io_alloc(blk, count, pattern);
1083     }
1084 
1085     gettimeofday(&t1, NULL);
1086     if (bflag) {
1087         ret = do_save_vmstate(blk, buf, offset, count, &total);
1088     } else if (zflag) {
1089         ret = do_co_pwrite_zeroes(blk, offset, count, flags, &total);
1090     } else if (cflag) {
1091         ret = do_write_compressed(blk, buf, offset, count, &total);
1092     } else {
1093         ret = do_pwrite(blk, buf, offset, count, flags, &total);
1094     }
1095     gettimeofday(&t2, NULL);
1096 
1097     if (ret < 0) {
1098         printf("write failed: %s\n", strerror(-ret));
1099         goto out;
1100     }
1101     cnt = ret;
1102 
1103     ret = 0;
1104 
1105     if (qflag) {
1106         goto out;
1107     }
1108 
1109     /* Finally, report back -- -C gives a parsable format */
1110     t2 = tsub(t2, t1);
1111     print_report("wrote", &t2, offset, count, total, cnt, Cflag);
1112 
1113 out:
1114     if (!zflag) {
1115         qemu_io_free(buf);
1116     }
1117     return ret;
1118 }
1119 
1120 static void
1121 writev_help(void)
1122 {
1123     printf(
1124 "\n"
1125 " writes a range of bytes from the given offset source from multiple buffers\n"
1126 "\n"
1127 " Example:\n"
1128 " 'writev 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1129 "\n"
1130 " Writes into a segment of the currently open file, using a buffer\n"
1131 " filled with a set pattern (0xcdcdcdcd).\n"
1132 " -P, -- use different pattern to fill file\n"
1133 " -C, -- report statistics in a machine parsable format\n"
1134 " -f, -- use Force Unit Access semantics\n"
1135 " -q, -- quiet mode, do not show I/O statistics\n"
1136 "\n");
1137 }
1138 
1139 static int writev_f(BlockBackend *blk, int argc, char **argv);
1140 
1141 static const cmdinfo_t writev_cmd = {
1142     .name       = "writev",
1143     .cfunc      = writev_f,
1144     .perm       = BLK_PERM_WRITE,
1145     .argmin     = 2,
1146     .argmax     = -1,
1147     .args       = "[-Cfq] [-P pattern] off len [len..]",
1148     .oneline    = "writes a number of bytes at a specified offset",
1149     .help       = writev_help,
1150 };
1151 
1152 static int writev_f(BlockBackend *blk, int argc, char **argv)
1153 {
1154     struct timeval t1, t2;
1155     bool Cflag = false, qflag = false;
1156     int flags = 0;
1157     int c, cnt, ret;
1158     char *buf;
1159     int64_t offset;
1160     /* Some compilers get confused and warn if this is not initialized.  */
1161     int total = 0;
1162     int nr_iov;
1163     int pattern = 0xcd;
1164     QEMUIOVector qiov;
1165 
1166     while ((c = getopt(argc, argv, "CfqP:")) != -1) {
1167         switch (c) {
1168         case 'C':
1169             Cflag = true;
1170             break;
1171         case 'f':
1172             flags |= BDRV_REQ_FUA;
1173             break;
1174         case 'q':
1175             qflag = true;
1176             break;
1177         case 'P':
1178             pattern = parse_pattern(optarg);
1179             if (pattern < 0) {
1180                 return -EINVAL;
1181             }
1182             break;
1183         default:
1184             qemuio_command_usage(&writev_cmd);
1185             return -EINVAL;
1186         }
1187     }
1188 
1189     if (optind > argc - 2) {
1190         qemuio_command_usage(&writev_cmd);
1191         return -EINVAL;
1192     }
1193 
1194     offset = cvtnum(argv[optind]);
1195     if (offset < 0) {
1196         print_cvtnum_err(offset, argv[optind]);
1197         return offset;
1198     }
1199     optind++;
1200 
1201     nr_iov = argc - optind;
1202     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
1203     if (buf == NULL) {
1204         return -EINVAL;
1205     }
1206 
1207     gettimeofday(&t1, NULL);
1208     ret = do_aio_writev(blk, &qiov, offset, flags, &total);
1209     gettimeofday(&t2, NULL);
1210 
1211     if (ret < 0) {
1212         printf("writev failed: %s\n", strerror(-ret));
1213         goto out;
1214     }
1215     cnt = ret;
1216 
1217     ret = 0;
1218 
1219     if (qflag) {
1220         goto out;
1221     }
1222 
1223     /* Finally, report back -- -C gives a parsable format */
1224     t2 = tsub(t2, t1);
1225     print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
1226 out:
1227     qemu_iovec_destroy(&qiov);
1228     qemu_io_free(buf);
1229     return ret;
1230 }
1231 
1232 struct aio_ctx {
1233     BlockBackend *blk;
1234     QEMUIOVector qiov;
1235     int64_t offset;
1236     char *buf;
1237     bool qflag;
1238     bool vflag;
1239     bool Cflag;
1240     bool Pflag;
1241     bool zflag;
1242     BlockAcctCookie acct;
1243     int pattern;
1244     struct timeval t1;
1245 };
1246 
1247 static void aio_write_done(void *opaque, int ret)
1248 {
1249     struct aio_ctx *ctx = opaque;
1250     struct timeval t2;
1251 
1252     gettimeofday(&t2, NULL);
1253 
1254 
1255     if (ret < 0) {
1256         printf("aio_write failed: %s\n", strerror(-ret));
1257         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1258         goto out;
1259     }
1260 
1261     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1262 
1263     if (ctx->qflag) {
1264         goto out;
1265     }
1266 
1267     /* Finally, report back -- -C gives a parsable format */
1268     t2 = tsub(t2, ctx->t1);
1269     print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
1270                  ctx->qiov.size, 1, ctx->Cflag);
1271 out:
1272     if (!ctx->zflag) {
1273         qemu_io_free(ctx->buf);
1274         qemu_iovec_destroy(&ctx->qiov);
1275     }
1276     g_free(ctx);
1277 }
1278 
1279 static void aio_read_done(void *opaque, int ret)
1280 {
1281     struct aio_ctx *ctx = opaque;
1282     struct timeval t2;
1283 
1284     gettimeofday(&t2, NULL);
1285 
1286     if (ret < 0) {
1287         printf("readv failed: %s\n", strerror(-ret));
1288         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1289         goto out;
1290     }
1291 
1292     if (ctx->Pflag) {
1293         void *cmp_buf = g_malloc(ctx->qiov.size);
1294 
1295         memset(cmp_buf, ctx->pattern, ctx->qiov.size);
1296         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
1297             printf("Pattern verification failed at offset %"
1298                    PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
1299         }
1300         g_free(cmp_buf);
1301     }
1302 
1303     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1304 
1305     if (ctx->qflag) {
1306         goto out;
1307     }
1308 
1309     if (ctx->vflag) {
1310         dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
1311     }
1312 
1313     /* Finally, report back -- -C gives a parsable format */
1314     t2 = tsub(t2, ctx->t1);
1315     print_report("read", &t2, ctx->offset, ctx->qiov.size,
1316                  ctx->qiov.size, 1, ctx->Cflag);
1317 out:
1318     qemu_io_free(ctx->buf);
1319     qemu_iovec_destroy(&ctx->qiov);
1320     g_free(ctx);
1321 }
1322 
1323 static void aio_read_help(void)
1324 {
1325     printf(
1326 "\n"
1327 " asynchronously reads a range of bytes from the given offset\n"
1328 "\n"
1329 " Example:\n"
1330 " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
1331 "\n"
1332 " Reads a segment of the currently open file, optionally dumping it to the\n"
1333 " standard output stream (with -v option) for subsequent inspection.\n"
1334 " The read is performed asynchronously and the aio_flush command must be\n"
1335 " used to ensure all outstanding aio requests have been completed.\n"
1336 " Note that due to its asynchronous nature, this command will be\n"
1337 " considered successful once the request is submitted, independently\n"
1338 " of potential I/O errors or pattern mismatches.\n"
1339 " -C, -- report statistics in a machine parsable format\n"
1340 " -P, -- use a pattern to verify read data\n"
1341 " -i, -- treat request as invalid, for exercising stats\n"
1342 " -v, -- dump buffer to standard output\n"
1343 " -q, -- quiet mode, do not show I/O statistics\n"
1344 "\n");
1345 }
1346 
1347 static int aio_read_f(BlockBackend *blk, int argc, char **argv);
1348 
1349 static const cmdinfo_t aio_read_cmd = {
1350     .name       = "aio_read",
1351     .cfunc      = aio_read_f,
1352     .argmin     = 2,
1353     .argmax     = -1,
1354     .args       = "[-Ciqv] [-P pattern] off len [len..]",
1355     .oneline    = "asynchronously reads a number of bytes",
1356     .help       = aio_read_help,
1357 };
1358 
1359 static int aio_read_f(BlockBackend *blk, int argc, char **argv)
1360 {
1361     int nr_iov, c;
1362     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1363 
1364     ctx->blk = blk;
1365     while ((c = getopt(argc, argv, "CP:iqv")) != -1) {
1366         switch (c) {
1367         case 'C':
1368             ctx->Cflag = true;
1369             break;
1370         case 'P':
1371             ctx->Pflag = true;
1372             ctx->pattern = parse_pattern(optarg);
1373             if (ctx->pattern < 0) {
1374                 g_free(ctx);
1375                 return -EINVAL;
1376             }
1377             break;
1378         case 'i':
1379             printf("injecting invalid read request\n");
1380             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1381             g_free(ctx);
1382             return 0;
1383         case 'q':
1384             ctx->qflag = true;
1385             break;
1386         case 'v':
1387             ctx->vflag = true;
1388             break;
1389         default:
1390             g_free(ctx);
1391             qemuio_command_usage(&aio_read_cmd);
1392             return -EINVAL;
1393         }
1394     }
1395 
1396     if (optind > argc - 2) {
1397         g_free(ctx);
1398         qemuio_command_usage(&aio_read_cmd);
1399         return -EINVAL;
1400     }
1401 
1402     ctx->offset = cvtnum(argv[optind]);
1403     if (ctx->offset < 0) {
1404         int ret = ctx->offset;
1405         print_cvtnum_err(ret, argv[optind]);
1406         g_free(ctx);
1407         return ret;
1408     }
1409     optind++;
1410 
1411     nr_iov = argc - optind;
1412     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
1413     if (ctx->buf == NULL) {
1414         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1415         g_free(ctx);
1416         return -EINVAL;
1417     }
1418 
1419     gettimeofday(&ctx->t1, NULL);
1420     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1421                      BLOCK_ACCT_READ);
1422     blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
1423     return 0;
1424 }
1425 
1426 static void aio_write_help(void)
1427 {
1428     printf(
1429 "\n"
1430 " asynchronously writes a range of bytes from the given offset source\n"
1431 " from multiple buffers\n"
1432 "\n"
1433 " Example:\n"
1434 " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1435 "\n"
1436 " Writes into a segment of the currently open file, using a buffer\n"
1437 " filled with a set pattern (0xcdcdcdcd).\n"
1438 " The write is performed asynchronously and the aio_flush command must be\n"
1439 " used to ensure all outstanding aio requests have been completed.\n"
1440 " Note that due to its asynchronous nature, this command will be\n"
1441 " considered successful once the request is submitted, independently\n"
1442 " of potential I/O errors or pattern mismatches.\n"
1443 " -P, -- use different pattern to fill file\n"
1444 " -C, -- report statistics in a machine parsable format\n"
1445 " -f, -- use Force Unit Access semantics\n"
1446 " -i, -- treat request as invalid, for exercising stats\n"
1447 " -q, -- quiet mode, do not show I/O statistics\n"
1448 " -u, -- with -z, allow unmapping\n"
1449 " -z, -- write zeroes using blk_aio_pwrite_zeroes\n"
1450 "\n");
1451 }
1452 
1453 static int aio_write_f(BlockBackend *blk, int argc, char **argv);
1454 
1455 static const cmdinfo_t aio_write_cmd = {
1456     .name       = "aio_write",
1457     .cfunc      = aio_write_f,
1458     .perm       = BLK_PERM_WRITE,
1459     .argmin     = 2,
1460     .argmax     = -1,
1461     .args       = "[-Cfiquz] [-P pattern] off len [len..]",
1462     .oneline    = "asynchronously writes a number of bytes",
1463     .help       = aio_write_help,
1464 };
1465 
1466 static int aio_write_f(BlockBackend *blk, int argc, char **argv)
1467 {
1468     int nr_iov, c;
1469     int pattern = 0xcd;
1470     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1471     int flags = 0;
1472 
1473     ctx->blk = blk;
1474     while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
1475         switch (c) {
1476         case 'C':
1477             ctx->Cflag = true;
1478             break;
1479         case 'f':
1480             flags |= BDRV_REQ_FUA;
1481             break;
1482         case 'q':
1483             ctx->qflag = true;
1484             break;
1485         case 'u':
1486             flags |= BDRV_REQ_MAY_UNMAP;
1487             break;
1488         case 'P':
1489             pattern = parse_pattern(optarg);
1490             if (pattern < 0) {
1491                 g_free(ctx);
1492                 return -EINVAL;
1493             }
1494             break;
1495         case 'i':
1496             printf("injecting invalid write request\n");
1497             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1498             g_free(ctx);
1499             return 0;
1500         case 'z':
1501             ctx->zflag = true;
1502             break;
1503         default:
1504             g_free(ctx);
1505             qemuio_command_usage(&aio_write_cmd);
1506             return -EINVAL;
1507         }
1508     }
1509 
1510     if (optind > argc - 2) {
1511         g_free(ctx);
1512         qemuio_command_usage(&aio_write_cmd);
1513         return -EINVAL;
1514     }
1515 
1516     if (ctx->zflag && optind != argc - 2) {
1517         printf("-z supports only a single length parameter\n");
1518         g_free(ctx);
1519         return -EINVAL;
1520     }
1521 
1522     if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
1523         printf("-u requires -z to be specified\n");
1524         g_free(ctx);
1525         return -EINVAL;
1526     }
1527 
1528     if (ctx->zflag && ctx->Pflag) {
1529         printf("-z and -P cannot be specified at the same time\n");
1530         g_free(ctx);
1531         return -EINVAL;
1532     }
1533 
1534     ctx->offset = cvtnum(argv[optind]);
1535     if (ctx->offset < 0) {
1536         int ret = ctx->offset;
1537         print_cvtnum_err(ret, argv[optind]);
1538         g_free(ctx);
1539         return ret;
1540     }
1541     optind++;
1542 
1543     if (ctx->zflag) {
1544         int64_t count = cvtnum(argv[optind]);
1545         if (count < 0) {
1546             print_cvtnum_err(count, argv[optind]);
1547             g_free(ctx);
1548             return count;
1549         }
1550 
1551         ctx->qiov.size = count;
1552         blk_aio_pwrite_zeroes(blk, ctx->offset, count, flags, aio_write_done,
1553                               ctx);
1554     } else {
1555         nr_iov = argc - optind;
1556         ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
1557                                 pattern);
1558         if (ctx->buf == NULL) {
1559             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1560             g_free(ctx);
1561             return -EINVAL;
1562         }
1563 
1564         gettimeofday(&ctx->t1, NULL);
1565         block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1566                          BLOCK_ACCT_WRITE);
1567 
1568         blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done,
1569                         ctx);
1570     }
1571 
1572     return 0;
1573 }
1574 
1575 static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
1576 {
1577     BlockAcctCookie cookie;
1578     block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
1579     blk_drain_all();
1580     block_acct_done(blk_get_stats(blk), &cookie);
1581     return 0;
1582 }
1583 
1584 static const cmdinfo_t aio_flush_cmd = {
1585     .name       = "aio_flush",
1586     .cfunc      = aio_flush_f,
1587     .oneline    = "completes all outstanding aio requests"
1588 };
1589 
1590 static int flush_f(BlockBackend *blk, int argc, char **argv)
1591 {
1592     return blk_flush(blk);
1593 }
1594 
1595 static const cmdinfo_t flush_cmd = {
1596     .name       = "flush",
1597     .altname    = "f",
1598     .cfunc      = flush_f,
1599     .oneline    = "flush all in-core file state to disk",
1600 };
1601 
1602 static int truncate_f(BlockBackend *blk, int argc, char **argv)
1603 {
1604     Error *local_err = NULL;
1605     int64_t offset;
1606     int ret;
1607 
1608     offset = cvtnum(argv[1]);
1609     if (offset < 0) {
1610         print_cvtnum_err(offset, argv[1]);
1611         return offset;
1612     }
1613 
1614     ret = blk_truncate(blk, offset, PREALLOC_MODE_OFF, &local_err);
1615     if (ret < 0) {
1616         error_report_err(local_err);
1617         return ret;
1618     }
1619 
1620     return 0;
1621 }
1622 
1623 static const cmdinfo_t truncate_cmd = {
1624     .name       = "truncate",
1625     .altname    = "t",
1626     .cfunc      = truncate_f,
1627     .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
1628     .argmin     = 1,
1629     .argmax     = 1,
1630     .args       = "off",
1631     .oneline    = "truncates the current file at the given offset",
1632 };
1633 
1634 static int length_f(BlockBackend *blk, int argc, char **argv)
1635 {
1636     int64_t size;
1637     char s1[64];
1638 
1639     size = blk_getlength(blk);
1640     if (size < 0) {
1641         printf("getlength: %s\n", strerror(-size));
1642         return size;
1643     }
1644 
1645     cvtstr(size, s1, sizeof(s1));
1646     printf("%s\n", s1);
1647     return 0;
1648 }
1649 
1650 
1651 static const cmdinfo_t length_cmd = {
1652     .name   = "length",
1653     .altname    = "l",
1654     .cfunc      = length_f,
1655     .oneline    = "gets the length of the current file",
1656 };
1657 
1658 
1659 static int info_f(BlockBackend *blk, int argc, char **argv)
1660 {
1661     BlockDriverState *bs = blk_bs(blk);
1662     BlockDriverInfo bdi;
1663     ImageInfoSpecific *spec_info;
1664     char s1[64], s2[64];
1665     int ret;
1666 
1667     if (bs->drv && bs->drv->format_name) {
1668         printf("format name: %s\n", bs->drv->format_name);
1669     }
1670     if (bs->drv && bs->drv->protocol_name) {
1671         printf("format name: %s\n", bs->drv->protocol_name);
1672     }
1673 
1674     ret = bdrv_get_info(bs, &bdi);
1675     if (ret) {
1676         return ret;
1677     }
1678 
1679     cvtstr(bdi.cluster_size, s1, sizeof(s1));
1680     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1681 
1682     printf("cluster size: %s\n", s1);
1683     printf("vm state offset: %s\n", s2);
1684 
1685     spec_info = bdrv_get_specific_info(bs);
1686     if (spec_info) {
1687         printf("Format specific information:\n");
1688         bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
1689         qapi_free_ImageInfoSpecific(spec_info);
1690     }
1691 
1692     return 0;
1693 }
1694 
1695 
1696 
1697 static const cmdinfo_t info_cmd = {
1698     .name       = "info",
1699     .altname    = "i",
1700     .cfunc      = info_f,
1701     .oneline    = "prints information about the current file",
1702 };
1703 
1704 static void discard_help(void)
1705 {
1706     printf(
1707 "\n"
1708 " discards a range of bytes from the given offset\n"
1709 "\n"
1710 " Example:\n"
1711 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1712 "\n"
1713 " Discards a segment of the currently open file.\n"
1714 " -C, -- report statistics in a machine parsable format\n"
1715 " -q, -- quiet mode, do not show I/O statistics\n"
1716 "\n");
1717 }
1718 
1719 static int discard_f(BlockBackend *blk, int argc, char **argv);
1720 
1721 static const cmdinfo_t discard_cmd = {
1722     .name       = "discard",
1723     .altname    = "d",
1724     .cfunc      = discard_f,
1725     .perm       = BLK_PERM_WRITE,
1726     .argmin     = 2,
1727     .argmax     = -1,
1728     .args       = "[-Cq] off len",
1729     .oneline    = "discards a number of bytes at a specified offset",
1730     .help       = discard_help,
1731 };
1732 
1733 static int discard_f(BlockBackend *blk, int argc, char **argv)
1734 {
1735     struct timeval t1, t2;
1736     bool Cflag = false, qflag = false;
1737     int c, ret;
1738     int64_t offset, bytes;
1739 
1740     while ((c = getopt(argc, argv, "Cq")) != -1) {
1741         switch (c) {
1742         case 'C':
1743             Cflag = true;
1744             break;
1745         case 'q':
1746             qflag = true;
1747             break;
1748         default:
1749             qemuio_command_usage(&discard_cmd);
1750             return -EINVAL;
1751         }
1752     }
1753 
1754     if (optind != argc - 2) {
1755         qemuio_command_usage(&discard_cmd);
1756         return -EINVAL;
1757     }
1758 
1759     offset = cvtnum(argv[optind]);
1760     if (offset < 0) {
1761         print_cvtnum_err(offset, argv[optind]);
1762         return offset;
1763     }
1764 
1765     optind++;
1766     bytes = cvtnum(argv[optind]);
1767     if (bytes < 0) {
1768         print_cvtnum_err(bytes, argv[optind]);
1769         return bytes;
1770     } else if (bytes >> BDRV_SECTOR_BITS > BDRV_REQUEST_MAX_SECTORS) {
1771         printf("length cannot exceed %"PRIu64", given %s\n",
1772                (uint64_t)BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS,
1773                argv[optind]);
1774         return -EINVAL;
1775     }
1776 
1777     gettimeofday(&t1, NULL);
1778     ret = blk_pdiscard(blk, offset, bytes);
1779     gettimeofday(&t2, NULL);
1780 
1781     if (ret < 0) {
1782         printf("discard failed: %s\n", strerror(-ret));
1783         return ret;
1784     }
1785 
1786     /* Finally, report back -- -C gives a parsable format */
1787     if (!qflag) {
1788         t2 = tsub(t2, t1);
1789         print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
1790     }
1791 
1792     return 0;
1793 }
1794 
1795 static int alloc_f(BlockBackend *blk, int argc, char **argv)
1796 {
1797     BlockDriverState *bs = blk_bs(blk);
1798     int64_t offset, start, remaining, count;
1799     char s1[64];
1800     int ret;
1801     int64_t num, sum_alloc;
1802 
1803     start = offset = cvtnum(argv[1]);
1804     if (offset < 0) {
1805         print_cvtnum_err(offset, argv[1]);
1806         return offset;
1807     }
1808 
1809     if (argc == 3) {
1810         count = cvtnum(argv[2]);
1811         if (count < 0) {
1812             print_cvtnum_err(count, argv[2]);
1813             return count;
1814         }
1815     } else {
1816         count = BDRV_SECTOR_SIZE;
1817     }
1818 
1819     remaining = count;
1820     sum_alloc = 0;
1821     while (remaining) {
1822         ret = bdrv_is_allocated(bs, offset, remaining, &num);
1823         if (ret < 0) {
1824             printf("is_allocated failed: %s\n", strerror(-ret));
1825             return ret;
1826         }
1827         offset += num;
1828         remaining -= num;
1829         if (ret) {
1830             sum_alloc += num;
1831         }
1832         if (num == 0) {
1833             count -= remaining;
1834             remaining = 0;
1835         }
1836     }
1837 
1838     cvtstr(start, s1, sizeof(s1));
1839 
1840     printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
1841            sum_alloc, count, s1);
1842     return 0;
1843 }
1844 
1845 static const cmdinfo_t alloc_cmd = {
1846     .name       = "alloc",
1847     .altname    = "a",
1848     .argmin     = 1,
1849     .argmax     = 2,
1850     .cfunc      = alloc_f,
1851     .args       = "offset [count]",
1852     .oneline    = "checks if offset is allocated in the file",
1853 };
1854 
1855 
1856 static int map_is_allocated(BlockDriverState *bs, int64_t offset,
1857                             int64_t bytes, int64_t *pnum)
1858 {
1859     int64_t num;
1860     int num_checked;
1861     int ret, firstret;
1862 
1863     num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1864     ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1865     if (ret < 0) {
1866         return ret;
1867     }
1868 
1869     firstret = ret;
1870     *pnum = num;
1871 
1872     while (bytes > 0 && ret == firstret) {
1873         offset += num;
1874         bytes -= num;
1875 
1876         num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1877         ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1878         if (ret == firstret && num) {
1879             *pnum += num;
1880         } else {
1881             break;
1882         }
1883     }
1884 
1885     return firstret;
1886 }
1887 
1888 static int map_f(BlockBackend *blk, int argc, char **argv)
1889 {
1890     int64_t offset, bytes;
1891     char s1[64], s2[64];
1892     int64_t num;
1893     int ret;
1894     const char *retstr;
1895 
1896     offset = 0;
1897     bytes = blk_getlength(blk);
1898     if (bytes < 0) {
1899         error_report("Failed to query image length: %s", strerror(-bytes));
1900         return bytes;
1901     }
1902 
1903     while (bytes) {
1904         ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
1905         if (ret < 0) {
1906             error_report("Failed to get allocation status: %s", strerror(-ret));
1907             return ret;
1908         } else if (!num) {
1909             error_report("Unexpected end of image");
1910             return -EIO;
1911         }
1912 
1913         retstr = ret ? "    allocated" : "not allocated";
1914         cvtstr(num, s1, sizeof(s1));
1915         cvtstr(offset, s2, sizeof(s2));
1916         printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
1917                s1, num, retstr, s2, offset);
1918 
1919         offset += num;
1920         bytes -= num;
1921     }
1922 
1923     return 0;
1924 }
1925 
1926 static const cmdinfo_t map_cmd = {
1927        .name           = "map",
1928        .argmin         = 0,
1929        .argmax         = 0,
1930        .cfunc          = map_f,
1931        .args           = "",
1932        .oneline        = "prints the allocated areas of a file",
1933 };
1934 
1935 static void reopen_help(void)
1936 {
1937     printf(
1938 "\n"
1939 " Changes the open options of an already opened image\n"
1940 "\n"
1941 " Example:\n"
1942 " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
1943 "\n"
1944 " -r, -- Reopen the image read-only\n"
1945 " -w, -- Reopen the image read-write\n"
1946 " -c, -- Change the cache mode to the given value\n"
1947 " -o, -- Changes block driver options (cf. 'open' command)\n"
1948 "\n");
1949 }
1950 
1951 static int reopen_f(BlockBackend *blk, int argc, char **argv);
1952 
1953 static QemuOptsList reopen_opts = {
1954     .name = "reopen",
1955     .merge_lists = true,
1956     .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
1957     .desc = {
1958         /* no elements => accept any params */
1959         { /* end of list */ }
1960     },
1961 };
1962 
1963 static const cmdinfo_t reopen_cmd = {
1964        .name           = "reopen",
1965        .argmin         = 0,
1966        .argmax         = -1,
1967        .cfunc          = reopen_f,
1968        .args           = "[(-r|-w)] [-c cache] [-o options]",
1969        .oneline        = "reopens an image with new options",
1970        .help           = reopen_help,
1971 };
1972 
1973 static int reopen_f(BlockBackend *blk, int argc, char **argv)
1974 {
1975     BlockDriverState *bs = blk_bs(blk);
1976     QemuOpts *qopts;
1977     QDict *opts;
1978     int c;
1979     int flags = bs->open_flags;
1980     bool writethrough = !blk_enable_write_cache(blk);
1981     bool has_rw_option = false;
1982     bool has_cache_option = false;
1983 
1984     BlockReopenQueue *brq;
1985     Error *local_err = NULL;
1986 
1987     while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
1988         switch (c) {
1989         case 'c':
1990             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
1991                 error_report("Invalid cache option: %s", optarg);
1992                 return -EINVAL;
1993             }
1994             has_cache_option = true;
1995             break;
1996         case 'o':
1997             if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
1998                 qemu_opts_reset(&reopen_opts);
1999                 return -EINVAL;
2000             }
2001             break;
2002         case 'r':
2003             if (has_rw_option) {
2004                 error_report("Only one -r/-w option may be given");
2005                 return -EINVAL;
2006             }
2007             flags &= ~BDRV_O_RDWR;
2008             has_rw_option = true;
2009             break;
2010         case 'w':
2011             if (has_rw_option) {
2012                 error_report("Only one -r/-w option may be given");
2013                 return -EINVAL;
2014             }
2015             flags |= BDRV_O_RDWR;
2016             has_rw_option = true;
2017             break;
2018         default:
2019             qemu_opts_reset(&reopen_opts);
2020             qemuio_command_usage(&reopen_cmd);
2021             return -EINVAL;
2022         }
2023     }
2024 
2025     if (optind != argc) {
2026         qemu_opts_reset(&reopen_opts);
2027         qemuio_command_usage(&reopen_cmd);
2028         return -EINVAL;
2029     }
2030 
2031     if (!writethrough != blk_enable_write_cache(blk) &&
2032         blk_get_attached_dev(blk))
2033     {
2034         error_report("Cannot change cache.writeback: Device attached");
2035         qemu_opts_reset(&reopen_opts);
2036         return -EBUSY;
2037     }
2038 
2039     if (!(flags & BDRV_O_RDWR)) {
2040         uint64_t orig_perm, orig_shared_perm;
2041 
2042         bdrv_drain(bs);
2043 
2044         blk_get_perm(blk, &orig_perm, &orig_shared_perm);
2045         blk_set_perm(blk,
2046                      orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
2047                      orig_shared_perm,
2048                      &error_abort);
2049     }
2050 
2051     qopts = qemu_opts_find(&reopen_opts, NULL);
2052     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new();
2053     qemu_opts_reset(&reopen_opts);
2054 
2055     if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
2056         if (has_rw_option) {
2057             error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
2058             qobject_unref(opts);
2059             return -EINVAL;
2060         }
2061     } else {
2062         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
2063     }
2064 
2065     if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
2066         qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
2067         if (has_cache_option) {
2068             error_report("Cannot set both -c and the cache options");
2069             qobject_unref(opts);
2070             return -EINVAL;
2071         }
2072     } else {
2073         qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
2074         qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
2075     }
2076 
2077     bdrv_subtree_drained_begin(bs);
2078     brq = bdrv_reopen_queue(NULL, bs, opts);
2079     bdrv_reopen_multiple(bdrv_get_aio_context(bs), brq, &local_err);
2080     bdrv_subtree_drained_end(bs);
2081 
2082     if (local_err) {
2083         error_report_err(local_err);
2084         return -EINVAL;
2085     }
2086 
2087     blk_set_enable_write_cache(blk, !writethrough);
2088     return 0;
2089 }
2090 
2091 static int break_f(BlockBackend *blk, int argc, char **argv)
2092 {
2093     int ret;
2094 
2095     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2096     if (ret < 0) {
2097         printf("Could not set breakpoint: %s\n", strerror(-ret));
2098         return ret;
2099     }
2100 
2101     return 0;
2102 }
2103 
2104 static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2105 {
2106     int ret;
2107 
2108     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2109     if (ret < 0) {
2110         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2111         return ret;
2112     }
2113 
2114     return 0;
2115 }
2116 
2117 static const cmdinfo_t break_cmd = {
2118        .name           = "break",
2119        .argmin         = 2,
2120        .argmax         = 2,
2121        .cfunc          = break_f,
2122        .args           = "event tag",
2123        .oneline        = "sets a breakpoint on event and tags the stopped "
2124                          "request as tag",
2125 };
2126 
2127 static const cmdinfo_t remove_break_cmd = {
2128        .name           = "remove_break",
2129        .argmin         = 1,
2130        .argmax         = 1,
2131        .cfunc          = remove_break_f,
2132        .args           = "tag",
2133        .oneline        = "remove a breakpoint by tag",
2134 };
2135 
2136 static int resume_f(BlockBackend *blk, int argc, char **argv)
2137 {
2138     int ret;
2139 
2140     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2141     if (ret < 0) {
2142         printf("Could not resume request: %s\n", strerror(-ret));
2143         return ret;
2144     }
2145 
2146     return 0;
2147 }
2148 
2149 static const cmdinfo_t resume_cmd = {
2150        .name           = "resume",
2151        .argmin         = 1,
2152        .argmax         = 1,
2153        .cfunc          = resume_f,
2154        .args           = "tag",
2155        .oneline        = "resumes the request tagged as tag",
2156 };
2157 
2158 static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2159 {
2160     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2161         aio_poll(blk_get_aio_context(blk), true);
2162     }
2163     return 0;
2164 }
2165 
2166 static const cmdinfo_t wait_break_cmd = {
2167        .name           = "wait_break",
2168        .argmin         = 1,
2169        .argmax         = 1,
2170        .cfunc          = wait_break_f,
2171        .args           = "tag",
2172        .oneline        = "waits for the suspension of a request",
2173 };
2174 
2175 static int abort_f(BlockBackend *blk, int argc, char **argv)
2176 {
2177     abort();
2178 }
2179 
2180 static const cmdinfo_t abort_cmd = {
2181        .name           = "abort",
2182        .cfunc          = abort_f,
2183        .flags          = CMD_NOFILE_OK,
2184        .oneline        = "simulate a program crash using abort(3)",
2185 };
2186 
2187 static void sigraise_help(void)
2188 {
2189     printf(
2190 "\n"
2191 " raises the given signal\n"
2192 "\n"
2193 " Example:\n"
2194 " 'sigraise %i' - raises SIGTERM\n"
2195 "\n"
2196 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2197 " given to sigraise.\n"
2198 "\n", SIGTERM);
2199 }
2200 
2201 static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2202 
2203 static const cmdinfo_t sigraise_cmd = {
2204     .name       = "sigraise",
2205     .cfunc      = sigraise_f,
2206     .argmin     = 1,
2207     .argmax     = 1,
2208     .flags      = CMD_NOFILE_OK,
2209     .args       = "signal",
2210     .oneline    = "raises a signal",
2211     .help       = sigraise_help,
2212 };
2213 
2214 static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2215 {
2216     int64_t sig = cvtnum(argv[1]);
2217     if (sig < 0) {
2218         print_cvtnum_err(sig, argv[1]);
2219         return sig;
2220     } else if (sig > NSIG) {
2221         printf("signal argument '%s' is too large to be a valid signal\n",
2222                argv[1]);
2223         return -EINVAL;
2224     }
2225 
2226     /* Using raise() to kill this process does not necessarily flush all open
2227      * streams. At least stdout and stderr (although the latter should be
2228      * non-buffered anyway) should be flushed, though. */
2229     fflush(stdout);
2230     fflush(stderr);
2231 
2232     raise(sig);
2233 
2234     return 0;
2235 }
2236 
2237 static void sleep_cb(void *opaque)
2238 {
2239     bool *expired = opaque;
2240     *expired = true;
2241 }
2242 
2243 static int sleep_f(BlockBackend *blk, int argc, char **argv)
2244 {
2245     char *endptr;
2246     long ms;
2247     struct QEMUTimer *timer;
2248     bool expired = false;
2249 
2250     ms = strtol(argv[1], &endptr, 0);
2251     if (ms < 0 || *endptr != '\0') {
2252         printf("%s is not a valid number\n", argv[1]);
2253         return -EINVAL;
2254     }
2255 
2256     timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2257     timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2258 
2259     while (!expired) {
2260         main_loop_wait(false);
2261     }
2262 
2263     timer_free(timer);
2264     return 0;
2265 }
2266 
2267 static const cmdinfo_t sleep_cmd = {
2268        .name           = "sleep",
2269        .argmin         = 1,
2270        .argmax         = 1,
2271        .cfunc          = sleep_f,
2272        .flags          = CMD_NOFILE_OK,
2273        .oneline        = "waits for the given value in milliseconds",
2274 };
2275 
2276 static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2277 {
2278     if (cmd) {
2279         printf("%s ", cmd);
2280     } else {
2281         printf("%s ", ct->name);
2282         if (ct->altname) {
2283             printf("(or %s) ", ct->altname);
2284         }
2285     }
2286 
2287     if (ct->args) {
2288         printf("%s ", ct->args);
2289     }
2290     printf("-- %s\n", ct->oneline);
2291 }
2292 
2293 static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2294 {
2295     help_oneline(cmd, ct);
2296     if (ct->help) {
2297         ct->help();
2298     }
2299 }
2300 
2301 static void help_all(void)
2302 {
2303     const cmdinfo_t *ct;
2304 
2305     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2306         help_oneline(ct->name, ct);
2307     }
2308     printf("\nUse 'help commandname' for extended help.\n");
2309 }
2310 
2311 static int help_f(BlockBackend *blk, int argc, char **argv)
2312 {
2313     const cmdinfo_t *ct;
2314 
2315     if (argc == 1) {
2316         help_all();
2317         return 0;
2318     }
2319 
2320     ct = find_command(argv[1]);
2321     if (ct == NULL) {
2322         printf("command %s not found\n", argv[1]);
2323         return -EINVAL;
2324     }
2325 
2326     help_onecmd(argv[1], ct);
2327     return 0;
2328 }
2329 
2330 static const cmdinfo_t help_cmd = {
2331     .name       = "help",
2332     .altname    = "?",
2333     .cfunc      = help_f,
2334     .argmin     = 0,
2335     .argmax     = 1,
2336     .flags      = CMD_FLAG_GLOBAL,
2337     .args       = "[command]",
2338     .oneline    = "help for one or all commands",
2339 };
2340 
2341 int qemuio_command(BlockBackend *blk, const char *cmd)
2342 {
2343     AioContext *ctx;
2344     char *input;
2345     const cmdinfo_t *ct;
2346     char **v;
2347     int c;
2348     int ret = 0;
2349 
2350     input = g_strdup(cmd);
2351     v = breakline(input, &c);
2352     if (c) {
2353         ct = find_command(v[0]);
2354         if (ct) {
2355             ctx = blk ? blk_get_aio_context(blk) : qemu_get_aio_context();
2356             aio_context_acquire(ctx);
2357             ret = command(blk, ct, c, v);
2358             aio_context_release(ctx);
2359         } else {
2360             fprintf(stderr, "command \"%s\" not found\n", v[0]);
2361             ret = -EINVAL;
2362         }
2363     }
2364     g_free(input);
2365     g_free(v);
2366 
2367     return ret;
2368 }
2369 
2370 static void __attribute((constructor)) init_qemuio_commands(void)
2371 {
2372     /* initialize commands */
2373     qemuio_add_command(&help_cmd);
2374     qemuio_add_command(&read_cmd);
2375     qemuio_add_command(&readv_cmd);
2376     qemuio_add_command(&write_cmd);
2377     qemuio_add_command(&writev_cmd);
2378     qemuio_add_command(&aio_read_cmd);
2379     qemuio_add_command(&aio_write_cmd);
2380     qemuio_add_command(&aio_flush_cmd);
2381     qemuio_add_command(&flush_cmd);
2382     qemuio_add_command(&truncate_cmd);
2383     qemuio_add_command(&length_cmd);
2384     qemuio_add_command(&info_cmd);
2385     qemuio_add_command(&discard_cmd);
2386     qemuio_add_command(&alloc_cmd);
2387     qemuio_add_command(&map_cmd);
2388     qemuio_add_command(&reopen_cmd);
2389     qemuio_add_command(&break_cmd);
2390     qemuio_add_command(&remove_break_cmd);
2391     qemuio_add_command(&resume_cmd);
2392     qemuio_add_command(&wait_break_cmd);
2393     qemuio_add_command(&abort_cmd);
2394     qemuio_add_command(&sleep_cmd);
2395     qemuio_add_command(&sigraise_cmd);
2396 }
2397