-----BEGIN PGP SIGNATURE-----

Version: GnuPG v1
 
 iQEcBAABAgAGBQJUiyFkAAoJEJykq7OBq3PIOxwH/iNwgJiag12KGBZbwOGJmc/L
 6Z1XuvLmSbp+bIrbUfxIx+Izss8b7S16f3QvbMwOVGGpFRWvfGVljerLgiKagarl
 cj2aU+TX+VQjKrWTE1KgG64Ai4GfD6cCzr3fXCBLHetDhmA1h0qUxaZk580zvP/6
 1h2WACNh+KeFGyh1gJHjj/aYGZbPq7hiN04/HMiT0E5swKYVuygrUX/blaffWk6O
 LnW2aRFQM4I5wZXdUOyL5BOHH4wnQUN8i4xUpSKvILUuAWx16At58FbORmtrgk4k
 hJmDREBMg+nbCWWh7ehkcQEhxoZPww8MVolqnJfkMYr8UHZHrBYh8UBuznaeGbU=
 =YeTr
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging

# gpg: Signature made Fri 12 Dec 2014 17:09:56 GMT using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request:
  linux-aio: simplify removal of completed iocbs from the list
  linux-aio: drop return code from laio_io_unplug and ioq_submit
  linux-aio: rename LaioQueue idx field to "n"
  linux-aio: track whether the queue is blocked
  linux-aio: queue requests that cannot be submitted
  block: drop unused bdrv_clear_incoming_migration_all() prototype
  block: Don't add trailing space in "Formating..." message
  qemu-iotests: Remove traling whitespaces in *.out
  block: vhdx - set .bdrv_has_zero_init to bdrv_has_zero_init_1
  iotests: Fix test 039
  iotests: Filter for "Killed" in qemu-io output
  qemu-io: Add sigraise command
  block: vhdx - change .vhdx_create default block state to ZERO
  block: vhdx - update PAYLOAD_BLOCK_UNMAPPED value to match 1.00 spec
  block: vhdx - remove redundant comments
  block/rbd: fix memory leak
  iotests: Add test for vmdk JSON file names
  vmdk: Fix error for JSON descriptor file names
  block migration: fix return value

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-12-12 17:10:44 +00:00
commit e0d3795654
98 changed files with 619 additions and 527 deletions

View File

@ -653,6 +653,7 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
{
int ret;
int64_t last_ftell = qemu_ftell(f);
int64_t delta_ftell;
DPRINTF("Enter save live iterate submitted %d transferred %d\n",
block_mig_state.submitted, block_mig_state.transferred);
@ -702,7 +703,14 @@ static int block_save_iterate(QEMUFile *f, void *opaque)
}
qemu_put_be64(f, BLK_MIG_FLAG_EOS);
return qemu_ftell(f) - last_ftell;
delta_ftell = qemu_ftell(f) - last_ftell;
if (delta_ftell > 0) {
return 1;
} else if (delta_ftell < 0) {
return -1;
} else {
return 0;
}
}
/* Called with iothread lock taken. */

View File

