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