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