xref: /openbmc/qemu/qemu-io-cmds.c (revision e7bbc9b1)
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 " -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     Error *local_err = NULL;
1665     char s1[64], s2[64];
1666     int ret;
1667 
1668     if (bs->drv && bs->drv->format_name) {
1669         printf("format name: %s\n", bs->drv->format_name);
1670     }
1671     if (bs->drv && bs->drv->protocol_name) {
1672         printf("format name: %s\n", bs->drv->protocol_name);
1673     }
1674 
1675     ret = bdrv_get_info(bs, &bdi);
1676     if (ret) {
1677         return ret;
1678     }
1679 
1680     cvtstr(bdi.cluster_size, s1, sizeof(s1));
1681     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1682 
1683     printf("cluster size: %s\n", s1);
1684     printf("vm state offset: %s\n", s2);
1685 
1686     spec_info = bdrv_get_specific_info(bs, &local_err);
1687     if (local_err) {
1688         error_report_err(local_err);
1689         return -EIO;
1690     }
1691     if (spec_info) {
1692         printf("Format specific information:\n");
1693         bdrv_image_info_specific_dump(fprintf, stdout, spec_info);
1694         qapi_free_ImageInfoSpecific(spec_info);
1695     }
1696 
1697     return 0;
1698 }
1699 
1700 
1701 
1702 static const cmdinfo_t info_cmd = {
1703     .name       = "info",
1704     .altname    = "i",
1705     .cfunc      = info_f,
1706     .oneline    = "prints information about the current file",
1707 };
1708 
1709 static void discard_help(void)
1710 {
1711     printf(
1712 "\n"
1713 " discards a range of bytes from the given offset\n"
1714 "\n"
1715 " Example:\n"
1716 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1717 "\n"
1718 " Discards a segment of the currently open file.\n"
1719 " -C, -- report statistics in a machine parsable format\n"
1720 " -q, -- quiet mode, do not show I/O statistics\n"
1721 "\n");
1722 }
1723 
1724 static int discard_f(BlockBackend *blk, int argc, char **argv);
1725 
1726 static const cmdinfo_t discard_cmd = {
1727     .name       = "discard",
1728     .altname    = "d",
1729     .cfunc      = discard_f,
1730     .perm       = BLK_PERM_WRITE,
1731     .argmin     = 2,
1732     .argmax     = -1,
1733     .args       = "[-Cq] off len",
1734     .oneline    = "discards a number of bytes at a specified offset",
1735     .help       = discard_help,
1736 };
1737 
1738 static int discard_f(BlockBackend *blk, int argc, char **argv)
1739 {
1740     struct timeval t1, t2;
1741     bool Cflag = false, qflag = false;
1742     int c, ret;
1743     int64_t offset, bytes;
1744 
1745     while ((c = getopt(argc, argv, "Cq")) != -1) {
1746         switch (c) {
1747         case 'C':
1748             Cflag = true;
1749             break;
1750         case 'q':
1751             qflag = true;
1752             break;
1753         default:
1754             qemuio_command_usage(&discard_cmd);
1755             return -EINVAL;
1756         }
1757     }
1758 
1759     if (optind != argc - 2) {
1760         qemuio_command_usage(&discard_cmd);
1761         return -EINVAL;
1762     }
1763 
1764     offset = cvtnum(argv[optind]);
1765     if (offset < 0) {
1766         print_cvtnum_err(offset, argv[optind]);
1767         return offset;
1768     }
1769 
1770     optind++;
1771     bytes = cvtnum(argv[optind]);
1772     if (bytes < 0) {
1773         print_cvtnum_err(bytes, argv[optind]);
1774         return bytes;
1775     } else if (bytes >> BDRV_SECTOR_BITS > BDRV_REQUEST_MAX_SECTORS) {
1776         printf("length cannot exceed %"PRIu64", given %s\n",
1777                (uint64_t)BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS,
1778                argv[optind]);
1779         return -EINVAL;
1780     }
1781 
1782     gettimeofday(&t1, NULL);
1783     ret = blk_pdiscard(blk, offset, bytes);
1784     gettimeofday(&t2, NULL);
1785 
1786     if (ret < 0) {
1787         printf("discard failed: %s\n", strerror(-ret));
1788         return ret;
1789     }
1790 
1791     /* Finally, report back -- -C gives a parsable format */
1792     if (!qflag) {
1793         t2 = tsub(t2, t1);
1794         print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
1795     }
1796 
1797     return 0;
1798 }
1799 
1800 static int alloc_f(BlockBackend *blk, int argc, char **argv)
1801 {
1802     BlockDriverState *bs = blk_bs(blk);
1803     int64_t offset, start, remaining, count;
1804     char s1[64];
1805     int ret;
1806     int64_t num, sum_alloc;
1807 
1808     start = offset = cvtnum(argv[1]);
1809     if (offset < 0) {
1810         print_cvtnum_err(offset, argv[1]);
1811         return offset;
1812     }
1813 
1814     if (argc == 3) {
1815         count = cvtnum(argv[2]);
1816         if (count < 0) {
1817             print_cvtnum_err(count, argv[2]);
1818             return count;
1819         }
1820     } else {
1821         count = BDRV_SECTOR_SIZE;
1822     }
1823 
1824     remaining = count;
1825     sum_alloc = 0;
1826     while (remaining) {
1827         ret = bdrv_is_allocated(bs, offset, remaining, &num);
1828         if (ret < 0) {
1829             printf("is_allocated failed: %s\n", strerror(-ret));
1830             return ret;
1831         }
1832         offset += num;
1833         remaining -= num;
1834         if (ret) {
1835             sum_alloc += num;
1836         }
1837         if (num == 0) {
1838             count -= remaining;
1839             remaining = 0;
1840         }
1841     }
1842 
1843     cvtstr(start, s1, sizeof(s1));
1844 
1845     printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
1846            sum_alloc, count, s1);
1847     return 0;
1848 }
1849 
1850 static const cmdinfo_t alloc_cmd = {
1851     .name       = "alloc",
1852     .altname    = "a",
1853     .argmin     = 1,
1854     .argmax     = 2,
1855     .cfunc      = alloc_f,
1856     .args       = "offset [count]",
1857     .oneline    = "checks if offset is allocated in the file",
1858 };
1859 
1860 
1861 static int map_is_allocated(BlockDriverState *bs, int64_t offset,
1862                             int64_t bytes, int64_t *pnum)
1863 {
1864     int64_t num;
1865     int num_checked;
1866     int ret, firstret;
1867 
1868     num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1869     ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1870     if (ret < 0) {
1871         return ret;
1872     }
1873 
1874     firstret = ret;
1875     *pnum = num;
1876 
1877     while (bytes > 0 && ret == firstret) {
1878         offset += num;
1879         bytes -= num;
1880 
1881         num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1882         ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1883         if (ret == firstret && num) {
1884             *pnum += num;
1885         } else {
1886             break;
1887         }
1888     }
1889 
1890     return firstret;
1891 }
1892 
1893 static int map_f(BlockBackend *blk, int argc, char **argv)
1894 {
1895     int64_t offset, bytes;
1896     char s1[64], s2[64];
1897     int64_t num;
1898     int ret;
1899     const char *retstr;
1900 
1901     offset = 0;
1902     bytes = blk_getlength(blk);
1903     if (bytes < 0) {
1904         error_report("Failed to query image length: %s", strerror(-bytes));
1905         return bytes;
1906     }
1907 
1908     while (bytes) {
1909         ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
1910         if (ret < 0) {
1911             error_report("Failed to get allocation status: %s", strerror(-ret));
1912             return ret;
1913         } else if (!num) {
1914             error_report("Unexpected end of image");
1915             return -EIO;
1916         }
1917 
1918         retstr = ret ? "    allocated" : "not allocated";
1919         cvtstr(num, s1, sizeof(s1));
1920         cvtstr(offset, s2, sizeof(s2));
1921         printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
1922                s1, num, retstr, s2, offset);
1923 
1924         offset += num;
1925         bytes -= num;
1926     }
1927 
1928     return 0;
1929 }
1930 
1931 static const cmdinfo_t map_cmd = {
1932        .name           = "map",
1933        .argmin         = 0,
1934        .argmax         = 0,
1935        .cfunc          = map_f,
1936        .args           = "",
1937        .oneline        = "prints the allocated areas of a file",
1938 };
1939 
1940 static void reopen_help(void)
1941 {
1942     printf(
1943 "\n"
1944 " Changes the open options of an already opened image\n"
1945 "\n"
1946 " Example:\n"
1947 " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
1948 "\n"
1949 " -r, -- Reopen the image read-only\n"
1950 " -w, -- Reopen the image read-write\n"
1951 " -c, -- Change the cache mode to the given value\n"
1952 " -o, -- Changes block driver options (cf. 'open' command)\n"
1953 "\n");
1954 }
1955 
1956 static int reopen_f(BlockBackend *blk, int argc, char **argv);
1957 
1958 static QemuOptsList reopen_opts = {
1959     .name = "reopen",
1960     .merge_lists = true,
1961     .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
1962     .desc = {
1963         /* no elements => accept any params */
1964         { /* end of list */ }
1965     },
1966 };
1967 
1968 static const cmdinfo_t reopen_cmd = {
1969        .name           = "reopen",
1970        .argmin         = 0,
1971        .argmax         = -1,
1972        .cfunc          = reopen_f,
1973        .args           = "[(-r|-w)] [-c cache] [-o options]",
1974        .oneline        = "reopens an image with new options",
1975        .help           = reopen_help,
1976 };
1977 
1978 static int reopen_f(BlockBackend *blk, int argc, char **argv)
1979 {
1980     BlockDriverState *bs = blk_bs(blk);
1981     QemuOpts *qopts;
1982     QDict *opts;
1983     int c;
1984     int flags = bs->open_flags;
1985     bool writethrough = !blk_enable_write_cache(blk);
1986     bool has_rw_option = false;
1987     bool has_cache_option = false;
1988 
1989     BlockReopenQueue *brq;
1990     Error *local_err = NULL;
1991 
1992     while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
1993         switch (c) {
1994         case 'c':
1995             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
1996                 error_report("Invalid cache option: %s", optarg);
1997                 return -EINVAL;
1998             }
1999             has_cache_option = true;
2000             break;
2001         case 'o':
2002             if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
2003                 qemu_opts_reset(&reopen_opts);
2004                 return -EINVAL;
2005             }
2006             break;
2007         case 'r':
2008             if (has_rw_option) {
2009                 error_report("Only one -r/-w option may be given");
2010                 return -EINVAL;
2011             }
2012             flags &= ~BDRV_O_RDWR;
2013             has_rw_option = true;
2014             break;
2015         case 'w':
2016             if (has_rw_option) {
2017                 error_report("Only one -r/-w option may be given");
2018                 return -EINVAL;
2019             }
2020             flags |= BDRV_O_RDWR;
2021             has_rw_option = true;
2022             break;
2023         default:
2024             qemu_opts_reset(&reopen_opts);
2025             qemuio_command_usage(&reopen_cmd);
2026             return -EINVAL;
2027         }
2028     }
2029 
2030     if (optind != argc) {
2031         qemu_opts_reset(&reopen_opts);
2032         qemuio_command_usage(&reopen_cmd);
2033         return -EINVAL;
2034     }
2035 
2036     if (!writethrough != blk_enable_write_cache(blk) &&
2037         blk_get_attached_dev(blk))
2038     {
2039         error_report("Cannot change cache.writeback: Device attached");
2040         qemu_opts_reset(&reopen_opts);
2041         return -EBUSY;
2042     }
2043 
2044     if (!(flags & BDRV_O_RDWR)) {
2045         uint64_t orig_perm, orig_shared_perm;
2046 
2047         bdrv_drain(bs);
2048 
2049         blk_get_perm(blk, &orig_perm, &orig_shared_perm);
2050         blk_set_perm(blk,
2051                      orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
2052                      orig_shared_perm,
2053                      &error_abort);
2054     }
2055 
2056     qopts = qemu_opts_find(&reopen_opts, NULL);
2057     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new();
2058     qemu_opts_reset(&reopen_opts);
2059 
2060     if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
2061         if (has_rw_option) {
2062             error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
2063             qobject_unref(opts);
2064             return -EINVAL;
2065         }
2066     } else {
2067         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
2068     }
2069 
2070     if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
2071         qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
2072         if (has_cache_option) {
2073             error_report("Cannot set both -c and the cache options");
2074             qobject_unref(opts);
2075             return -EINVAL;
2076         }
2077     } else {
2078         qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
2079         qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
2080     }
2081 
2082     bdrv_subtree_drained_begin(bs);
2083     brq = bdrv_reopen_queue(NULL, bs, opts);
2084     bdrv_reopen_multiple(bdrv_get_aio_context(bs), brq, &local_err);
2085     bdrv_subtree_drained_end(bs);
2086 
2087     if (local_err) {
2088         error_report_err(local_err);
2089         return -EINVAL;
2090     }
2091 
2092     blk_set_enable_write_cache(blk, !writethrough);
2093     return 0;
2094 }
2095 
2096 static int break_f(BlockBackend *blk, int argc, char **argv)
2097 {
2098     int ret;
2099 
2100     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2101     if (ret < 0) {
2102         printf("Could not set breakpoint: %s\n", strerror(-ret));
2103         return ret;
2104     }
2105 
2106     return 0;
2107 }
2108 
2109 static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2110 {
2111     int ret;
2112 
2113     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2114     if (ret < 0) {
2115         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2116         return ret;
2117     }
2118 
2119     return 0;
2120 }
2121 
2122 static const cmdinfo_t break_cmd = {
2123        .name           = "break",
2124        .argmin         = 2,
2125        .argmax         = 2,
2126        .cfunc          = break_f,
2127        .args           = "event tag",
2128        .oneline        = "sets a breakpoint on event and tags the stopped "
2129                          "request as tag",
2130 };
2131 
2132 static const cmdinfo_t remove_break_cmd = {
2133        .name           = "remove_break",
2134        .argmin         = 1,
2135        .argmax         = 1,
2136        .cfunc          = remove_break_f,
2137        .args           = "tag",
2138        .oneline        = "remove a breakpoint by tag",
2139 };
2140 
2141 static int resume_f(BlockBackend *blk, int argc, char **argv)
2142 {
2143     int ret;
2144 
2145     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2146     if (ret < 0) {
2147         printf("Could not resume request: %s\n", strerror(-ret));
2148         return ret;
2149     }
2150 
2151     return 0;
2152 }
2153 
2154 static const cmdinfo_t resume_cmd = {
2155        .name           = "resume",
2156        .argmin         = 1,
2157        .argmax         = 1,
2158        .cfunc          = resume_f,
2159        .args           = "tag",
2160        .oneline        = "resumes the request tagged as tag",
2161 };
2162 
2163 static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2164 {
2165     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2166         aio_poll(blk_get_aio_context(blk), true);
2167     }
2168     return 0;
2169 }
2170 
2171 static const cmdinfo_t wait_break_cmd = {
2172        .name           = "wait_break",
2173        .argmin         = 1,
2174        .argmax         = 1,
2175        .cfunc          = wait_break_f,
2176        .args           = "tag",
2177        .oneline        = "waits for the suspension of a request",
2178 };
2179 
2180 static int abort_f(BlockBackend *blk, int argc, char **argv)
2181 {
2182     abort();
2183 }
2184 
2185 static const cmdinfo_t abort_cmd = {
2186        .name           = "abort",
2187        .cfunc          = abort_f,
2188        .flags          = CMD_NOFILE_OK,
2189        .oneline        = "simulate a program crash using abort(3)",
2190 };
2191 
2192 static void sigraise_help(void)
2193 {
2194     printf(
2195 "\n"
2196 " raises the given signal\n"
2197 "\n"
2198 " Example:\n"
2199 " 'sigraise %i' - raises SIGTERM\n"
2200 "\n"
2201 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2202 " given to sigraise.\n"
2203 "\n", SIGTERM);
2204 }
2205 
2206 static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2207 
2208 static const cmdinfo_t sigraise_cmd = {
2209     .name       = "sigraise",
2210     .cfunc      = sigraise_f,
2211     .argmin     = 1,
2212     .argmax     = 1,
2213     .flags      = CMD_NOFILE_OK,
2214     .args       = "signal",
2215     .oneline    = "raises a signal",
2216     .help       = sigraise_help,
2217 };
2218 
2219 static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2220 {
2221     int64_t sig = cvtnum(argv[1]);
2222     if (sig < 0) {
2223         print_cvtnum_err(sig, argv[1]);
2224         return sig;
2225     } else if (sig > NSIG) {
2226         printf("signal argument '%s' is too large to be a valid signal\n",
2227                argv[1]);
2228         return -EINVAL;
2229     }
2230 
2231     /* Using raise() to kill this process does not necessarily flush all open
2232      * streams. At least stdout and stderr (although the latter should be
2233      * non-buffered anyway) should be flushed, though. */
2234     fflush(stdout);
2235     fflush(stderr);
2236 
2237     raise(sig);
2238 
2239     return 0;
2240 }
2241 
2242 static void sleep_cb(void *opaque)
2243 {
2244     bool *expired = opaque;
2245     *expired = true;
2246 }
2247 
2248 static int sleep_f(BlockBackend *blk, int argc, char **argv)
2249 {
2250     char *endptr;
2251     long ms;
2252     struct QEMUTimer *timer;
2253     bool expired = false;
2254 
2255     ms = strtol(argv[1], &endptr, 0);
2256     if (ms < 0 || *endptr != '\0') {
2257         printf("%s is not a valid number\n", argv[1]);
2258         return -EINVAL;
2259     }
2260 
2261     timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2262     timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2263 
2264     while (!expired) {
2265         main_loop_wait(false);
2266     }
2267 
2268     timer_free(timer);
2269     return 0;
2270 }
2271 
2272 static const cmdinfo_t sleep_cmd = {
2273        .name           = "sleep",
2274        .argmin         = 1,
2275        .argmax         = 1,
2276        .cfunc          = sleep_f,
2277        .flags          = CMD_NOFILE_OK,
2278        .oneline        = "waits for the given value in milliseconds",
2279 };
2280 
2281 static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2282 {
2283     if (cmd) {
2284         printf("%s ", cmd);
2285     } else {
2286         printf("%s ", ct->name);
2287         if (ct->altname) {
2288             printf("(or %s) ", ct->altname);
2289         }
2290     }
2291 
2292     if (ct->args) {
2293         printf("%s ", ct->args);
2294     }
2295     printf("-- %s\n", ct->oneline);
2296 }
2297 
2298 static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2299 {
2300     help_oneline(cmd, ct);
2301     if (ct->help) {
2302         ct->help();
2303     }
2304 }
2305 
2306 static void help_all(void)
2307 {
2308     const cmdinfo_t *ct;
2309 
2310     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2311         help_oneline(ct->name, ct);
2312     }
2313     printf("\nUse 'help commandname' for extended help.\n");
2314 }
2315 
2316 static int help_f(BlockBackend *blk, int argc, char **argv)
2317 {
2318     const cmdinfo_t *ct;
2319 
2320     if (argc == 1) {
2321         help_all();
2322         return 0;
2323     }
2324 
2325     ct = find_command(argv[1]);
2326     if (ct == NULL) {
2327         printf("command %s not found\n", argv[1]);
2328         return -EINVAL;
2329     }
2330 
2331     help_onecmd(argv[1], ct);
2332     return 0;
2333 }
2334 
2335 static const cmdinfo_t help_cmd = {
2336     .name       = "help",
2337     .altname    = "?",
2338     .cfunc      = help_f,
2339     .argmin     = 0,
2340     .argmax     = 1,
2341     .flags      = CMD_FLAG_GLOBAL,
2342     .args       = "[command]",
2343     .oneline    = "help for one or all commands",
2344 };
2345 
2346 int qemuio_command(BlockBackend *blk, const char *cmd)
2347 {
2348     AioContext *ctx;
2349     char *input;
2350     const cmdinfo_t *ct;
2351     char **v;
2352     int c;
2353     int ret = 0;
2354 
2355     input = g_strdup(cmd);
2356     v = breakline(input, &c);
2357     if (c) {
2358         ct = find_command(v[0]);
2359         if (ct) {
2360             ctx = blk ? blk_get_aio_context(blk) : qemu_get_aio_context();
2361             aio_context_acquire(ctx);
2362             ret = command(blk, ct, c, v);
2363             aio_context_release(ctx);
2364         } else {
2365             fprintf(stderr, "command \"%s\" not found\n", v[0]);
2366             ret = -EINVAL;
2367         }
2368     }
2369     g_free(input);
2370     g_free(v);
2371 
2372     return ret;
2373 }
2374 
2375 static void __attribute((constructor)) init_qemuio_commands(void)
2376 {
2377     /* initialize commands */
2378     qemuio_add_command(&help_cmd);
2379     qemuio_add_command(&read_cmd);
2380     qemuio_add_command(&readv_cmd);
2381     qemuio_add_command(&write_cmd);
2382     qemuio_add_command(&writev_cmd);
2383     qemuio_add_command(&aio_read_cmd);
2384     qemuio_add_command(&aio_write_cmd);
2385     qemuio_add_command(&aio_flush_cmd);
2386     qemuio_add_command(&flush_cmd);
2387     qemuio_add_command(&truncate_cmd);
2388     qemuio_add_command(&length_cmd);
2389     qemuio_add_command(&info_cmd);
2390     qemuio_add_command(&discard_cmd);
2391     qemuio_add_command(&alloc_cmd);
2392     qemuio_add_command(&map_cmd);
2393     qemuio_add_command(&reopen_cmd);
2394     qemuio_add_command(&break_cmd);
2395     qemuio_add_command(&remove_break_cmd);
2396     qemuio_add_command(&resume_cmd);
2397     qemuio_add_command(&wait_break_cmd);
2398     qemuio_add_command(&abort_cmd);
2399     qemuio_add_command(&sleep_cmd);
2400     qemuio_add_command(&sigraise_cmd);
2401 }
2402