2012-01-18 18:40:44 +04:00
|
|
|
/*
|
|
|
|
* Image streaming
|
|
|
|
*
|
|
|
|
* Copyright IBM, Corp. 2011
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
|
|
|
*
|
|
|
|
* This work is licensed under the terms of the GNU LGPL, version 2 or later.
|
|
|
|
* See the COPYING.LIB file in the top-level directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2016-01-18 21:01:42 +03:00
|
|
|
#include "qemu/osdep.h"
|
2012-01-18 18:40:44 +04:00
|
|
|
#include "trace.h"
|
2012-12-17 21:19:44 +04:00
|
|
|
#include "block/block_int.h"
|
2016-10-27 19:07:00 +03:00
|
|
|
#include "block/blockjob_int.h"
|
include/qemu/osdep.h: Don't include qapi/error.h
Commit 57cb38b included qapi/error.h into qemu/osdep.h to get the
Error typedef. Since then, we've moved to include qemu/osdep.h
everywhere. Its file comment explains: "To avoid getting into
possible circular include dependencies, this file should not include
any other QEMU headers, with the exceptions of config-host.h,
compiler.h, os-posix.h and os-win32.h, all of which are doing a
similar job to this file and are under similar constraints."
qapi/error.h doesn't do a similar job, and it doesn't adhere to
similar constraints: it includes qapi-types.h. That's in excess of
100KiB of crap most .c files don't actually need.
Add the typedef to qemu/typedefs.h, and include that instead of
qapi/error.h. Include qapi/error.h in .c files that need it and don't
get it now. Include qapi-types.h in qom/object.h for uint16List.
Update scripts/clean-includes accordingly. Update it further to match
reality: replace config.h by config-target.h, add sysemu/os-posix.h,
sysemu/os-win32.h. Update the list of includes in the qemu/osdep.h
comment quoted above similarly.
This reduces the number of objects depending on qapi/error.h from "all
of them" to less than a third. Unfortunately, the number depending on
qapi-types.h shrinks only a little. More work is needed for that one.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
[Fix compilation without the spice devel packages. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2016-03-14 11:01:28 +03:00
|
|
|
#include "qapi/error.h"
|
2020-12-16 09:17:03 +03:00
|
|
|
#include "qapi/qmp/qdict.h"
|
2012-05-09 18:09:46 +04:00
|
|
|
#include "qemu/ratelimit.h"
|
2015-10-19 18:53:22 +03:00
|
|
|
#include "sysemu/block-backend.h"
|
2020-12-16 09:17:03 +03:00
|
|
|
#include "block/copy-on-read.h"
|
2012-01-18 18:40:44 +04:00
|
|
|
|
|
|
|
enum {
|
|
|
|
/*
|
2019-07-25 13:05:49 +03:00
|
|
|
* Maximum chunk size to feed to copy-on-read. This should be
|
|
|
|
* large enough to process multiple clusters in a single call, so
|
|
|
|
* that populating contiguous regions of the image is efficient.
|
2012-01-18 18:40:44 +04:00
|
|
|
*/
|
2019-07-25 13:05:49 +03:00
|
|
|
STREAM_CHUNK = 512 * 1024, /* in bytes */
|
2012-01-18 18:40:44 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct StreamBlockJob {
|
|
|
|
BlockJob common;
|
2021-05-06 17:13:55 +03:00
|
|
|
BlockBackend *blk;
|
2019-06-12 18:48:11 +03:00
|
|
|
BlockDriverState *base_overlay; /* COW overlay (stream from this) */
|
|
|
|
BlockDriverState *above_base; /* Node directly above the base */
|
2020-12-16 09:17:03 +03:00
|
|
|
BlockDriverState *cor_filter_bs;
|
2020-12-16 09:17:02 +03:00
|
|
|
BlockDriverState *target_bs;
|
2012-09-28 19:22:59 +04:00
|
|
|
BlockdevOnError on_error;
|
block: add backing-file option to block-stream
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block job.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-stream api, the user is able to change
the backing file of the active layer as part of the block-stream
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the active image metadata fails, then the block-stream
operation returns failure, without disrupting the guest.
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-25 23:40:11 +04:00
|
|
|
char *backing_file_str;
|
2018-11-12 17:00:37 +03:00
|
|
|
bool bs_read_only;
|
2012-01-18 18:40:44 +04:00
|
|
|
} StreamBlockJob;
|
|
|
|
|
2016-04-12 16:15:49 +03:00
|
|
|
static int coroutine_fn stream_populate(BlockBackend *blk,
|
2019-07-25 13:05:49 +03:00
|
|
|
int64_t offset, uint64_t bytes)
|
2012-01-18 18:40:44 +04:00
|
|
|
{
|
2017-07-07 15:44:41 +03:00
|
|
|
assert(bytes < SIZE_MAX);
|
2012-01-18 18:40:44 +04:00
|
|
|
|
2020-12-16 09:17:03 +03:00
|
|
|
return blk_co_preadv(blk, offset, bytes, NULL, BDRV_REQ_PREFETCH);
|
2019-03-12 19:48:43 +03:00
|
|
|
}
|
|
|
|
|
2018-09-06 16:02:16 +03:00
|
|
|
static int stream_prepare(Job *job)
|
2014-10-21 15:03:57 +04:00
|
|
|
{
|
2018-04-17 17:41:17 +03:00
|
|
|
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
|
2020-12-16 09:17:02 +03:00
|
|
|
BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
|
2021-11-15 17:53:57 +03:00
|
|
|
BlockDriverState *base;
|
|
|
|
BlockDriverState *unfiltered_base;
|
2017-02-17 22:42:32 +03:00
|
|
|
Error *local_err = NULL;
|
2018-09-06 16:02:16 +03:00
|
|
|
int ret = 0;
|
2014-10-21 15:03:57 +04:00
|
|
|
|
2020-12-16 09:17:03 +03:00
|
|
|
/* We should drop filter at this point, as filter hold the backing chain */
|
|
|
|
bdrv_cor_filter_drop(s->cor_filter_bs);
|
|
|
|
s->cor_filter_bs = NULL;
|
2019-03-12 19:48:43 +03:00
|
|
|
|
2022-11-18 20:41:04 +03:00
|
|
|
/*
|
|
|
|
* bdrv_set_backing_hd() requires that unfiltered_bs is drained. Drain
|
|
|
|
* already here and use bdrv_set_backing_hd_drained() instead because
|
|
|
|
* the polling during drained_begin() might change the graph, and if we do
|
|
|
|
* this only later, we may end up working with the wrong base node (or it
|
|
|
|
* might even have gone away by the time we want to use it).
|
|
|
|
*/
|
|
|
|
bdrv_drained_begin(unfiltered_bs);
|
block/stream: Drain subtree around graph change
When the stream block job cuts out the nodes between top and base in
stream_prepare(), it does not drain the subtree manually; it fetches the
base node, and tries to insert it as the top node's backing node with
bdrv_set_backing_hd(). bdrv_set_backing_hd() however will drain, and so
the actual base node might change (because the base node is actually not
part of the stream job) before the old base node passed to
bdrv_set_backing_hd() is installed.
This has two implications:
First, the stream job does not keep a strong reference to the base node.
Therefore, if it is deleted in bdrv_set_backing_hd()'s drain (e.g.
because some other block job is drained to finish), we will get a
use-after-free. We should keep a strong reference to that node.
Second, even with such a strong reference, the problem remains that the
base node might change before bdrv_set_backing_hd() actually runs and as
a result the wrong base node is installed.
Both effects can be seen in 030's TestParallelOps.test_overlapping_5()
case, which has five nodes, and simultaneously streams from the middle
node to the top node, and commits the middle node down to the base node.
As it is, this will sometimes crash, namely when we encounter the
above-described use-after-free.
Taking a strong reference to the base node, we no longer get a crash,
but the resuling block graph is less than ideal: The expected result is
obviously that all middle nodes are cut out and the base node is the
immediate backing child of the top node. However, if stream_prepare()
takes a strong reference to its base node (the middle node), and then
the commit job finishes in bdrv_set_backing_hd(), supposedly dropping
that middle node, the stream job will just reinstall it again.
Therefore, we need to keep the whole subtree drained in
stream_prepare(), so that the graph modification it performs is
effectively atomic, i.e. that the base node it fetches is still the base
node when bdrv_set_backing_hd() sets it as the top node's backing node.
Verify this by asserting in said 030's test case that the base node is
always the top node's immediate backing child when both jobs are done.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220324140907.17192-1-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
2022-03-24 17:09:07 +03:00
|
|
|
|
2021-11-15 17:53:57 +03:00
|
|
|
base = bdrv_filter_or_cow_bs(s->above_base);
|
|
|
|
unfiltered_base = bdrv_skip_filters(base);
|
|
|
|
|
2019-06-12 18:48:11 +03:00
|
|
|
if (bdrv_cow_child(unfiltered_bs)) {
|
2014-10-21 15:03:57 +04:00
|
|
|
const char *base_id = NULL, *base_fmt = NULL;
|
2020-12-16 09:16:59 +03:00
|
|
|
if (unfiltered_base) {
|
|
|
|
base_id = s->backing_file_str ?: unfiltered_base->filename;
|
|
|
|
if (unfiltered_base->drv) {
|
|
|
|
base_fmt = unfiltered_base->drv->format_name;
|
2014-10-21 15:03:57 +04:00
|
|
|
}
|
|
|
|
}
|
block/stream: Drain subtree around graph change
When the stream block job cuts out the nodes between top and base in
stream_prepare(), it does not drain the subtree manually; it fetches the
base node, and tries to insert it as the top node's backing node with
bdrv_set_backing_hd(). bdrv_set_backing_hd() however will drain, and so
the actual base node might change (because the base node is actually not
part of the stream job) before the old base node passed to
bdrv_set_backing_hd() is installed.
This has two implications:
First, the stream job does not keep a strong reference to the base node.
Therefore, if it is deleted in bdrv_set_backing_hd()'s drain (e.g.
because some other block job is drained to finish), we will get a
use-after-free. We should keep a strong reference to that node.
Second, even with such a strong reference, the problem remains that the
base node might change before bdrv_set_backing_hd() actually runs and as
a result the wrong base node is installed.
Both effects can be seen in 030's TestParallelOps.test_overlapping_5()
case, which has five nodes, and simultaneously streams from the middle
node to the top node, and commits the middle node down to the base node.
As it is, this will sometimes crash, namely when we encounter the
above-described use-after-free.
Taking a strong reference to the base node, we no longer get a crash,
but the resuling block graph is less than ideal: The expected result is
obviously that all middle nodes are cut out and the base node is the
immediate backing child of the top node. However, if stream_prepare()
takes a strong reference to its base node (the middle node), and then
the commit job finishes in bdrv_set_backing_hd(), supposedly dropping
that middle node, the stream job will just reinstall it again.
Therefore, we need to keep the whole subtree drained in
stream_prepare(), so that the graph modification it performs is
effectively atomic, i.e. that the base node it fetches is still the base
node when bdrv_set_backing_hd() sets it as the top node's backing node.
Verify this by asserting in said 030's test case that the base node is
always the top node's immediate backing child when both jobs are done.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220324140907.17192-1-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
2022-03-24 17:09:07 +03:00
|
|
|
|
2022-11-18 20:41:04 +03:00
|
|
|
bdrv_set_backing_hd_drained(unfiltered_bs, base, &local_err);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This call will do I/O, so the graph can change again from here on.
|
|
|
|
* We have already completed the graph change, so we are not in danger
|
|
|
|
* of operating on the wrong node any more if this happens.
|
|
|
|
*/
|
2019-06-12 18:48:11 +03:00
|
|
|
ret = bdrv_change_backing_file(unfiltered_bs, base_id, base_fmt, false);
|
2017-02-17 22:42:32 +03:00
|
|
|
if (local_err) {
|
|
|
|
error_report_err(local_err);
|
block/stream: Drain subtree around graph change
When the stream block job cuts out the nodes between top and base in
stream_prepare(), it does not drain the subtree manually; it fetches the
base node, and tries to insert it as the top node's backing node with
bdrv_set_backing_hd(). bdrv_set_backing_hd() however will drain, and so
the actual base node might change (because the base node is actually not
part of the stream job) before the old base node passed to
bdrv_set_backing_hd() is installed.
This has two implications:
First, the stream job does not keep a strong reference to the base node.
Therefore, if it is deleted in bdrv_set_backing_hd()'s drain (e.g.
because some other block job is drained to finish), we will get a
use-after-free. We should keep a strong reference to that node.
Second, even with such a strong reference, the problem remains that the
base node might change before bdrv_set_backing_hd() actually runs and as
a result the wrong base node is installed.
Both effects can be seen in 030's TestParallelOps.test_overlapping_5()
case, which has five nodes, and simultaneously streams from the middle
node to the top node, and commits the middle node down to the base node.
As it is, this will sometimes crash, namely when we encounter the
above-described use-after-free.
Taking a strong reference to the base node, we no longer get a crash,
but the resuling block graph is less than ideal: The expected result is
obviously that all middle nodes are cut out and the base node is the
immediate backing child of the top node. However, if stream_prepare()
takes a strong reference to its base node (the middle node), and then
the commit job finishes in bdrv_set_backing_hd(), supposedly dropping
that middle node, the stream job will just reinstall it again.
Therefore, we need to keep the whole subtree drained in
stream_prepare(), so that the graph modification it performs is
effectively atomic, i.e. that the base node it fetches is still the base
node when bdrv_set_backing_hd() sets it as the top node's backing node.
Verify this by asserting in said 030's test case that the base node is
always the top node's immediate backing child when both jobs are done.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220324140907.17192-1-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
2022-03-24 17:09:07 +03:00
|
|
|
ret = -EPERM;
|
|
|
|
goto out;
|
2017-02-17 22:42:32 +03:00
|
|
|
}
|
2014-10-21 15:03:57 +04:00
|
|
|
}
|
|
|
|
|
block/stream: Drain subtree around graph change
When the stream block job cuts out the nodes between top and base in
stream_prepare(), it does not drain the subtree manually; it fetches the
base node, and tries to insert it as the top node's backing node with
bdrv_set_backing_hd(). bdrv_set_backing_hd() however will drain, and so
the actual base node might change (because the base node is actually not
part of the stream job) before the old base node passed to
bdrv_set_backing_hd() is installed.
This has two implications:
First, the stream job does not keep a strong reference to the base node.
Therefore, if it is deleted in bdrv_set_backing_hd()'s drain (e.g.
because some other block job is drained to finish), we will get a
use-after-free. We should keep a strong reference to that node.
Second, even with such a strong reference, the problem remains that the
base node might change before bdrv_set_backing_hd() actually runs and as
a result the wrong base node is installed.
Both effects can be seen in 030's TestParallelOps.test_overlapping_5()
case, which has five nodes, and simultaneously streams from the middle
node to the top node, and commits the middle node down to the base node.
As it is, this will sometimes crash, namely when we encounter the
above-described use-after-free.
Taking a strong reference to the base node, we no longer get a crash,
but the resuling block graph is less than ideal: The expected result is
obviously that all middle nodes are cut out and the base node is the
immediate backing child of the top node. However, if stream_prepare()
takes a strong reference to its base node (the middle node), and then
the commit job finishes in bdrv_set_backing_hd(), supposedly dropping
that middle node, the stream job will just reinstall it again.
Therefore, we need to keep the whole subtree drained in
stream_prepare(), so that the graph modification it performs is
effectively atomic, i.e. that the base node it fetches is still the base
node when bdrv_set_backing_hd() sets it as the top node's backing node.
Verify this by asserting in said 030's test case that the base node is
always the top node's immediate backing child when both jobs are done.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220324140907.17192-1-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Acked-by: Vladimir Sementsov-Ogievskiy <v.sementsov-og@mail.ru>
2022-03-24 17:09:07 +03:00
|
|
|
out:
|
2022-11-18 20:41:04 +03:00
|
|
|
bdrv_drained_end(unfiltered_bs);
|
2018-09-06 16:02:16 +03:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void stream_clean(Job *job)
|
|
|
|
{
|
|
|
|
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
|
|
|
|
|
2020-12-16 09:17:03 +03:00
|
|
|
if (s->cor_filter_bs) {
|
|
|
|
bdrv_cor_filter_drop(s->cor_filter_bs);
|
|
|
|
s->cor_filter_bs = NULL;
|
|
|
|
}
|
|
|
|
|
2021-05-06 17:13:55 +03:00
|
|
|
blk_unref(s->blk);
|
|
|
|
s->blk = NULL;
|
|
|
|
|
2016-10-28 10:08:10 +03:00
|
|
|
/* Reopen the image back in read-only mode if necessary */
|
2018-11-12 17:00:37 +03:00
|
|
|
if (s->bs_read_only) {
|
2017-02-09 15:34:18 +03:00
|
|
|
/* Give up write permissions before making it read-only */
|
2020-12-16 09:17:02 +03:00
|
|
|
bdrv_reopen_set_read_only(s->target_bs, true, NULL);
|
2016-10-28 10:08:10 +03:00
|
|
|
}
|
|
|
|
|
2014-10-21 15:03:57 +04:00
|
|
|
g_free(s->backing_file_str);
|
|
|
|
}
|
|
|
|
|
2018-08-30 04:57:26 +03:00
|
|
|
static int coroutine_fn stream_run(Job *job, Error **errp)
|
2012-01-18 18:40:44 +04:00
|
|
|
{
|
2018-08-30 04:57:26 +03:00
|
|
|
StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
|
2020-12-16 09:17:02 +03:00
|
|
|
BlockDriverState *unfiltered_bs = bdrv_skip_filters(s->target_bs);
|
2018-01-18 20:08:22 +03:00
|
|
|
int64_t len;
|
2017-07-07 15:44:43 +03:00
|
|
|
int64_t offset = 0;
|
2012-09-28 19:22:59 +04:00
|
|
|
int error = 0;
|
block: Make bdrv_is_allocated_above() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, for the most part this patch is just the
addition of scaling at the callers followed by inverse scaling at
bdrv_is_allocated(). But some code, particularly stream_run(),
gets a lot simpler because it no longer has to mess with sectors.
Leave comments where we can further simplify by switching to
byte-based iterations, once later patches eliminate the need for
sector-aligned operations.
For ease of review, bdrv_is_allocated() was tackled separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 15:44:59 +03:00
|
|
|
int64_t n = 0; /* bytes */
|
2012-01-18 18:40:44 +04:00
|
|
|
|
2019-06-12 18:48:11 +03:00
|
|
|
if (unfiltered_bs == s->base_overlay) {
|
2019-05-29 20:56:16 +03:00
|
|
|
/* Nothing to stream */
|
2019-05-29 20:56:15 +03:00
|
|
|
return 0;
|
2013-11-13 23:37:58 +04:00
|
|
|
}
|
|
|
|
|
2023-02-03 18:22:02 +03:00
|
|
|
WITH_GRAPH_RDLOCK_GUARD() {
|
|
|
|
len = bdrv_co_getlength(s->target_bs);
|
|
|
|
if (len < 0) {
|
|
|
|
return len;
|
|
|
|
}
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|
2018-05-04 13:17:20 +03:00
|
|
|
job_progress_set_remaining(&s->common.job, len);
|
2012-01-18 18:40:44 +04:00
|
|
|
|
2018-01-18 20:08:22 +03:00
|
|
|
for ( ; offset < len; offset += n) {
|
2012-05-08 18:52:00 +04:00
|
|
|
bool copy;
|
2020-03-02 16:07:04 +03:00
|
|
|
int ret;
|
2012-05-08 18:51:45 +04:00
|
|
|
|
|
|
|
/* Note that even when no rate limit is applied we need to yield
|
2012-11-13 19:35:13 +04:00
|
|
|
* with no pending I/O here so that bdrv_drain_all() returns.
|
2012-05-08 18:51:45 +04:00
|
|
|
*/
|
2023-05-10 23:36:00 +03:00
|
|
|
block_job_ratelimit_sleep(&s->common);
|
2018-04-17 13:56:07 +03:00
|
|
|
if (job_is_cancelled(&s->common.job)) {
|
2012-01-18 18:40:44 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-09-22 10:19:10 +04:00
|
|
|
copy = false;
|
|
|
|
|
2023-02-03 18:21:43 +03:00
|
|
|
WITH_GRAPH_RDLOCK_GUARD() {
|
|
|
|
ret = bdrv_is_allocated(unfiltered_bs, offset, STREAM_CHUNK, &n);
|
|
|
|
if (ret == 1) {
|
|
|
|
/* Allocated in the top, no need to copy. */
|
|
|
|
} else if (ret >= 0) {
|
|
|
|
/*
|
|
|
|
* Copy if allocated in the intermediate images. Limit to the
|
|
|
|
* known-unallocated area [offset, offset+n*BDRV_SECTOR_SIZE).
|
|
|
|
*/
|
|
|
|
ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs),
|
|
|
|
s->base_overlay, true,
|
|
|
|
offset, n, &n);
|
|
|
|
/* Finish early if end of backing file has been reached */
|
|
|
|
if (ret == 0 && n == 0) {
|
|
|
|
n = len - offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
copy = (ret > 0);
|
2012-08-28 18:26:48 +04:00
|
|
|
}
|
2012-05-08 18:52:00 +04:00
|
|
|
}
|
block: Make bdrv_is_allocated_above() byte-based
We are gradually moving away from sector-based interfaces, towards
byte-based. In the common case, allocation is unlikely to ever use
values that are not naturally sector-aligned, but it is possible
that byte-based values will let us be more precise about allocation
at the end of an unaligned file that can do byte-based access.
Changing the signature of the function to use int64_t *pnum ensures
that the compiler enforces that all callers are updated. For now,
the io.c layer still assert()s that all callers are sector-aligned,
but that can be relaxed when a later patch implements byte-based
block status. Therefore, for the most part this patch is just the
addition of scaling at the callers followed by inverse scaling at
bdrv_is_allocated(). But some code, particularly stream_run(),
gets a lot simpler because it no longer has to mess with sectors.
Leave comments where we can further simplify by switching to
byte-based iterations, once later patches eliminate the need for
sector-aligned operations.
For ease of review, bdrv_is_allocated() was tackled separately.
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2017-07-07 15:44:59 +03:00
|
|
|
trace_stream_one_iteration(s, offset, n, ret);
|
2013-09-22 10:19:10 +04:00
|
|
|
if (copy) {
|
2021-05-06 17:13:55 +03:00
|
|
|
ret = stream_populate(s->blk, offset, n);
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|
|
|
|
if (ret < 0) {
|
2012-09-28 19:22:59 +04:00
|
|
|
BlockErrorAction action =
|
2016-04-18 12:36:38 +03:00
|
|
|
block_job_error_action(&s->common, s->on_error, true, -ret);
|
2014-06-18 10:43:30 +04:00
|
|
|
if (action == BLOCK_ERROR_ACTION_STOP) {
|
2012-09-28 19:22:59 +04:00
|
|
|
n = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (error == 0) {
|
|
|
|
error = ret;
|
|
|
|
}
|
2014-06-18 10:43:30 +04:00
|
|
|
if (action == BLOCK_ERROR_ACTION_REPORT) {
|
2012-09-28 19:22:59 +04:00
|
|
|
break;
|
|
|
|
}
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Publish progress */
|
2018-05-04 13:17:20 +03:00
|
|
|
job_progress_update(&s->common.job, n);
|
2018-01-18 23:19:38 +03:00
|
|
|
if (copy) {
|
2023-05-10 23:36:00 +03:00
|
|
|
block_job_ratelimit_processed_bytes(&s->common, n);
|
Improve block job rate limiting for small bandwidth values
ratelimit_calculate_delay() previously reset the accounting every time
slice, no matter how much data had been processed before. This had (at
least) two consequences:
1. The minimum speed is rather large, e.g. 5 MiB/s for commit and stream.
Not sure if there are real-world use cases where this would be a
problem. Mirroring and backup over a slow link (e.g. DSL) would
come to mind, though.
2. Tests for block job operations (e.g. cancel) were rather racy
All block jobs currently use a time slice of 100ms. That's a
reasonable value to get smooth output during regular
operation. However this also meant that the state of block jobs
changed every 100ms, no matter how low the configured limit was. On
busy hosts, qemu often transferred additional chunks until the test
case had a chance to cancel the job.
Fix the block job rate limit code to delay for more than one time
slice to address the above issues. To make it easier to handle
oversized chunks we switch the semantics from returning a delay
_before_ the current request to a delay _after_ the current
request. If necessary, this delay consists of multiple time slice
units.
Since the mirror job sends multiple chunks in one go even if the rate
limit was exceeded in between, we need to keep track of the start of
the current time slice so we can correctly re-compute the delay for
the updated amount of data.
The minimum bandwidth now is 1 data unit per time slice. The block
jobs are currently passing the amount of data transferred in sectors
and using 100ms time slices, so this translates to 5120
bytes/second. With chunk sizes usually being O(512KiB), tests have
plenty of time (O(100s)) to operate on block jobs. The chance of a
race condition now is fairly remote, except possibly on insanely
loaded systems.
Signed-off-by: Sascha Silbe <silbe@linux.vnet.ibm.com>
Message-id: 1467127721-9564-2-git-send-email-silbe@linux.vnet.ibm.com
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
2016-06-28 18:28:41 +03:00
|
|
|
}
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
2019-05-29 20:56:15 +03:00
|
|
|
/* Do not remove the backing file if an error was there but ignored. */
|
|
|
|
return error;
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|
|
|
|
|
2013-10-08 13:29:38 +04:00
|
|
|
static const BlockJobDriver stream_job_driver = {
|
2018-04-12 18:29:59 +03:00
|
|
|
.job_driver = {
|
|
|
|
.instance_size = sizeof(StreamBlockJob),
|
2018-04-12 18:57:08 +03:00
|
|
|
.job_type = JOB_TYPE_STREAM,
|
2018-04-13 19:50:05 +03:00
|
|
|
.free = block_job_free,
|
2018-08-30 04:57:26 +03:00
|
|
|
.run = stream_run,
|
2018-09-06 16:02:16 +03:00
|
|
|
.prepare = stream_prepare,
|
|
|
|
.clean = stream_clean,
|
2018-04-18 18:10:26 +03:00
|
|
|
.user_resume = block_job_user_resume,
|
2018-04-12 18:29:59 +03:00
|
|
|
},
|
2012-01-18 18:40:44 +04:00
|
|
|
};
|
|
|
|
|
2016-07-05 17:28:59 +03:00
|
|
|
void stream_start(const char *job_id, BlockDriverState *bs,
|
|
|
|
BlockDriverState *base, const char *backing_file_str,
|
2020-12-16 09:17:00 +03:00
|
|
|
BlockDriverState *bottom,
|
2018-09-06 16:02:12 +03:00
|
|
|
int creation_flags, int64_t speed,
|
2020-12-16 09:16:54 +03:00
|
|
|
BlockdevOnError on_error,
|
|
|
|
const char *filter_node_name,
|
|
|
|
Error **errp)
|
2012-01-18 18:40:44 +04:00
|
|
|
{
|
2021-03-09 20:34:51 +03:00
|
|
|
StreamBlockJob *s = NULL;
|
2016-10-28 10:08:10 +03:00
|
|
|
BlockDriverState *iter;
|
2018-11-12 17:00:37 +03:00
|
|
|
bool bs_read_only;
|
2019-05-29 20:56:16 +03:00
|
|
|
int basic_flags = BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED;
|
2020-12-16 09:17:00 +03:00
|
|
|
BlockDriverState *base_overlay;
|
2020-12-16 09:17:03 +03:00
|
|
|
BlockDriverState *cor_filter_bs = NULL;
|
2019-06-12 18:48:11 +03:00
|
|
|
BlockDriverState *above_base;
|
2020-12-16 09:17:03 +03:00
|
|
|
QDict *opts;
|
2021-03-09 20:34:51 +03:00
|
|
|
int ret;
|
2012-01-18 18:40:44 +04:00
|
|
|
|
2022-03-03 18:15:57 +03:00
|
|
|
GLOBAL_STATE_CODE();
|
|
|
|
|
2020-12-16 09:17:00 +03:00
|
|
|
assert(!(base && bottom));
|
|
|
|
assert(!(backing_file_str && bottom));
|
|
|
|
|
|
|
|
if (bottom) {
|
|
|
|
/*
|
|
|
|
* New simple interface. The code is written in terms of old interface
|
|
|
|
* with @base parameter (still, it doesn't freeze link to base, so in
|
|
|
|
* this mean old code is correct for new interface). So, for now, just
|
|
|
|
* emulate base_overlay and above_base. Still, when old interface
|
|
|
|
* finally removed, we should refactor code to use only "bottom", but
|
|
|
|
* not "*base*" things.
|
|
|
|
*/
|
|
|
|
assert(!bottom->drv->is_filter);
|
|
|
|
base_overlay = above_base = bottom;
|
|
|
|
} else {
|
|
|
|
base_overlay = bdrv_find_overlay(bs, base);
|
|
|
|
if (!base_overlay) {
|
|
|
|
error_setg(errp, "'%s' is not in the backing chain of '%s'",
|
|
|
|
base->node_name, bs->node_name);
|
|
|
|
return;
|
|
|
|
}
|
2019-06-12 18:48:11 +03:00
|
|
|
|
2020-12-16 09:17:00 +03:00
|
|
|
/*
|
|
|
|
* Find the node directly above @base. @base_overlay is a COW overlay,
|
|
|
|
* so it must have a bdrv_cow_child(), but it is the immediate overlay
|
|
|
|
* of @base, so between the two there can only be filters.
|
|
|
|
*/
|
|
|
|
above_base = base_overlay;
|
|
|
|
if (bdrv_cow_bs(above_base) != base) {
|
|
|
|
above_base = bdrv_cow_bs(above_base);
|
|
|
|
while (bdrv_filter_bs(above_base) != base) {
|
|
|
|
above_base = bdrv_filter_bs(above_base);
|
|
|
|
}
|
2019-06-12 18:48:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-28 10:08:10 +03:00
|
|
|
/* Make sure that the image is opened in read-write mode */
|
2018-11-12 17:00:37 +03:00
|
|
|
bs_read_only = bdrv_is_read_only(bs);
|
|
|
|
if (bs_read_only) {
|
2020-12-16 09:17:03 +03:00
|
|
|
int ret;
|
|
|
|
/* Hold the chain during reopen */
|
|
|
|
if (bdrv_freeze_backing_chain(bs, above_base, errp) < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = bdrv_reopen_set_read_only(bs, false, errp);
|
|
|
|
|
|
|
|
/* failure, or cor-filter will hold the chain */
|
|
|
|
bdrv_unfreeze_backing_chain(bs, above_base);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
return;
|
2016-10-28 10:08:10 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-16 09:17:03 +03:00
|
|
|
opts = qdict_new();
|
|
|
|
|
|
|
|
qdict_put_str(opts, "driver", "copy-on-read");
|
|
|
|
qdict_put_str(opts, "file", bdrv_get_node_name(bs));
|
|
|
|
/* Pass the base_overlay node name as 'bottom' to COR driver */
|
|
|
|
qdict_put_str(opts, "bottom", base_overlay->node_name);
|
|
|
|
if (filter_node_name) {
|
|
|
|
qdict_put_str(opts, "node-name", filter_node_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
cor_filter_bs = bdrv_insert_node(bs, opts, BDRV_O_RDWR, errp);
|
|
|
|
if (!cor_filter_bs) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!filter_node_name) {
|
|
|
|
cor_filter_bs->implicit = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = block_job_create(job_id, &stream_job_driver, NULL, cor_filter_bs,
|
2021-05-06 17:13:55 +03:00
|
|
|
0, BLK_PERM_ALL,
|
2018-09-06 16:02:12 +03:00
|
|
|
speed, creation_flags, NULL, NULL, errp);
|
2017-02-09 15:34:18 +03:00
|
|
|
if (!s) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2021-05-06 17:13:55 +03:00
|
|
|
s->blk = blk_new_with_bs(cor_filter_bs, BLK_PERM_CONSISTENT_READ,
|
|
|
|
basic_flags | BLK_PERM_WRITE, errp);
|
|
|
|
if (!s->blk) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Disable request queuing in the BlockBackend to avoid deadlocks on drain:
|
|
|
|
* The job reports that it's busy until it reaches a pause point.
|
|
|
|
*/
|
|
|
|
blk_set_disable_request_queuing(s->blk, true);
|
|
|
|
blk_set_allow_aio_context_change(s->blk, true);
|
|
|
|
|
2020-12-16 09:17:03 +03:00
|
|
|
/*
|
|
|
|
* Prevent concurrent jobs trying to modify the graph structure here, we
|
|
|
|
* already have our own plans. Also don't allow resize as the image size is
|
|
|
|
* queried only at the job start and then cached.
|
|
|
|
*/
|
|
|
|
if (block_job_add_bdrv(&s->common, "active node", bs, 0,
|
2021-03-09 20:34:51 +03:00
|
|
|
basic_flags | BLK_PERM_WRITE, errp)) {
|
2020-12-16 09:17:03 +03:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2017-02-09 15:34:18 +03:00
|
|
|
/* Block all intermediate nodes between bs and base, because they will
|
|
|
|
* disappear from the chain after this operation. The streaming job reads
|
2019-05-29 20:56:16 +03:00
|
|
|
* every block only once, assuming that it doesn't change, so forbid writes
|
|
|
|
* and resizes. Reassign the base node pointer because the backing BS of the
|
|
|
|
* bottom node might change after the call to bdrv_reopen_set_read_only()
|
|
|
|
* due to parallel block jobs running.
|
2019-06-12 18:48:11 +03:00
|
|
|
* above_base node might change after the call to
|
|
|
|
* bdrv_reopen_set_read_only() due to parallel block jobs running.
|
2019-05-29 20:56:16 +03:00
|
|
|
*/
|
2019-06-12 18:48:11 +03:00
|
|
|
base = bdrv_filter_or_cow_bs(above_base);
|
|
|
|
for (iter = bdrv_filter_or_cow_bs(bs); iter != base;
|
|
|
|
iter = bdrv_filter_or_cow_bs(iter))
|
|
|
|
{
|
2021-03-09 20:34:51 +03:00
|
|
|
ret = block_job_add_bdrv(&s->common, "intermediate node", iter, 0,
|
|
|
|
basic_flags, errp);
|
|
|
|
if (ret < 0) {
|
|
|
|
goto fail;
|
|
|
|
}
|
2016-10-28 10:08:10 +03:00
|
|
|
}
|
|
|
|
|
2019-06-12 18:48:11 +03:00
|
|
|
s->base_overlay = base_overlay;
|
|
|
|
s->above_base = above_base;
|
block: add backing-file option to block-stream
On some image chains, QEMU may not always be able to resolve the
filenames properly, when updating the backing file of an image
after a block job.
For instance, certain relative pathnames may fail, or drives may
have been specified originally by file descriptor (e.g. /dev/fd/???),
or a relative protocol pathname may have been used.
In these instances, QEMU may lack the information to be able to make
the correct choice, but the user or management layer most likely does
have that knowledge.
With this extension to the block-stream api, the user is able to change
the backing file of the active layer as part of the block-stream
operation.
This allows the change to be 'safe', in the sense that if the attempt
to write the active image metadata fails, then the block-stream
operation returns failure, without disrupting the guest.
If a backing file string is not specified in the command, the backing
file string to use is determined in the same manner as it was
previously.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-25 23:40:11 +04:00
|
|
|
s->backing_file_str = g_strdup(backing_file_str);
|
2020-12-16 09:17:03 +03:00
|
|
|
s->cor_filter_bs = cor_filter_bs;
|
2020-12-16 09:17:02 +03:00
|
|
|
s->target_bs = bs;
|
2018-11-12 17:00:37 +03:00
|
|
|
s->bs_read_only = bs_read_only;
|
2012-01-18 18:40:44 +04:00
|
|
|
|
2012-09-28 19:22:59 +04:00
|
|
|
s->on_error = on_error;
|
2016-11-08 09:50:37 +03:00
|
|
|
trace_stream_start(bs, base, s);
|
2018-04-13 18:31:02 +03:00
|
|
|
job_start(&s->common.job);
|
2017-02-09 15:34:18 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
fail:
|
2021-03-09 20:34:51 +03:00
|
|
|
if (s) {
|
|
|
|
job_early_fail(&s->common.job);
|
|
|
|
}
|
2020-12-16 09:17:03 +03:00
|
|
|
if (cor_filter_bs) {
|
|
|
|
bdrv_cor_filter_drop(cor_filter_bs);
|
|
|
|
}
|
2018-11-12 17:00:37 +03:00
|
|
|
if (bs_read_only) {
|
|
|
|
bdrv_reopen_set_read_only(bs, true, NULL);
|
2017-02-09 15:34:18 +03:00
|
|
|
}
|
2012-01-18 18:40:44 +04:00
|
|
|
}
|