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