Block patches

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJTGcncAAoJEH8JsnLIjy/WaIwP/iXPS19/Xax3kXyVDdMONhmQ
 6hT8oilKRIVwo+1dw59IWxvLPisY0cTtChzsKUxVAAKtjlc5LgAVxX+3memM9AHr
 WA8FjW+fmOf2D+3iNv/Vg/aCf0ck8ghHIDW68vAHhcdmiD7DThm7MTGzsPTANQ2/
 HhTg1/p7vDdpq5LXvpJCRKZjyeQqUOlv+Y8ctFpAiQ+iQT19eG7wVZNHLu4jhnN9
 qzpgpbvv8T7Ayx4XocWYsXZrT/cnmipj1DOC7IjTLoHfynq13l9UazBb3xSdFqzz
 hpHc8KlEXvZkX1L3BXl/GKC4GN0pdbPp/Vj9/F3b++logGnDMIVgt4JFdJLjoeyA
 R8mHevbXiecJRaOagdQoIzDpglZ5fHSUjbk+zy/yISsYxjlndVs+K61O7UFGzpoG
 auBlQD31JZGc2/5ygNL0QHvCZVF2DHF3UOS5HWwO0U5AYAall932GtMdm6hQJ5GO
 2VJgv20d2GF1kTkaZPcuSG8W9mFDO0Uf24JTMtAbq3+s3u+IGTJiRk1GycfSBdLy
 DqK1lovq/AxCo+VF/WQacxn9G1vXN0wOJZ31PQmUme9Q/qyxIFGV4EskEDcMvfWx
 AC2tjsA3T8YxwTO+379Ls0RbIYuiuIXlHGKl8jJ0Gz9kaUDpQf35Sm2zkpW564Px
 D+nD26nj43Lt8uhoha9m
 =6sTe
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block patches

# gpg: Signature made Fri 07 Mar 2014 13:30:04 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream:
  block: qemu-iotests 085 - live snapshots tests
  hw/ide/ahci.h: Avoid shifting left into sign bit
  block: Fix error path segfault in bdrv_open()
  qemu-iotests: Test a few blockdev-add error cases
  blockdev: Fix NULL pointer dereference in blockdev-add
  blockdev: Fail blockdev-add with encrypted images
  block/raw-win32: Strip "file:" prefix on creation
  block/raw-win32: Implement bdrv_parse_filename()
  block/raw-posix: Strip "file:" prefix on creation
  block/raw-posix: Implement bdrv_parse_filename()
  block: Keep "filename" option after parsing
  block: mirror - remove code cruft that has no function
  block: make bdrv_swap rebuild the bs graph node list field.
  block: Fix bs->request_alignment assertion for bs->sg=1
  iscsi: Use bs->sg for everything else than disks
  qemu-iotests: Test progress output for conversion
  qemu-img convert: Fix progress output
  gluster: Remove unused defines and header include
  gluster: Change licence to GPLv2+

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-03-08 12:17:17 +00:00
commit d7c698af8a
18 changed files with 608 additions and 46 deletions

32
block.c
View File

