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)
1702{
1703    Error *local_err = NULL;
1704    int64_t offset;
1705    int ret;
1706
1707    offset = cvtnum(argv[1]);
1708    if (offset < 0) {
1709        print_cvtnum_err(offset, argv[1]);
1710        return offset;
1711    }
1712
1713    /*
1714     * qemu-io is a debugging tool, so let us be strict here and pass
1715     * exact=true.  It is better to err on the "emit more errors" side
1716     * than to be overly permissive.
1717     */
1718    ret = blk_truncate(blk, offset, false, PREALLOC_MODE_OFF, 0, &local_err);
1719    if (ret < 0) {
1720        error_report_err(local_err);
1721        return ret;
1722    }
1723
1724    return 0;
1725}
1726
1727static const cmdinfo_t truncate_cmd = {
1728    .name       = "truncate",
1729    .altname    = "t",
1730    .cfunc      = truncate_f,
1731    .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
1732    .argmin     = 1,
1733    .argmax     = 1,
1734    .args       = "off",
1735    .oneline    = "truncates the current file at the given offset",
1736};
1737
1738static int length_f(BlockBackend *blk, int argc, char **argv)
1739{
1740    int64_t size;
1741    char s1[64];
1742
1743    size = blk_getlength(blk);
1744    if (size < 0) {
1745        printf("getlength: %s\n", strerror(-size));
1746        return size;
1747    }
1748
1749    cvtstr(size, s1, sizeof(s1));
1750    printf("%s\n", s1);
1751    return 0;
1752}
1753
1754
1755static const cmdinfo_t length_cmd = {
1756    .name   = "length",
1757    .altname    = "l",
1758    .cfunc      = length_f,
1759    .oneline    = "gets the length of the current file",
1760};
1761
1762
1763static int info_f(BlockBackend *blk, int argc, char **argv)
1764{
1765    BlockDriverState *bs = blk_bs(blk);
1766    BlockDriverInfo bdi;
1767    ImageInfoSpecific *spec_info;
1768    Error *local_err = NULL;
1769    char s1[64], s2[64];
1770    int ret;
1771
1772    if (bs->drv && bs->drv->format_name) {
1773        printf("format name: %s\n", bs->drv->format_name);
1774    }
1775    if (bs->drv && bs->drv->protocol_name) {
1776        printf("format name: %s\n", bs->drv->protocol_name);
1777    }
1778
1779    ret = bdrv_get_info(bs, &bdi);
1780    if (ret) {
1781        return ret;
1782    }
1783
1784    cvtstr(bdi.cluster_size, s1, sizeof(s1));
1785    cvtstr(bdi.vm_state_offset, s2, sizeof(s2));
1786
1787    printf("cluster size: %s\n", s1);
1788    printf("vm state offset: %s\n", s2);
1789
1790    spec_info = bdrv_get_specific_info(bs, &local_err);
1791    if (local_err) {
1792        error_report_err(local_err);
1793        return -EIO;
1794    }
1795    if (spec_info) {
1796        printf("Format specific information:\n");
1797        bdrv_image_info_specific_dump(spec_info);
1798        qapi_free_ImageInfoSpecific(spec_info);
1799    }
1800
1801    return 0;
1802}
1803
1804
1805
1806static const cmdinfo_t info_cmd = {
1807    .name       = "info",
1808    .altname    = "i",
1809    .cfunc      = info_f,
1810    .oneline    = "prints information about the current file",
1811};
1812
1813static void discard_help(void)
1814{
1815    printf(
1816"\n"
1817" discards a range of bytes from the given offset\n"
1818"\n"
1819" Example:\n"
1820" 'discard 512 1k' - discards 1 kilobyte from 512 bytes into the file\n"
1821"\n"
1822" Discards a segment of the currently open file.\n"
1823" -C, -- report statistics in a machine parsable format\n"
1824" -q, -- quiet mode, do not show I/O statistics\n"
1825"\n");
1826}
1827
1828static int discard_f(BlockBackend *blk, int argc, char **argv);
1829
1830static const cmdinfo_t discard_cmd = {
1831    .name       = "discard",
1832    .altname    = "d",
1833    .cfunc      = discard_f,
1834    .perm       = BLK_PERM_WRITE,
1835    .argmin     = 2,
1836    .argmax     = -1,
1837    .args       = "[-Cq] off len",
1838    .oneline    = "discards a number of bytes at a specified offset",
1839    .help       = discard_help,
1840};
1841
1842static int discard_f(BlockBackend *blk, int argc, char **argv)
1843{
1844    struct timespec t1, t2;
1845    bool Cflag = false, qflag = false;
1846    int c, ret;
1847    int64_t offset, bytes;
1848
1849    while ((c = getopt(argc, argv, "Cq")) != -1) {
1850        switch (c) {
1851        case 'C':
1852            Cflag = true;
1853            break;
1854        case 'q':
1855            qflag = true;
1856            break;
1857        default:
1858            qemuio_command_usage(&discard_cmd);
1859            return -EINVAL;
1860        }
1861    }
1862
1863    if (optind != argc - 2) {
1864        qemuio_command_usage(&discard_cmd);
1865        return -EINVAL;
1866    }
1867
1868    offset = cvtnum(argv[optind]);
1869    if (offset < 0) {
1870        print_cvtnum_err(offset, argv[optind]);
1871        return offset;
1872    }
1873
1874    optind++;
1875    bytes = cvtnum(argv[optind]);
1876    if (bytes < 0) {
1877        print_cvtnum_err(bytes, argv[optind]);
1878        return bytes;
1879    } else if (bytes > BDRV_REQUEST_MAX_BYTES) {
1880        printf("length cannot exceed %"PRIu64", given %s\n",
1881               (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
1882        return -EINVAL;
1883    }
1884
1885    clock_gettime(CLOCK_MONOTONIC, &t1);
1886    ret = blk_pdiscard(blk, offset, bytes);
1887    clock_gettime(CLOCK_MONOTONIC, &t2);
1888
1889    if (ret < 0) {
1890        printf("discard failed: %s\n", strerror(-ret));
1891        return ret;
1892    }
1893
1894    /* Finally, report back -- -C gives a parsable format */
1895    if (!qflag) {
1896        t2 = tsub(t2, t1);
1897        print_report("discard", &t2, offset, bytes, bytes, 1, Cflag);
1898    }
1899
1900    return 0;
1901}
1902
1903static int alloc_f(BlockBackend *blk, int argc, char **argv)
1904{
1905    BlockDriverState *bs = blk_bs(blk);
1906    int64_t offset, start, remaining, count;
1907    char s1[64];
1908    int ret;
1909    int64_t num, sum_alloc;
1910
1911    start = offset = cvtnum(argv[1]);
1912    if (offset < 0) {
1913        print_cvtnum_err(offset, argv[1]);
1914        return offset;
1915    }
1916
1917    if (argc == 3) {
1918        count = cvtnum(argv[2]);
1919        if (count < 0) {
1920            print_cvtnum_err(count, argv[2]);
1921            return count;
1922        }
1923    } else {
1924        count = BDRV_SECTOR_SIZE;
1925    }
1926
1927    remaining = count;
1928    sum_alloc = 0;
1929    while (remaining) {
1930        ret = bdrv_is_allocated(bs, offset, remaining, &num);
1931        if (ret < 0) {
1932            printf("is_allocated failed: %s\n", strerror(-ret));
1933            return ret;
1934        }
1935        offset += num;
1936        remaining -= num;
1937        if (ret) {
1938            sum_alloc += num;
1939        }
1940        if (num == 0) {
1941            count -= remaining;
1942            remaining = 0;
1943        }
1944    }
1945
1946    cvtstr(start, s1, sizeof(s1));
1947
1948    printf("%"PRId64"/%"PRId64" bytes allocated at offset %s\n",
1949           sum_alloc, count, s1);
1950    return 0;
1951}
1952
1953static const cmdinfo_t alloc_cmd = {
1954    .name       = "alloc",
1955    .altname    = "a",
1956    .argmin     = 1,
1957    .argmax     = 2,
1958    .cfunc      = alloc_f,
1959    .args       = "offset [count]",
1960    .oneline    = "checks if offset is allocated in the file",
1961};
1962
1963
1964static int map_is_allocated(BlockDriverState *bs, int64_t offset,
1965                            int64_t bytes, int64_t *pnum)
1966{
1967    int64_t num;
1968    int num_checked;
1969    int ret, firstret;
1970
1971    num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1972    ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1973    if (ret < 0) {
1974        return ret;
1975    }
1976
1977    firstret = ret;
1978    *pnum = num;
1979
1980    while (bytes > 0 && ret == firstret) {
1981        offset += num;
1982        bytes -= num;
1983
1984        num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
1985        ret = bdrv_is_allocated(bs, offset, num_checked, &num);
1986        if (ret == firstret && num) {
1987            *pnum += num;
1988        } else {
1989            break;
1990        }
1991    }
1992
1993    return firstret;
1994}
1995
1996static int map_f(BlockBackend *blk, int argc, char **argv)
1997{
1998    int64_t offset, bytes;
1999    char s1[64], s2[64];
2000    int64_t num;
2001    int ret;
2002    const char *retstr;
2003
2004    offset = 0;
2005    bytes = blk_getlength(blk);
2006    if (bytes < 0) {
2007        error_report("Failed to query image length: %s", strerror(-bytes));
2008        return bytes;
2009    }
2010
2011    while (bytes) {
2012        ret = map_is_allocated(blk_bs(blk), offset, bytes, &num);
2013        if (ret < 0) {
2014            error_report("Failed to get allocation status: %s", strerror(-ret));
2015            return ret;
2016        } else if (!num) {
2017            error_report("Unexpected end of image");
2018            return -EIO;
2019        }
2020
2021        retstr = ret ? "    allocated" : "not allocated";
2022        cvtstr(num, s1, sizeof(s1));
2023        cvtstr(offset, s2, sizeof(s2));
2024        printf("%s (0x%" PRIx64 ") bytes %s at offset %s (0x%" PRIx64 ")\n",
2025               s1, num, retstr, s2, offset);
2026
2027        offset += num;
2028        bytes -= num;
2029    }
2030
2031    return 0;
2032}
2033
2034static const cmdinfo_t map_cmd = {
2035       .name           = "map",
2036       .argmin         = 0,
2037       .argmax         = 0,
2038       .cfunc          = map_f,
2039       .args           = "",
2040       .oneline        = "prints the allocated areas of a file",
2041};
2042
2043static void reopen_help(void)
2044{
2045    printf(
2046"\n"
2047" Changes the open options of an already opened image\n"
2048"\n"
2049" Example:\n"
2050" 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
2051"\n"
2052" -r, -- Reopen the image read-only\n"
2053" -w, -- Reopen the image read-write\n"
2054" -c, -- Change the cache mode to the given value\n"
2055" -o, -- Changes block driver options (cf. 'open' command)\n"
2056"\n");
2057}
2058
2059static int reopen_f(BlockBackend *blk, int argc, char **argv);
2060
2061static QemuOptsList reopen_opts = {
2062    .name = "reopen",
2063    .merge_lists = true,
2064    .head = QTAILQ_HEAD_INITIALIZER(reopen_opts.head),
2065    .desc = {
2066        /* no elements => accept any params */
2067        { /* end of list */ }
2068    },
2069};
2070
2071static const cmdinfo_t reopen_cmd = {
2072       .name           = "reopen",
2073       .argmin         = 0,
2074       .argmax         = -1,
2075       .cfunc          = reopen_f,
2076       .args           = "[(-r|-w)] [-c cache] [-o options]",
2077       .oneline        = "reopens an image with new options",
2078       .help           = reopen_help,
2079};
2080
2081static int reopen_f(BlockBackend *blk, int argc, char **argv)
2082{
2083    BlockDriverState *bs = blk_bs(blk);
2084    QemuOpts *qopts;
2085    QDict *opts;
2086    int c;
2087    int flags = bs->open_flags;
2088    bool writethrough = !blk_enable_write_cache(blk);
2089    bool has_rw_option = false;
2090    bool has_cache_option = false;
2091
2092    BlockReopenQueue *brq;
2093    Error *local_err = NULL;
2094
2095    while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
2096        switch (c) {
2097        case 'c':
2098            if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
2099                error_report("Invalid cache option: %s", optarg);
2100                return -EINVAL;
2101            }
2102            has_cache_option = true;
2103            break;
2104        case 'o':
2105            if (!qemu_opts_parse_noisily(&reopen_opts, optarg, 0)) {
2106                qemu_opts_reset(&reopen_opts);
2107                return -EINVAL;
2108            }
2109            break;
2110        case 'r':
2111            if (has_rw_option) {
2112                error_report("Only one -r/-w option may be given");
2113                return -EINVAL;
2114            }
2115            flags &= ~BDRV_O_RDWR;
2116            has_rw_option = true;
2117            break;
2118        case 'w':
2119            if (has_rw_option) {
2120                error_report("Only one -r/-w option may be given");
2121                return -EINVAL;
2122            }
2123            flags |= BDRV_O_RDWR;
2124            has_rw_option = true;
2125            break;
2126        default:
2127            qemu_opts_reset(&reopen_opts);
2128            qemuio_command_usage(&reopen_cmd);
2129            return -EINVAL;
2130        }
2131    }
2132
2133    if (optind != argc) {
2134        qemu_opts_reset(&reopen_opts);
2135        qemuio_command_usage(&reopen_cmd);
2136        return -EINVAL;
2137    }
2138
2139    if (!writethrough != blk_enable_write_cache(blk) &&
2140        blk_get_attached_dev(blk))
2141    {
2142        error_report("Cannot change cache.writeback: Device attached");
2143        qemu_opts_reset(&reopen_opts);
2144        return -EBUSY;
2145    }
2146
2147    if (!(flags & BDRV_O_RDWR)) {
2148        uint64_t orig_perm, orig_shared_perm;
2149
2150        bdrv_drain(bs);
2151
2152        blk_get_perm(blk, &orig_perm, &orig_shared_perm);
2153        blk_set_perm(blk,
2154                     orig_perm & ~(BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED),
2155                     orig_shared_perm,
2156                     &error_abort);
2157    }
2158
2159    qopts = qemu_opts_find(&reopen_opts, NULL);
2160    opts = qopts ? qemu_opts_to_qdict(qopts, NULL) : qdict_new();
2161    qemu_opts_reset(&reopen_opts);
2162
2163    if (qdict_haskey(opts, BDRV_OPT_READ_ONLY)) {
2164        if (has_rw_option) {
2165            error_report("Cannot set both -r/-w and '" BDRV_OPT_READ_ONLY "'");
2166            qobject_unref(opts);
2167            return -EINVAL;
2168        }
2169    } else {
2170        qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !(flags & BDRV_O_RDWR));
2171    }
2172
2173    if (qdict_haskey(opts, BDRV_OPT_CACHE_DIRECT) ||
2174        qdict_haskey(opts, BDRV_OPT_CACHE_NO_FLUSH)) {
2175        if (has_cache_option) {
2176            error_report("Cannot set both -c and the cache options");
2177            qobject_unref(opts);
2178            return -EINVAL;
2179        }
2180    } else {
2181        qdict_put_bool(opts, BDRV_OPT_CACHE_DIRECT, flags & BDRV_O_NOCACHE);
2182        qdict_put_bool(opts, BDRV_OPT_CACHE_NO_FLUSH, flags & BDRV_O_NO_FLUSH);
2183    }
2184
2185    bdrv_subtree_drained_begin(bs);
2186    brq = bdrv_reopen_queue(NULL, bs, opts, true);
2187    bdrv_reopen_multiple(brq, &local_err);
2188    bdrv_subtree_drained_end(bs);
2189
2190    if (local_err) {
2191        error_report_err(local_err);
2192        return -EINVAL;
2193    }
2194
2195    blk_set_enable_write_cache(blk, !writethrough);
2196    return 0;
2197}
2198
2199static int break_f(BlockBackend *blk, int argc, char **argv)
2200{
2201    int ret;
2202
2203    ret = bdrv_debug_breakpoint(blk_bs(blk), argv[1], argv[2]);
2204    if (ret < 0) {
2205        printf("Could not set breakpoint: %s\n", strerror(-ret));
2206        return ret;
2207    }
2208
2209    return 0;
2210}
2211
2212static int remove_break_f(BlockBackend *blk, int argc, char **argv)
2213{
2214    int ret;
2215
2216    ret = bdrv_debug_remove_breakpoint(blk_bs(blk), argv[1]);
2217    if (ret < 0) {
2218        printf("Could not remove breakpoint %s: %s\n", argv[1], strerror(-ret));
2219        return ret;
2220    }
2221
2222    return 0;
2223}
2224
2225static const cmdinfo_t break_cmd = {
2226       .name           = "break",
2227       .argmin         = 2,
2228       .argmax         = 2,
2229       .cfunc          = break_f,
2230       .args           = "event tag",
2231       .oneline        = "sets a breakpoint on event and tags the stopped "
2232                         "request as tag",
2233};
2234
2235static const cmdinfo_t remove_break_cmd = {
2236       .name           = "remove_break",
2237       .argmin         = 1,
2238       .argmax         = 1,
2239       .cfunc          = remove_break_f,
2240       .args           = "tag",
2241       .oneline        = "remove a breakpoint by tag",
2242};
2243
2244static int resume_f(BlockBackend *blk, int argc, char **argv)
2245{
2246    int ret;
2247
2248    ret = bdrv_debug_resume(blk_bs(blk), argv[1]);
2249    if (ret < 0) {
2250        printf("Could not resume request: %s\n", strerror(-ret));
2251        return ret;
2252    }
2253
2254    return 0;
2255}
2256
2257static const cmdinfo_t resume_cmd = {
2258       .name           = "resume",
2259       .argmin         = 1,
2260       .argmax         = 1,
2261       .cfunc          = resume_f,
2262       .args           = "tag",
2263       .oneline        = "resumes the request tagged as tag",
2264};
2265
2266static int wait_break_f(BlockBackend *blk, int argc, char **argv)
2267{
2268    while (!bdrv_debug_is_suspended(blk_bs(blk), argv[1])) {
2269        aio_poll(blk_get_aio_context(blk), true);
2270    }
2271    return 0;
2272}
2273
2274static const cmdinfo_t wait_break_cmd = {
2275       .name           = "wait_break",
2276       .argmin         = 1,
2277       .argmax         = 1,
2278       .cfunc          = wait_break_f,
2279       .args           = "tag",
2280       .oneline        = "waits for the suspension of a request",
2281};
2282
2283static int abort_f(BlockBackend *blk, int argc, char **argv)
2284{
2285    abort();
2286}
2287
2288static const cmdinfo_t abort_cmd = {
2289       .name           = "abort",
2290       .cfunc          = abort_f,
2291       .flags          = CMD_NOFILE_OK,
2292       .oneline        = "simulate a program crash using abort(3)",
2293};
2294
2295static void sigraise_help(void)
2296{
2297    printf(
2298"\n"
2299" raises the given signal\n"
2300"\n"
2301" Example:\n"
2302" 'sigraise %i' - raises SIGTERM\n"
2303"\n"
2304" Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
2305" given to sigraise.\n"
2306"\n", SIGTERM);
2307}
2308
2309static int sigraise_f(BlockBackend *blk, int argc, char **argv);
2310
2311static const cmdinfo_t sigraise_cmd = {
2312    .name       = "sigraise",
2313    .cfunc      = sigraise_f,
2314    .argmin     = 1,
2315    .argmax     = 1,
2316    .flags      = CMD_NOFILE_OK,
2317    .args       = "signal",
2318    .oneline    = "raises a signal",
2319    .help       = sigraise_help,
2320};
2321
2322static int sigraise_f(BlockBackend *blk, int argc, char **argv)
2323{
2324    int64_t sig = cvtnum(argv[1]);
2325    if (sig < 0) {
2326        print_cvtnum_err(sig, argv[1]);
2327        return sig;
2328    } else if (sig > NSIG) {
2329        printf("signal argument '%s' is too large to be a valid signal\n",
2330               argv[1]);
2331        return -EINVAL;
2332    }
2333
2334    /* Using raise() to kill this process does not necessarily flush all open
2335     * streams. At least stdout and stderr (although the latter should be
2336     * non-buffered anyway) should be flushed, though. */
2337    fflush(stdout);
2338    fflush(stderr);
2339
2340    raise(sig);
2341
2342    return 0;
2343}
2344
2345static void sleep_cb(void *opaque)
2346{
2347    bool *expired = opaque;
2348    *expired = true;
2349}
2350
2351static int sleep_f(BlockBackend *blk, int argc, char **argv)
2352{
2353    char *endptr;
2354    long ms;
2355    struct QEMUTimer *timer;
2356    bool expired = false;
2357
2358    ms = strtol(argv[1], &endptr, 0);
2359    if (ms < 0 || *endptr != '\0') {
2360        printf("%s is not a valid number\n", argv[1]);
2361        return -EINVAL;
2362    }
2363
2364    timer = timer_new_ns(QEMU_CLOCK_HOST, sleep_cb, &expired);
2365    timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_HOST) + SCALE_MS * ms);
2366
2367    while (!expired) {
2368        main_loop_wait(false);
2369    }
2370
2371    timer_free(timer);
2372    return 0;
2373}
2374
2375static const cmdinfo_t sleep_cmd = {
2376       .name           = "sleep",
2377       .argmin         = 1,
2378       .argmax         = 1,
2379       .cfunc          = sleep_f,
2380       .flags          = CMD_NOFILE_OK,
2381       .oneline        = "waits for the given value in milliseconds",
2382};
2383
2384static void help_oneline(const char *cmd, const cmdinfo_t *ct)
2385{
2386    if (cmd) {
2387        printf("%s ", cmd);
2388    } else {
2389        printf("%s ", ct->name);
2390        if (ct->altname) {
2391            printf("(or %s) ", ct->altname);
2392        }
2393    }
2394
2395    if (ct->args) {
2396        printf("%s ", ct->args);
2397    }
2398    printf("-- %s\n", ct->oneline);
2399}
2400
2401static void help_onecmd(const char *cmd, const cmdinfo_t *ct)
2402{
2403    help_oneline(cmd, ct);
2404    if (ct->help) {
2405        ct->help();
2406    }
2407}
2408
2409static void help_all(void)
2410{
2411    const cmdinfo_t *ct;
2412
2413    for (ct = cmdtab; ct < &cmdtab[ncmds]; ct++) {
2414        help_oneline(ct->name, ct);
2415    }
2416    printf("\nUse 'help commandname' for extended help.\n");
2417}
2418
2419static int help_f(BlockBackend *blk, int argc, char **argv)
2420{
2421    const cmdinfo_t *ct;
2422
2423    if (argc == 1) {
2424        help_all();
2425        return 0;
2426    }
2427
2428    ct = find_command(argv[1]);
2429    if (ct == NULL) {
2430        printf("command %s not found\n", argv[1]);
2431        return -EINVAL;
2432    }
2433
2434    help_onecmd(argv[1], ct);
2435    return 0;
2436}
2437
2438static const cmdinfo_t help_cmd = {
2439    .name       = "help",
2440    .altname    = "?",
2441    .cfunc      = help_f,
2442    .argmin     = 0,
2443    .argmax     = 1,
2444    .flags      = CMD_FLAG_GLOBAL,
2445    .args       = "[command]",
2446    .oneline    = "help for one or all commands",
2447};
2448
2449int qemuio_command(BlockBackend *blk, const char *cmd)
2450{
2451    AioContext *ctx;
2452    char *input;
2453    const cmdinfo_t *ct;
2454    char **v;
2455    int c;
2456    int ret = 0;
2457
2458    input = g_strdup(cmd);
2459    v = breakline(input, &c);
2460    if (c) {
2461        ct = find_command(v[0]);
2462        if (ct) {
2463            ctx = blk ? blk_get_aio_context(blk) : qemu_get_aio_context();
2464            aio_context_acquire(ctx);
2465            ret = command(blk, ct, c, v);
2466            aio_context_release(ctx);
2467        } else {
2468            fprintf(stderr, "command \"%s\" not found\n", v[0]);
2469            ret = -EINVAL;
2470        }
2471    }
2472    g_free(input);
2473    g_free(v);
2474
2475    return ret;
2476}
2477
2478static void __attribute((constructor)) init_qemuio_commands(void)
2479{
2480    /* initialize commands */
2481    qemuio_add_command(&help_cmd);
2482    qemuio_add_command(&read_cmd);
2483    qemuio_add_command(&readv_cmd);
2484    qemuio_add_command(&write_cmd);
2485    qemuio_add_command(&writev_cmd);
2486    qemuio_add_command(&aio_read_cmd);
2487    qemuio_add_command(&aio_write_cmd);
2488    qemuio_add_command(&aio_flush_cmd);
2489    qemuio_add_command(&flush_cmd);
2490    qemuio_add_command(&truncate_cmd);
2491    qemuio_add_command(&length_cmd);
2492    qemuio_add_command(&info_cmd);
2493    qemuio_add_command(&discard_cmd);
2494    qemuio_add_command(&alloc_cmd);
2495    qemuio_add_command(&map_cmd);
2496    qemuio_add_command(&reopen_cmd);
2497    qemuio_add_command(&break_cmd);
2498    qemuio_add_command(&remove_break_cmd);
2499    qemuio_add_command(&resume_cmd);
2500    qemuio_add_command(&wait_break_cmd);
2501    qemuio_add_command(&abort_cmd);
2502    qemuio_add_command(&sleep_cmd);
2503    qemuio_add_command(&sigraise_cmd);
2504}
2505