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