@ -935,7 +935,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
bdrv_refresh_limits(bs); bdrv_refresh_limits(bs);
assert(bdrv_opt_mem_align(bs) != 0); assert(bdrv_opt_mem_align(bs) != 0);
assert(bs->request_alignment != 0); assert((bs->request_alignment != 0) || bs->sg);
#ifndef _WIN32 #ifndef _WIN32
if (bs->is_temporary) { if (bs->is_temporary) {
@ -1017,7 +1017,12 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename,
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;
} }
if (!drv->bdrv_needs_filename) {
qdict_del(*options, "filename"); qdict_del(*options, "filename");
} else {
filename = qdict_get_str(*options, "filename");
}
} }
if (!drv->bdrv_file_open) { if (!drv->bdrv_file_open) {
@ -1229,6 +1234,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
ret = bdrv_file_open(bs, filename, &options, flags & ~BDRV_O_PROTOCOL, ret = bdrv_file_open(bs, filename, &options, flags & ~BDRV_O_PROTOCOL,
&local_err); &local_err);
if (!ret) { if (!ret) {
drv = bs->drv;
goto done; goto done;
} else if (bs->drv) { } else if (bs->drv) {
goto close_and_fail; goto close_and_fail;
@ -1847,11 +1853,6 @@ static void bdrv_move_feature_fields(BlockDriverState *bs_dest,
pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name), pstrcpy(bs_dest->device_name, sizeof(bs_dest->device_name),
bs_src->device_name); bs_src->device_name);
bs_dest->device_list = bs_src->device_list; bs_dest->device_list = bs_src->device_list;
/* keep the same entry in graph_bdrv_states
* We do want to swap name but don't want to swap linked list entries
*/
bs_dest->node_list = bs_src->node_list;
} }
/* /*
@ -1870,6 +1871,17 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
{ {
BlockDriverState tmp; BlockDriverState tmp;
/* The code needs to swap the node_name but simply swapping node_list won't
* work so first remove the nodes from the graph list, do the swap then
* insert them back if needed.
*/
if (bs_new->node_name[0] != '\0') {
QTAILQ_REMOVE(&graph_bdrv_states, bs_new, node_list);
}
if (bs_old->node_name[0] != '\0') {
QTAILQ_REMOVE(&graph_bdrv_states, bs_old, node_list);
}
/* bs_new must be anonymous and shouldn't have anything fancy enabled */ /* bs_new must be anonymous and shouldn't have anything fancy enabled */
assert(bs_new->device_name[0] == '\0'); assert(bs_new->device_name[0] == '\0');
assert(QLIST_EMPTY(&bs_new->dirty_bitmaps)); assert(QLIST_EMPTY(&bs_new->dirty_bitmaps));
@ -1898,6 +1910,14 @@ void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old)
assert(bs_new->io_limits_enabled == false); assert(bs_new->io_limits_enabled == false);
assert(!throttle_have_timer(&bs_new->throttle_state)); assert(!throttle_have_timer(&bs_new->throttle_state));
/* insert the nodes back into the graph node list if needed */
if (bs_new->node_name[0] != '\0') {
QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs_new, node_list);
}
if (bs_old->node_name[0] != '\0') {
QTAILQ_INSERT_TAIL(&graph_bdrv_states, bs_old, node_list);
}
bdrv_rebind(bs_new); bdrv_rebind(bs_new);
bdrv_rebind(bs_old); bdrv_rebind(bs_old);
} }

View File

