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