@ -229,7 +229,7 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs)
}
/* check if the path starts with "<protocol>:" */
static int path_has_protocol(const char *path)
int path_has_protocol(const char *path)
{
const char *p;
@ -5668,8 +5668,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
if (!quiet) {
printf("Formatting '%s', fmt=%s ", filename, fmt);
qemu_opts_print(opts);
printf("Formatting '%s', fmt=%s", filename, fmt);
qemu_opts_print(opts, " ");
puts("");
}

View File

@ -35,14 +35,14 @@ struct qemu_laiocb {
size_t nbytes;
QEMUIOVector *qiov;
bool is_read;
QLIST_ENTRY(qemu_laiocb) node;
QSIMPLEQ_ENTRY(qemu_laiocb) next;
};
typedef struct {
struct iocb *iocbs[MAX_QUEUED_IO];
int plugged;
unsigned int size;
unsigned int idx;
unsigned int n;
bool blocked;
QSIMPLEQ_HEAD(, qemu_laiocb) pending;
} LaioQueue;
struct qemu_laio_state {
@ -59,6 +59,8 @@ struct qemu_laio_state {
int event_max;
};
static void ioq_submit(struct qemu_laio_state *s);
static inline ssize_t io_event_ret(struct io_event *ev)
{
return (ssize_t)(((uint64_t)ev->res2 << 32) | ev->res);
@ -135,6 +137,10 @@ static void qemu_laio_completion_bh(void *opaque)
qemu_laio_process_completion(s, laiocb);
}
if (!s->io_q.plugged && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
ioq_submit(s);
}
}
static void qemu_laio_completion_cb(EventNotifier *e)
@ -172,50 +178,41 @@ static const AIOCBInfo laio_aiocb_info = {
static void ioq_init(LaioQueue *io_q)
{
io_q->size = MAX_QUEUED_IO;
io_q->idx = 0;
QSIMPLEQ_INIT(&io_q->pending);
io_q->plugged = 0;
io_q->n = 0;
io_q->blocked = false;
}
static int ioq_submit(struct qemu_laio_state *s)
static void ioq_submit(struct qemu_laio_state *s)
{
int ret, i = 0;
int len = s->io_q.idx;
int ret, len;
struct qemu_laiocb *aiocb;
struct iocb *iocbs[MAX_QUEUED_IO];
QSIMPLEQ_HEAD(, qemu_laiocb) completed;
do {
ret = io_submit(s->ctx, len, s->io_q.iocbs);
} while (i++ < 3 && ret == -EAGAIN);
/* empty io queue */
s->io_q.idx = 0;
len = 0;
QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) {
iocbs[len++] = &aiocb->iocb;
if (len == MAX_QUEUED_IO) {
break;
}
}
ret = io_submit(s->ctx, len, iocbs);
if (ret == -EAGAIN) {
break;
}
if (ret < 0) {
i = 0;
} else {
i = ret;
abort();
}
for (; i < len; i++) {
struct qemu_laiocb *laiocb =
container_of(s->io_q.iocbs[i], struct qemu_laiocb, iocb);
laiocb->ret = (ret < 0) ? ret : -EIO;
qemu_laio_process_completion(s, laiocb);
}
return ret;
}
static void ioq_enqueue(struct qemu_laio_state *s, struct iocb *iocb)
{
unsigned int idx = s->io_q.idx;
s->io_q.iocbs[idx++] = iocb;
s->io_q.idx = idx;
/* submit immediately if queue is full */
if (idx == s->io_q.size) {
ioq_submit(s);
}
s->io_q.n -= ret;
aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb);
QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed);
} while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending));
s->io_q.blocked = (s->io_q.n > 0);
}
void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
@ -225,22 +222,19 @@ void laio_io_plug(BlockDriverState *bs, void *aio_ctx)
s->io_q.plugged++;
}
int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug)
{
struct qemu_laio_state *s = aio_ctx;
int ret = 0;
assert(s->io_q.plugged > 0 || !unplug);
if (unplug && --s->io_q.plugged > 0) {
return 0;
return;
}
if (s->io_q.idx > 0) {
ret = ioq_submit(s);
if (!s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending)) {
ioq_submit(s);
}
return ret;
}
BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
@ -276,12 +270,11 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
}
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
if (!s->io_q.plugged) {
if (io_submit(s->ctx, 1, &iocbs) < 0) {
goto out_free_aiocb;
}
} else {
ioq_enqueue(s, iocbs);
QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next);
s->io_q.n++;
if (!s->io_q.blocked &&
(!s->io_q.plugged || s->io_q.n >= MAX_QUEUED_IO)) {
ioq_submit(s);
}
return &laiocb->common;

View File

@ -41,7 +41,7 @@ BlockAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
void laio_detach_aio_context(void *s, AioContext *old_context);
void laio_attach_aio_context(void *s, AioContext *new_context);
void laio_io_plug(BlockDriverState *bs, void *aio_ctx);
int laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
void laio_io_unplug(BlockDriverState *bs, void *aio_ctx, bool unplug);
#endif
#ifdef _WIN32

View File