@ -3,21 +3,12 @@
* *
* Copyright (C) 2012 Bharata B Rao <bharata@linux.vnet.ibm.com> * Copyright (C) 2012 Bharata B Rao <bharata@linux.vnet.ibm.com>
* *
* Pipe handling mechanism in AIO implementation is derived from * This work is licensed under the terms of the GNU GPL, version 2 or later.
* block/rbd.c. Hence, * See the COPYING file in the top-level directory.
* *
* Copyright (C) 2010-2011 Christian Brunner <chb@muc.de>,
* Josh Durgin <josh.durgin@dreamhost.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/ */
#include <glusterfs/api/glfs.h> #include <glusterfs/api/glfs.h>
#include "block/block_int.h" #include "block/block_int.h"
#include "qemu/sockets.h"
#include "qemu/uri.h" #include "qemu/uri.h"
typedef struct GlusterAIOCB { typedef struct GlusterAIOCB {
@ -32,9 +23,6 @@ typedef struct BDRVGlusterState {
struct glfs_fd *fd; struct glfs_fd *fd;
} BDRVGlusterState; } BDRVGlusterState;
#define GLUSTER_FD_READ 0
#define GLUSTER_FD_WRITE 1
typedef struct GlusterConf { typedef struct GlusterConf {
char *server; char *server;
int port; int port;

View File

@ -1231,12 +1231,11 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun);
bs->request_alignment = iscsilun->block_size; bs->request_alignment = iscsilun->block_size;
/* Medium changer or tape. We dont have any emulation for this so this must /* We don't have any emulation for devices other than disks and CD-ROMs, so
* be sg ioctl compatible. We force it to be sg, otherwise qemu will try * this must be sg ioctl compatible. We force it to be sg, otherwise qemu
* to read from the device to guess the image format. * will try to read from the device to guess the image format.
*/ */
if (iscsilun->type == TYPE_MEDIUM_CHANGER || if (iscsilun->type != TYPE_DISK && iscsilun->type != TYPE_ROM) {
iscsilun->type == TYPE_TAPE) {
bs->sg = 1; bs->sg = 1;
} }

View File

@ -520,9 +520,6 @@ static void mirror_complete(BlockJob *job, Error **errp)
ret = bdrv_open_backing_file(s->target, NULL, &local_err); ret = bdrv_open_backing_file(s->target, NULL, &local_err);
if (ret < 0) { if (ret < 0) {
char backing_filename[PATH_MAX];
bdrv_get_full_backing_filename(s->target, backing_filename,
sizeof(backing_filename));
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; return;
} }

View File

@ -336,6 +336,17 @@ error:
} }
#endif #endif
static void raw_parse_filename(const char *filename, QDict *options,
Error **errp)
{
/* The filename does not have to be prefixed by the protocol name, since
* "file" is the default protocol; therefore, the return value of this
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
}
static QemuOptsList raw_runtime_opts = { static QemuOptsList raw_runtime_opts = {
.name = "raw", .name = "raw",
.head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head),
@ -1230,6 +1241,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
int result = 0; int result = 0;
int64_t total_size = 0; int64_t total_size = 0;
strstart(filename, "file:", &filename);
/* Read out options */ /* Read out options */
while (options && options->name) { while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
@ -1412,6 +1425,7 @@ static BlockDriver bdrv_file = {
.instance_size = sizeof(BDRVRawState), .instance_size = sizeof(BDRVRawState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_probe = NULL, /* no probe for protocols */ .bdrv_probe = NULL, /* no probe for protocols */
.bdrv_parse_filename = raw_parse_filename,
.bdrv_file_open = raw_open, .bdrv_file_open = raw_open,
.bdrv_reopen_prepare = raw_reopen_prepare, .bdrv_reopen_prepare = raw_reopen_prepare,
.bdrv_reopen_commit = raw_reopen_commit, .bdrv_reopen_commit = raw_reopen_commit,

View File

@ -251,6 +251,17 @@ static void raw_parse_flags(int flags, int *access_flags, DWORD *overlapped)
} }
} }
static void raw_parse_filename(const char *filename, QDict *options,
Error **errp)
{
/* The filename does not have to be prefixed by the protocol name, since
* "file" is the default protocol; therefore, the return value of this
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
}
static QemuOptsList raw_runtime_opts = { static QemuOptsList raw_runtime_opts = {
.name = "raw", .name = "raw",
.head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head), .head = QTAILQ_HEAD_INITIALIZER(raw_runtime_opts.head),
@ -470,6 +481,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
int fd; int fd;
int64_t total_size = 0; int64_t total_size = 0;
strstart(filename, "file:", &filename);
/* Read out options */ /* Read out options */
while (options && options->name) { while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
@ -504,6 +517,7 @@ static BlockDriver bdrv_file = {
.protocol_name = "file", .protocol_name = "file",
.instance_size = sizeof(BDRVRawState), .instance_size = sizeof(BDRVRawState),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.bdrv_parse_filename = raw_parse_filename,
.bdrv_file_open = raw_open, .bdrv_file_open = raw_open,
.bdrv_close = raw_close, .bdrv_close = raw_close,
.bdrv_create = raw_create, .bdrv_create = raw_create,

View File

@ -2266,6 +2266,7 @@ void qmp_block_job_complete(const char *device, Error **errp)
void qmp_blockdev_add(BlockdevOptions *options, Error **errp) void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
{ {
QmpOutputVisitor *ov = qmp_output_visitor_new(); QmpOutputVisitor *ov = qmp_output_visitor_new();
DriveInfo *dinfo;
QObject *obj; QObject *obj;
QDict *qdict; QDict *qdict;
Error *local_err = NULL; Error *local_err = NULL;
@ -2282,8 +2283,10 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
* *
* For now, simply forbidding the combination for all drivers will do. */ * For now, simply forbidding the combination for all drivers will do. */
if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) { if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {
bool direct = options->cache->has_direct && options->cache->direct; bool direct = options->has_cache &&
if (!options->has_cache && !direct) { options->cache->has_direct &&
options->cache->direct;
if (!direct) {
error_setg(errp, "aio=native requires cache.direct=true"); error_setg(errp, "aio=native requires cache.direct=true");
goto fail; goto fail;
} }
@ -2301,12 +2304,18 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
qdict_flatten(qdict); qdict_flatten(qdict);
blockdev_init(NULL, qdict, &local_err); dinfo = blockdev_init(NULL, qdict, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto fail; goto fail;
} }
if (bdrv_key_required(dinfo->bdrv)) {
drive_uninit(dinfo);
error_setg(errp, "blockdev-add doesn't support encrypted devices");
goto fail;
}
fail: fail:
qmp_output_visitor_cleanup(ov); qmp_output_visitor_cleanup(ov);
} }

View File

@ -40,7 +40,7 @@
#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \ #define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
AHCI_RX_FIS_SZ) AHCI_RX_FIS_SZ)
#define AHCI_IRQ_ON_SG (1 << 31) #define AHCI_IRQ_ON_SG (1U << 31)
#define AHCI_CMD_ATAPI (1 << 5) #define AHCI_CMD_ATAPI (1 << 5)
#define AHCI_CMD_WRITE (1 << 6) #define AHCI_CMD_WRITE (1 << 6)
#define AHCI_CMD_PREFETCH (1 << 7) #define AHCI_CMD_PREFETCH (1 << 7)
@ -61,7 +61,7 @@
/* HOST_CTL bits */ /* HOST_CTL bits */
#define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear */ #define HOST_CTL_RESET (1 << 0) /* reset controller; self-clear */
#define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */ #define HOST_CTL_IRQ_EN (1 << 1) /* global IRQ enable */
#define HOST_CTL_AHCI_EN (1 << 31) /* AHCI enabled */ #define HOST_CTL_AHCI_EN (1U << 31) /* AHCI enabled */
/* HOST_CAP bits */ /* HOST_CAP bits */
#define HOST_CAP_SSC (1 << 14) /* Slumber capable */ #define HOST_CAP_SSC (1 << 14) /* Slumber capable */
@ -69,7 +69,7 @@
#define HOST_CAP_CLO (1 << 24) /* Command List Override support */ #define HOST_CAP_CLO (1 << 24) /* Command List Override support */
#define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */ #define HOST_CAP_SSS (1 << 27) /* Staggered Spin-up */
#define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */ #define HOST_CAP_NCQ (1 << 30) /* Native Command Queueing */
#define HOST_CAP_64 (1 << 31) /* PCI DAC (64-bit DMA) support */ #define HOST_CAP_64 (1U << 31) /* PCI DAC (64-bit DMA) support */
/* registers for each SATA port */ /* registers for each SATA port */
#define PORT_LST_ADDR 0x00 /* command list DMA addr */ #define PORT_LST_ADDR 0x00 /* command list DMA addr */
@ -89,7 +89,7 @@
#define PORT_RESERVED 0x3c /* reserved */ #define PORT_RESERVED 0x3c /* reserved */
/* PORT_IRQ_{STAT,MASK} bits */ /* PORT_IRQ_{STAT,MASK} bits */
#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ #define PORT_IRQ_COLD_PRES (1U << 31) /* cold presence detect */
#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ #define PORT_IRQ_TF_ERR (1 << 30) /* task file error */
#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */ #define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */
#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */ #define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */
@ -151,7 +151,7 @@
#define PORT_IRQ_STAT_HBDS (1 << 28) /* Host Bus Data Error Status */ #define PORT_IRQ_STAT_HBDS (1 << 28) /* Host Bus Data Error Status */
#define PORT_IRQ_STAT_HBFS (1 << 29) /* Host Bus Fatal Error Status */ #define PORT_IRQ_STAT_HBFS (1 << 29) /* Host Bus Fatal Error Status */
#define PORT_IRQ_STAT_TFES (1 << 30) /* Task File Error Status */ #define PORT_IRQ_STAT_TFES (1 << 30) /* Task File Error Status */
#define PORT_IRQ_STAT_CPDS (1 << 31) /* Code Port Detect Status */ #define PORT_IRQ_STAT_CPDS (1U << 31) /* Code Port Detect Status */
/* ap->flags bits */ /* ap->flags bits */
#define AHCI_FLAG_NO_NCQ (1 << 24) #define AHCI_FLAG_NO_NCQ (1 << 24)

View File

@ -1162,9 +1162,6 @@ static int img_convert(int argc, char **argv)
Error *local_err = NULL; Error *local_err = NULL;
QemuOpts *sn_opts = NULL; QemuOpts *sn_opts = NULL;
/* Initialize before goto out */
qemu_progress_init(progress, 1.0);
fmt = NULL; fmt = NULL;
out_fmt = "raw"; out_fmt = "raw";
cache = "unsafe"; cache = "unsafe";
@ -1197,17 +1194,17 @@ static int img_convert(int argc, char **argv)
error_report("option -e is deprecated, please use \'-o " error_report("option -e is deprecated, please use \'-o "
"encryption\' instead!"); "encryption\' instead!");
ret = -1; ret = -1;
goto out; goto fail_getopt;
case '6': case '6':
error_report("option -6 is deprecated, please use \'-o " error_report("option -6 is deprecated, please use \'-o "
"compat6\' instead!"); "compat6\' instead!");
ret = -1; ret = -1;
goto out; goto fail_getopt;
case 'o': case 'o':
if (!is_valid_option_list(optarg)) { if (!is_valid_option_list(optarg)) {
error_report("Invalid option list: %s", optarg); error_report("Invalid option list: %s", optarg);
ret = -1; ret = -1;
goto out; goto fail_getopt;
} }
if (!options) { if (!options) {
options = g_strdup(optarg); options = g_strdup(optarg);
@ -1227,7 +1224,7 @@ static int img_convert(int argc, char **argv)
error_report("Failed in parsing snapshot param '%s'", error_report("Failed in parsing snapshot param '%s'",
optarg); optarg);
ret = -1; ret = -1;
goto out; goto fail_getopt;
} }
} else { } else {
snapshot_name = optarg; snapshot_name = optarg;
@ -1241,7 +1238,7 @@ static int img_convert(int argc, char **argv)
if (sval < 0 || *end) { if (sval < 0 || *end) {
error_report("Invalid minimum zero buffer size for sparse output specified"); error_report("Invalid minimum zero buffer size for sparse output specified");
ret = -1; ret = -1;
goto out; goto fail_getopt;
} }
min_sparse = sval / BDRV_SECTOR_SIZE; min_sparse = sval / BDRV_SECTOR_SIZE;
@ -1262,9 +1259,12 @@ static int img_convert(int argc, char **argv)
} }
} }
/* Initialize before goto out */
if (quiet) { if (quiet) {
progress = 0; progress = 0;
} }
qemu_progress_init(progress, 1.0);
bs_n = argc - optind - 1; bs_n = argc - optind - 1;
out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; out_filename = bs_n >= 1 ? argv[argc - 1] : NULL;
@ -1667,7 +1667,6 @@ out:
free_option_parameters(create_options); free_option_parameters(create_options);
free_option_parameters(param); free_option_parameters(param);
qemu_vfree(buf); qemu_vfree(buf);
g_free(options);
if (sn_opts) { if (sn_opts) {
qemu_opts_del(sn_opts); qemu_opts_del(sn_opts);
} }
@ -1682,6 +1681,9 @@ out:
} }
g_free(bs); g_free(bs);
} }
fail_getopt:
g_free(options);
if (ret) { if (ret) {
return 1; return 1;
} }

