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