xref: /openbmc/qemu/qemu-io-cmds.c (revision 5242ef88)
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 {
343     void *buf;
344 
345     if (qemuio_misalign) {
346         len += MISALIGN_OFFSET;
347     }
348     buf = blk_blockalign(blk, len);
349     memset(buf, pattern, len);
350     if (qemuio_misalign) {
351         buf += MISALIGN_OFFSET;
352     }
353     return buf;
354 }
355 
356 static void qemu_io_free(void *p)
357 {
358     if (qemuio_misalign) {
359         p -= MISALIGN_OFFSET;
360     }
361     qemu_vfree(p);
362 }
363 
364 /*
365  * qemu_io_alloc_from_file()
366  *
367  * Allocates the buffer and populates it with the content of the given file
368  * up to @len bytes. If the file length is less than @len, then the buffer
369  * is populated with the file content cyclically.
370  *
371  * @blk - the block backend where the buffer content is going to be written to
372  * @len - the buffer length
373  * @file_name - the file to read the content from
374  *
375  * Returns: the buffer pointer on success
376  *          NULL on error
377  */
378 static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
379                                      const char *file_name)
380 {
381     char *buf, *buf_origin;
382     FILE *f = fopen(file_name, "r");
383     int pattern_len;
384 
385     if (!f) {
386         perror(file_name);
387         return NULL;
388     }
389 
390     if (qemuio_misalign) {
391         len += MISALIGN_OFFSET;
392     }
393 
394     buf_origin = buf = blk_blockalign(blk, len);
395 
396     if (qemuio_misalign) {
397         buf_origin += MISALIGN_OFFSET;
398         buf += MISALIGN_OFFSET;
399         len -= MISALIGN_OFFSET;
400     }
401 
402     pattern_len = fread(buf_origin, 1, len, f);
403 
404     if (ferror(f)) {
405         perror(file_name);
406         goto error;
407     }
408 
409     if (pattern_len == 0) {
410         fprintf(stderr, "%s: file is empty\n", file_name);
411         goto error;
412     }
413 
414     fclose(f);
415     f = NULL;
416 
417     if (len > pattern_len) {
418         len -= pattern_len;
419         buf += pattern_len;
420 
421         while (len > 0) {
422             size_t len_to_copy = MIN(pattern_len, len);
423 
424             memcpy(buf, buf_origin, len_to_copy);
425 
426             len -= len_to_copy;
427             buf += len_to_copy;
428         }
429     }
430 
431     return buf_origin;
432 
433 error:
434     qemu_io_free(buf_origin);
435     if (f) {
436         fclose(f);
437     }
438     return NULL;
439 }
440 
441 static void dump_buffer(const void *buffer, int64_t offset, int64_t len)
442 {
443     uint64_t i;
444     int j;
445     const uint8_t *p;
446 
447     for (i = 0, p = buffer; i < len; i += 16) {
448         const uint8_t *s = p;
449 
450         printf("%08" PRIx64 ":  ", offset + i);
451         for (j = 0; j < 16 && i + j < len; j++, p++) {
452             printf("%02x ", *p);
453         }
454         printf(" ");
455         for (j = 0; j < 16 && i + j < len; j++, s++) {
456             if (isalnum(*s)) {
457                 printf("%c", *s);
458             } else {
459                 printf(".");
460             }
461         }
462         printf("\n");
463     }
464 }
465 
466 static void print_report(const char *op, struct timespec *t, int64_t offset,
467                          int64_t count, int64_t total, int cnt, bool Cflag)
468 {
469     char s1[64], s2[64], ts[64];
470 
471     timestr(t, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
472     if (!Cflag) {
473         cvtstr((double)total, s1, sizeof(s1));
474         cvtstr(tdiv((double)total, *t), s2, sizeof(s2));
475         printf("%s %"PRId64"/%"PRId64" bytes at offset %" PRId64 "\n",
476                op, total, count, offset);
477         printf("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n",
478                s1, cnt, ts, s2, tdiv((double)cnt, *t));
479     } else {/* bytes,ops,time,bytes/sec,ops/sec */
480         printf("%"PRId64",%d,%s,%.3f,%.3f\n",
481             total, cnt, ts,
482             tdiv((double)total, *t),
483             tdiv((double)cnt, *t));
484     }
485 }
486 
487 /*
488  * Parse multiple length statements for vectored I/O, and construct an I/O
489  * vector matching it.
490  */
491 static void *
492 create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
493              int pattern)
494 {
495     size_t *sizes = g_new0(size_t, nr_iov);
496     size_t count = 0;
497     void *buf = NULL;
498     void *p;
499     int i;
500 
501     for (i = 0; i < nr_iov; i++) {
502         char *arg = argv[i];
503         int64_t len;
504 
505         len = cvtnum(arg);
506         if (len < 0) {
507             print_cvtnum_err(len, arg);
508             goto fail;
509         }
510 
511         if (len > BDRV_REQUEST_MAX_BYTES) {
512             printf("Argument '%s' exceeds maximum size %" PRIu64 "\n", arg,
513                    (uint64_t)BDRV_REQUEST_MAX_BYTES);
514             goto fail;
515         }
516 
517         if (count > BDRV_REQUEST_MAX_BYTES - len) {
518             printf("The total number of bytes exceed the maximum size %" PRIu64
519                    "\n", (uint64_t)BDRV_REQUEST_MAX_BYTES);
520             goto fail;
521         }
522 
523         sizes[i] = len;
524         count += len;
525     }
526 
527     qemu_iovec_init(qiov, nr_iov);
528 
529     buf = p = qemu_io_alloc(blk, count, pattern);
530 
531     for (i = 0; i < nr_iov; i++) {
532         qemu_iovec_add(qiov, p, sizes[i]);
533         p += sizes[i];
534     }
535 
536 fail:
537     g_free(sizes);
538     return buf;
539 }
540 
541 static int do_pread(BlockBackend *blk, char *buf, int64_t offset,
542                     int64_t bytes, int64_t *total)
543 {
544     if (bytes > INT_MAX) {
545         return -ERANGE;
546     }
547 
548     *total = blk_pread(blk, offset, (uint8_t *)buf, bytes);
549     if (*total < 0) {
550         return *total;
551     }
552     return 1;
553 }
554 
555 static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset,
556                      int64_t bytes, int flags, int64_t *total)
557 {
558     if (bytes > INT_MAX) {
559         return -ERANGE;
560     }
561 
562     *total = blk_pwrite(blk, offset, (uint8_t *)buf, bytes, flags);
563     if (*total < 0) {
564         return *total;
565     }
566     return 1;
567 }
568 
569 typedef struct {
570     BlockBackend *blk;
571     int64_t offset;
572     int64_t bytes;
573     int64_t *total;
574     int flags;
575     int ret;
576     bool done;
577 } CoWriteZeroes;
578 
579 static void coroutine_fn co_pwrite_zeroes_entry(void *opaque)
580 {
581     CoWriteZeroes *data = opaque;
582 
583     data->ret = blk_co_pwrite_zeroes(data->blk, data->offset, data->bytes,
584                                      data->flags);
585     data->done = true;
586     if (data->ret < 0) {
587         *data->total = data->ret;
588         return;
589     }
590 
591     *data->total = data->bytes;
592 }
593 
594 static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
595                                int64_t bytes, int flags, int64_t *total)
596 {
597     Coroutine *co;
598     CoWriteZeroes data = {
599         .blk    = blk,
600         .offset = offset,
601         .bytes  = bytes,
602         .total  = total,
603         .flags  = flags,
604         .done   = false,
605     };
606 
607     co = qemu_coroutine_create(co_pwrite_zeroes_entry, &data);
608     bdrv_coroutine_enter(blk_bs(blk), co);
609     while (!data.done) {
610         aio_poll(blk_get_aio_context(blk), true);
611     }
612     if (data.ret < 0) {
613         return data.ret;
614     } else {
615         return 1;
616     }
617 }
618 
619 static int do_write_compressed(BlockBackend *blk, char *buf, int64_t offset,
620                                int64_t bytes, int64_t *total)
621 {
622     int ret;
623 
624     if (bytes > BDRV_REQUEST_MAX_BYTES) {
625         return -ERANGE;
626     }
627 
628     ret = blk_pwrite_compressed(blk, offset, buf, bytes);
629     if (ret < 0) {
630         return ret;
631     }
632     *total = bytes;
633     return 1;
634 }
635 
636 static int do_load_vmstate(BlockBackend *blk, char *buf, int64_t offset,
637                            int64_t count, int64_t *total)
638 {
639     if (count > INT_MAX) {
640         return -ERANGE;
641     }
642 
643     *total = blk_load_vmstate(blk, (uint8_t *)buf, offset, count);
644     if (*total < 0) {
645         return *total;
646     }
647     return 1;
648 }
649 
650 static int do_save_vmstate(BlockBackend *blk, char *buf, int64_t offset,
651                            int64_t count, int64_t *total)
652 {
653     if (count > INT_MAX) {
654         return -ERANGE;
655     }
656 
657     *total = blk_save_vmstate(blk, (uint8_t *)buf, offset, count);
658     if (*total < 0) {
659         return *total;
660     }
661     return 1;
662 }
663 
664 #define NOT_DONE 0x7fffffff
665 static void aio_rw_done(void *opaque, int ret)
666 {
667     *(int *)opaque = ret;
668 }
669 
670 static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov,
671                         int64_t offset, int *total)
672 {
673     int async_ret = NOT_DONE;
674 
675     blk_aio_preadv(blk, offset, qiov, 0, aio_rw_done, &async_ret);
676     while (async_ret == NOT_DONE) {
677         main_loop_wait(false);
678     }
679 
680     *total = qiov->size;
681     return async_ret < 0 ? async_ret : 1;
682 }
683 
684 static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov,
685                          int64_t offset, int flags, int *total)
686 {
687     int async_ret = NOT_DONE;
688 
689     blk_aio_pwritev(blk, offset, qiov, flags, aio_rw_done, &async_ret);
690     while (async_ret == NOT_DONE) {
691         main_loop_wait(false);
692     }
693 
694     *total = qiov->size;
695     return async_ret < 0 ? async_ret : 1;
696 }
697 
698 static void read_help(void)
699 {
700     printf(
701 "\n"
702 " reads a range of bytes from the given offset\n"
703 "\n"
704 " Example:\n"
705 " 'read -v 512 1k' - dumps 1 kilobyte read from 512 bytes into the file\n"
706 "\n"
707 " Reads a segment of the currently open file, optionally dumping it to the\n"
708 " standard output stream (with -v option) for subsequent inspection.\n"
709 " -b, -- read from the VM state rather than the virtual disk\n"
710 " -C, -- report statistics in a machine parsable format\n"
711 " -l, -- length for pattern verification (only with -P)\n"
712 " -p, -- ignored for backwards compatibility\n"
713 " -P, -- use a pattern to verify read data\n"
714 " -q, -- quiet mode, do not show I/O statistics\n"
715 " -s, -- start offset for pattern verification (only with -P)\n"
716 " -v, -- dump buffer to standard output\n"
717 "\n");
718 }
719 
720 static int read_f(BlockBackend *blk, int argc, char **argv);
721 
722 static const cmdinfo_t read_cmd = {
723     .name       = "read",
724     .altname    = "r",
725     .cfunc      = read_f,
726     .argmin     = 2,
727     .argmax     = -1,
728     .args       = "[-abCqv] [-P pattern [-s off] [-l len]] off len",
729     .oneline    = "reads a number of bytes at a specified offset",
730     .help       = read_help,
731 };
732 
733 static int read_f(BlockBackend *blk, int argc, char **argv)
734 {
735     struct timespec t1, t2;
736     bool Cflag = false, qflag = false, vflag = false;
737     bool Pflag = false, sflag = false, lflag = false, bflag = false;
738     int c, cnt, ret;
739     char *buf;
740     int64_t offset;
741     int64_t count;
742     /* Some compilers get confused and warn if this is not initialized.  */
743     int64_t total = 0;
744     int pattern = 0;
745     int64_t pattern_offset = 0, pattern_count = 0;
746 
747     while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) {
748         switch (c) {
749         case 'b':
750             bflag = true;
751             break;
752         case 'C':
753             Cflag = true;
754             break;
755         case 'l':
756             lflag = true;
757             pattern_count = cvtnum(optarg);
758             if (pattern_count < 0) {
759                 print_cvtnum_err(pattern_count, optarg);
760                 return pattern_count;
761             }
762             break;
763         case 'p':
764             /* Ignored for backwards compatibility */
765             break;
766         case 'P':
767             Pflag = true;
768             pattern = parse_pattern(optarg);
769             if (pattern < 0) {
770                 return -EINVAL;
771             }
772             break;
773         case 'q':
774             qflag = true;
775             break;
776         case 's':
777             sflag = true;
778             pattern_offset = cvtnum(optarg);
779             if (pattern_offset < 0) {
780                 print_cvtnum_err(pattern_offset, optarg);
781                 return pattern_offset;
782             }
783             break;
784         case 'v':
785             vflag = true;
786             break;
787         default:
788             qemuio_command_usage(&read_cmd);
789             return -EINVAL;
790         }
791     }
792 
793     if (optind != argc - 2) {
794         qemuio_command_usage(&read_cmd);
795         return -EINVAL;
796     }
797 
798     offset = cvtnum(argv[optind]);
799     if (offset < 0) {
800         print_cvtnum_err(offset, argv[optind]);
801         return offset;
802     }
803 
804     optind++;
805     count = cvtnum(argv[optind]);
806     if (count < 0) {
807         print_cvtnum_err(count, argv[optind]);
808         return count;
809     } else if (count > BDRV_REQUEST_MAX_BYTES) {
810         printf("length cannot exceed %" PRIu64 ", given %s\n",
811                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
812         return -EINVAL;
813     }
814 
815     if (!Pflag && (lflag || sflag)) {
816         qemuio_command_usage(&read_cmd);
817         return -EINVAL;
818     }
819 
820     if (!lflag) {
821         pattern_count = count - pattern_offset;
822     }
823 
824     if ((pattern_count < 0) || (pattern_count + pattern_offset > count))  {
825         printf("pattern verification range exceeds end of read data\n");
826         return -EINVAL;
827     }
828 
829     if (bflag) {
830         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
831             printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
832                    offset);
833             return -EINVAL;
834         }
835         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
836             printf("%"PRId64" is not a sector-aligned value for 'count'\n",
837                    count);
838             return -EINVAL;
839         }
840     }
841 
842     buf = qemu_io_alloc(blk, count, 0xab);
843 
844     clock_gettime(CLOCK_MONOTONIC, &t1);
845     if (bflag) {
846         ret = do_load_vmstate(blk, buf, offset, count, &total);
847     } else {
848         ret = do_pread(blk, buf, offset, count, &total);
849     }
850     clock_gettime(CLOCK_MONOTONIC, &t2);
851 
852     if (ret < 0) {
853         printf("read failed: %s\n", strerror(-ret));
854         goto out;
855     }
856     cnt = ret;
857 
858     ret = 0;
859 
860     if (Pflag) {
861         void *cmp_buf = g_malloc(pattern_count);
862         memset(cmp_buf, pattern, pattern_count);
863         if (memcmp(buf + pattern_offset, cmp_buf, pattern_count)) {
864             printf("Pattern verification failed at offset %"
865                    PRId64 ", %"PRId64" bytes\n",
866                    offset + pattern_offset, pattern_count);
867             ret = -EINVAL;
868         }
869         g_free(cmp_buf);
870     }
871 
872     if (qflag) {
873         goto out;
874     }
875 
876     if (vflag) {
877         dump_buffer(buf, offset, count);
878     }
879 
880     /* Finally, report back -- -C gives a parsable format */
881     t2 = tsub(t2, t1);
882     print_report("read", &t2, offset, count, total, cnt, Cflag);
883 
884 out:
885     qemu_io_free(buf);
886     return ret;
887 }
888 
889 static void readv_help(void)
890 {
891     printf(
892 "\n"
893 " reads a range of bytes from the given offset into multiple buffers\n"
894 "\n"
895 " Example:\n"
896 " 'readv -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
897 "\n"
898 " Reads a segment of the currently open file, optionally dumping it to the\n"
899 " standard output stream (with -v option) for subsequent inspection.\n"
900 " Uses multiple iovec buffers if more than one byte range is specified.\n"
901 " -C, -- report statistics in a machine parsable format\n"
902 " -P, -- use a pattern to verify read data\n"
903 " -v, -- dump buffer to standard output\n"
904 " -q, -- quiet mode, do not show I/O statistics\n"
905 "\n");
906 }
907 
908 static int readv_f(BlockBackend *blk, int argc, char **argv);
909 
910 static const cmdinfo_t readv_cmd = {
911     .name       = "readv",
912     .cfunc      = readv_f,
913     .argmin     = 2,
914     .argmax     = -1,
915     .args       = "[-Cqv] [-P pattern] off len [len..]",
916     .oneline    = "reads a number of bytes at a specified offset",
917     .help       = readv_help,
918 };
919 
920 static int readv_f(BlockBackend *blk, int argc, char **argv)
921 {
922     struct timespec t1, t2;
923     bool Cflag = false, qflag = false, vflag = false;
924     int c, cnt, ret;
925     char *buf;
926     int64_t offset;
927     /* Some compilers get confused and warn if this is not initialized.  */
928     int total = 0;
929     int nr_iov;
930     QEMUIOVector qiov;
931     int pattern = 0;
932     bool Pflag = false;
933 
934     while ((c = getopt(argc, argv, "CP:qv")) != -1) {
935         switch (c) {
936         case 'C':
937             Cflag = true;
938             break;
939         case 'P':
940             Pflag = true;
941             pattern = parse_pattern(optarg);
942             if (pattern < 0) {
943                 return -EINVAL;
944             }
945             break;
946         case 'q':
947             qflag = true;
948             break;
949         case 'v':
950             vflag = true;
951             break;
952         default:
953             qemuio_command_usage(&readv_cmd);
954             return -EINVAL;
955         }
956     }
957 
958     if (optind > argc - 2) {
959         qemuio_command_usage(&readv_cmd);
960         return -EINVAL;
961     }
962 
963 
964     offset = cvtnum(argv[optind]);
965     if (offset < 0) {
966         print_cvtnum_err(offset, argv[optind]);
967         return offset;
968     }
969     optind++;
970 
971     nr_iov = argc - optind;
972     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab);
973     if (buf == NULL) {
974         return -EINVAL;
975     }
976 
977     clock_gettime(CLOCK_MONOTONIC, &t1);
978     ret = do_aio_readv(blk, &qiov, offset, &total);
979     clock_gettime(CLOCK_MONOTONIC, &t2);
980 
981     if (ret < 0) {
982         printf("readv failed: %s\n", strerror(-ret));
983         goto out;
984     }
985     cnt = ret;
986 
987     ret = 0;
988 
989     if (Pflag) {
990         void *cmp_buf = g_malloc(qiov.size);
991         memset(cmp_buf, pattern, qiov.size);
992         if (memcmp(buf, cmp_buf, qiov.size)) {
993             printf("Pattern verification failed at offset %"
994                    PRId64 ", %zu bytes\n", offset, qiov.size);
995             ret = -EINVAL;
996         }
997         g_free(cmp_buf);
998     }
999 
1000     if (qflag) {
1001         goto out;
1002     }
1003 
1004     if (vflag) {
1005         dump_buffer(buf, offset, qiov.size);
1006     }
1007 
1008     /* Finally, report back -- -C gives a parsable format */
1009     t2 = tsub(t2, t1);
1010     print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);
1011 
1012 out:
1013     qemu_iovec_destroy(&qiov);
1014     qemu_io_free(buf);
1015     return ret;
1016 }
1017 
1018 static void write_help(void)
1019 {
1020     printf(
1021 "\n"
1022 " writes a range of bytes from the given offset\n"
1023 "\n"
1024 " Example:\n"
1025 " 'write 512 1k' - writes 1 kilobyte at 512 bytes into the open file\n"
1026 "\n"
1027 " Writes into a segment of the currently open file, using a buffer\n"
1028 " filled with a set pattern (0xcdcdcdcd).\n"
1029 " -b, -- write to the VM state rather than the virtual disk\n"
1030 " -c, -- write compressed data with blk_write_compressed\n"
1031 " -f, -- use Force Unit Access semantics\n"
1032 " -n, -- with -z, don't allow slow fallback\n"
1033 " -p, -- ignored for backwards compatibility\n"
1034 " -P, -- use different pattern to fill file\n"
1035 " -s, -- use a pattern file to fill the write buffer\n"
1036 " -C, -- report statistics in a machine parsable format\n"
1037 " -q, -- quiet mode, do not show I/O statistics\n"
1038 " -u, -- with -z, allow unmapping\n"
1039 " -z, -- write zeroes using blk_co_pwrite_zeroes\n"
1040 "\n");
1041 }
1042 
1043 static int write_f(BlockBackend *blk, int argc, char **argv);
1044 
1045 static const cmdinfo_t write_cmd = {
1046     .name       = "write",
1047     .altname    = "w",
1048     .cfunc      = write_f,
1049     .perm       = BLK_PERM_WRITE,
1050     .argmin     = 2,
1051     .argmax     = -1,
1052     .args       = "[-bcCfnquz] [-P pattern | -s source_file] off len",
1053     .oneline    = "writes a number of bytes at a specified offset",
1054     .help       = write_help,
1055 };
1056 
1057 static int write_f(BlockBackend *blk, int argc, char **argv)
1058 {
1059     struct timespec t1, t2;
1060     bool Cflag = false, qflag = false, bflag = false;
1061     bool Pflag = false, zflag = false, cflag = false, sflag = false;
1062     int flags = 0;
1063     int c, cnt, ret;
1064     char *buf = NULL;
1065     int64_t offset;
1066     int64_t count;
1067     /* Some compilers get confused and warn if this is not initialized.  */
1068     int64_t total = 0;
1069     int pattern = 0xcd;
1070     const char *file_name = NULL;
1071 
1072     while ((c = getopt(argc, argv, "bcCfnpP:qs:uz")) != -1) {
1073         switch (c) {
1074         case 'b':
1075             bflag = true;
1076             break;
1077         case 'c':
1078             cflag = true;
1079             break;
1080         case 'C':
1081             Cflag = true;
1082             break;
1083         case 'f':
1084             flags |= BDRV_REQ_FUA;
1085             break;
1086         case 'n':
1087             flags |= BDRV_REQ_NO_FALLBACK;
1088             break;
1089         case 'p':
1090             /* Ignored for backwards compatibility */
1091             break;
1092         case 'P':
1093             Pflag = true;
1094             pattern = parse_pattern(optarg);
1095             if (pattern < 0) {
1096                 return -EINVAL;
1097             }
1098             break;
1099         case 'q':
1100             qflag = true;
1101             break;
1102         case 's':
1103             sflag = true;
1104             file_name = optarg;
1105             break;
1106         case 'u':
1107             flags |= BDRV_REQ_MAY_UNMAP;
1108             break;
1109         case 'z':
1110             zflag = true;
1111             break;
1112         default:
1113             qemuio_command_usage(&write_cmd);
1114             return -EINVAL;
1115         }
1116     }
1117 
1118     if (optind != argc - 2) {
1119         qemuio_command_usage(&write_cmd);
1120         return -EINVAL;
1121     }
1122 
1123     if (bflag && zflag) {
1124         printf("-b and -z cannot be specified at the same time\n");
1125         return -EINVAL;
1126     }
1127 
1128     if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) {
1129         printf("-f and -b or -c cannot be specified at the same time\n");
1130         return -EINVAL;
1131     }
1132 
1133     if ((flags & BDRV_REQ_NO_FALLBACK) && !zflag) {
1134         printf("-n requires -z to be specified\n");
1135         return -EINVAL;
1136     }
1137 
1138     if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) {
1139         printf("-u requires -z to be specified\n");
1140         return -EINVAL;
1141     }
1142 
1143     if (zflag + Pflag + sflag > 1) {
1144         printf("Only one of -z, -P, and -s "
1145                "can be specified at the same time\n");
1146         return -EINVAL;
1147     }
1148 
1149     offset = cvtnum(argv[optind]);
1150     if (offset < 0) {
1151         print_cvtnum_err(offset, argv[optind]);
1152         return offset;
1153     }
1154 
1155     optind++;
1156     count = cvtnum(argv[optind]);
1157     if (count < 0) {
1158         print_cvtnum_err(count, argv[optind]);
1159         return count;
1160     } else if (count > BDRV_REQUEST_MAX_BYTES &&
1161                !(flags & BDRV_REQ_NO_FALLBACK)) {
1162         printf("length cannot exceed %" PRIu64 " without -n, given %s\n",
1163                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1164         return -EINVAL;
1165     }
1166 
1167     if (bflag || cflag) {
1168         if (!QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE)) {
1169             printf("%" PRId64 " is not a sector-aligned value for 'offset'\n",
1170                    offset);
1171             return -EINVAL;
1172         }
1173 
1174         if (!QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE)) {
1175             printf("%"PRId64" is not a sector-aligned value for 'count'\n",
1176                    count);
1177             return -EINVAL;
1178         }
1179     }
1180 
1181     if (!zflag) {
1182         if (sflag) {
1183             buf = qemu_io_alloc_from_file(blk, count, file_name);
1184             if (!buf) {
1185                 return -EINVAL;
1186             }
1187         } else {
1188             buf = qemu_io_alloc(blk, count, pattern);
1189         }
1190     }
1191 
1192     clock_gettime(CLOCK_MONOTONIC, &t1);
1193     if (bflag) {
1194         ret = do_save_vmstate(blk, buf, offset, count, &total);
1195     } else if (zflag) {
1196         ret = do_co_pwrite_zeroes(blk, offset, count, flags, &total);
1197     } else if (cflag) {
1198         ret = do_write_compressed(blk, buf, offset, count, &total);
1199     } else {
1200         ret = do_pwrite(blk, buf, offset, count, flags, &total);
1201     }
1202     clock_gettime(CLOCK_MONOTONIC, &t2);
1203 
1204     if (ret < 0) {
1205         printf("write failed: %s\n", strerror(-ret));
1206         goto out;
1207     }
1208     cnt = ret;
1209 
1210     ret = 0;
1211 
1212     if (qflag) {
1213         goto out;
1214     }
1215 
1216     /* Finally, report back -- -C gives a parsable format */
1217     t2 = tsub(t2, t1);
1218     print_report("wrote", &t2, offset, count, total, cnt, Cflag);
1219 
1220 out:
1221     if (!zflag) {
1222         qemu_io_free(buf);
1223     }
1224     return ret;
1225 }
1226 
1227 static void
1228 writev_help(void)
1229 {
1230     printf(
1231 "\n"
1232 " writes a range of bytes from the given offset source from multiple buffers\n"
1233 "\n"
1234 " Example:\n"
1235 " 'writev 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1236 "\n"
1237 " Writes into a segment of the currently open file, using a buffer\n"
1238 " filled with a set pattern (0xcdcdcdcd).\n"
1239 " -P, -- use different pattern to fill file\n"
1240 " -C, -- report statistics in a machine parsable format\n"
1241 " -f, -- use Force Unit Access semantics\n"
1242 " -q, -- quiet mode, do not show I/O statistics\n"
1243 "\n");
1244 }
1245 
1246 static int writev_f(BlockBackend *blk, int argc, char **argv);
1247 
1248 static const cmdinfo_t writev_cmd = {
1249     .name       = "writev",
1250     .cfunc      = writev_f,
1251     .perm       = BLK_PERM_WRITE,
1252     .argmin     = 2,
1253     .argmax     = -1,
1254     .args       = "[-Cfq] [-P pattern] off len [len..]",
1255     .oneline    = "writes a number of bytes at a specified offset",
1256     .help       = writev_help,
1257 };
1258 
1259 static int writev_f(BlockBackend *blk, int argc, char **argv)
1260 {
1261     struct timespec t1, t2;
1262     bool Cflag = false, qflag = false;
1263     int flags = 0;
1264     int c, cnt, ret;
1265     char *buf;
1266     int64_t offset;
1267     /* Some compilers get confused and warn if this is not initialized.  */
1268     int total = 0;
1269     int nr_iov;
1270     int pattern = 0xcd;
1271     QEMUIOVector qiov;
1272 
1273     while ((c = getopt(argc, argv, "CfqP:")) != -1) {
1274         switch (c) {
1275         case 'C':
1276             Cflag = true;
1277             break;
1278         case 'f':
1279             flags |= BDRV_REQ_FUA;
1280             break;
1281         case 'q':
1282             qflag = true;
1283             break;
1284         case 'P':
1285             pattern = parse_pattern(optarg);
1286             if (pattern < 0) {
1287                 return -EINVAL;
1288             }
1289             break;
1290         default:
1291             qemuio_command_usage(&writev_cmd);
1292             return -EINVAL;
1293         }
1294     }
1295 
1296     if (optind > argc - 2) {
1297         qemuio_command_usage(&writev_cmd);
1298         return -EINVAL;
1299     }
1300 
1301     offset = cvtnum(argv[optind]);
1302     if (offset < 0) {
1303         print_cvtnum_err(offset, argv[optind]);
1304         return offset;
1305     }
1306     optind++;
1307 
1308     nr_iov = argc - optind;
1309     buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern);
1310     if (buf == NULL) {
1311         return -EINVAL;
1312     }
1313 
1314     clock_gettime(CLOCK_MONOTONIC, &t1);
1315     ret = do_aio_writev(blk, &qiov, offset, flags, &total);
1316     clock_gettime(CLOCK_MONOTONIC, &t2);
1317 
1318     if (ret < 0) {
1319         printf("writev failed: %s\n", strerror(-ret));
1320         goto out;
1321     }
1322     cnt = ret;
1323 
1324     ret = 0;
1325 
1326     if (qflag) {
1327         goto out;
1328     }
1329 
1330     /* Finally, report back -- -C gives a parsable format */
1331     t2 = tsub(t2, t1);
1332     print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag);
1333 out:
1334     qemu_iovec_destroy(&qiov);
1335     qemu_io_free(buf);
1336     return ret;
1337 }
1338 
1339 struct aio_ctx {
1340     BlockBackend *blk;
1341     QEMUIOVector qiov;
1342     int64_t offset;
1343     char *buf;
1344     bool qflag;
1345     bool vflag;
1346     bool Cflag;
1347     bool Pflag;
1348     bool zflag;
1349     BlockAcctCookie acct;
1350     int pattern;
1351     struct timespec t1;
1352 };
1353 
1354 static void aio_write_done(void *opaque, int ret)
1355 {
1356     struct aio_ctx *ctx = opaque;
1357     struct timespec t2;
1358 
1359     clock_gettime(CLOCK_MONOTONIC, &t2);
1360 
1361 
1362     if (ret < 0) {
1363         printf("aio_write failed: %s\n", strerror(-ret));
1364         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1365         goto out;
1366     }
1367 
1368     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1369 
1370     if (ctx->qflag) {
1371         goto out;
1372     }
1373 
1374     /* Finally, report back -- -C gives a parsable format */
1375     t2 = tsub(t2, ctx->t1);
1376     print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
1377                  ctx->qiov.size, 1, ctx->Cflag);
1378 out:
1379     if (!ctx->zflag) {
1380         qemu_io_free(ctx->buf);
1381         qemu_iovec_destroy(&ctx->qiov);
1382     }
1383     g_free(ctx);
1384 }
1385 
1386 static void aio_read_done(void *opaque, int ret)
1387 {
1388     struct aio_ctx *ctx = opaque;
1389     struct timespec t2;
1390 
1391     clock_gettime(CLOCK_MONOTONIC, &t2);
1392 
1393     if (ret < 0) {
1394         printf("readv failed: %s\n", strerror(-ret));
1395         block_acct_failed(blk_get_stats(ctx->blk), &ctx->acct);
1396         goto out;
1397     }
1398 
1399     if (ctx->Pflag) {
1400         void *cmp_buf = g_malloc(ctx->qiov.size);
1401 
1402         memset(cmp_buf, ctx->pattern, ctx->qiov.size);
1403         if (memcmp(ctx->buf, cmp_buf, ctx->qiov.size)) {
1404             printf("Pattern verification failed at offset %"
1405                    PRId64 ", %zu bytes\n", ctx->offset, ctx->qiov.size);
1406         }
1407         g_free(cmp_buf);
1408     }
1409 
1410     block_acct_done(blk_get_stats(ctx->blk), &ctx->acct);
1411 
1412     if (ctx->qflag) {
1413         goto out;
1414     }
1415 
1416     if (ctx->vflag) {
1417         dump_buffer(ctx->buf, ctx->offset, ctx->qiov.size);
1418     }
1419 
1420     /* Finally, report back -- -C gives a parsable format */
1421     t2 = tsub(t2, ctx->t1);
1422     print_report("read", &t2, ctx->offset, ctx->qiov.size,
1423                  ctx->qiov.size, 1, ctx->Cflag);
1424 out:
1425     qemu_io_free(ctx->buf);
1426     qemu_iovec_destroy(&ctx->qiov);
1427     g_free(ctx);
1428 }
1429 
1430 static void aio_read_help(void)
1431 {
1432     printf(
1433 "\n"
1434 " asynchronously reads a range of bytes from the given offset\n"
1435 "\n"
1436 " Example:\n"
1437 " 'aio_read -v 512 1k 1k ' - dumps 2 kilobytes read from 512 bytes into the file\n"
1438 "\n"
1439 " Reads a segment of the currently open file, optionally dumping it to the\n"
1440 " standard output stream (with -v option) for subsequent inspection.\n"
1441 " The read is performed asynchronously and the aio_flush command must be\n"
1442 " used to ensure all outstanding aio requests have been completed.\n"
1443 " Note that due to its asynchronous nature, this command will be\n"
1444 " considered successful once the request is submitted, independently\n"
1445 " of potential I/O errors or pattern mismatches.\n"
1446 " -C, -- report statistics in a machine parsable format\n"
1447 " -P, -- use a pattern to verify read data\n"
1448 " -i, -- treat request as invalid, for exercising stats\n"
1449 " -v, -- dump buffer to standard output\n"
1450 " -q, -- quiet mode, do not show I/O statistics\n"
1451 "\n");
1452 }
1453 
1454 static int aio_read_f(BlockBackend *blk, int argc, char **argv);
1455 
1456 static const cmdinfo_t aio_read_cmd = {
1457     .name       = "aio_read",
1458     .cfunc      = aio_read_f,
1459     .argmin     = 2,
1460     .argmax     = -1,
1461     .args       = "[-Ciqv] [-P pattern] off len [len..]",
1462     .oneline    = "asynchronously reads a number of bytes",
1463     .help       = aio_read_help,
1464 };
1465 
1466 static int aio_read_f(BlockBackend *blk, int argc, char **argv)
1467 {
1468     int nr_iov, c;
1469     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1470 
1471     ctx->blk = blk;
1472     while ((c = getopt(argc, argv, "CP:iqv")) != -1) {
1473         switch (c) {
1474         case 'C':
1475             ctx->Cflag = true;
1476             break;
1477         case 'P':
1478             ctx->Pflag = true;
1479             ctx->pattern = parse_pattern(optarg);
1480             if (ctx->pattern < 0) {
1481                 g_free(ctx);
1482                 return -EINVAL;
1483             }
1484             break;
1485         case 'i':
1486             printf("injecting invalid read request\n");
1487             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1488             g_free(ctx);
1489             return 0;
1490         case 'q':
1491             ctx->qflag = true;
1492             break;
1493         case 'v':
1494             ctx->vflag = true;
1495             break;
1496         default:
1497             g_free(ctx);
1498             qemuio_command_usage(&aio_read_cmd);
1499             return -EINVAL;
1500         }
1501     }
1502 
1503     if (optind > argc - 2) {
1504         g_free(ctx);
1505         qemuio_command_usage(&aio_read_cmd);
1506         return -EINVAL;
1507     }
1508 
1509     ctx->offset = cvtnum(argv[optind]);
1510     if (ctx->offset < 0) {
1511         int ret = ctx->offset;
1512         print_cvtnum_err(ret, argv[optind]);
1513         g_free(ctx);
1514         return ret;
1515     }
1516     optind++;
1517 
1518     nr_iov = argc - optind;
1519     ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab);
1520     if (ctx->buf == NULL) {
1521         block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ);
1522         g_free(ctx);
1523         return -EINVAL;
1524     }
1525 
1526     clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
1527     block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1528                      BLOCK_ACCT_READ);
1529     blk_aio_preadv(blk, ctx->offset, &ctx->qiov, 0, aio_read_done, ctx);
1530     return 0;
1531 }
1532 
1533 static void aio_write_help(void)
1534 {
1535     printf(
1536 "\n"
1537 " asynchronously writes a range of bytes from the given offset source\n"
1538 " from multiple buffers\n"
1539 "\n"
1540 " Example:\n"
1541 " 'aio_write 512 1k 1k' - writes 2 kilobytes at 512 bytes into the open file\n"
1542 "\n"
1543 " Writes into a segment of the currently open file, using a buffer\n"
1544 " filled with a set pattern (0xcdcdcdcd).\n"
1545 " The write is performed asynchronously and the aio_flush command must be\n"
1546 " used to ensure all outstanding aio requests have been completed.\n"
1547 " Note that due to its asynchronous nature, this command will be\n"
1548 " considered successful once the request is submitted, independently\n"
1549 " of potential I/O errors or pattern mismatches.\n"
1550 " -P, -- use different pattern to fill file\n"
1551 " -C, -- report statistics in a machine parsable format\n"
1552 " -f, -- use Force Unit Access semantics\n"
1553 " -i, -- treat request as invalid, for exercising stats\n"
1554 " -q, -- quiet mode, do not show I/O statistics\n"
1555 " -u, -- with -z, allow unmapping\n"
1556 " -z, -- write zeroes using blk_aio_pwrite_zeroes\n"
1557 "\n");
1558 }
1559 
1560 static int aio_write_f(BlockBackend *blk, int argc, char **argv);
1561 
1562 static const cmdinfo_t aio_write_cmd = {
1563     .name       = "aio_write",
1564     .cfunc      = aio_write_f,
1565     .perm       = BLK_PERM_WRITE,
1566     .argmin     = 2,
1567     .argmax     = -1,
1568     .args       = "[-Cfiquz] [-P pattern] off len [len..]",
1569     .oneline    = "asynchronously writes a number of bytes",
1570     .help       = aio_write_help,
1571 };
1572 
1573 static int aio_write_f(BlockBackend *blk, int argc, char **argv)
1574 {
1575     int nr_iov, c;
1576     int pattern = 0xcd;
1577     struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
1578     int flags = 0;
1579 
1580     ctx->blk = blk;
1581     while ((c = getopt(argc, argv, "CfiqP:uz")) != -1) {
1582         switch (c) {
1583         case 'C':
1584             ctx->Cflag = true;
1585             break;
1586         case 'f':
1587             flags |= BDRV_REQ_FUA;
1588             break;
1589         case 'q':
1590             ctx->qflag = true;
1591             break;
1592         case 'u':
1593             flags |= BDRV_REQ_MAY_UNMAP;
1594             break;
1595         case 'P':
1596             pattern = parse_pattern(optarg);
1597             if (pattern < 0) {
1598                 g_free(ctx);
1599                 return -EINVAL;
1600             }
1601             break;
1602         case 'i':
1603             printf("injecting invalid write request\n");
1604             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1605             g_free(ctx);
1606             return 0;
1607         case 'z':
1608             ctx->zflag = true;
1609             break;
1610         default:
1611             g_free(ctx);
1612             qemuio_command_usage(&aio_write_cmd);
1613             return -EINVAL;
1614         }
1615     }
1616 
1617     if (optind > argc - 2) {
1618         g_free(ctx);
1619         qemuio_command_usage(&aio_write_cmd);
1620         return -EINVAL;
1621     }
1622 
1623     if (ctx->zflag && optind != argc - 2) {
1624         printf("-z supports only a single length parameter\n");
1625         g_free(ctx);
1626         return -EINVAL;
1627     }
1628 
1629     if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) {
1630         printf("-u requires -z to be specified\n");
1631         g_free(ctx);
1632         return -EINVAL;
1633     }
1634 
1635     if (ctx->zflag && ctx->Pflag) {
1636         printf("-z and -P cannot be specified at the same time\n");
1637         g_free(ctx);
1638         return -EINVAL;
1639     }
1640 
1641     ctx->offset = cvtnum(argv[optind]);
1642     if (ctx->offset < 0) {
1643         int ret = ctx->offset;
1644         print_cvtnum_err(ret, argv[optind]);
1645         g_free(ctx);
1646         return ret;
1647     }
1648     optind++;
1649 
1650     if (ctx->zflag) {
1651         int64_t count = cvtnum(argv[optind]);
1652         if (count < 0) {
1653             print_cvtnum_err(count, argv[optind]);
1654             g_free(ctx);
1655             return count;
1656         }
1657 
1658         ctx->qiov.size = count;
1659         blk_aio_pwrite_zeroes(blk, ctx->offset, count, flags, aio_write_done,
1660                               ctx);
1661     } else {
1662         nr_iov = argc - optind;
1663         ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
1664                                 pattern);
1665         if (ctx->buf == NULL) {
1666             block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
1667             g_free(ctx);
1668             return -EINVAL;
1669         }
1670 
1671         clock_gettime(CLOCK_MONOTONIC, &ctx->t1);
1672         block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
1673                          BLOCK_ACCT_WRITE);
1674 
1675         blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done,
1676                         ctx);
1677     }
1678 
1679     return 0;
1680 }
1681 
1682 static int aio_flush_f(BlockBackend *blk, int argc, char **argv)
1683 {
1684     BlockAcctCookie cookie;
1685     block_acct_start(blk_get_stats(blk), &cookie, 0, BLOCK_ACCT_FLUSH);
1686     blk_drain_all();
1687     block_acct_done(blk_get_stats(blk), &cookie);
1688     return 0;
1689 }
1690 
1691 static const cmdinfo_t aio_flush_cmd = {
1692     .name       = "aio_flush",
1693     .cfunc      = aio_flush_f,
1694     .oneline    = "completes all outstanding aio requests"
1695 };
1696 
1697 static int flush_f(BlockBackend *blk, int argc, char **argv)
1698 {
1699     return blk_flush(blk);
1700 }
1701 
1702 static const cmdinfo_t flush_cmd = {
1703     .name       = "flush",
1704     .altname    = "f",
1705     .cfunc      = flush_f,
1706     .oneline    = "flush all in-core file state to disk",
1707 };
1708 
1709 static int truncate_f(BlockBackend *blk, int argc, char **argv);
1710 static const cmdinfo_t truncate_cmd = {
1711     .name       = "truncate",
1712     .altname    = "t",
1713     .cfunc      = truncate_f,
1714     .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
1715     .argmin     = 1,
1716     .argmax     = 3,
1717     .args       = "[-m prealloc_mode] off",
1718     .oneline    = "truncates the current file at the given offset",
1719 };
1720 
1721 static int truncate_f(BlockBackend *blk, int argc, char **argv)
1722 {
1723     Error *local_err = NULL;
1724     int64_t offset;
1725     int c, ret;
1726     PreallocMode prealloc = PREALLOC_MODE_OFF;
1727 
1728     while ((c = getopt(argc, argv, "m:")) != -1) {
1729         switch (c) {
1730         case 'm':
1731             prealloc = qapi_enum_parse(&PreallocMode_lookup, optarg,
1732                                        PREALLOC_MODE__MAX, NULL);
1733             if (prealloc == PREALLOC_MODE__MAX) {
1734                 error_report("Invalid preallocation mode '%s'", optarg);
1735                 return -EINVAL;
1736             }
1737             break;
1738         default:
1739             qemuio_command_usage(&truncate_cmd);
1740             return -EINVAL;
1741         }
1742     }
1743 
1744     offset = cvtnum(argv[optind]);
1745     if (offset < 0) {
1746         print_cvtnum_err(offset, argv[1]);
1747         return offset;
1748     }
1749 
1750     /*
1751      * qemu-io is a debugging tool, so let us be strict here and pass
1752      * exact=true.  It is better to err on the "emit more errors" side
1753      * than to be overly permissive.
1754      */
1755     ret = blk_truncate(blk, offset, false, prealloc, 0, &local_err);
1756     if (ret < 0) {
1757         error_report_err(local_err);
1758         return ret;
1759     }
1760 
1761     return 0;
1762 }
1763 
1764 static int length_f(BlockBackend *blk, int argc, char **argv)
1765 {
1766     int64_t size;
1767     char s1[64];
1768 
1769     size = blk_getlength(blk);
1770     if (size < 0) {
1771         printf("getlength: %s\n", strerror(-size));
1772         return size;
1773     }
1774 
1775     cvtstr(size, s1, sizeof(s1));
1776     printf("%s\n", s1);
1777     return 0;
1778 }
1779 
1780 
1781 static const cmdinfo_t length_cmd = {
1782     .name   = "length",
1783     .altname    = "l",
1784     .cfunc      = length_f,
1785     .oneline    = "gets the length of the current file",
1786 };
1787 
1788 
1789 static int info_f(BlockBackend *blk, int argc, char **argv)
1790 {
1791     BlockDriverState *bs = blk_bs(blk);
1792     BlockDriverInfo bdi;
1793     ImageInfoSpecific *spec_info;
1794     Error *local_err = NULL;
1795     char s1[64], s2[64];
1796     int ret;
1797 
1798     if (bs->drv && bs->drv->format_name) {
1799         printf("format name: %s\n", bs->drv->format_name);
1800     }
1801     if (bs->drv && bs->drv->protocol_name) {
1802         printf("format name: %s\n", bs->drv->protocol_name);
1803     }
1804 
1805     ret = bdrv_get_info(bs, &bdi);
1806     if (ret) {
1807         return ret;
1808     }
1809 
1810     cvtstr(bdi.cluster_size, s1, sizeof(s1));
1811     cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1812 
1813     printf("cluster size: %s\n", s1);
1814     printf("vm state offset: %s\n", s2);
1815 
1816     spec_info = bdrv_get_specific_info(bs, &local_err);
1817     if (local_err) {
1818         error_report_err(local_err);
1819         return -EIO;
1820     }
1821     if (spec_info) {
1822         printf("Format specific information:\n");
1823         bdrv_image_info_specific_dump(spec_info);
1824         qapi_free_ImageInfoSpecific(spec_info);
1825     }
1826 
1827     return 0;
1828 }
1829 
1830 
1831 
1832 static const cmdinfo_t info_cmd = {
1833     .name       = "info",
1834     .altname    = "i",
1835     .cfunc      = info_f,
1836     .oneline    = "prints information about the current file",
1837 };
1838 
1839 static void discard_help(void)
1840 {
1841     printf(
1842 "\n"
1843 " discards a range of bytes from the given offset\n"
1844 "\n"
1845 " Example:\n"
1846 " 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1847 "\n"
1848 " Discards a segment of the currently open file.\n"
1849 " -C, -- report statistics in a machine parsable format\n"
1850 " -q, -- quiet mode, do not show I/O statistics\n"
1851 "\n");
1852 }
1853 
1854 static int discard_f(BlockBackend *blk, int argc, char **argv);
1855 
1856 static const cmdinfo_t discard_cmd = {
1857     .name       = "discard",
1858     .altname    = "d",
1859     .cfunc      = discard_f,
1860     .perm       = BLK_PERM_WRITE,
1861     .argmin     = 2,
1862     .argmax     = -1,
1863     .args       = "[-Cq] off len",
1864     .oneline    = "discards a number of bytes at a specified offset",
1865     .help       = discard_help,
1866 };
1867 
1868 static int discard_f(BlockBackend *blk, int argc, char **argv)
1869 {
1870     struct timespec t1, t2;
1871     bool Cflag = false, qflag = false;
1872     int c, ret;
1873     int64_t offset, bytes;
1874 
1875     while ((c = getopt(argc, argv, "Cq")) != -1) {
1876         switch (c) {
1877         case 'C':
1878             Cflag = true;
1879             break;
1880         case 'q':
1881             qflag = true;
1882             break;
1883         default:
1884             qemuio_command_usage(&discard_cmd);
1885             return -EINVAL;
1886         }
1887     }
1888 
1889     if (optind != argc - 2) {
1890         qemuio_command_usage(&discard_cmd);
1891         return -EINVAL;
1892     }
1893 
1894     offset = cvtnum(argv[optind]);
1895     if (offset < 0) {
1896         print_cvtnum_err(offset, argv[optind]);
1897         return offset;
1898     }
1899 
1900     optind++;
1901     bytes = cvtnum(argv[optind]);
1902     if (bytes < 0) {
1903         print_cvtnum_err(bytes, argv[optind]);
1904         return bytes;
1905     } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
1906         printf("length cannot exceed %"PRIu64", given %s\n",
1907                (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1908         return -EINVAL;
1909     }
1910 
1911     clock_gettime(CLOCK_MONOTONIC, &t1);
1912     ret = blk_pdiscard(blk, offset, bytes);
1913     clock_gettime(CLOCK_MONOTONIC, &t2);
1914 
1915     if (ret < 0) {
1916         printf("discard failed: %s\n", strerror(-ret));
1917         return ret;
1918     }
1919 
1920     /* Finally, report back -- -C gives a parsable format */
1921     if (!qflag) {
1922         t2 = tsub(t2, t1);
1923         print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
1924     }
1925 
1926     return 0;
1927 }
1928 
1929 static int alloc_f(BlockBackend *blk, int argc, char **argv)
1930 {
1931     BlockDriverState *bs = blk_bs(blk);
1932     int64_t offset, start, remaining, count;
1933     char s1[64];
1934     int ret;
1935     int64_t num, sum_alloc;
1936 
1937     start = offset = cvtnum(argv[1]);
1938     if (offset < 0) {
1939         print_cvtnum_err(offset, argv[1]);
1940         return offset;
1941     }
1942 
1943     if (argc == 3) {
1944         count = cvtnum(argv[2]);
1945         if (count < 0) {
1946             print_cvtnum_err(count, argv[2]);
1947             return count;
1948         }
1949     } else {
1950         count = BDRV_SECTOR_SIZE;
1951     }
1952 
1953     remaining = count;
1954     sum_alloc = 0;
1955     while (remaining) {
1956         ret = bdrv_is_allocated(bs, offset, remaining, &num);
1957         if (ret < 0) {
1958             printf("is_allocated failed: %s\n", strerror(-ret));
1959             return ret;
1960         }
1961         offset += num;
1962         remaining -= num;
1963         if (ret) {
1964             sum_alloc += num;
1965         }
1966         if (num == 0) {
1967             count -= remaining;
1968             remaining = 0;
1969         }
1970     }
1971 
1972     cvtstr(start, s1, sizeof(s1));
1973 
1974     printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
1975            sum_alloc, count, s1);
1976     return 0;
1977 }
1978 
1979 static const cmdinfo_t alloc_cmd = {
1980     .name       = "alloc",
1981     .altname    = "a",
1982     .argmin     = 1,
1983     .argmax     = 2,
1984     .cfunc      = alloc_f,
1985     .args       = "offset [count]",
1986     .oneline    = "checks if offset is allocated in the file",
1987 };
1988 
1989 
1990 static int map_is_allocated(BlockDriverState *bs, int64_t offset,
1991                             int64_t bytes, int64_t *pnum)
1992 {
1993     int64_t num;
1994     int ret, firstret;
1995 
1996     ret = bdrv_is_allocated(bs, offset, bytes, &num);
1997     if (ret < 0) {
1998         return ret;
1999     }
2000 
2001     firstret = ret;
2002     *pnum = num;
2003 
2004     while (bytes > 0 && ret == firstret) {
2005         offset += num;
2006         bytes -= num;
2007 
2008         ret = bdrv_is_allocated(bs, offset, bytes, &num);
2009         if (ret == firstret && num) {
2010             *pnum += num;
2011         } else {
2012             break;
2013         }
2014     }
2015 
2016     return firstret;
2017 }
2018 
2019 static int map_f(BlockBackend *blk, int argc, char **argv)
2020 {
2021     int64_t offset, bytes;
2022     char s1[64], s2[64];
2023     int64_t num;
2024     int ret;
2025     const char *retstr;
2026 
2027     offset = 0;
2028     bytes = blk_getlength(blk);
2029     if (bytes < 0) {
2030         error_report("Failed to query image length: %s", strerror(-bytes));
2031         return bytes;
2032     }
2033 
2034     while (bytes) {
2035         ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
2036         if (ret < 0) {
2037             error_report("Failed to get allocation status: %s", strerror(-ret));
2038             return ret;
2039         } else if (!num) {
2040             error_report("Unexpected end of image");
2041             return -EIO;
2042         }
2043 
2044         retstr = ret ? "    allocated" : "not allocated";
2045         cvtstr(num, s1, sizeof(s1));
2046         cvtstr(offset, s2, sizeof(s2));
2047         printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
2048                s1, num, retstr, s2, offset);
2049 
2050         offset += num;
2051         bytes -= num;
2052     }
2053 
2054     return 0;
2055 }
2056 
2057 static const cmdinfo_t map_cmd = {
2058        .name           = "map",
2059        .argmin         = 0,
2060        .argmax         = 0,
2061        .cfunc          = map_f,
2062        .args           = "",
2063        .oneline        = "prints the allocated areas of a file",
2064 };
2065 
2066 static void reopen_help(void)
2067 {
2068     printf(
2069 "\n"
2070 " Changes the open options of an already opened image\n"
2071 "\n"
2072 " Example:\n"
2073 " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
2074 "\n"
2075 " -r, -- Reopen the image read-only\n"
2076 " -w, -- Reopen the image read-write\n"
2077 " -c, -- Change the cache mode to the given value\n"
2078 " -o, -- Changes block driver options (cf. 'open' command)\n"
2079 "\n");
2080 }
2081 
2082 static int reopen_f(BlockBackend *blk, int argc, char **argv);
2083 
2084 static QemuOptsList reopen_opts = {
2085     .name = "reopen",
2086     .merge_lists = true,
2087     .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
2088     .desc = {
2089         /* no elements => accept any params */
2090         { /* end of list */ }
2091     },
2092 };
2093 
2094 static const cmdinfo_t reopen_cmd = {
2095        .name           = "reopen",
2096        .argmin         = 0,
2097        .argmax         = -1,
2098        .cfunc          = reopen_f,
2099        .args           = "[(-r|-w)] [-c cache] [-o options]",
2100        .oneline        = "reopens an image with new options",
2101        .help           = reopen_help,
2102 };
2103 
2104 static int reopen_f(BlockBackend *blk, int argc, char **argv)
2105 {
2106     BlockDriverState *bs = blk_bs(blk);
2107     QemuOpts *qopts;
2108     QDict *opts;
2109     int c;
2110     int flags = bs->open_flags;
2111     bool writethrough = !blk_enable_write_cache(blk);
2112     bool has_rw_option = false;
2113     bool has_cache_option = false;
2114     Error *local_err = NULL;
2115 
2116     while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
2117         switch (c) {
2118         case 'c':
2119             if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
2120                 error_report("Invalid cache option: %s", optarg);
2121                 return -EINVAL;
2122             }
2123             has_cache_option = true;
2124             break;
2125         case 'o':
2126             if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
2127                 qemu_opts_reset(&reopen_opts);
2128                 return -EINVAL;
2129             }
2130             break;
2131         case 'r':
2132             if (has_rw_option) {
2133                 error_report("Only one -r/-w option may be given");
2134                 return -EINVAL;
2135             }
2136             flags &= ~BDRV_O_RDWR;
2137             has_rw_option = true;
2138             break;
2139         case 'w':
2140             if (has_rw_option) {
2141                 error_report("Only one -r/-w option may be given");
2142                 return -EINVAL;
2143             }
2144             flags |= BDRV_O_RDWR;
2145             has_rw_option = true;
2146             break;
2147         default:
2148             qemu_opts_reset(&reopen_opts);
2149             qemuio_command_usage(&reopen_cmd);
2150             return -EINVAL;
2151         }
2152     }
2153 
2154     if (optind != argc) {
2155         qemu_opts_reset(&reopen_opts);
2156         qemuio_command_usage(&reopen_cmd);
2157         return -EINVAL;
2158     }
2159 
2160     if (!writethrough != blk_enable_write_cache(blk) &&
2161         blk_get_attached_dev(blk))
2162     {
2163         error_report("Cannot change cache.writeback: Device attached");
2164         qemu_opts_reset(&reopen_opts);
2165         return -EBUSY;
2166     }
2167 
2168     if (!(flags & BDRV_O_RDWR)) {
2169         uint64_t orig_perm, orig_shared_perm;
2170 
2171         bdrv_drain(bs);
2172 
2173         blk_get_perm(blk, &orig_perm, &orig_shared_perm);
2174         blk_set_perm(blk,
2175                      orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
2176                      orig_shared_perm,
2177                      &error_abort);
2178     }
2179 
2180     qopts = qemu_opts_find(&reopen_opts, NULL);
2181     opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new();
2182     qemu_opts_reset(&reopen_opts);
2183 
2184     if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
2185         if (has_rw_option) {
2186             error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
2187             qobject_unref(opts);
2188             return -EINVAL;
2189         }
2190     } else {
2191         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
2192     }
2193 
2194     if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
2195         qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
2196         if (has_cache_option) {
2197             error_report("Cannot set both -c and the cache options");
2198             qobject_unref(opts);
2199             return -EINVAL;
2200         }
2201     } else {
2202         qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
2203         qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
2204     }
2205 
2206     bdrv_reopen(bs, opts, true, &local_err);
2207 
2208     if (local_err) {
2209         error_report_err(local_err);
2210         return -EINVAL;
2211     }
2212 
2213     blk_set_enable_write_cache(blk, !writethrough);
2214     return 0;
2215 }
2216 
2217 static int break_f(BlockBackend *blk, int argc, char **argv)
2218 {
2219     int ret;
2220 
2221     ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2222     if (ret < 0) {
2223         printf("Could not set breakpoint: %s\n", strerror(-ret));
2224         return ret;
2225     }
2226 
2227     return 0;
2228 }
2229 
2230 static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2231 {
2232     int ret;
2233 
2234     ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2235     if (ret < 0) {
2236         printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2237         return ret;
2238     }
2239 
2240     return 0;
2241 }
2242 
2243 static const cmdinfo_t break_cmd = {
2244        .name           = "break",
2245        .argmin         = 2,
2246        .argmax         = 2,
2247        .cfunc          = break_f,
2248        .args           = "event tag",
2249        .oneline        = "sets a breakpoint on event and tags the stopped "
2250                          "request as tag",
2251 };
2252 
2253 static const cmdinfo_t remove_break_cmd = {
2254        .name           = "remove_break",
2255        .argmin         = 1,
2256        .argmax         = 1,
2257        .cfunc          = remove_break_f,
2258        .args           = "tag",
2259        .oneline        = "remove a breakpoint by tag",
2260 };
2261 
2262 static int resume_f(BlockBackend *blk, int argc, char **argv)
2263 {
2264     int ret;
2265 
2266     ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2267     if (ret < 0) {
2268         printf("Could not resume request: %s\n", strerror(-ret));
2269         return ret;
2270     }
2271 
2272     return 0;
2273 }
2274 
2275 static const cmdinfo_t resume_cmd = {
2276        .name           = "resume",
2277        .argmin         = 1,
2278        .argmax         = 1,
2279        .cfunc          = resume_f,
2280        .args           = "tag",
2281        .oneline        = "resumes the request tagged as tag",
2282 };
2283 
2284 static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2285 {
2286     while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2287         aio_poll(blk_get_aio_context(blk), true);
2288     }
2289     return 0;
2290 }
2291 
2292 static const cmdinfo_t wait_break_cmd = {
2293        .name           = "wait_break",
2294        .argmin         = 1,
2295        .argmax         = 1,
2296        .cfunc          = wait_break_f,
2297        .args           = "tag",
2298        .oneline        = "waits for the suspension of a request",
2299 };
2300 
2301 static int abort_f(BlockBackend *blk, int argc, char **argv)
2302 {
2303     abort();
2304 }
2305 
2306 static const cmdinfo_t abort_cmd = {
2307        .name           = "abort",
2308        .cfunc          = abort_f,
2309        .flags          = CMD_NOFILE_OK,
2310        .oneline        = "simulate a program crash using abort(3)",
2311 };
2312 
2313 static void sigraise_help(void)
2314 {
2315     printf(
2316 "\n"
2317 " raises the given signal\n"
2318 "\n"
2319 " Example:\n"
2320 " 'sigraise %i' - raises SIGTERM\n"
2321 "\n"
2322 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2323 " given to sigraise.\n"
2324 "\n", SIGTERM);
2325 }
2326 
2327 static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2328 
2329 static const cmdinfo_t sigraise_cmd = {
2330     .name       = "sigraise",
2331     .cfunc      = sigraise_f,
2332     .argmin     = 1,
2333     .argmax     = 1,
2334     .flags      = CMD_NOFILE_OK,
2335     .args       = "signal",
2336     .oneline    = "raises a signal",
2337     .help       = sigraise_help,
2338 };
2339 
2340 static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2341 {
2342     int64_t sig = cvtnum(argv[1]);
2343     if (sig < 0) {
2344         print_cvtnum_err(sig, argv[1]);
2345         return sig;
2346     } else if (sig > NSIG) {
2347         printf("signal argument '%s' is too large to be a valid signal\n",
2348                argv[1]);
2349         return -EINVAL;
2350     }
2351 
2352     /* Using raise() to kill this process does not necessarily flush all open
2353      * streams. At least stdout and stderr (although the latter should be
2354      * non-buffered anyway) should be flushed, though. */
2355     fflush(stdout);
2356     fflush(stderr);
2357 
2358     raise(sig);
2359 
2360     return 0;
2361 }
2362 
2363 static void sleep_cb(void *opaque)
2364 {
2365     bool *expired = opaque;
2366     *expired = true;
2367 }
2368 
2369 static int sleep_f(BlockBackend *blk, int argc, char **argv)
2370 {
2371     char *endptr;
2372     long ms;
2373     struct QEMUTimer *timer;
2374     bool expired = false;
2375 
2376     ms = strtol(argv[1], &endptr, 0);
2377     if (ms < 0 || *endptr != '\0') {
2378         printf("%s is not a valid number\n", argv[1]);
2379         return -EINVAL;
2380     }
2381 
2382     timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2383     timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2384 
2385     while (!expired) {
2386         main_loop_wait(false);
2387     }
2388 
2389     timer_free(timer);
2390     return 0;
2391 }
2392 
2393 static const cmdinfo_t sleep_cmd = {
2394        .name           = "sleep",
2395        .argmin         = 1,
2396        .argmax         = 1,
2397        .cfunc          = sleep_f,
2398        .flags          = CMD_NOFILE_OK,
2399        .oneline        = "waits for the given value in milliseconds",
2400 };
2401 
2402 static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2403 {
2404     printf("%s ", cmd);
2405 
2406     if (ct->args) {
2407         printf("%s ", ct->args);
2408     }
2409     printf("-- %s\n", ct->oneline);
2410 }
2411 
2412 static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2413 {
2414     help_oneline(cmd, ct);
2415     if (ct->help) {
2416         ct->help();
2417     }
2418 }
2419 
2420 static void help_all(void)
2421 {
2422     const cmdinfo_t *ct;
2423 
2424     for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2425         help_oneline(ct->name, ct);
2426     }
2427     printf("\nUse 'help commandname' for extended help.\n");
2428 }
2429 
2430 static int help_f(BlockBackend *blk, int argc, char **argv)
2431 {
2432     const cmdinfo_t *ct;
2433 
2434     if (argc < 2) {
2435         help_all();
2436         return 0;
2437     }
2438 
2439     ct = find_command(argv[1]);
2440     if (ct == NULL) {
2441         printf("command %s not found\n", argv[1]);
2442         return -EINVAL;
2443     }
2444 
2445     help_onecmd(argv[1], ct);
2446     return 0;
2447 }
2448 
2449 static const cmdinfo_t help_cmd = {
2450     .name       = "help",
2451     .altname    = "?",
2452     .cfunc      = help_f,
2453     .argmin     = 0,
2454     .argmax     = 1,
2455     .flags      = CMD_FLAG_GLOBAL,
2456     .args       = "[command]",
2457     .oneline    = "help for one or all commands",
2458 };
2459 
2460 /*
2461  * Called with aio context of blk acquired. Or with qemu_get_aio_context()
2462  * context acquired if blk is NULL.
2463  */
2464 int qemuio_command(BlockBackend *blk, const char *cmd)
2465 {
2466     char *input;
2467     const cmdinfo_t *ct;
2468     char **v;
2469     int c;
2470     int ret = 0;
2471 
2472     input = g_strdup(cmd);
2473     v = breakline(input, &c);
2474     if (c) {
2475         ct = find_command(v[0]);
2476         if (ct) {
2477             ret = command(blk, ct, c, v);
2478         } else {
2479             fprintf(stderr, "command \"%s\" not found\n", v[0]);
2480             ret = -EINVAL;
2481         }
2482     }
2483     g_free(input);
2484     g_free(v);
2485 
2486     return ret;
2487 }
2488 
2489 static void __attribute((constructor)) init_qemuio_commands(void)
2490 {
2491     /* initialize commands */
2492     qemuio_add_command(&help_cmd);
2493     qemuio_add_command(&read_cmd);
2494     qemuio_add_command(&readv_cmd);
2495     qemuio_add_command(&write_cmd);
2496     qemuio_add_command(&writev_cmd);
2497     qemuio_add_command(&aio_read_cmd);
2498     qemuio_add_command(&aio_write_cmd);
2499     qemuio_add_command(&aio_flush_cmd);
2500     qemuio_add_command(&flush_cmd);
2501     qemuio_add_command(&truncate_cmd);
2502     qemuio_add_command(&length_cmd);
2503     qemuio_add_command(&info_cmd);
2504     qemuio_add_command(&discard_cmd);
2505     qemuio_add_command(&alloc_cmd);
2506     qemuio_add_command(&map_cmd);
2507     qemuio_add_command(&reopen_cmd);
2508     qemuio_add_command(&break_cmd);
2509     qemuio_add_command(&remove_break_cmd);
2510     qemuio_add_command(&resume_cmd);
2511     qemuio_add_command(&wait_break_cmd);
2512     qemuio_add_command(&abort_cmd);
2513     qemuio_add_command(&sleep_cmd);
2514     qemuio_add_command(&sigraise_cmd);
2515 }
2516