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