View File

@ -77,6 +77,15 @@ run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=on
run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=1234 run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=1234
run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=foo run_qemu -drive file="$TEST_IMG",format=qcow2,unknown_opt=foo
echo
echo === Unknown protocol option ===
echo
run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=
run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=on
run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=1234
run_qemu -drive file="$TEST_IMG",format=qcow2,file.unknown_opt=foo
echo echo
echo === Invalid format === echo === Invalid format ===
echo echo

View File

@ -17,6 +17,21 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt' QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block format 'qcow2' used by device 'ide0-hd0' doesn't support the option 'unknown_opt'
=== Unknown protocol option ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=on: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=1234: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,file.unknown_opt=foo: could not open disk image TEST_DIR/t.qcow2: Block protocol 'file' doesn't support the option 'unknown_opt'
=== Invalid format === === Invalid format ===
Testing: -drive file=TEST_DIR/t.qcow2,format=foo Testing: -drive file=TEST_DIR/t.qcow2,format=foo

192
tests/qemu-iotests/085 Executable file
View File

@ -0,0 +1,192 @@
#!/bin/bash
#
# Live snapshot tests
#
# This tests live snapshots of images on a running QEMU instance, using
# QMP commands. Both single disk snapshots, and transactional group
# snapshots are performed.
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=jcody@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
qemu_pid=
QMP_IN="${TEST_DIR}/qmp-in-$$"
QMP_OUT="${TEST_DIR}/qmp-out-$$"
snapshot_virt0="snapshot-v0.qcow2"
snapshot_virt1="snapshot-v1.qcow2"
MAX_SNAPSHOTS=10
_cleanup()
{
kill -KILL ${qemu_pid}
wait ${qemu_pid} 2>/dev/null # silent kill
rm -f "${QMP_IN}" "${QMP_OUT}"
for i in $(seq 1 ${MAX_SNAPSHOTS})
do
rm -f "${TEST_DIR}/${i}-${snapshot_virt0}"
rm -f "${TEST_DIR}/${i}-${snapshot_virt1}"
done
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
# Wait for expected QMP response from QEMU. Will time out
# after 10 seconds, which counts as failure.
#
# $1 is the string to expect
#
# If $silent is set to anything but an empty string, then
# response is not echoed out.
function timed_wait_for()
{
while read -t 10 resp <&5
do
if [ "${silent}" == "" ]; then
echo "${resp}" | _filter_testdir | _filter_qemu
fi
grep -q "${1}" < <(echo ${resp})
if [ $? -eq 0 ]; then
return
fi
done
echo "Timeout waiting for ${1}"
exit 1 # Timeout means the test failed
}
# Sends QMP command to QEMU, and waits for the expected response
#
# ${1}: String of the QMP command to send
# ${2}: String that the QEMU response should contain
function send_qmp_cmd()
{
echo "${1}" >&6
timed_wait_for "${2}"
}
# ${1}: unique identifier for the snapshot filename
function create_single_snapshot()
{
cmd="{ 'execute': 'blockdev-snapshot-sync',
'arguments': { 'device': 'virtio0',
'snapshot-file':'"${TEST_DIR}/${1}-${snapshot_virt0}"',
'format': 'qcow2' } }"
send_qmp_cmd "${cmd}" "return"
}
# ${1}: unique identifier for the snapshot filename
function create_group_snapshot()
{
cmd="{ 'execute': 'transaction', 'arguments':
{'actions': [
{ 'type': 'blockdev-snapshot-sync', 'data' :
{ 'device': 'virtio0',
'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt0}"' } },
{ 'type': 'blockdev-snapshot-sync', 'data' :
{ 'device': 'virtio1',
'snapshot-file': '"${TEST_DIR}/${1}-${snapshot_virt1}"' } } ]
} }"
send_qmp_cmd "${cmd}" "return"
}
size=128M
mkfifo "${QMP_IN}"
mkfifo "${QMP_OUT}"
_make_test_img $size
mv "${TEST_IMG}" "${TEST_IMG}.orig"
_make_test_img $size
echo
echo === Running QEMU ===
echo
"${QEMU}" -nographic -monitor none -serial none -qmp stdio\
-drive file="${TEST_IMG}.orig",if=virtio\
-drive file="${TEST_IMG}",if=virtio 2>&1 >"${QMP_OUT}" <"${QMP_IN}"&
qemu_pid=$!
# redirect fifos to file descriptors, to keep from blocking
exec 5<"${QMP_OUT}"
exec 6>"${QMP_IN}"
# Don't print response, since it has version information in it
silent=yes timed_wait_for "capabilities"
echo
echo === Sending capabilities ===
echo
send_qmp_cmd "{ 'execute': 'qmp_capabilities' }" "return"
echo
echo === Create a single snapshot on virtio0 ===
echo
create_single_snapshot 1
echo
echo === Invalid command - missing device and nodename ===
echo
send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
'arguments': { 'snapshot-file':'"${TEST_DIR}"/1-${snapshot_virt0}',
'format': 'qcow2' } }" "error"
echo
echo === Invalid command - missing snapshot-file ===
echo
send_qmp_cmd "{ 'execute': 'blockdev-snapshot-sync',
'arguments': { 'device': 'virtio0',
'format': 'qcow2' } }" "error"
echo
echo
echo === Create several transactional group snapshots ===
echo
for i in $(seq 2 ${MAX_SNAPSHOTS})
do
create_group_snapshot ${i}
done
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,55 @@
QA output created by 085
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== Running QEMU ===
=== Sending capabilities ===
{"return": {}}
=== Create a single snapshot on virtio0 ===
Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2.orig' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
=== Invalid command - missing device and nodename ===
{"error": {"class": "GenericError", "desc": "Cannot find device= nor node_name="}}
=== Invalid command - missing snapshot-file ===
{"error": {"class": "GenericError", "desc": "Parameter 'snapshot-file' is missing"}}
=== Create several transactional group snapshots ===
Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/1-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/t.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/2-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/3-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/4-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/5-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/6-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/7-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/8-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v0.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file='TEST_DIR/9-snapshot-v1.qcow2' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off
{"return": {}}
*** done

