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