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