@ -459,7 +459,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
error_setg(&local_err, "error initializing");
error_setg(errp, "error initializing");
goto failed_opts;
}
@ -495,19 +495,19 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
r = rados_connect(s->cluster);
if (r < 0) {
error_setg(&local_err, "error connecting");
error_setg(errp, "error connecting");
goto failed_shutdown;
}
r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
if (r < 0) {
error_setg(&local_err, "error opening pool %s", pool);
error_setg(errp, "error opening pool %s", pool);
goto failed_shutdown;
}
r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
if (r < 0) {
error_setg(&local_err, "error reading header from %s", s->name);
error_setg(errp, "error reading header from %s", s->name);
goto failed_open;
}

View File

@ -1109,8 +1109,9 @@ static coroutine_fn int vhdx_co_readv(BlockDriverState *bs, int64_t sector_num,
/* check the payload block state */
switch (s->bat[sinfo.bat_idx] & VHDX_BAT_STATE_BIT_MASK) {
case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
case PAYLOAD_BLOCK_UNDEFINED: /* fall through */
case PAYLOAD_BLOCK_UNMAPPED: /* fall through */
case PAYLOAD_BLOCK_UNDEFINED:
case PAYLOAD_BLOCK_UNMAPPED:
case PAYLOAD_BLOCK_UNMAPPED_v095:
case PAYLOAD_BLOCK_ZERO:
/* return zero */
qemu_iovec_memset(&hd_qiov, 0, 0, sinfo.bytes_avail);
@ -1277,11 +1278,11 @@ static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num,
sectors_to_write += iov2.iov_len >> BDRV_SECTOR_BITS;
}
}
/* fall through */
case PAYLOAD_BLOCK_NOT_PRESENT: /* fall through */
case PAYLOAD_BLOCK_UNMAPPED: /* fall through */
case PAYLOAD_BLOCK_UNDEFINED: /* fall through */
case PAYLOAD_BLOCK_UNMAPPED:
case PAYLOAD_BLOCK_UNMAPPED_v095:
case PAYLOAD_BLOCK_UNDEFINED:
bat_prior_offset = sinfo.file_offset;
ret = vhdx_allocate_block(bs, s, &sinfo.file_offset);
if (ret < 0) {
@ -1773,7 +1774,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false);
use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, true);
if (image_size > VHDX_MAX_IMAGE_SIZE) {
error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
@ -1935,7 +1936,9 @@ static QemuOptsList vhdx_create_opts = {
{
.name = VHDX_BLOCK_OPT_ZERO,
.type = QEMU_OPT_BOOL,
.help = "Force use of payload blocks of type 'ZERO'. Non-standard."
.help = "Force use of payload blocks of type 'ZERO'. "\
"Non-standard, but default. Do not set to 'off' when "\
"using 'qemu-img convert' with subformat=dynamic."
},
{ NULL }
}
@ -1953,6 +1956,7 @@ static BlockDriver bdrv_vhdx = {
.bdrv_create = vhdx_create,
.bdrv_get_info = vhdx_get_info,
.bdrv_check = vhdx_check,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.create_opts = &vhdx_create_opts,
};

View File

@ -226,7 +226,8 @@ typedef struct QEMU_PACKED VHDXLogDataSector {
#define PAYLOAD_BLOCK_NOT_PRESENT 0
#define PAYLOAD_BLOCK_UNDEFINED 1
#define PAYLOAD_BLOCK_ZERO 2
#define PAYLOAD_BLOCK_UNMAPPED 5
#define PAYLOAD_BLOCK_UNMAPPED 3
#define PAYLOAD_BLOCK_UNMAPPED_v095 5
#define PAYLOAD_BLOCK_FULLY_PRESENT 6
#define PAYLOAD_BLOCK_PARTIALLY_PRESENT 7

View File

@ -833,6 +833,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
goto next_line;
}
if (!path_is_absolute(fname) && !path_has_protocol(fname) &&
!desc_file_path[0])
{
error_setg(errp, "Cannot use relative extent paths with VMDK "
"descriptor file '%s'", bs->file->filename);
return -EINVAL;
}
path_combine(extent_path, sizeof(extent_path),
desc_file_path, fname);
extent_file = NULL;
@ -909,7 +917,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
}
s->create_type = g_strdup(ct);
s->desc_offset = 0;
ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
ret = vmdk_parse_extents(buf, bs, bs->file->exact_filename, errp);
exit:
return ret;
}

