xref: /openbmc/qemu/qemu-io-cmds.c (revision 1141159c)
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 do_aio_zone_append(BlockBackend *blk, QEMUIOVector *qiov,
1878                               int64_t *offset, int flags, int *total)
1879 {
1880     int async_ret = NOT_DONE;
1881 
1882     blk_aio_zone_append(blk, offset, qiov, flags, aio_rw_done, &async_ret);
1883     while (async_ret == NOT_DONE) {
1884         main_loop_wait(false);
1885     }
1886 
1887     *total = qiov->size;
1888     return async_ret < 0 ? async_ret : 1;
1889 }
1890 
1891 static int zone_append_f(BlockBackend *blk, int argc, char **argv)
1892 {
1893     int ret;
1894     bool pflag = false;
1895     int flags = 0;
1896     int total = 0;
1897     int64_t offset;
1898     char *buf;
1899     int c, nr_iov;
1900     int pattern = 0xcd;
1901     QEMUIOVector qiov;
1902 
1903     if (optind > argc - 3) {
1904         return -EINVAL;
1905     }
1906 
1907     if ((c = getopt(argc, argv, "p")) != -1) {
1908         pflag = true;
1909     }
1910 
1911     offset = cvtnum(argv[optind]);
1912     if (offset < 0) {
1913         print_cvtnum_err(offset, argv[optind]);
1914         return offset;
1915     }
1916     optind++;
1917     nr_iov = argc - optind;
1918     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern,
1919                        flags & BDRV_REQ_REGISTERED_BUF);
1920     if (buf == NULL) {
1921         return -EINVAL;
1922     }
1923     ret = do_aio_zone_append(blk, &qiov, &offset, flags, &total);
1924     if (ret < 0) {
1925         printf("zone append failed: %s\n", strerror(-ret));
1926         goto out;
1927     }
1928 
1929     if (pflag) {
1930         printf("After zap done, the append sector is 0x%" PRIx64 "\n",
1931                tosector(offset));
1932     }
1933 
1934 out:
1935     qemu_io_free(blk, buf, qiov.size,
1936                  flags & BDRV_REQ_REGISTERED_BUF);
1937     qemu_iovec_destroy(&qiov);
1938     return ret;
1939 }
1940 
1941 static const cmdinfo_t zone_append_cmd = {
1942     .name = "zone_append",
1943     .altname = "zap",
1944     .cfunc = zone_append_f,
1945     .argmin = 3,
1946     .argmax = 4,
1947     .args = "offset len [len..]",
1948     .oneline = "append write a number of bytes at a specified offset",
1949 };
1950 
1951 static int truncate_f(BlockBackend *blk, int argc, char **argv);
1952 static const cmdinfo_t truncate_cmd = {
1953     .name       = "truncate",
1954     .altname    = "t",
1955     .cfunc      = truncate_f,
1956     .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
1957     .argmin     = 1,
1958     .argmax     = 3,
1959     .args       = "[-m prealloc_mode] off",
1960     .oneline    = "truncates the current file at the given offset",
1961 };
1962 
1963 static int truncate_f(BlockBackend *blk, int argc, char **argv)
1964 {
1965     Error *local_err = NULL;
1966     int64_t offset;
1967     int c, ret;
1968     PreallocMode prealloc = PREALLOC_MODE_OFF;
1969 
1970     while ((c = getopt(argc, argv, "m:")) != -1) {
1971         switch (c) {
1972         case 'm':
1973             prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
1974                                        PREALLOC_MODE__MAX, NULL);
1975             if (prealloc == PREALLOC_MODE__MAX) {
1976                 error_report("Invalid preallocation mode '%s'", optarg);
1977                 return -EINVAL;
1978             }
1979             break;
1980         default:
1981             qemuio_command_usage(&truncate_cmd);
1982             return -EINVAL;
1983         }
1984     }
1985 
1986     offset = cvtnum(argv[optind]);
1987     if (offset < 0) {
1988         print_cvtnum_err(offset, argv[1]);
1989         return offset;
1990     }
1991 
1992     /*
1993      * qemu-io is a debugging tool, so let us be strict here and pass
1994      * exact=true.  It is better to err on the "emit more errors" side
1995      * than to be overly permissive.
1996      */
1997     ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
1998     if (ret < 0) {
1999         error_report_err(local_err);
2000         return ret;
2001     }
2002 
2003     return 0;
2004 }
2005 
2006 static int length_f(BlockBackend *blk, int argc, char **argv)
2007 {
2008     int64_t size;
2009     char s1[64];
2010 
2011     size = blk_getlength(blk);
2012     if (size < 0) {
2013         printf("getlength: %s\n", strerror(-size));
2014         return size;
2015     }
2016 
2017     cvtstr(size, s1, sizeof(s1));
2018     printf("%s\n", s1);
2019     return 0;
2020 }
2021 
2022 
2023 static const cmdinfo_t length_cmd = {
2024     .name   = "length",
2025     .altname    = "l",
2026     .cfunc      = length_f,
2027     .oneline    = "gets the length of the current file",
2028 };
2029 
2030 
2031 static int info_f(BlockBackend *blk, int argc, char **argv)
2032 {
2033     BlockDriverState *bs = blk_bs(blk);
2034     BlockDriverInfo bdi;
2035     ImageInfoSpecific *spec_info;
2036     Error *local_err = NULL;
2037     char s1[64], s2[64];
2038     int ret;
2039 
2040     if (bs->drv && bs->drv->format_name) {
2041         printf("format name: %s\n", bs->drv->format_name);
2042     }
2043     if (bs->drv && bs->drv->protocol_name) {
2044         printf("format name: %s\n", bs->drv->protocol_name);
2045     }
2046 
2047     ret = bdrv_get_info(bs, &bdi);
2048     if (ret) {
2049         return ret;
2050     }
2051 
2052     cvtstr(bdi.cluster_size, s1, sizeof(s1));
2053     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
2054 
2055     printf("cluster size: %s\n", s1);
2056     printf("vm state offset: %s\n", s2);
2057 
2058     spec_info = bdrv_get_specific_info(bs, &local_err);
2059     if (local_err) {
2060         error_report_err(local_err);
2061         return -EIO;
2062     }
2063     if (spec_info) {
2064         bdrv_image_info_specific_dump(spec_info,
2065                                       "Format specific information:\n",
2066                                       0);
2067         qapi_free_ImageInfoSpecific(spec_info);
2068     }
2069 
2070     return 0;
2071 }
2072 
2073 
2074 
2075 static const cmdinfo_t info_cmd = {
2076     .name       = "info",
2077     .altname    = "i",
2078     .cfunc      = info_f,
2079     .oneline    = "prints information about the current file",
2080 };
2081 
2082 static void discard_help(void)
2083 {
2084     printf(
2085 "\n"
2086 " discards a range of bytes from the given offset\n"
2087 "\n"
2088 " Example:\n"
2089 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
2090 "\n"
2091 " Discards a segment of the currently open file.\n"
2092 " -C, -- report statistics in a machine parsable format\n"
2093 " -q, -- quiet mode, do not show I/O statistics\n"
2094 "\n");
2095 }
2096 
2097 static int discard_f(BlockBackend *blk, int argc, char **argv);
2098 
2099 static const cmdinfo_t discard_cmd = {
2100     .name       = "discard",
2101     .altname    = "d",
2102     .cfunc      = discard_f,
2103     .perm       = BLK_PERM_WRITE,
2104     .argmin     = 2,
2105     .argmax     = -1,
2106     .args       = "[-Cq] off len",
2107     .oneline    = "discards a number of bytes at a specified offset",
2108     .help       = discard_help,
2109 };
2110 
2111 static int discard_f(BlockBackend *blk, int argc, char **argv)
2112 {
2113     struct timespec t1, t2;
2114     bool Cflag = false, qflag = false;
2115     int c, ret;
2116     int64_t offset, bytes;
2117 
2118     while ((c = getopt(argc, argv, "Cq")) != -1) {
2119         switch (c) {
2120         case 'C':
2121             Cflag = true;
2122             break;
2123         case 'q':
2124             qflag = true;
2125             break;
2126         default:
2127             qemuio_command_usage(&discard_cmd);
2128             return -EINVAL;
2129         }
2130     }
2131 
2132     if (optind != argc - 2) {
2133         qemuio_command_usage(&discard_cmd);
2134         return -EINVAL;
2135     }
2136 
2137     offset = cvtnum(argv[optind]);
2138     if (offset < 0) {
2139         print_cvtnum_err(offset, argv[optind]);
2140         return offset;
2141     }
2142 
2143     optind++;
2144     bytes = cvtnum(argv[optind]);
2145     if (bytes < 0) {
2146         print_cvtnum_err(bytes, argv[optind]);
2147         return bytes;
2148     } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
2149         printf("length cannot exceed %"PRIu64", given %s\n",
2150                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
2151         return -EINVAL;
2152     }
2153 
2154     clock_gettime(CLOCK_MONOTONIC, &t1);
2155     ret = blk_pdiscard(blk, offset, bytes);
2156     clock_gettime(CLOCK_MONOTONIC, &t2);
2157 
2158     if (ret < 0) {
2159         printf("discard failed: %s\n", strerror(-ret));
2160         return ret;
2161     }
2162 
2163     /* Finally, report back -- -C gives a parsable format */
2164     if (!qflag) {
2165         t2 = tsub(t2, t1);
2166         print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
2167     }
2168 
2169     return 0;
2170 }
2171 
2172 static int alloc_f(BlockBackend *blk, int argc, char **argv)
2173 {
2174     BlockDriverState *bs = blk_bs(blk);
2175     int64_t offset, start, remaining, count;
2176     char s1[64];
2177     int ret;
2178     int64_t num, sum_alloc;
2179 
2180     start = offset = cvtnum(argv[1]);
2181     if (offset < 0) {
2182         print_cvtnum_err(offset, argv[1]);
2183         return offset;
2184     }
2185 
2186     if (argc == 3) {
2187         count = cvtnum(argv[2]);
2188         if (count < 0) {
2189             print_cvtnum_err(count, argv[2]);
2190             return count;
2191         }
2192     } else {
2193         count = BDRV_SECTOR_SIZE;
2194     }
2195 
2196     remaining = count;
2197     sum_alloc = 0;
2198     while (remaining) {
2199         ret = bdrv_is_allocated(bs, offset, remaining, &num);
2200         if (ret < 0) {
2201             printf("is_allocated failed: %s\n", strerror(-ret));
2202             return ret;
2203         }
2204         offset += num;
2205         remaining -= num;
2206         if (ret) {
2207             sum_alloc += num;
2208         }
2209         if (num == 0) {
2210             count -= remaining;
2211             remaining = 0;
2212         }
2213     }
2214 
2215     cvtstr(start, s1, sizeof(s1));
2216 
2217     printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
2218            sum_alloc, count, s1);
2219     return 0;
2220 }
2221 
2222 static const cmdinfo_t alloc_cmd = {
2223     .name       = "alloc",
2224     .altname    = "a",
2225     .argmin     = 1,
2226     .argmax     = 2,
2227     .cfunc      = alloc_f,
2228     .args       = "offset [count]",
2229     .oneline    = "checks if offset is allocated in the file",
2230 };
2231 
2232 
2233 static int map_is_allocated(BlockDriverState *bs, int64_t offset,
2234                             int64_t bytes, int64_t *pnum)
2235 {
2236     int64_t num;
2237     int ret, firstret;
2238 
2239     ret = bdrv_is_allocated(bs, offset, bytes, &num);
2240     if (ret < 0) {
2241         return ret;
2242     }
2243 
2244     firstret = ret;
2245     *pnum = num;
2246 
2247     while (bytes > 0 && ret == firstret) {
2248         offset += num;
2249         bytes -= num;
2250 
2251         ret = bdrv_is_allocated(bs, offset, bytes, &num);
2252         if (ret == firstret && num) {
2253             *pnum += num;
2254         } else {
2255             break;
2256         }
2257     }
2258 
2259     return firstret;
2260 }
2261 
2262 static int map_f(BlockBackend *blk, int argc, char **argv)
2263 {
2264     int64_t offset, bytes;
2265     char s1[64], s2[64];
2266     int64_t num;
2267     int ret;
2268     const char *retstr;
2269 
2270     offset = 0;
2271     bytes = blk_getlength(blk);
2272     if (bytes < 0) {
2273         error_report("Failed to query image length: %s", strerror(-bytes));
2274         return bytes;
2275     }
2276 
2277     while (bytes) {
2278         ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
2279         if (ret < 0) {
2280             error_report("Failed to get allocation status: %s", strerror(-ret));
2281             return ret;
2282         } else if (!num) {
2283             error_report("Unexpected end of image");
2284             return -EIO;
2285         }
2286 
2287         retstr = ret ? "    allocated" : "not allocated";
2288         cvtstr(num, s1, sizeof(s1));
2289         cvtstr(offset, s2, sizeof(s2));
2290         printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
2291                s1, num, retstr, s2, offset);
2292 
2293         offset += num;
2294         bytes -= num;
2295     }
2296 
2297     return 0;
2298 }
2299 
2300 static const cmdinfo_t map_cmd = {
2301        .name           = "map",
2302        .argmin         = 0,
2303        .argmax         = 0,
2304        .cfunc          = map_f,
2305        .args           = "",
2306        .oneline        = "prints the allocated areas of a file",
2307 };
2308 
2309 static void reopen_help(void)
2310 {
2311     printf(
2312 "\n"
2313 " Changes the open options of an already opened image\n"
2314 "\n"
2315 " Example:\n"
2316 " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
2317 "\n"
2318 " -r, -- Reopen the image read-only\n"
2319 " -w, -- Reopen the image read-write\n"
2320 " -c, -- Change the cache mode to the given value\n"
2321 " -o, -- Changes block driver options (cf. 'open' command)\n"
2322 "\n");
2323 }
2324 
2325 static int reopen_f(BlockBackend *blk, int argc, char **argv);
2326 
2327 static QemuOptsList reopen_opts = {
2328     .name = "reopen",
2329     .merge_lists = true,
2330     .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
2331     .desc = {
2332         /* no elements => accept any params */
2333         { /* end of list */ }
2334     },
2335 };
2336 
2337 static const cmdinfo_t reopen_cmd = {
2338        .name           = "reopen",
2339        .argmin         = 0,
2340        .argmax         = -1,
2341        .cfunc          = reopen_f,
2342        .args           = "[(-r|-w)] [-c cache] [-o options]",
2343        .oneline        = "reopens an image with new options",
2344        .help           = reopen_help,
2345 };
2346 
2347 static int reopen_f(BlockBackend *blk, int argc, char **argv)
2348 {
2349     BlockDriverState *bs = blk_bs(blk);
2350     QemuOpts *qopts;
2351     QDict *opts;
2352     int c;
2353     int flags = bs->open_flags;
2354     bool writethrough = !blk_enable_write_cache(blk);
2355     bool has_rw_option = false;
2356     bool has_cache_option = false;
2357     Error *local_err = NULL;
2358 
2359     while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
2360         switch (c) {
2361         case 'c':
2362             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
2363                 error_report("Invalid cache option: %s", optarg);
2364                 return -EINVAL;
2365             }
2366             has_cache_option = true;
2367             break;
2368         case 'o':
2369             if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
2370                 qemu_opts_reset(&reopen_opts);
2371                 return -EINVAL;
2372             }
2373             break;
2374         case 'r':
2375             if (has_rw_option) {
2376                 error_report("Only one -r/-w option may be given");
2377                 return -EINVAL;
2378             }
2379             flags &= ~BDRV_O_RDWR;
2380             has_rw_option = true;
2381             break;
2382         case 'w':
2383             if (has_rw_option) {
2384                 error_report("Only one -r/-w option may be given");
2385                 return -EINVAL;
2386             }
2387             flags |= BDRV_O_RDWR;
2388             has_rw_option = true;
2389             break;
2390         default:
2391             qemu_opts_reset(&reopen_opts);
2392             qemuio_command_usage(&reopen_cmd);
2393             return -EINVAL;
2394         }
2395     }
2396 
2397     if (optind != argc) {
2398         qemu_opts_reset(&reopen_opts);
2399         qemuio_command_usage(&reopen_cmd);
2400         return -EINVAL;
2401     }
2402 
2403     if (!writethrough != blk_enable_write_cache(blk) &&
2404         blk_get_attached_dev(blk))
2405     {
2406         error_report("Cannot change cache.writeback: Device attached");
2407         qemu_opts_reset(&reopen_opts);
2408         return -EBUSY;
2409     }
2410 
2411     if (!(flags & BDRV_O_RDWR)) {
2412         uint64_t orig_perm, orig_shared_perm;
2413 
2414         bdrv_drain(bs);
2415 
2416         blk_get_perm(blk, &orig_perm, &orig_shared_perm);
2417         blk_set_perm(blk,
2418                      orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
2419                      orig_shared_perm,
2420                      &error_abort);
2421     }
2422 
2423     qopts = qemu_opts_find(&reopen_opts, NULL);
2424     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new();
2425     qemu_opts_reset(&reopen_opts);
2426 
2427     if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
2428         if (has_rw_option) {
2429             error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
2430             qobject_unref(opts);
2431             return -EINVAL;
2432         }
2433     } else {
2434         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
2435     }
2436 
2437     if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
2438         qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
2439         if (has_cache_option) {
2440             error_report("Cannot set both -c and the cache options");
2441             qobject_unref(opts);
2442             return -EINVAL;
2443         }
2444     } else {
2445         qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
2446         qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
2447     }
2448 
2449     bdrv_reopen(bs, opts, true, &local_err);
2450 
2451     if (local_err) {
2452         error_report_err(local_err);
2453         return -EINVAL;
2454     }
2455 
2456     blk_set_enable_write_cache(blk, !writethrough);
2457     return 0;
2458 }
2459 
2460 static int break_f(BlockBackend *blk, int argc, char **argv)
2461 {
2462     int ret;
2463 
2464     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2465     if (ret < 0) {
2466         printf("Could not set breakpoint: %s\n", strerror(-ret));
2467         return ret;
2468     }
2469 
2470     return 0;
2471 }
2472 
2473 static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2474 {
2475     int ret;
2476 
2477     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2478     if (ret < 0) {
2479         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2480         return ret;
2481     }
2482 
2483     return 0;
2484 }
2485 
2486 static const cmdinfo_t break_cmd = {
2487        .name           = "break",
2488        .argmin         = 2,
2489        .argmax         = 2,
2490        .cfunc          = break_f,
2491        .args           = "event tag",
2492        .oneline        = "sets a breakpoint on event and tags the stopped "
2493                          "request as tag",
2494 };
2495 
2496 static const cmdinfo_t remove_break_cmd = {
2497        .name           = "remove_break",
2498        .argmin         = 1,
2499        .argmax         = 1,
2500        .cfunc          = remove_break_f,
2501        .args           = "tag",
2502        .oneline        = "remove a breakpoint by tag",
2503 };
2504 
2505 static int resume_f(BlockBackend *blk, int argc, char **argv)
2506 {
2507     int ret;
2508 
2509     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2510     if (ret < 0) {
2511         printf("Could not resume request: %s\n", strerror(-ret));
2512         return ret;
2513     }
2514 
2515     return 0;
2516 }
2517 
2518 static const cmdinfo_t resume_cmd = {
2519        .name           = "resume",
2520        .argmin         = 1,
2521        .argmax         = 1,
2522        .cfunc          = resume_f,
2523        .args           = "tag",
2524        .oneline        = "resumes the request tagged as tag",
2525 };
2526 
2527 static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2528 {
2529     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2530         aio_poll(blk_get_aio_context(blk), true);
2531     }
2532     return 0;
2533 }
2534 
2535 static const cmdinfo_t wait_break_cmd = {
2536        .name           = "wait_break",
2537        .argmin         = 1,
2538        .argmax         = 1,
2539        .cfunc          = wait_break_f,
2540        .args           = "tag",
2541        .oneline        = "waits for the suspension of a request",
2542 };
2543 
2544 static int abort_f(BlockBackend *blk, int argc, char **argv)
2545 {
2546     abort();
2547 }
2548 
2549 static const cmdinfo_t abort_cmd = {
2550        .name           = "abort",
2551        .cfunc          = abort_f,
2552        .flags          = CMD_NOFILE_OK,
2553        .oneline        = "simulate a program crash using abort(3)",
2554 };
2555 
2556 static void sigraise_help(void)
2557 {
2558     printf(
2559 "\n"
2560 " raises the given signal\n"
2561 "\n"
2562 " Example:\n"
2563 " 'sigraise %i' - raises SIGTERM\n"
2564 "\n"
2565 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2566 " given to sigraise.\n"
2567 "\n", SIGTERM);
2568 }
2569 
2570 static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2571 
2572 static const cmdinfo_t sigraise_cmd = {
2573     .name       = "sigraise",
2574     .cfunc      = sigraise_f,
2575     .argmin     = 1,
2576     .argmax     = 1,
2577     .flags      = CMD_NOFILE_OK,
2578     .args       = "signal",
2579     .oneline    = "raises a signal",
2580     .help       = sigraise_help,
2581 };
2582 
2583 static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2584 {
2585     int64_t sig = cvtnum(argv[1]);
2586     if (sig < 0) {
2587         print_cvtnum_err(sig, argv[1]);
2588         return sig;
2589     } else if (sig > NSIG) {
2590         printf("signal argument '%s' is too large to be a valid signal\n",
2591                argv[1]);
2592         return -EINVAL;
2593     }
2594 
2595     /* Using raise() to kill this process does not necessarily flush all open
2596      * streams. At least stdout and stderr (although the latter should be
2597      * non-buffered anyway) should be flushed, though. */
2598     fflush(stdout);
2599     fflush(stderr);
2600 
2601     raise(sig);
2602 
2603     return 0;
2604 }
2605 
2606 static void sleep_cb(void *opaque)
2607 {
2608     bool *expired = opaque;
2609     *expired = true;
2610 }
2611 
2612 static int sleep_f(BlockBackend *blk, int argc, char **argv)
2613 {
2614     char *endptr;
2615     long ms;
2616     struct QEMUTimer *timer;
2617     bool expired = false;
2618 
2619     ms = strtol(argv[1], &endptr, 0);
2620     if (ms < 0 || *endptr != '\0') {
2621         printf("%s is not a valid number\n", argv[1]);
2622         return -EINVAL;
2623     }
2624 
2625     timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2626     timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2627 
2628     while (!expired) {
2629         main_loop_wait(false);
2630     }
2631 
2632     timer_free(timer);
2633     return 0;
2634 }
2635 
2636 static const cmdinfo_t sleep_cmd = {
2637        .name           = "sleep",
2638        .argmin         = 1,
2639        .argmax         = 1,
2640        .cfunc          = sleep_f,
2641        .flags          = CMD_NOFILE_OK,
2642        .oneline        = "waits for the given value in milliseconds",
2643 };
2644 
2645 static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2646 {
2647     printf("%s ", cmd);
2648 
2649     if (ct->args) {
2650         printf("%s ", ct->args);
2651     }
2652     printf("-- %s\n", ct->oneline);
2653 }
2654 
2655 static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2656 {
2657     help_oneline(cmd, ct);
2658     if (ct->help) {
2659         ct->help();
2660     }
2661 }
2662 
2663 static void help_all(void)
2664 {
2665     const cmdinfo_t *ct;
2666 
2667     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2668         help_oneline(ct->name, ct);
2669     }
2670     printf("\nUse 'help commandname' for extended help.\n");
2671 }
2672 
2673 static int help_f(BlockBackend *blk, int argc, char **argv)
2674 {
2675     const cmdinfo_t *ct;
2676 
2677     if (argc < 2) {
2678         help_all();
2679         return 0;
2680     }
2681 
2682     ct = find_command(argv[1]);
2683     if (ct == NULL) {
2684         printf("command %s not found\n", argv[1]);
2685         return -EINVAL;
2686     }
2687 
2688     help_onecmd(argv[1], ct);
2689     return 0;
2690 }
2691 
2692 static const cmdinfo_t help_cmd = {
2693     .name       = "help",
2694     .altname    = "?",
2695     .cfunc      = help_f,
2696     .argmin     = 0,
2697     .argmax     = 1,
2698     .flags      = CMD_FLAG_GLOBAL,
2699     .args       = "[command]",
2700     .oneline    = "help for one or all commands",
2701 };
2702 
2703 /*
2704  * Called with aio context of blk acquired. Or with qemu_get_aio_context()
2705  * context acquired if blk is NULL.
2706  */
2707 int qemuio_command(BlockBackend *blk, const char *cmd)
2708 {
2709     char *input;
2710     const cmdinfo_t *ct;
2711     char **v;
2712     int c;
2713     int ret = 0;
2714 
2715     input = g_strdup(cmd);
2716     v = breakline(input, &c);
2717     if (c) {
2718         ct = find_command(v[0]);
2719         if (ct) {
2720             ret = command(blk, ct, c, v);
2721         } else {
2722             fprintf(stderr, "command \"%s\" not found\n", v[0]);
2723             ret = -EINVAL;
2724         }
2725     }
2726     g_free(input);
2727     g_free(v);
2728 
2729     return ret;
2730 }
2731 
2732 static void __attribute((constructor)) init_qemuio_commands(void)
2733 {
2734     /* initialize commands */
2735     qemuio_add_command(&help_cmd);
2736     qemuio_add_command(&read_cmd);
2737     qemuio_add_command(&readv_cmd);
2738     qemuio_add_command(&write_cmd);
2739     qemuio_add_command(&writev_cmd);
2740     qemuio_add_command(&aio_read_cmd);
2741     qemuio_add_command(&aio_write_cmd);
2742     qemuio_add_command(&aio_flush_cmd);
2743     qemuio_add_command(&flush_cmd);
2744     qemuio_add_command(&zone_report_cmd);
2745     qemuio_add_command(&zone_open_cmd);
2746     qemuio_add_command(&zone_close_cmd);
2747     qemuio_add_command(&zone_finish_cmd);
2748     qemuio_add_command(&zone_reset_cmd);
2749     qemuio_add_command(&zone_append_cmd);
2750     qemuio_add_command(&truncate_cmd);
2751     qemuio_add_command(&length_cmd);
2752     qemuio_add_command(&info_cmd);
2753     qemuio_add_command(&discard_cmd);
2754     qemuio_add_command(&alloc_cmd);
2755     qemuio_add_command(&map_cmd);
2756     qemuio_add_command(&reopen_cmd);
2757     qemuio_add_command(&break_cmd);
2758     qemuio_add_command(&remove_break_cmd);
2759     qemuio_add_command(&resume_cmd);
2760     qemuio_add_command(&wait_break_cmd);
2761     qemuio_add_command(&abort_cmd);
2762     qemuio_add_command(&sleep_cmd);
2763     qemuio_add_command(&sigraise_cmd);
2764 }
2765