diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-11-29 16:25:23 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-11-29 16:25:23 +0000 |
commit | 915308bc3f0f4815ba95b27f424edc96f7853278 (patch) | |
tree | 183bbb703c578b493215e3c9b9af4f233d02588c | |
parent | 844496f3e55a2155200fdcf7f6320acef03d4e9f (diff) | |
parent | 5591c001a1056910afd903df3fc3c03f30746623 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.11.0-rc3
# gpg: Signature made Wed 29 Nov 2017 15:25:13 GMT
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
block/nfs: fix nfs_client_open for filesize greater than 1TB
blockjob: reimplement block_job_sleep_ns to allow cancellation
blockjob: introduce block_job_do_yield
blockjob: remove clock argument from block_job_sleep_ns
block: Expect graph changes in bdrv_parent_drained_begin/end
blockjob: Remove the job from the list earlier in block_job_unref()
QAPI & interop: Clarify events emitted by 'block-job-cancel'
qemu-options: Mention locking option of file driver
docs: Add image locking subsection
iotests: fix 075 and 078
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | block/backup.c | 4 | ||||
-rw-r--r-- | block/commit.c | 2 | ||||
-rw-r--r-- | block/io.c | 8 | ||||
-rw-r--r-- | block/mirror.c | 6 | ||||
-rw-r--r-- | block/nfs.c | 7 | ||||
-rw-r--r-- | block/stream.c | 2 | ||||
-rw-r--r-- | blockjob.c | 84 | ||||
-rw-r--r-- | docs/interop/live-block-operations.rst | 50 | ||||
-rw-r--r-- | docs/qemu-block-drivers.texi | 36 | ||||
-rw-r--r-- | include/block/blockjob.h | 8 | ||||
-rw-r--r-- | include/block/blockjob_int.h | 7 | ||||
-rw-r--r-- | qapi/block-core.json | 6 | ||||
-rw-r--r-- | qemu-doc.texi | 1 | ||||
-rw-r--r-- | qemu-options.hx | 4 | ||||
-rwxr-xr-x | tests/qemu-iotests/075 | 18 | ||||
-rwxr-xr-x | tests/qemu-iotests/078 | 14 | ||||
-rw-r--r-- | tests/test-blockjob-txn.c | 2 |
17 files changed, 187 insertions, 72 deletions
diff --git a/block/backup.c b/block/backup.c index 06ddbfd03d..99e6bcc748 100644 --- a/block/backup.c +++ b/block/backup.c @@ -346,9 +346,9 @@ static bool coroutine_fn yield_and_check(BackupBlockJob *job) uint64_t delay_ns = ratelimit_calculate_delay(&job->limit, job->bytes_read); job->bytes_read = 0; - block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns); + block_job_sleep_ns(&job->common, delay_ns); } else { - block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0); + block_job_sleep_ns(&job->common, 0); } if (block_job_is_cancelled(&job->common)) { diff --git a/block/commit.c b/block/commit.c index 5036eec434..c5327551ce 100644 --- a/block/commit.c +++ b/block/commit.c @@ -174,7 +174,7 @@ static void coroutine_fn commit_run(void *opaque) /* Note that even when no rate limit is applied we need to yield * with no pending I/O here so that bdrv_drain_all() returns. */ - block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns); + block_job_sleep_ns(&s->common, delay_ns); if (block_job_is_cancelled(&s->common)) { break; } diff --git a/block/io.c b/block/io.c index 4fdf93a014..6773926fc1 100644 --- a/block/io.c +++ b/block/io.c @@ -42,9 +42,9 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs, void bdrv_parent_drained_begin(BlockDriverState *bs) { - BdrvChild *c; + BdrvChild *c, *next; - QLIST_FOREACH(c, &bs->parents, next_parent) { + QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) { if (c->role->drained_begin) { c->role->drained_begin(c); } @@ -53,9 +53,9 @@ void bdrv_parent_drained_begin(BlockDriverState *bs) void bdrv_parent_drained_end(BlockDriverState *bs) { - BdrvChild *c; + BdrvChild *c, *next; - QLIST_FOREACH(c, &bs->parents, next_parent) { + QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) { if (c->role->drained_end) { c->role->drained_end(c); } diff --git a/block/mirror.c b/block/mirror.c index 307b6391a8..c9badc1203 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -598,7 +598,7 @@ static void mirror_throttle(MirrorBlockJob *s) if (now - s->last_pause_ns > SLICE_TIME) { s->last_pause_ns = now; - block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0); + block_job_sleep_ns(&s->common, 0); } else { block_job_pause_point(&s->common); } @@ -870,13 +870,13 @@ static void coroutine_fn mirror_run(void *opaque) ret = 0; trace_mirror_before_sleep(s, cnt, s->synced, delay_ns); if (!s->synced) { - block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns); + block_job_sleep_ns(&s->common, delay_ns); if (block_job_is_cancelled(&s->common)) { break; } } else if (!should_complete) { delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0); - block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns); + block_job_sleep_ns(&s->common, delay_ns); } s->last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); } diff --git a/block/nfs.c b/block/nfs.c index 337fcd9c84..effc8719b5 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -1,7 +1,7 @@ /* * QEMU Block driver for native access to files on NFS shares * - * Copyright (c) 2014-2016 Peter Lieven <pl@kamp.de> + * Copyright (c) 2014-2017 Peter Lieven <pl@kamp.de> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -496,7 +496,7 @@ out: static int64_t nfs_client_open(NFSClient *client, QDict *options, int flags, int open_flags, Error **errp) { - int ret = -EINVAL; + int64_t ret = -EINVAL; QemuOpts *opts = NULL; Error *local_err = NULL; struct stat st; @@ -686,8 +686,7 @@ static QemuOptsList nfs_create_opts = { static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp) { - int ret = 0; - int64_t total_size = 0; + int64_t ret, total_size; NFSClient *client = g_new0(NFSClient, 1); QDict *options = NULL; diff --git a/block/stream.c b/block/stream.c index e6f72346e5..499cdacdb0 100644 --- a/block/stream.c +++ b/block/stream.c @@ -141,7 +141,7 @@ static void coroutine_fn stream_run(void *opaque) /* Note that even when no rate limit is applied we need to yield * with no pending I/O here so that bdrv_drain_all() returns. */ - block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns); + block_job_sleep_ns(&s->common, delay_ns); if (block_job_is_cancelled(&s->common)) { break; } diff --git a/blockjob.c b/blockjob.c index ff9a614531..0ed50b953b 100644 --- a/blockjob.c +++ b/blockjob.c @@ -37,6 +37,26 @@ #include "qemu/timer.h" #include "qapi-event.h" +/* Right now, this mutex is only needed to synchronize accesses to job->busy + * and job->sleep_timer, such as concurrent calls to block_job_do_yield and + * block_job_enter. */ +static QemuMutex block_job_mutex; + +static void block_job_lock(void) +{ + qemu_mutex_lock(&block_job_mutex); +} + +static void block_job_unlock(void) +{ + qemu_mutex_unlock(&block_job_mutex); +} + +static void __attribute__((__constructor__)) block_job_init(void) +{ + qemu_mutex_init(&block_job_mutex); +} + static void block_job_event_cancelled(BlockJob *job); static void block_job_event_completed(BlockJob *job, const char *msg); @@ -152,6 +172,7 @@ void block_job_unref(BlockJob *job) { if (--job->refcnt == 0) { BlockDriverState *bs = blk_bs(job->blk); + QLIST_REMOVE(job, job_list); bs->job = NULL; block_job_remove_all_bdrv(job); blk_remove_aio_context_notifier(job->blk, @@ -160,7 +181,7 @@ void block_job_unref(BlockJob *job) blk_unref(job->blk); error_free(job->blocker); g_free(job->id); - QLIST_REMOVE(job, job_list); + assert(!timer_pending(&job->sleep_timer)); g_free(job); } } @@ -287,6 +308,13 @@ static void coroutine_fn block_job_co_entry(void *opaque) job->driver->start(job); } +static void block_job_sleep_timer_cb(void *opaque) +{ + BlockJob *job = opaque; + + block_job_enter(job); +} + void block_job_start(BlockJob *job) { assert(job && !block_job_started(job) && job->paused && @@ -556,7 +584,7 @@ BlockJobInfo *block_job_query(BlockJob *job, Error **errp) info->type = g_strdup(BlockJobType_str(job->driver->job_type)); info->device = g_strdup(job->id); info->len = job->len; - info->busy = job->busy; + info->busy = atomic_read(&job->busy); info->paused = job->pause_count > 0; info->offset = job->offset; info->speed = job->speed; @@ -664,6 +692,9 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, job->paused = true; job->pause_count = 1; job->refcnt = 1; + aio_timer_init(qemu_get_aio_context(), &job->sleep_timer, + QEMU_CLOCK_REALTIME, SCALE_NS, + block_job_sleep_timer_cb, job); error_setg(&job->blocker, "block device is in use by block job: %s", BlockJobType_str(driver->job_type)); @@ -729,6 +760,26 @@ static bool block_job_should_pause(BlockJob *job) return job->pause_count > 0; } +/* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds. + * Reentering the job coroutine with block_job_enter() before the timer has + * expired is allowed and cancels the timer. + * + * If @ns is (uint64_t) -1, no timer is scheduled and block_job_enter() must be + * called explicitly. */ +static void block_job_do_yield(BlockJob *job, uint64_t ns) +{ + block_job_lock(); + if (ns != -1) { + timer_mod(&job->sleep_timer, ns); + } + job->busy = false; + block_job_unlock(); + qemu_coroutine_yield(); + + /* Set by block_job_enter before re-entering the coroutine. */ + assert(job->busy); +} + void coroutine_fn block_job_pause_point(BlockJob *job) { assert(job && block_job_started(job)); @@ -746,9 +797,7 @@ void coroutine_fn block_job_pause_point(BlockJob *job) if (block_job_should_pause(job) && !block_job_is_cancelled(job)) { job->paused = true; - job->busy = false; - qemu_coroutine_yield(); /* wait for block_job_resume() */ - job->busy = true; + block_job_do_yield(job, -1); job->paused = false; } @@ -778,9 +827,17 @@ void block_job_enter(BlockJob *job) return; } - if (!job->busy) { - bdrv_coroutine_enter(blk_bs(job->blk), job->co); + block_job_lock(); + if (job->busy) { + block_job_unlock(); + return; } + + assert(!job->deferred_to_main_loop); + timer_del(&job->sleep_timer); + job->busy = true; + block_job_unlock(); + aio_co_wake(job->co); } bool block_job_is_cancelled(BlockJob *job) @@ -788,7 +845,7 @@ bool block_job_is_cancelled(BlockJob *job) return job->cancelled; } -void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns) +void block_job_sleep_ns(BlockJob *job, int64_t ns) { assert(job->busy); @@ -797,13 +854,8 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns) return; } - /* We need to leave job->busy set here, because when we have - * put a coroutine to 'sleep', we have scheduled it to run in - * the future. We cannot enter that same coroutine again before - * it wakes and runs, otherwise we risk double-entry or entry after - * completion. */ if (!block_job_should_pause(job)) { - co_aio_sleep_ns(blk_get_aio_context(job->blk), type, ns); + block_job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns); } block_job_pause_point(job); @@ -818,11 +870,9 @@ void block_job_yield(BlockJob *job) return; } - job->busy = false; if (!block_job_should_pause(job)) { - qemu_coroutine_yield(); + block_job_do_yield(job, -1); } - job->busy = true; block_job_pause_point(job); } diff --git a/docs/interop/live-block-operations.rst b/docs/interop/live-block-operations.rst index 5f0179749f..734252bc80 100644 --- a/docs/interop/live-block-operations.rst +++ b/docs/interop/live-block-operations.rst @@ -506,26 +506,40 @@ Again, given our familiar disk image chain:: [A] <-- [B] <-- [C] <-- [D] -The ``drive-mirror`` (and its newer equivalent ``blockdev-mirror``) allows -you to copy data from the entire chain into a single target image (which -can be located on a different host). - -Once a 'mirror' job has started, there are two possible actions while a -``drive-mirror`` job is active: - -(1) Issuing the command ``block-job-cancel`` after it emits the event - ``BLOCK_JOB_CANCELLED``: will (after completing synchronization of - the content from the disk image chain to the target image, [E]) - create a point-in-time (which is at the time of *triggering* the - cancel command) copy, contained in image [E], of the the entire disk +The ``drive-mirror`` (and its newer equivalent ``blockdev-mirror``) +allows you to copy data from the entire chain into a single target image +(which can be located on a different host), [E]. + +.. note:: + + When you cancel an in-progress 'mirror' job *before* the source and + target are synchronized, ``block-job-cancel`` will emit the event + ``BLOCK_JOB_CANCELLED``. However, note that if you cancel a + 'mirror' job *after* it has indicated (via the event + ``BLOCK_JOB_READY``) that the source and target have reached + synchronization, then the event emitted by ``block-job-cancel`` + changes to ``BLOCK_JOB_COMPLETED``. + + Besides the 'mirror' job, the "active ``block-commit``" is the only + other block device job that emits the event ``BLOCK_JOB_READY``. + The rest of the block device jobs ('stream', "non-active + ``block-commit``", and 'backup') end automatically. + +So there are two possible actions to take, after a 'mirror' job has +emitted the event ``BLOCK_JOB_READY``, indicating that the source and +target have reached synchronization: + +(1) Issuing the command ``block-job-cancel`` (after it emits the event + ``BLOCK_JOB_COMPLETED``) will create a point-in-time (which is at + the time of *triggering* the cancel command) copy of the entire disk image chain (or only the top-most image, depending on the ``sync`` - mode). + mode), contained in the target image [E]. One use case for this is + live VM migration with non-shared storage. -(2) Issuing the command ``block-job-complete`` after it emits the event - ``BLOCK_JOB_COMPLETED``: will, after completing synchronization of - the content, adjust the guest device (i.e. live QEMU) to point to - the target image, and, causing all the new writes from this point on - to happen there. One use case for this is live storage migration. +(2) Issuing the command ``block-job-complete`` (after it emits the event + ``BLOCK_JOB_COMPLETED``) will adjust the guest device (i.e. live + QEMU) to point to the target image, [E], causing all the new writes + from this point on to happen there. About synchronization modes: The synchronization mode determines *which* part of the disk image chain will be copied to the target. diff --git a/docs/qemu-block-drivers.texi b/docs/qemu-block-drivers.texi index 1cb1e55686..503c1847aa 100644 --- a/docs/qemu-block-drivers.texi +++ b/docs/qemu-block-drivers.texi @@ -785,6 +785,42 @@ warning: ssh server @code{ssh.example.com:22} does not support fsync With sufficiently new versions of libssh2 and OpenSSH, @code{fsync} is supported. +@node disk_image_locking +@subsection Disk image file locking + +By default, QEMU tries to protect image files from unexpected concurrent +access, as long as it's supported by the block protocol driver and host +operating system. If multiple QEMU processes (including QEMU emulators and +utilities) try to open the same image with conflicting accessing modes, all but +the first one will get an error. + +This feature is currently supported by the file protocol on Linux with the Open +File Descriptor (OFD) locking API, and can be configured to fall back to POSIX +locking if the POSIX host doesn't support Linux OFD locking. + +To explicitly enable image locking, specify "locking=on" in the file protocol +driver options. If OFD locking is not possible, a warning will be printed and +the POSIX locking API will be used. In this case there is a risk that the lock +will get silently lost when doing hot plugging and block jobs, due to the +shortcomings of the POSIX locking API. + +QEMU transparently handles lock handover during shared storage migration. For +shared virtual disk images between multiple VMs, the "share-rw" device option +should be used. + +Alternatively, locking can be fully disabled by "locking=off" block device +option. In the command line, the option is usually in the form of +"file.locking=off" as the protocol driver is normally placed as a "file" child +under a format driver. For example: + +@code{-blockdev driver=qcow2,file.filename=/path/to/image,file.locking=off,file.driver=file} + +To check if image locking is active, check the output of the "lslocks" command +on host and see if there are locks held by the QEMU process on the image file. +More than one byte could be locked by the QEMU instance, each byte of which +reflects a particular permission that is acquired or protected by the running +block driver. + @c man end @ignore diff --git a/include/block/blockjob.h b/include/block/blockjob.h index 67c0968fa5..00403d9482 100644 --- a/include/block/blockjob.h +++ b/include/block/blockjob.h @@ -77,7 +77,7 @@ typedef struct BlockJob { /** * Set to false by the job while the coroutine has yielded and may be * re-entered by block_job_enter(). There may still be I/O or event loop - * activity pending. + * activity pending. Accessed under block_job_mutex (in blockjob.c). */ bool busy; @@ -135,6 +135,12 @@ typedef struct BlockJob { */ int ret; + /** + * Timer that is used by @block_job_sleep_ns. Accessed under + * block_job_mutex (in blockjob.c). + */ + QEMUTimer sleep_timer; + /** Non-NULL if this job is part of a transaction */ BlockJobTxn *txn; QLIST_ENTRY(BlockJob) txn_list; diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h index 43f3be2965..c9b23b0cc9 100644 --- a/include/block/blockjob_int.h +++ b/include/block/blockjob_int.h @@ -139,14 +139,13 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver, /** * block_job_sleep_ns: * @job: The job that calls the function. - * @clock: The clock to sleep on. * @ns: How many nanoseconds to stop for. * * Put the job to sleep (assuming that it wasn't canceled) for @ns - * nanoseconds. Canceling the job will not interrupt the wait, so the - * cancel will not process until the coroutine wakes up. + * %QEMU_CLOCK_REALTIME nanoseconds. Canceling the job will immediately + * interrupt the wait. */ -void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns); +void block_job_sleep_ns(BlockJob *job, int64_t ns); /** * block_job_yield: diff --git a/qapi/block-core.json b/qapi/block-core.json index 76bf50f813..dd763dcf87 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2065,6 +2065,12 @@ # BLOCK_JOB_CANCELLED event. Before that happens the job is still visible when # enumerated using query-block-jobs. # +# Note that if you issue 'block-job-cancel' after 'drive-mirror' has indicated +# (via the event BLOCK_JOB_READY) that the source and destination are +# synchronized, then the event triggered by this command changes to +# BLOCK_JOB_COMPLETED, to indicate that the mirroring has ended and the +# destination now has a point-in-time copy tied to the time of the cancellation. +# # For streaming, the image file retains its backing file unless the streaming # operation happens to complete just as it is being cancelled. A new streaming # operation can be started at a later time to finish copying all data from the diff --git a/qemu-doc.texi b/qemu-doc.texi index 617254917d..db2351c746 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -405,6 +405,7 @@ encrypted disk images. * disk_images_iscsi:: iSCSI LUNs * disk_images_gluster:: GlusterFS disk images * disk_images_ssh:: Secure Shell (ssh) disk images +* disk_image_locking:: Disk image file locking @end menu @node disk_images_quickstart diff --git a/qemu-options.hx b/qemu-options.hx index 3728e9b4dd..f11c4ac960 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -693,6 +693,10 @@ This is the protocol-level block driver for accessing regular files. The path to the image file in the local filesystem @item aio Specifies the AIO backend (threads/native, default: threads) +@item locking +Specifies whether the image file is protected with Linux OFD / POSIX locks. The +default is to use the Linux Open File Descriptor API if available, otherwise no +lock is applied. (auto/on/off, default: auto) @end table Example: @example diff --git a/tests/qemu-iotests/075 b/tests/qemu-iotests/075 index 770d51c6cb..caa30d4743 100755 --- a/tests/qemu-iotests/075 +++ b/tests/qemu-iotests/075 @@ -48,56 +48,56 @@ offsets_offset=136 echo echo "== check that the first sector can be read ==" _use_sample_img simple-pattern.cloop.bz2 -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== check that the last sector can be read ==" _use_sample_img simple-pattern.cloop.bz2 -$QEMU_IO -c "read $((1024 * 1024 - 512)) 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read $((1024 * 1024 - 512)) 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== block_size must be a multiple of 512 ==" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$block_size_offset" "\x00\x00\x02\x01" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== block_size cannot be zero ==" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$block_size_offset" "\x00\x00\x00\x00" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== huge block_size ===" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$block_size_offset" "\xff\xff\xfe\x00" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== offsets_size overflow ===" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$n_blocks_offset" "\xff\xff\xff\xff" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== refuse images that require too many offsets ===" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$n_blocks_offset" "\x04\x00\x00\x01" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== refuse images with non-monotonically increasing offsets ==" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$offsets_offset" "\x00\x00\x00\x00\xff\xff\xff\xff" poke_file "$TEST_IMG" $((offsets_offset + 8)) "\x00\x00\x00\x00\xff\xfe\x00\x00" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== refuse images with invalid compressed block size ==" _use_sample_img simple-pattern.cloop.bz2 poke_file "$TEST_IMG" "$offsets_offset" "\x00\x00\x00\x00\x00\x00\x00\x00" poke_file "$TEST_IMG" $((offsets_offset + 8)) "\xff\xff\xff\xff\xff\xff\xff\xff" -$QEMU_IO -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir +$QEMU_IO -r -c "read 0 512" $TEST_IMG 2>&1 | _filter_qemu_io | _filter_testdir # success, all done echo "*** done" diff --git a/tests/qemu-iotests/078 b/tests/qemu-iotests/078 index f333e9ac84..a106c26f6b 100755 --- a/tests/qemu-iotests/078 +++ b/tests/qemu-iotests/078 @@ -48,41 +48,41 @@ disk_size_offset=$((0x58)) echo echo "== Read from a valid image ==" _use_sample_img empty.bochs.bz2 -{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== Negative catalog size ==" _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$catalog_size_offset" "\xff\xff\xff\xff" -{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== Overflow for catalog size * sizeof(uint32_t) ==" _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$catalog_size_offset" "\x00\x00\x00\x40" -{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== Too small catalog bitmap for image size ==" _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$disk_size_offset" "\x00\xc0\x0f\x00\x00\x00\x00\x7f" -{ $QEMU_IO -c "read 2T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 2T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$catalog_size_offset" "\x10\x00\x00\x00" -{ $QEMU_IO -c "read 0xfbe00 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 0xfbe00 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== Negative extent size ==" _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$extent_size_offset" "\x00\x00\x00\x80" -{ $QEMU_IO -c "read 768k 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 768k 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo echo "== Zero extent size ==" _use_sample_img empty.bochs.bz2 poke_file "$TEST_IMG" "$extent_size_offset" "\x00\x00\x00\x00" -{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +{ $QEMU_IO -r -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir # success, all done echo "*** done" diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c index c77343fc04..3591c9617f 100644 --- a/tests/test-blockjob-txn.c +++ b/tests/test-blockjob-txn.c @@ -44,7 +44,7 @@ static void coroutine_fn test_block_job_run(void *opaque) while (s->iterations--) { if (s->use_timer) { - block_job_sleep_ns(job, QEMU_CLOCK_REALTIME, 0); + block_job_sleep_ns(job, 0); } else { block_job_yield(job); } |