blob: 5defe48e97d5912ccf593dd7dac3099751bb7ef2 [file] [log] [blame]
Philippe Mathieu-Daudé7c477522020-01-30 17:32:30 +01001#!/usr/bin/env python3
Vladimir Sementsov-Ogievskiy9dd003a2021-01-16 16:44:19 +03002# group: auto quick
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +03003#
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +03004# Test for copy-before-write filter permission conflict
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +03005#
6# Copyright (c) 2019 Virtuozzo International GmbH.
7#
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21
22import iotests
23
24# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs
John Snow7d814052020-03-30 20:00:11 -040025iotests.script_initialize(
26 supported_fmts=['qcow2'],
27)
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +030028
29size = 1024 * 1024
30
31""" Test description
32
33When performing a backup, all writes on the source subtree must go through the
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +030034copy-before-write filter so it can copy all data to the target before it is
35changed. copy-before-write filter is appended above source node, to achieve
36this thing, so all parents of source node are handled. A configuration with
37side parents of source sub-tree with write permission is unsupported (we'd have
38append several copy-before-write filter like nodes to handle such parents). The
39test create an example of such configuration and checks that a backup is then
40not allowed (blockdev-backup command should fail).
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +030041
42The configuration:
43
44 ┌────────┐ target ┌─────────────┐
45 │ target │ ◀─────── │ backup_top │
46 └────────┘ └─────────────┘
47
48 │ backing
49
50 ┌─────────────┐
51 │ source │
52 └─────────────┘
53
54 │ file
55
56 ┌─────────────┐ write perm ┌───────┐
57 │ base │ ◀──────────── │ other │
58 └─────────────┘ └───────┘
59
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +030060copy-before-write filter wants to unshare write permission on its source child.
61Write unsharing will be propagated to the "source->base" link and will conflict
62with other node write permission. So permission update will fail and backup job
63will not be started.
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +030064
65Note, that the only thing which prevents backup of running on such
66configuration is default permission propagation scheme. It may be altered by
67different block drivers, so backup will run in invalid configuration. But
68something is better than nothing. Also, before the previous commit (commit
69preceding this test creation), starting backup on such configuration led to
70crash, so current "something" is a lot better, and this test actual goal is
71to check that crash is fixed :)
72"""
73
74vm = iotests.VM()
75vm.launch()
76
Kevin Wolf813cc252020-04-30 16:27:52 +020077vm.qmp_log('blockdev-add', **{
78 'node-name': 'target',
79 'driver': 'null-co',
80 'size': size,
81})
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +030082
83vm.qmp_log('blockdev-add', **{
84 'node-name': 'source',
85 'driver': 'blkdebug',
86 'image': {'node-name': 'base', 'driver': 'null-co', 'size': size}
87})
88
89vm.qmp_log('blockdev-add', **{
90 'node-name': 'other',
91 'driver': 'blkdebug',
92 'image': 'base',
93 'take-child-perms': ['write']
94})
95
Vladimir Sementsov-Ogievskiy985cac82021-05-06 17:13:57 +030096vm.qmp_log('blockdev-backup', sync='full', device='source', target='target',
97 job_id="backup0")
Vladimir Sementsov-Ogievskiya541fcc2020-01-21 17:28:02 +030098
99vm.shutdown()
Max Reitze4179942021-02-19 16:33:48 +0100100
101
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +0300102print('\n=== copy-before-write filter should be gone after job-finalize ===\n')
Max Reitze4179942021-02-19 16:33:48 +0100103
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +0300104# Check that the copy-before-write node is gone after job-finalize.
Max Reitze4179942021-02-19 16:33:48 +0100105
106vm = iotests.VM()
107vm.launch()
108
109vm.qmp_log('blockdev-add', **{
110 'node-name': 'source',
111 'driver': 'null-co',
112})
113
114vm.qmp_log('blockdev-add', **{
115 'node-name': 'target',
116 'driver': 'null-co',
117})
118
119vm.qmp_log('blockdev-backup',
120 job_id='backup',
121 device='source',
122 target='target',
123 sync='full',
124 filter_node_name='backup-filter',
125 auto_finalize=False,
126 auto_dismiss=False)
127
128vm.event_wait('BLOCK_JOB_PENDING', 5.0)
129
Vladimir Sementsov-Ogievskiyd003e0a2021-08-24 11:38:27 +0300130# The copy-before-write filter should still be present prior to finalization
Max Reitze4179942021-02-19 16:33:48 +0100131assert vm.node_info('backup-filter') is not None
132
133vm.qmp_log('job-finalize', id='backup')
134vm.event_wait('BLOCK_JOB_COMPLETED', 5.0)
135
136# The filter should be gone now. Check that by trying to access it
137# with qemu-io (which will most likely crash qemu if it is still
138# there.).
139vm.qmp_log('human-monitor-command',
140 command_line='qemu-io backup-filter "write 0 1M"')
141
142# (Also, do an explicit check.)
143assert vm.node_info('backup-filter') is None
144
145vm.qmp_log('job-dismiss', id='backup')
146vm.event_wait('JOB_STATUS_CHANGE', 5.0, {'data': {'status': 'null'}})
147
148vm.shutdown()