65
tests/qemu-iotests/086 Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
#
# Test qemu-img progress output
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
function run_qemu_img()
{
echo
echo Testing: "$@" | _filter_testdir
}
size=128M
_make_test_img $size
$QEMU_IO -c 'write 0 1M' $TEST_IMG | _filter_qemu_io
$QEMU_IO -c 'write 2M 1M' $TEST_IMG | _filter_qemu_io
$QEMU_IO -c 'write 4M 1M' $TEST_IMG | _filter_qemu_io
$QEMU_IO -c 'write 32M 1M' $TEST_IMG | _filter_qemu_io
$QEMU_IMG convert -p -O $IMGFMT -f $IMGFMT "$TEST_IMG" "$TEST_IMG".base 2>&1 |\
_filter_testdir | sed -e 's/\r/\n/g'
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,18 @@
QA output created by 086
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 1048576/1048576 bytes at offset 0
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1048576/1048576 bytes at offset 2097152
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1048576/1048576 bytes at offset 4194304
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 1048576/1048576 bytes at offset 33554432
1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
(0.00/100%)
(25.00/100%)
(50.00/100%)
(75.00/100%)
(100.00/100%)
(100.00/100%)
*** done

122
tests/qemu-iotests/087 Executable file
View File

@ -0,0 +1,122 @@
#!/bin/bash
#
# Test unsupported blockdev-add cases
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
tmp=/tmp/$$
status=1 # failure is the default!
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
function do_run_qemu()
{
echo Testing: "$@"
$QEMU -nographic -qmp stdio -serial none "$@"
echo
}
function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | sed -e 's/\("actual-size":\s*\)[0-9]\+/\1SIZE/g'
}
size=128M
_make_test_img $size
echo
echo === Missing ID ===
echo
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"options": {
"driver": "$IMGFMT",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
}
}
}
{ "execute": "quit" }
EOF
echo
echo === aio=native without O_DIRECT ===
echo
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"options": {
"driver": "$IMGFMT",
"id": "disk",
"aio": "native",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
}
}
}
{ "execute": "quit" }
EOF
echo
echo === Encrypted image ===
echo
_make_test_img -o encryption=on $size
run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"options": {
"driver": "$IMGFMT",
"id": "disk",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
}
}
}
{ "execute": "quit" }
EOF
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,40 @@
QA output created by 087
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== Missing ID ===
Testing:
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "Block device needs an ID"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
=== aio=native without O_DIRECT ===
Testing:
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "aio=native requires cache.direct=true"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
=== Encrypted image ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on
Testing:
QMP_VERSION
{"return": {}}
{"error": {"class": "GenericError", "desc": "blockdev-add doesn't support encrypted devices"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
*** done

View File

@ -85,3 +85,6 @@
079 rw auto 079 rw auto
081 rw auto 081 rw auto
082 rw auto quick 082 rw auto quick
085 rw auto quick
086 rw auto quick
087 rw auto quick