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