View File

@ -329,8 +329,6 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp);
void bdrv_invalidate_cache_all(Error **errp);
void bdrv_clear_incoming_migration_all(void);
/* Ensure contents are flushed to disk. */
int bdrv_flush(BlockDriverState *bs);
int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
@ -401,6 +399,7 @@ void bdrv_get_full_backing_filename(BlockDriverState *bs,
char *dest, size_t sz);
int bdrv_is_snapshot(BlockDriverState *bs);
int path_has_protocol(const char *path);
int path_is_absolute(const char *path);
void path_combine(char *dest, int dest_size,
const char *base_path,

View File

@ -124,7 +124,7 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp);
typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
void qemu_opts_print(QemuOpts *opts);
void qemu_opts_print(QemuOpts *opts, const char *sep);
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
int abort_on_failure);
void qemu_opts_print_help(QemuOptsList *list);

View File

@ -268,6 +268,17 @@ struct { \
(head)->sqh_last = &(head)->sqh_first; \
} while (/*CONSTCOND*/0)
#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \
QSIMPLEQ_INIT(removed); \
if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \
(head)->sqh_last = &(head)->sqh_first; \
} \
(removed)->sqh_last = &(elm)->field.sqe_next; \
(elm)->field.sqe_next = NULL; \
} \
} while (/*CONSTCOND*/0)
#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
QSIMPLEQ_REMOVE_HEAD((head), field); \

View File

@ -698,7 +698,11 @@ Supported options:
Specifies which VHDX subformat to use. Valid options are
@code{dynamic} (default) and @code{fixed}.
@item block_state_zero
Force use of payload blocks of type 'ZERO'.
Force use of payload blocks of type 'ZERO'. Can be set to @code{on} (default)
or @code{off}. When set to @code{off}, new blocks will be created as
@code{PAYLOAD_BLOCK_NOT_PRESENT}, which means parsers are free to return
arbitrary data for those blocks. Do not set to @code{off} when using
@code{qemu-img convert} with @code{subformat=dynamic}.
@item block_size
Block size; min 1 MB, max 256 MB. 0 means auto-calculate based on image size.
@item log_size

View File

@ -2048,6 +2048,51 @@ static const cmdinfo_t abort_cmd = {
.oneline = "simulate a program crash using abort(3)",
};
static void sigraise_help(void)
{
printf(
"\n"
" raises the given signal\n"
"\n"
" Example:\n"
" 'sigraise %i' - raises SIGTERM\n"
"\n"
" Invokes raise(signal), where \"signal\" is the mandatory integer argument\n"
" given to sigraise.\n"
"\n", SIGTERM);
}
static int sigraise_f(BlockDriverState *bs, int argc, char **argv);
static const cmdinfo_t sigraise_cmd = {
.name = "sigraise",
.cfunc = sigraise_f,
.argmin = 1,
.argmax = 1,
.flags = CMD_NOFILE_OK,
.args = "signal",
.oneline = "raises a signal",
.help = sigraise_help,
};
static int sigraise_f(BlockDriverState *bs, int argc, char **argv)
{
int sig = cvtnum(argv[1]);
if (sig < 0) {
printf("non-numeric signal number argument -- %s\n", argv[1]);
return 0;
}
/* Using raise() to kill this process does not necessarily flush all open
* streams. At least stdout and stderr (although the latter should be
* non-buffered anyway) should be flushed, though. */
fflush(stdout);
fflush(stderr);
raise(sig);
return 0;
}
static void sleep_cb(void *opaque)
{
bool *expired = opaque;
@ -2202,4 +2247,5 @@ static void __attribute((constructor)) init_qemuio_commands(void)
qemuio_add_command(&wait_break_cmd);
qemuio_add_command(&abort_cmd);
qemuio_add_command(&sleep_cmd);
qemuio_add_command(&sigraise_cmd);
}

