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