2020-01-30 17:32:30 +01:00
|
|
|
#!/usr/bin/env python3
|
2021-01-16 14:44:19 +01:00
|
|
|
# group: auto quick
|
2020-01-21 15:28:02 +01:00
|
|
|
#
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
# Test for copy-before-write filter permission conflict
|
2020-01-21 15:28:02 +01:00
|
|
|
#
|
|
|
|
# Copyright (c) 2019 Virtuozzo International GmbH.
|
|
|
|
#
|
|
|
|
# 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/>.
|
|
|
|
#
|
|
|
|
|
|
|
|
import iotests
|
|
|
|
|
|
|
|
# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs
|
2020-03-31 02:00:11 +02:00
|
|
|
iotests.script_initialize(
|
|
|
|
supported_fmts=['qcow2'],
|
|
|
|
)
|
2020-01-21 15:28:02 +01:00
|
|
|
|
|
|
|
size = 1024 * 1024
|
|
|
|
|
|
|
|
""" Test description
|
|
|
|
|
|
|
|
When performing a backup, all writes on the source subtree must go through the
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
copy-before-write filter so it can copy all data to the target before it is
|
|
|
|
changed. copy-before-write filter is appended above source node, to achieve
|
|
|
|
this thing, so all parents of source node are handled. A configuration with
|
|
|
|
side parents of source sub-tree with write permission is unsupported (we'd have
|
|
|
|
append several copy-before-write filter like nodes to handle such parents). The
|
|
|
|
test create an example of such configuration and checks that a backup is then
|
|
|
|
not allowed (blockdev-backup command should fail).
|
2020-01-21 15:28:02 +01:00
|
|
|
|
|
|
|
The configuration:
|
|
|
|
|
|
|
|
┌────────┐ target ┌─────────────┐
|
|
|
|
│ target │ ◀─────── │ backup_top │
|
|
|
|
└────────┘ └─────────────┘
|
|
|
|
│
|
|
|
|
│ backing
|
|
|
|
▼
|
|
|
|
┌─────────────┐
|
|
|
|
│ source │
|
|
|
|
└─────────────┘
|
|
|
|
│
|
|
|
|
│ file
|
|
|
|
▼
|
|
|
|
┌─────────────┐ write perm ┌───────┐
|
|
|
|
│ base │ ◀──────────── │ other │
|
|
|
|
└─────────────┘ └───────┘
|
|
|
|
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
copy-before-write filter wants to unshare write permission on its source child.
|
|
|
|
Write unsharing will be propagated to the "source->base" link and will conflict
|
|
|
|
with other node write permission. So permission update will fail and backup job
|
|
|
|
will not be started.
|
2020-01-21 15:28:02 +01:00
|
|
|
|
|
|
|
Note, that the only thing which prevents backup of running on such
|
|
|
|
configuration is default permission propagation scheme. It may be altered by
|
|
|
|
different block drivers, so backup will run in invalid configuration. But
|
|
|
|
something is better than nothing. Also, before the previous commit (commit
|
|
|
|
preceding this test creation), starting backup on such configuration led to
|
|
|
|
crash, so current "something" is a lot better, and this test actual goal is
|
|
|
|
to check that crash is fixed :)
|
|
|
|
"""
|
|
|
|
|
|
|
|
vm = iotests.VM()
|
|
|
|
vm.launch()
|
|
|
|
|
2020-04-30 16:27:52 +02:00
|
|
|
vm.qmp_log('blockdev-add', **{
|
|
|
|
'node-name': 'target',
|
|
|
|
'driver': 'null-co',
|
|
|
|
'size': size,
|
|
|
|
})
|
2020-01-21 15:28:02 +01:00
|
|
|
|
|
|
|
vm.qmp_log('blockdev-add', **{
|
|
|
|
'node-name': 'source',
|
|
|
|
'driver': 'blkdebug',
|
|
|
|
'image': {'node-name': 'base', 'driver': 'null-co', 'size': size}
|
|
|
|
})
|
|
|
|
|
|
|
|
vm.qmp_log('blockdev-add', **{
|
|
|
|
'node-name': 'other',
|
|
|
|
'driver': 'blkdebug',
|
|
|
|
'image': 'base',
|
|
|
|
'take-child-perms': ['write']
|
|
|
|
})
|
|
|
|
|
|
|
|
vm.qmp_log('blockdev-backup', sync='full', device='source', target='target')
|
|
|
|
|
|
|
|
vm.shutdown()
|
iotests/283: Check that finalize drops backup-top
Without any of HEAD^ or HEAD^^ applied, qemu will most likely crash on
the qemu-io invocation, for a variety of immediate reasons. The
underlying problem is generally a use-after-free access into
backup-top's BlockCopyState.
With only HEAD^ applied, qemu-io will run into an EIO (which is not
capture by the output, but you can see that the qemu-io invocation will
be accepted (i.e., qemu-io will run) in contrast to the reference
output, where the node name cannot be found), and qemu will then crash
in query-named-block-nodes: bdrv_get_allocated_file_size() detects
backup-top to be a filter and passes the request through to its child.
However, after bdrv_backup_top_drop(), that child is NULL, so the
recursive call crashes.
With HEAD^^ applied, this test should pass.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210219153348.41861-4-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-02-19 16:33:48 +01:00
|
|
|
|
|
|
|
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
print('\n=== copy-before-write filter should be gone after job-finalize ===\n')
|
iotests/283: Check that finalize drops backup-top
Without any of HEAD^ or HEAD^^ applied, qemu will most likely crash on
the qemu-io invocation, for a variety of immediate reasons. The
underlying problem is generally a use-after-free access into
backup-top's BlockCopyState.
With only HEAD^ applied, qemu-io will run into an EIO (which is not
capture by the output, but you can see that the qemu-io invocation will
be accepted (i.e., qemu-io will run) in contrast to the reference
output, where the node name cannot be found), and qemu will then crash
in query-named-block-nodes: bdrv_get_allocated_file_size() detects
backup-top to be a filter and passes the request through to its child.
However, after bdrv_backup_top_drop(), that child is NULL, so the
recursive call crashes.
With HEAD^^ applied, this test should pass.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210219153348.41861-4-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-02-19 16:33:48 +01:00
|
|
|
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
# Check that the copy-before-write node is gone after job-finalize.
|
iotests/283: Check that finalize drops backup-top
Without any of HEAD^ or HEAD^^ applied, qemu will most likely crash on
the qemu-io invocation, for a variety of immediate reasons. The
underlying problem is generally a use-after-free access into
backup-top's BlockCopyState.
With only HEAD^ applied, qemu-io will run into an EIO (which is not
capture by the output, but you can see that the qemu-io invocation will
be accepted (i.e., qemu-io will run) in contrast to the reference
output, where the node name cannot be found), and qemu will then crash
in query-named-block-nodes: bdrv_get_allocated_file_size() detects
backup-top to be a filter and passes the request through to its child.
However, after bdrv_backup_top_drop(), that child is NULL, so the
recursive call crashes.
With HEAD^^ applied, this test should pass.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210219153348.41861-4-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-02-19 16:33:48 +01:00
|
|
|
|
|
|
|
vm = iotests.VM()
|
|
|
|
vm.launch()
|
|
|
|
|
|
|
|
vm.qmp_log('blockdev-add', **{
|
|
|
|
'node-name': 'source',
|
|
|
|
'driver': 'null-co',
|
|
|
|
})
|
|
|
|
|
|
|
|
vm.qmp_log('blockdev-add', **{
|
|
|
|
'node-name': 'target',
|
|
|
|
'driver': 'null-co',
|
|
|
|
})
|
|
|
|
|
|
|
|
vm.qmp_log('blockdev-backup',
|
|
|
|
job_id='backup',
|
|
|
|
device='source',
|
|
|
|
target='target',
|
|
|
|
sync='full',
|
|
|
|
filter_node_name='backup-filter',
|
|
|
|
auto_finalize=False,
|
|
|
|
auto_dismiss=False)
|
|
|
|
|
|
|
|
vm.event_wait('BLOCK_JOB_PENDING', 5.0)
|
|
|
|
|
block: rename backup-top to copy-before-write
We are going to convert backup_top to full featured public filter,
which can be used in separate of backup job. Start from renaming from
"how it used" to "what it does".
While updating comments in 283 iotest, drop and rephrase also things
about ".active", as this field is now dropped, and filter doesn't have
"inactive" mode.
Note that this change may be considered as incompatible interface
change, as backup-top filter format name was visible through
query-block and query-named-block-nodes.
Still, consider the following reasoning:
1. backup-top was never documented, so if someone depends on format
name (for driver that can't be used other than it is automatically
inserted on backup job start), it's a kind of "undocumented feature
use". So I think we are free to change it.
2. There is a hope, that there is no such users: it's a lot more native
to give a good node-name to backup-top filter if need to operate
with it somehow, and don't touch format name.
3. Another "incompatible" change in further commit would be moving
copy-before-write filter from using backing child to file child. And
this is even more reasonable than renaming: for now all public
filters are file-child based.
So, it's a risky change, but risk seems small and good interface worth
it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210824083856.17408-6-vsementsov@virtuozzo.com>
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
2021-08-24 10:38:27 +02:00
|
|
|
# The copy-before-write filter should still be present prior to finalization
|
iotests/283: Check that finalize drops backup-top
Without any of HEAD^ or HEAD^^ applied, qemu will most likely crash on
the qemu-io invocation, for a variety of immediate reasons. The
underlying problem is generally a use-after-free access into
backup-top's BlockCopyState.
With only HEAD^ applied, qemu-io will run into an EIO (which is not
capture by the output, but you can see that the qemu-io invocation will
be accepted (i.e., qemu-io will run) in contrast to the reference
output, where the node name cannot be found), and qemu will then crash
in query-named-block-nodes: bdrv_get_allocated_file_size() detects
backup-top to be a filter and passes the request through to its child.
However, after bdrv_backup_top_drop(), that child is NULL, so the
recursive call crashes.
With HEAD^^ applied, this test should pass.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210219153348.41861-4-mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2021-02-19 16:33:48 +01:00
|
|
|
assert vm.node_info('backup-filter') is not None
|
|
|
|
|
|
|
|
vm.qmp_log('job-finalize', id='backup')
|
|
|
|
vm.event_wait('BLOCK_JOB_COMPLETED', 5.0)
|
|
|
|
|
|
|
|
# The filter should be gone now. Check that by trying to access it
|
|
|
|
# with qemu-io (which will most likely crash qemu if it is still
|
|
|
|
# there.).
|
|
|
|
vm.qmp_log('human-monitor-command',
|
|
|
|
command_line='qemu-io backup-filter "write 0 1M"')
|
|
|
|
|
|
|
|
# (Also, do an explicit check.)
|
|
|
|
assert vm.node_info('backup-filter') is None
|
|
|
|
|
|
|
|
vm.qmp_log('job-dismiss', id='backup')
|
|
|
|
vm.event_wait('JOB_STATUS_CHANGE', 5.0, {'data': {'status': 'null'}})
|
|
|
|
|
|
|
|
vm.shutdown()
|