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