diff options
| author | Kevin Wolf <kwolf@redhat.com> | 2016-05-12 15:35:20 +0200 |
|---|---|---|
| committer | Kevin Wolf <kwolf@redhat.com> | 2016-05-12 15:35:20 +0200 |
| commit | efc2645f714aae1bcf22e8165cad51c57f34fdf3 (patch) | |
| tree | b7f6c7ceae0977dc2cc569d0de1e6942d5aa6fb0 /qemu-io-cmds.c | |
| parent | aad0b7a0bfbd6d200f617396c0d3b71ac7abfa40 (diff) | |
| parent | 5a8fabf3333c8b445f514377a4292ad0354fd35c (diff) | |
| download | focaccia-qemu-efc2645f714aae1bcf22e8165cad51c57f34fdf3.tar.gz focaccia-qemu-efc2645f714aae1bcf22e8165cad51c57f34fdf3.zip | |
Merge remote-tracking branch 'mreitz/tags/pull-block-for-kevin-2016-05-12' into queue-block
Block patches for 2.7 # gpg: Signature made Thu May 12 15:34:13 2016 CEST using RSA key ID E838ACAD # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" * mreitz/tags/pull-block-for-kevin-2016-05-12: qemu-iotests: iotests: fail hard if not run via "check" block: enable testing of LUKS driver with block I/O tests block: add support for encryption secrets in block I/O tests block: add support for --image-opts in block I/O tests qemu-io: Add 'write -z -u' to test MAY_UNMAP flag qemu-io: Add 'write -f' to test FUA flag qemu-io: Allow unaligned access by default qemu-io: Use bool for command line flags qemu-io: Make 'open' subcommand more like command line qemu-io: Add missing option documentation qmp: add monitor command to add/remove a child quorum: implement bdrv_add_child() and bdrv_del_child() Add new block driver interface to add/delete a BDS's child qemu-img: check block status of backing file when converting. iotests: fix the redirection order in 083 Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'qemu-io-cmds.c')
| -rw-r--r-- | qemu-io-cmds.c | 228 |
1 files changed, 116 insertions, 112 deletions
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 767ea5ecdb..4a00bc604d 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1,7 +1,7 @@ /* * Command line utility to exercise the QEMU I/O path. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009-2016 Red Hat, Inc. * Copyright (c) 2003-2005 Silicon Graphics, Inc. * * This work is licensed under the terms of the GNU GPL, version 2 or later. @@ -345,7 +345,7 @@ static void dump_buffer(const void *buffer, int64_t offset, int64_t len) } static void print_report(const char *op, struct timeval *t, int64_t offset, - int64_t count, int64_t total, int cnt, int Cflag) + int64_t count, int64_t total, int cnt, bool Cflag) { char s1[64], s2[64], ts[64]; @@ -395,12 +395,6 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov, goto fail; } - if (len & 0x1ff) { - printf("length argument %" PRId64 - " is not sector aligned\n", len); - goto fail; - } - sizes[i] = len; count += len; } @@ -434,13 +428,13 @@ static int do_pread(BlockBackend *blk, char *buf, int64_t offset, } static int do_pwrite(BlockBackend *blk, char *buf, int64_t offset, - int64_t count, int64_t *total) + int64_t count, int flags, int64_t *total) { if (count > INT_MAX) { return -ERANGE; } - *total = blk_pwrite(blk, offset, (uint8_t *)buf, count, 0); + *total = blk_pwrite(blk, offset, (uint8_t *)buf, count, flags); if (*total < 0) { return *total; } @@ -452,6 +446,7 @@ typedef struct { int64_t offset; int64_t count; int64_t *total; + int flags; int ret; bool done; } CoWriteZeroes; @@ -460,7 +455,8 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque) { CoWriteZeroes *data = opaque; - data->ret = blk_co_write_zeroes(data->blk, data->offset, data->count, 0); + data->ret = blk_co_write_zeroes(data->blk, data->offset, data->count, + data->flags); data->done = true; if (data->ret < 0) { *data->total = data->ret; @@ -471,7 +467,7 @@ static void coroutine_fn co_write_zeroes_entry(void *opaque) } static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count, - int64_t *total) + int flags, int64_t *total) { Coroutine *co; CoWriteZeroes data = { @@ -479,6 +475,7 @@ static int do_co_write_zeroes(BlockBackend *blk, int64_t offset, int64_t count, .offset = offset, .count = count, .total = total, + .flags = flags, .done = false, }; @@ -564,11 +561,11 @@ static int do_aio_readv(BlockBackend *blk, QEMUIOVector *qiov, } static int do_aio_writev(BlockBackend *blk, QEMUIOVector *qiov, - int64_t offset, int *total) + int64_t offset, int flags, int *total) { int async_ret = NOT_DONE; - blk_aio_pwritev(blk, offset, qiov, 0, aio_rw_done, &async_ret); + blk_aio_pwritev(blk, offset, qiov, flags, aio_rw_done, &async_ret); while (async_ret == NOT_DONE) { main_loop_wait(false); } @@ -634,7 +631,7 @@ static void read_help(void) " -b, -- read from the VM state rather than the virtual disk\n" " -C, -- report statistics in a machine parsable format\n" " -l, -- length for pattern verification (only with -P)\n" -" -p, -- allow unaligned access\n" +" -p, -- ignored for backwards compatibility\n" " -P, -- use a pattern to verify read data\n" " -q, -- quiet mode, do not show I/O statistics\n" " -s, -- start offset for pattern verification (only with -P)\n" @@ -650,7 +647,7 @@ static const cmdinfo_t read_cmd = { .cfunc = read_f, .argmin = 2, .argmax = -1, - .args = "[-abCpqv] [-P pattern [-s off] [-l len]] off len", + .args = "[-abCqv] [-P pattern [-s off] [-l len]] off len", .oneline = "reads a number of bytes at a specified offset", .help = read_help, }; @@ -658,8 +655,8 @@ static const cmdinfo_t read_cmd = { static int read_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, vflag = 0; - int Pflag = 0, sflag = 0, lflag = 0, bflag = 0; + bool Cflag = false, qflag = false, vflag = false; + bool Pflag = false, sflag = false, lflag = false, bflag = false; int c, cnt; char *buf; int64_t offset; @@ -672,13 +669,13 @@ static int read_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "bCl:pP:qs:v")) != -1) { switch (c) { case 'b': - bflag = 1; + bflag = true; break; case 'C': - Cflag = 1; + Cflag = true; break; case 'l': - lflag = 1; + lflag = true; pattern_count = cvtnum(optarg); if (pattern_count < 0) { print_cvtnum_err(pattern_count, optarg); @@ -686,20 +683,20 @@ static int read_f(BlockBackend *blk, int argc, char **argv) } break; case 'p': - pflag = 1; + /* Ignored for backwards compatibility */ break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; break; case 's': - sflag = 1; + sflag = true; pattern_offset = cvtnum(optarg); if (pattern_offset < 0) { print_cvtnum_err(pattern_offset, optarg); @@ -707,7 +704,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv) } break; case 'v': - vflag = 1; + vflag = true; break; default: return qemuio_command_usage(&read_cmd); @@ -718,11 +715,6 @@ static int read_f(BlockBackend *blk, int argc, char **argv) return qemuio_command_usage(&read_cmd); } - if (bflag && pflag) { - printf("-b and -p cannot be specified at the same time\n"); - return 0; - } - offset = cvtnum(argv[optind]); if (offset < 0) { print_cvtnum_err(offset, argv[optind]); @@ -753,7 +745,7 @@ static int read_f(BlockBackend *blk, int argc, char **argv) return 0; } - if (!pflag) { + if (bflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); @@ -836,7 +828,7 @@ static const cmdinfo_t readv_cmd = { .cfunc = readv_f, .argmin = 2, .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", + .args = "[-Cqv] [-P pattern] off len [len..]", .oneline = "reads a number of bytes at a specified offset", .help = readv_help, }; @@ -844,7 +836,7 @@ static const cmdinfo_t readv_cmd = { static int readv_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0, vflag = 0; + bool Cflag = false, qflag = false, vflag = false; int c, cnt; char *buf; int64_t offset; @@ -853,25 +845,25 @@ static int readv_f(BlockBackend *blk, int argc, char **argv) int nr_iov; QEMUIOVector qiov; int pattern = 0; - int Pflag = 0; + bool Pflag = false; while ((c = getopt(argc, argv, "CP:qv")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; break; case 'v': - vflag = 1; + vflag = true; break; default: return qemuio_command_usage(&readv_cmd); @@ -890,12 +882,6 @@ static int readv_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - nr_iov = argc - optind; buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, 0xab); if (buf == NULL) { @@ -952,10 +938,12 @@ static void write_help(void) " filled with a set pattern (0xcdcdcdcd).\n" " -b, -- write to the VM state rather than the virtual disk\n" " -c, -- write compressed data with blk_write_compressed\n" -" -p, -- allow unaligned access\n" +" -f, -- use Force Unit Access semantics\n" +" -p, -- ignored for backwards compatibility\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" " -q, -- quiet mode, do not show I/O statistics\n" +" -u, -- with -z, allow unmapping\n" " -z, -- write zeroes using blk_co_write_zeroes\n" "\n"); } @@ -968,7 +956,7 @@ static const cmdinfo_t write_cmd = { .cfunc = write_f, .argmin = 2, .argmax = -1, - .args = "[-bcCpqz] [-P pattern ] off len", + .args = "[-bcCfquz] [-P pattern] off len", .oneline = "writes a number of bytes at a specified offset", .help = write_help, }; @@ -976,8 +964,9 @@ static const cmdinfo_t write_cmd = { static int write_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0; - int cflag = 0; + bool Cflag = false, qflag = false, bflag = false; + bool Pflag = false, zflag = false, cflag = false; + int flags = 0; int c, cnt; char *buf = NULL; int64_t offset; @@ -986,32 +975,38 @@ static int write_f(BlockBackend *blk, int argc, char **argv) int64_t total = 0; int pattern = 0xcd; - while ((c = getopt(argc, argv, "bcCpP:qz")) != -1) { + while ((c = getopt(argc, argv, "bcCfpP:quz")) != -1) { switch (c) { case 'b': - bflag = 1; + bflag = true; break; case 'c': - cflag = 1; + cflag = true; break; case 'C': - Cflag = 1; + Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'p': - pflag = 1; + /* Ignored for backwards compatibility */ break; case 'P': - Pflag = 1; + Pflag = true; pattern = parse_pattern(optarg); if (pattern < 0) { return 0; } break; case 'q': - qflag = 1; + qflag = true; + break; + case 'u': + flags |= BDRV_REQ_MAY_UNMAP; break; case 'z': - zflag = 1; + zflag = true; break; default: return qemuio_command_usage(&write_cmd); @@ -1022,8 +1017,18 @@ static int write_f(BlockBackend *blk, int argc, char **argv) return qemuio_command_usage(&write_cmd); } - if (bflag + pflag + zflag > 1) { - printf("-b, -p, or -z cannot be specified at the same time\n"); + if (bflag && zflag) { + printf("-b and -z cannot be specified at the same time\n"); + return 0; + } + + if ((flags & BDRV_REQ_FUA) && (bflag || cflag)) { + printf("-f and -b or -c cannot be specified at the same time\n"); + return 0; + } + + if ((flags & BDRV_REQ_MAY_UNMAP) && !zflag) { + printf("-u requires -z to be specified\n"); return 0; } @@ -1049,7 +1054,7 @@ static int write_f(BlockBackend *blk, int argc, char **argv) return 0; } - if (!pflag) { + if (bflag || cflag) { if (offset & 0x1ff) { printf("offset %" PRId64 " is not sector aligned\n", offset); @@ -1071,11 +1076,11 @@ static int write_f(BlockBackend *blk, int argc, char **argv) if (bflag) { cnt = do_save_vmstate(blk, buf, offset, count, &total); } else if (zflag) { - cnt = do_co_write_zeroes(blk, offset, count, &total); + cnt = do_co_write_zeroes(blk, offset, count, flags, &total); } else if (cflag) { cnt = do_write_compressed(blk, buf, offset, count, &total); } else { - cnt = do_pwrite(blk, buf, offset, count, &total); + cnt = do_pwrite(blk, buf, offset, count, flags, &total); } gettimeofday(&t2, NULL); @@ -1114,6 +1119,7 @@ writev_help(void) " filled with a set pattern (0xcdcdcdcd).\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" +" -f, -- use Force Unit Access semantics\n" " -q, -- quiet mode, do not show I/O statistics\n" "\n"); } @@ -1125,7 +1131,7 @@ static const cmdinfo_t writev_cmd = { .cfunc = writev_f, .argmin = 2, .argmax = -1, - .args = "[-Cq] [-P pattern ] off len [len..]", + .args = "[-Cfq] [-P pattern] off len [len..]", .oneline = "writes a number of bytes at a specified offset", .help = writev_help, }; @@ -1133,7 +1139,8 @@ static const cmdinfo_t writev_cmd = { static int writev_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; + int flags = 0; int c, cnt; char *buf; int64_t offset; @@ -1146,10 +1153,13 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CqP:")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'q': - qflag = 1; + qflag = true; break; case 'P': pattern = parse_pattern(optarg); @@ -1173,12 +1183,6 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - offset); - return 0; - } - nr_iov = argc - optind; buf = create_iovec(blk, &qiov, &argv[optind], nr_iov, pattern); if (buf == NULL) { @@ -1186,7 +1190,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv) } gettimeofday(&t1, NULL); - cnt = do_aio_writev(blk, &qiov, offset, &total); + cnt = do_aio_writev(blk, &qiov, offset, flags, &total); gettimeofday(&t2, NULL); if (cnt < 0) { @@ -1242,7 +1246,7 @@ static const cmdinfo_t multiwrite_cmd = { static int multiwrite_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; int c, cnt; char **buf; int64_t offset, first_offset = 0; @@ -1258,10 +1262,10 @@ static int multiwrite_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CqP:")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'q': - qflag = 1; + qflag = true; break; case 'P': pattern = parse_pattern(optarg); @@ -1371,11 +1375,11 @@ struct aio_ctx { QEMUIOVector qiov; int64_t offset; char *buf; - int qflag; - int vflag; - int Cflag; - int Pflag; - int zflag; + bool qflag; + bool vflag; + bool Cflag; + bool Pflag; + bool zflag; BlockAcctCookie acct; int pattern; struct timeval t1; @@ -1484,7 +1488,7 @@ static const cmdinfo_t aio_read_cmd = { .cfunc = aio_read_f, .argmin = 2, .argmax = -1, - .args = "[-Cqv] [-P pattern ] off len [len..]", + .args = "[-Cqv] [-P pattern] off len [len..]", .oneline = "asynchronously reads a number of bytes", .help = aio_read_help, }; @@ -1498,10 +1502,10 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) while ((c = getopt(argc, argv, "CP:qv")) != -1) { switch (c) { case 'C': - ctx->Cflag = 1; + ctx->Cflag = true; break; case 'P': - ctx->Pflag = 1; + ctx->Pflag = true; ctx->pattern = parse_pattern(optarg); if (ctx->pattern < 0) { g_free(ctx); @@ -1509,10 +1513,10 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) } break; case 'q': - ctx->qflag = 1; + ctx->qflag = true; break; case 'v': - ctx->vflag = 1; + ctx->vflag = true; break; default: g_free(ctx); @@ -1533,14 +1537,6 @@ static int aio_read_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_READ); - g_free(ctx); - return 0; - } - nr_iov = argc - optind; ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, 0xab); if (ctx->buf == NULL) { @@ -1572,7 +1568,9 @@ static void aio_write_help(void) " used to ensure all outstanding aio requests have been completed.\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" +" -f, -- use Force Unit Access semantics\n" " -q, -- quiet mode, do not show I/O statistics\n" +" -u, -- with -z, allow unmapping\n" " -z, -- write zeroes using blk_aio_write_zeroes\n" "\n"); } @@ -1584,7 +1582,7 @@ static const cmdinfo_t aio_write_cmd = { .cfunc = aio_write_f, .argmin = 2, .argmax = -1, - .args = "[-Cqz] [-P pattern ] off len [len..]", + .args = "[-Cfquz] [-P pattern] off len [len..]", .oneline = "asynchronously writes a number of bytes", .help = aio_write_help, }; @@ -1594,15 +1592,22 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) int nr_iov, c; int pattern = 0xcd; struct aio_ctx *ctx = g_new0(struct aio_ctx, 1); + int flags = 0; ctx->blk = blk; - while ((c = getopt(argc, argv, "CqP:z")) != -1) { + while ((c = getopt(argc, argv, "CfqP:z")) != -1) { switch (c) { case 'C': - ctx->Cflag = 1; + ctx->Cflag = true; + break; + case 'f': + flags |= BDRV_REQ_FUA; break; case 'q': - ctx->qflag = 1; + ctx->qflag = true; + break; + case 'u': + flags |= BDRV_REQ_MAY_UNMAP; break; case 'P': pattern = parse_pattern(optarg); @@ -1612,7 +1617,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) } break; case 'z': - ctx->zflag = 1; + ctx->zflag = true; break; default: g_free(ctx); @@ -1631,6 +1636,11 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) return 0; } + if ((flags & BDRV_REQ_MAY_UNMAP) && !ctx->zflag) { + printf("-u requires -z to be specified\n"); + return 0; + } + if (ctx->zflag && ctx->Pflag) { printf("-z and -P cannot be specified at the same time\n"); g_free(ctx); @@ -1645,14 +1655,6 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) } optind++; - if (ctx->offset & 0x1ff) { - printf("offset %" PRId64 " is not sector aligned\n", - ctx->offset); - block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE); - g_free(ctx); - return 0; - } - if (ctx->zflag) { int64_t count = cvtnum(argv[optind]); if (count < 0) { @@ -1662,7 +1664,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) } ctx->qiov.size = count; - blk_aio_write_zeroes(blk, ctx->offset, count, 0, aio_write_done, ctx); + blk_aio_write_zeroes(blk, ctx->offset, count, flags, aio_write_done, + ctx); } else { nr_iov = argc - optind; ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, @@ -1677,7 +1680,8 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv) block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size, BLOCK_ACCT_WRITE); - blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, 0, aio_write_done, ctx); + blk_aio_pwritev(blk, ctx->offset, &ctx->qiov, flags, aio_write_done, + ctx); } return 0; } @@ -1841,17 +1845,17 @@ static const cmdinfo_t discard_cmd = { static int discard_f(BlockBackend *blk, int argc, char **argv) { struct timeval t1, t2; - int Cflag = 0, qflag = 0; + bool Cflag = false, qflag = false; int c, ret; int64_t offset, count; while ((c = getopt(argc, argv, "Cq")) != -1) { switch (c) { case 'C': - Cflag = 1; + Cflag = true; break; case 'q': - qflag = 1; + qflag = true; break; default: return qemuio_command_usage(&discard_cmd); |