This patch is the first one in the series where the COR-filter node will be hard-coded for using in the block-stream job. The block jobs may be run in parallel. Exclude conflicts with filter nodes used for a concurrent job while checking for the blocked operations. It incurs changes in the iotests 030::test_overlapping_4 that now passes with no conflict because the stream job does not have a real dependency on its base and on a filter above it.
Signed-off-by: Andrey Shinkevich <andrey.shinkev...@virtuozzo.com> --- blockdev.c | 11 +++++++++-- tests/qemu-iotests/030 | 9 ++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/blockdev.c b/blockdev.c index b3c840e..97c2ba2 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2763,6 +2763,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, Error *local_err = NULL; const char *base_name = NULL; int job_flags = JOB_DEFAULT; + BlockDriverState *bottom_cow_node; if (!has_on_error) { on_error = BLOCKDEV_ON_ERROR_REPORT; @@ -2807,8 +2808,14 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, base_name = base_bs->filename; } - /* Check for op blockers in the whole chain between bs and base */ - for (iter = bs; iter && iter != base_bs; iter = backing_bs(iter)) { + bottom_cow_node = bdrv_find_overlay(bs, base_bs); + if (!bottom_cow_node) { + error_setg(errp, "bottom node is not found, nothing to stream"); + goto out; + } + /* Check for op blockers in the whole chain between bs and bottom */ + for (iter = bs; iter && iter != bdrv_filtered_bs(bottom_cow_node); + iter = bdrv_filtered_bs(iter)) { if (bdrv_op_is_blocked(iter, BLOCK_OP_TYPE_STREAM, errp)) { goto out; } diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index 104e3ce..d7638cd 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -368,8 +368,7 @@ class TestParallelOps(iotests.QMPTestCase): self.wait_until_completed(drive='commit-drive0') # In this case the base node of the stream job is the same as the - # top node of commit job. Since this results in the commit filter - # node being part of the stream chain, this is not allowed. + # top node of commit job. def test_overlapping_4(self): self.assert_no_active_block_jobs() @@ -381,13 +380,13 @@ class TestParallelOps(iotests.QMPTestCase): # Stream from node2 into node4 result = self.vm.qmp('block-stream', device='node4', base_node='node2', job_id='node4') - self.assert_qmp(result, 'error/desc', - "Cannot freeze 'backing' link to 'commit-filter'") + self.assert_qmp(result, 'return', {}) result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0) self.assert_qmp(result, 'return', {}) - self.wait_until_completed() + self.vm.run_job(job='drive0', auto_dismiss=True) + self.vm.run_job(job='node4', auto_dismiss=True) self.assert_no_active_block_jobs() # In this case the base node of the stream job is the commit job's -- 1.8.3.1