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