View File

@ -47,9 +47,11 @@ _supported_os Linux
_default_cache_mode "writethrough"
_supported_cache_modes "writethrough"
_no_dump_exec()
_subshell_exec()
{
(ulimit -c 0; exec "$@")
# Executing crashing commands in a subshell prevents information like the
# "Killed" line from being lost
(exec "$@")
}
size=128M
@ -72,7 +74,9 @@ echo "== Creating a dirty image file =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
# The dirty bit must be set
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
@ -105,7 +109,9 @@ echo "== Opening a dirty image read/write should repair it =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
# The dirty bit must be set
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
@ -121,7 +127,9 @@ echo "== Creating an image file with lazy_refcounts=off =="
IMGOPTS="compat=1.1,lazy_refcounts=off"
_make_test_img $size
_no_dump_exec $QEMU_IO -c "write -P 0x5a 0 512" -c "abort" "$TEST_IMG" 2>&1 | _filter_qemu_io
_subshell_exec $QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
# The dirty bit must not be set since lazy_refcounts=off
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features

View File

@ -11,7 +11,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./039: Aborted ( ulimit -c 0; exec "$@" )
./039: Killed ( exec "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@ -46,7 +46,7 @@ read 512/512 bytes at offset 0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./039: Aborted ( ulimit -c 0; exec "$@" )
./039: Killed ( exec "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
Rebuilding refcount structure
@ -60,7 +60,7 @@ incompatible_features 0x0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./039: Aborted ( ulimit -c 0; exec "$@" )
./039: Killed ( exec "$@" )
incompatible_features 0x0
No errors were found on the image.

View File

@ -110,6 +110,12 @@ $QEMU_IO -f qcow2 -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
$QEMU_IO -f qcow2 -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1
echo
echo "=== Testing monolithicFlat with internally generated JSON file name ==="
IMGOPTS="subformat=monolithicFlat" _make_test_img 64M
$QEMU_IO -c "open -o driver=$IMGFMT,file.driver=blkdebug,file.image.filename=$TEST_IMG,file.inject-error.0.event=read_aio" 2>&1 \
| _filter_testdir | _filter_imgfmt
echo
echo "=== Testing version 3 ==="
_use_sample_img iotest-version3.vmdk.bz2

View File

@ -2053,6 +2053,10 @@ wrote 512/512 bytes at offset 0
wrote 512/512 bytes at offset 10240
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
=== Testing monolithicFlat with internally generated JSON file name ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "read_aio"}'
=== Testing version 3 ===
image: TEST_DIR/iotest-version3.IMGFMT
file format: IMGFMT

View File

@ -150,7 +150,7 @@ _filter_win32()
_filter_qemu_io()
{
_filter_win32 | sed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
-e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\)/:\1/" \
-e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
-e "s/qemu-io> //g"
}

View File

@ -737,14 +737,14 @@ void qemu_opts_del(QemuOpts *opts)
g_free(opts);
}
void qemu_opts_print(QemuOpts *opts)
void qemu_opts_print(QemuOpts *opts, const char *sep)
{
QemuOpt *opt;
QemuOptDesc *desc = opts->list->desc;
if (desc[0].name == NULL) {
QTAILQ_FOREACH(opt, &opts->head, next) {
printf("%s=\"%s\" ", opt->name, opt->str);
printf("%s%s=\"%s\"", sep, opt->name, opt->str);
}
return;
}
@ -757,12 +757,12 @@ void qemu_opts_print(QemuOpts *opts)
continue;
}
if (desc->type == QEMU_OPT_STRING) {
printf("%s='%s' ", desc->name, value);
printf("%s%s='%s'", sep, desc->name, value);
} else if ((desc->type == QEMU_OPT_SIZE ||
desc->type == QEMU_OPT_NUMBER) && opt) {
printf("%s=%" PRId64 " ", desc->name, opt->value.uint);
printf("%s%s=%" PRId64, sep, desc->name, opt->value.uint);
} else {
printf("%s=%s ", desc->name, value);
printf("%s%s=%s", sep, desc->name, value);
}
}
}