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