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