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