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