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