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 2120 BlockReopenQueue *brq; 2121 Error *local_err = NULL; 2122 2123 while ((c = getopt(argc, argv, "c:o:rw")) != -1) { 2124 switch (c) { 2125 case 'c': 2126 if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { 2127 error_report("Invalid cache option: %s", optarg); 2128 return -EINVAL; 2129 } 2130 has_cache_option = true; 2131 break; 2132 case 'o': 2133 if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) { 2134 qemu_opts_reset(&reopen_opts); 2135 return -EINVAL; 2136 } 2137 break; 2138 case 'r': 2139 if (has_rw_option) { 2140 error_report("Only one -r/-w option may be given"); 2141 return -EINVAL; 2142 } 2143 flags &= ~BDRV_O_RDWR; 2144 has_rw_option = true; 2145 break; 2146 case 'w': 2147 if (has_rw_option) { 2148 error_report("Only one -r/-w option may be given"); 2149 return -EINVAL; 2150 } 2151 flags |= BDRV_O_RDWR; 2152 has_rw_option = true; 2153 break; 2154 default: 2155 qemu_opts_reset(&reopen_opts); 2156 qemuio_command_usage(&reopen_cmd); 2157 return -EINVAL; 2158 } 2159 } 2160 2161 if (optind != argc) { 2162 qemu_opts_reset(&reopen_opts); 2163 qemuio_command_usage(&reopen_cmd); 2164 return -EINVAL; 2165 } 2166 2167 if (!writethrough != blk_enable_write_cache(blk) && 2168 blk_get_attached_dev(blk)) 2169 { 2170 error_report("Cannot change cache.writeback: Device attached"); 2171 qemu_opts_reset(&reopen_opts); 2172 return -EBUSY; 2173 } 2174 2175 if (!(flags & BDRV_O_RDWR)) { 2176 uint64_t orig_perm, orig_shared_perm; 2177 2178 bdrv_drain(bs); 2179 2180 blk_get_perm(blk, &orig_perm, &orig_shared_perm); 2181 blk_set_perm(blk, 2182 orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED), 2183 orig_shared_perm, 2184 &error_abort); 2185 } 2186 2187 qopts = qemu_opts_find(&reopen_opts, NULL); 2188 opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new(); 2189 qemu_opts_reset(&reopen_opts); 2190 2191 if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) { 2192 if (has_rw_option) { 2193 error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'"); 2194 qobject_unref(opts); 2195 return -EINVAL; 2196 } 2197 } else { 2198 qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR)); 2199 } 2200 2201 if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) || 2202 qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) { 2203 if (has_cache_option) { 2204 error_report("Cannot set both -c and the cache options"); 2205 qobject_unref(opts); 2206 return -EINVAL; 2207 } 2208 } else { 2209 qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE); 2210 qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH); 2211 } 2212 2213 bdrv_subtree_drained_begin(bs); 2214 brq = bdrv_reopen_queue(NULL, bs, opts, true); 2215 bdrv_reopen_multiple(brq, &local_err); 2216 bdrv_subtree_drained_end(bs); 2217 2218 if (local_err) { 2219 error_report_err(local_err); 2220 return -EINVAL; 2221 } 2222 2223 blk_set_enable_write_cache(blk, !writethrough); 2224 return 0; 2225 } 2226 2227 static int break_f(BlockBackend *blk, int argc, char **argv) 2228 { 2229 int ret; 2230 2231 ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]); 2232 if (ret < 0) { 2233 printf("Could not set breakpoint: %s\n", strerror(-ret)); 2234 return ret; 2235 } 2236 2237 return 0; 2238 } 2239 2240 static int remove_break_f(BlockBackend *blk, int argc, char **argv) 2241 { 2242 int ret; 2243 2244 ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]); 2245 if (ret < 0) { 2246 printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret)); 2247 return ret; 2248 } 2249 2250 return 0; 2251 } 2252 2253 static const cmdinfo_t break_cmd = { 2254 .name = "break", 2255 .argmin = 2, 2256 .argmax = 2, 2257 .cfunc = break_f, 2258 .args = "event tag", 2259 .oneline = "sets a breakpoint on event and tags the stopped " 2260 "request as tag", 2261 }; 2262 2263 static const cmdinfo_t remove_break_cmd = { 2264 .name = "remove_break", 2265 .argmin = 1, 2266 .argmax = 1, 2267 .cfunc = remove_break_f, 2268 .args = "tag", 2269 .oneline = "remove a breakpoint by tag", 2270 }; 2271 2272 static int resume_f(BlockBackend *blk, int argc, char **argv) 2273 { 2274 int ret; 2275 2276 ret = bdrv_debug_resume(blk_bs(blk), argv[1]); 2277 if (ret < 0) { 2278 printf("Could not resume request: %s\n", strerror(-ret)); 2279 return ret; 2280 } 2281 2282 return 0; 2283 } 2284 2285 static const cmdinfo_t resume_cmd = { 2286 .name = "resume", 2287 .argmin = 1, 2288 .argmax = 1, 2289 .cfunc = resume_f, 2290 .args = "tag", 2291 .oneline = "resumes the request tagged as tag", 2292 }; 2293 2294 static int wait_break_f(BlockBackend *blk, int argc, char **argv) 2295 { 2296 while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) { 2297 aio_poll(blk_get_aio_context(blk), true); 2298 } 2299 return 0; 2300 } 2301 2302 static const cmdinfo_t wait_break_cmd = { 2303 .name = "wait_break", 2304 .argmin = 1, 2305 .argmax = 1, 2306 .cfunc = wait_break_f, 2307 .args = "tag", 2308 .oneline = "waits for the suspension of a request", 2309 }; 2310 2311 static int abort_f(BlockBackend *blk, int argc, char **argv) 2312 { 2313 abort(); 2314 } 2315 2316 static const cmdinfo_t abort_cmd = { 2317 .name = "abort", 2318 .cfunc = abort_f, 2319 .flags = CMD_NOFILE_OK, 2320 .oneline = "simulate a program crash using abort(3)", 2321 }; 2322 2323 static void sigraise_help(void) 2324 { 2325 printf( 2326 "\n" 2327 " raises the given signal\n" 2328 "\n" 2329 " Example:\n" 2330 " 'sigraise %i' - raises SIGTERM\n" 2331 "\n" 2332 " Invokes raise(signal), where \"signal\" is the mandatory integer argument\n" 2333 " given to sigraise.\n" 2334 "\n", SIGTERM); 2335 } 2336 2337 static int sigraise_f(BlockBackend *blk, int argc, char **argv); 2338 2339 static const cmdinfo_t sigraise_cmd = { 2340 .name = "sigraise", 2341 .cfunc = sigraise_f, 2342 .argmin = 1, 2343 .argmax = 1, 2344 .flags = CMD_NOFILE_OK, 2345 .args = "signal", 2346 .oneline = "raises a signal", 2347 .help = sigraise_help, 2348 }; 2349 2350 static int sigraise_f(BlockBackend *blk, int argc, char **argv) 2351 { 2352 int64_t sig = cvtnum(argv[1]); 2353 if (sig < 0) { 2354 print_cvtnum_err(sig, argv[1]); 2355 return sig; 2356 } else if (sig > NSIG) { 2357 printf("signal argument '%s' is too large to be a valid signal\n", 2358 argv[1]); 2359 return -EINVAL; 2360 } 2361 2362 /* Using raise() to kill this process does not necessarily flush all open 2363 * streams. At least stdout and stderr (although the latter should be 2364 * non-buffered anyway) should be flushed, though. */ 2365 fflush(stdout); 2366 fflush(stderr); 2367 2368 raise(sig); 2369 2370 return 0; 2371 } 2372 2373 static void sleep_cb(void *opaque) 2374 { 2375 bool *expired = opaque; 2376 *expired = true; 2377 } 2378 2379 static int sleep_f(BlockBackend *blk, int argc, char **argv) 2380 { 2381 char *endptr; 2382 long ms; 2383 struct QEMUTimer *timer; 2384 bool expired = false; 2385 2386 ms = strtol(argv[1], &endptr, 0); 2387 if (ms < 0 || *endptr != '\0') { 2388 printf("%s is not a valid number\n", argv[1]); 2389 return -EINVAL; 2390 } 2391 2392 timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired); 2393 timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms); 2394 2395 while (!expired) { 2396 main_loop_wait(false); 2397 } 2398 2399 timer_free(timer); 2400 return 0; 2401 } 2402 2403 static const cmdinfo_t sleep_cmd = { 2404 .name = "sleep", 2405 .argmin = 1, 2406 .argmax = 1, 2407 .cfunc = sleep_f, 2408 .flags = CMD_NOFILE_OK, 2409 .oneline = "waits for the given value in milliseconds", 2410 }; 2411 2412 static void help_oneline(const char *cmd, const cmdinfo_t *ct) 2413 { 2414 printf("%s ", cmd); 2415 2416 if (ct->args) { 2417 printf("%s ", ct->args); 2418 } 2419 printf("-- %s\n", ct->oneline); 2420 } 2421 2422 static void help_onecmd(const char *cmd, const cmdinfo_t *ct) 2423 { 2424 help_oneline(cmd, ct); 2425 if (ct->help) { 2426 ct->help(); 2427 } 2428 } 2429 2430 static void help_all(void) 2431 { 2432 const cmdinfo_t *ct; 2433 2434 for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) { 2435 help_oneline(ct->name, ct); 2436 } 2437 printf("\nUse 'help commandname' for extended help.\n"); 2438 } 2439 2440 static int help_f(BlockBackend *blk, int argc, char **argv) 2441 { 2442 const cmdinfo_t *ct; 2443 2444 if (argc < 2) { 2445 help_all(); 2446 return 0; 2447 } 2448 2449 ct = find_command(argv[1]); 2450 if (ct == NULL) { 2451 printf("command %s not found\n", argv[1]); 2452 return -EINVAL; 2453 } 2454 2455 help_onecmd(argv[1], ct); 2456 return 0; 2457 } 2458 2459 static const cmdinfo_t help_cmd = { 2460 .name = "help", 2461 .altname = "?", 2462 .cfunc = help_f, 2463 .argmin = 0, 2464 .argmax = 1, 2465 .flags = CMD_FLAG_GLOBAL, 2466 .args = "[command]", 2467 .oneline = "help for one or all commands", 2468 }; 2469 2470 /* 2471 * Called with aio context of blk acquired. Or with qemu_get_aio_context() 2472 * context acquired if blk is NULL. 2473 */ 2474 int qemuio_command(BlockBackend *blk, const char *cmd) 2475 { 2476 char *input; 2477 const cmdinfo_t *ct; 2478 char **v; 2479 int c; 2480 int ret = 0; 2481 2482 input = g_strdup(cmd); 2483 v = breakline(input, &c); 2484 if (c) { 2485 ct = find_command(v[0]); 2486 if (ct) { 2487 ret = command(blk, ct, c, v); 2488 } else { 2489 fprintf(stderr, "command \"%s\" not found\n", v[0]); 2490 ret = -EINVAL; 2491 } 2492 } 2493 g_free(input); 2494 g_free(v); 2495 2496 return ret; 2497 } 2498 2499 static void __attribute((constructor)) init_qemuio_commands(void) 2500 { 2501 /* initialize commands */ 2502 qemuio_add_command(&help_cmd); 2503 qemuio_add_command(&read_cmd); 2504 qemuio_add_command(&readv_cmd); 2505 qemuio_add_command(&write_cmd); 2506 qemuio_add_command(&writev_cmd); 2507 qemuio_add_command(&aio_read_cmd); 2508 qemuio_add_command(&aio_write_cmd); 2509 qemuio_add_command(&aio_flush_cmd); 2510 qemuio_add_command(&flush_cmd); 2511 qemuio_add_command(&truncate_cmd); 2512 qemuio_add_command(&length_cmd); 2513 qemuio_add_command(&info_cmd); 2514 qemuio_add_command(&discard_cmd); 2515 qemuio_add_command(&alloc_cmd); 2516 qemuio_add_command(&map_cmd); 2517 qemuio_add_command(&reopen_cmd); 2518 qemuio_add_command(&break_cmd); 2519 qemuio_add_command(&remove_break_cmd); 2520 qemuio_add_command(&resume_cmd); 2521 qemuio_add_command(&wait_break_cmd); 2522 qemuio_add_command(&abort_cmd); 2523 qemuio_add_command(&sleep_cmd); 2524 qemuio_add_command(&sigraise_cmd); 2525 } 2526