1*a541fcc2SVladimir Sementsov-Ogievskiy#!/usr/bin/env python 2*a541fcc2SVladimir Sementsov-Ogievskiy# 3*a541fcc2SVladimir Sementsov-Ogievskiy# Test for backup-top filter permission activation failure 4*a541fcc2SVladimir Sementsov-Ogievskiy# 5*a541fcc2SVladimir Sementsov-Ogievskiy# Copyright (c) 2019 Virtuozzo International GmbH. 6*a541fcc2SVladimir Sementsov-Ogievskiy# 7*a541fcc2SVladimir Sementsov-Ogievskiy# This program is free software; you can redistribute it and/or modify 8*a541fcc2SVladimir Sementsov-Ogievskiy# it under the terms of the GNU General Public License as published by 9*a541fcc2SVladimir Sementsov-Ogievskiy# the Free Software Foundation; either version 2 of the License, or 10*a541fcc2SVladimir Sementsov-Ogievskiy# (at your option) any later version. 11*a541fcc2SVladimir Sementsov-Ogievskiy# 12*a541fcc2SVladimir Sementsov-Ogievskiy# This program is distributed in the hope that it will be useful, 13*a541fcc2SVladimir Sementsov-Ogievskiy# but WITHOUT ANY WARRANTY; without even the implied warranty of 14*a541fcc2SVladimir Sementsov-Ogievskiy# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*a541fcc2SVladimir Sementsov-Ogievskiy# GNU General Public License for more details. 16*a541fcc2SVladimir Sementsov-Ogievskiy# 17*a541fcc2SVladimir Sementsov-Ogievskiy# You should have received a copy of the GNU General Public License 18*a541fcc2SVladimir Sementsov-Ogievskiy# along with this program. If not, see <http://www.gnu.org/licenses/>. 19*a541fcc2SVladimir Sementsov-Ogievskiy# 20*a541fcc2SVladimir Sementsov-Ogievskiy 21*a541fcc2SVladimir Sementsov-Ogievskiyimport iotests 22*a541fcc2SVladimir Sementsov-Ogievskiy 23*a541fcc2SVladimir Sementsov-Ogievskiy# The test is unrelated to formats, restrict it to qcow2 to avoid extra runs 24*a541fcc2SVladimir Sementsov-Ogievskiyiotests.verify_image_format(supported_fmts=['qcow2']) 25*a541fcc2SVladimir Sementsov-Ogievskiy 26*a541fcc2SVladimir Sementsov-Ogievskiysize = 1024 * 1024 27*a541fcc2SVladimir Sementsov-Ogievskiy 28*a541fcc2SVladimir Sementsov-Ogievskiy""" Test description 29*a541fcc2SVladimir Sementsov-Ogievskiy 30*a541fcc2SVladimir Sementsov-OgievskiyWhen performing a backup, all writes on the source subtree must go through the 31*a541fcc2SVladimir Sementsov-Ogievskiybackup-top filter so it can copy all data to the target before it is changed. 32*a541fcc2SVladimir Sementsov-Ogievskiybackup-top filter is appended above source node, to achieve this thing, so all 33*a541fcc2SVladimir Sementsov-Ogievskiyparents of source node are handled. A configuration with side parents of source 34*a541fcc2SVladimir Sementsov-Ogievskiysub-tree with write permission is unsupported (we'd have append several 35*a541fcc2SVladimir Sementsov-Ogievskiybackup-top filter like nodes to handle such parents). The test create an 36*a541fcc2SVladimir Sementsov-Ogievskiyexample of such configuration and checks that a backup is then not allowed 37*a541fcc2SVladimir Sementsov-Ogievskiy(blockdev-backup command should fail). 38*a541fcc2SVladimir Sementsov-Ogievskiy 39*a541fcc2SVladimir Sementsov-OgievskiyThe configuration: 40*a541fcc2SVladimir Sementsov-Ogievskiy 41*a541fcc2SVladimir Sementsov-Ogievskiy ┌────────┐ target ┌─────────────┐ 42*a541fcc2SVladimir Sementsov-Ogievskiy │ target │ ◀─────── │ backup_top │ 43*a541fcc2SVladimir Sementsov-Ogievskiy └────────┘ └─────────────┘ 44*a541fcc2SVladimir Sementsov-Ogievskiy │ 45*a541fcc2SVladimir Sementsov-Ogievskiy │ backing 46*a541fcc2SVladimir Sementsov-Ogievskiy ▼ 47*a541fcc2SVladimir Sementsov-Ogievskiy ┌─────────────┐ 48*a541fcc2SVladimir Sementsov-Ogievskiy │ source │ 49*a541fcc2SVladimir Sementsov-Ogievskiy └─────────────┘ 50*a541fcc2SVladimir Sementsov-Ogievskiy │ 51*a541fcc2SVladimir Sementsov-Ogievskiy │ file 52*a541fcc2SVladimir Sementsov-Ogievskiy ▼ 53*a541fcc2SVladimir Sementsov-Ogievskiy ┌─────────────┐ write perm ┌───────┐ 54*a541fcc2SVladimir Sementsov-Ogievskiy │ base │ ◀──────────── │ other │ 55*a541fcc2SVladimir Sementsov-Ogievskiy └─────────────┘ └───────┘ 56*a541fcc2SVladimir Sementsov-Ogievskiy 57*a541fcc2SVladimir Sementsov-OgievskiyOn activation (see .active field of backup-top state in block/backup-top.c), 58*a541fcc2SVladimir Sementsov-Ogievskiybackup-top is going to unshare write permission on its source child. Write 59*a541fcc2SVladimir Sementsov-Ogievskiyunsharing will be propagated to the "source->base" link and will conflict with 60*a541fcc2SVladimir Sementsov-Ogievskiyother node write permission. So permission update will fail and backup job will 61*a541fcc2SVladimir Sementsov-Ogievskiynot be started. 62*a541fcc2SVladimir Sementsov-Ogievskiy 63*a541fcc2SVladimir Sementsov-OgievskiyNote, that the only thing which prevents backup of running on such 64*a541fcc2SVladimir Sementsov-Ogievskiyconfiguration is default permission propagation scheme. It may be altered by 65*a541fcc2SVladimir Sementsov-Ogievskiydifferent block drivers, so backup will run in invalid configuration. But 66*a541fcc2SVladimir Sementsov-Ogievskiysomething is better than nothing. Also, before the previous commit (commit 67*a541fcc2SVladimir Sementsov-Ogievskiypreceding this test creation), starting backup on such configuration led to 68*a541fcc2SVladimir Sementsov-Ogievskiycrash, so current "something" is a lot better, and this test actual goal is 69*a541fcc2SVladimir Sementsov-Ogievskiyto check that crash is fixed :) 70*a541fcc2SVladimir Sementsov-Ogievskiy""" 71*a541fcc2SVladimir Sementsov-Ogievskiy 72*a541fcc2SVladimir Sementsov-Ogievskiyvm = iotests.VM() 73*a541fcc2SVladimir Sementsov-Ogievskiyvm.launch() 74*a541fcc2SVladimir Sementsov-Ogievskiy 75*a541fcc2SVladimir Sementsov-Ogievskiyvm.qmp_log('blockdev-add', **{'node-name': 'target', 'driver': 'null-co'}) 76*a541fcc2SVladimir Sementsov-Ogievskiy 77*a541fcc2SVladimir Sementsov-Ogievskiyvm.qmp_log('blockdev-add', **{ 78*a541fcc2SVladimir Sementsov-Ogievskiy 'node-name': 'source', 79*a541fcc2SVladimir Sementsov-Ogievskiy 'driver': 'blkdebug', 80*a541fcc2SVladimir Sementsov-Ogievskiy 'image': {'node-name': 'base', 'driver': 'null-co', 'size': size} 81*a541fcc2SVladimir Sementsov-Ogievskiy}) 82*a541fcc2SVladimir Sementsov-Ogievskiy 83*a541fcc2SVladimir Sementsov-Ogievskiyvm.qmp_log('blockdev-add', **{ 84*a541fcc2SVladimir Sementsov-Ogievskiy 'node-name': 'other', 85*a541fcc2SVladimir Sementsov-Ogievskiy 'driver': 'blkdebug', 86*a541fcc2SVladimir Sementsov-Ogievskiy 'image': 'base', 87*a541fcc2SVladimir Sementsov-Ogievskiy 'take-child-perms': ['write'] 88*a541fcc2SVladimir Sementsov-Ogievskiy}) 89*a541fcc2SVladimir Sementsov-Ogievskiy 90*a541fcc2SVladimir Sementsov-Ogievskiyvm.qmp_log('blockdev-backup', sync='full', device='source', target='target') 91*a541fcc2SVladimir Sementsov-Ogievskiy 92*a541fcc2SVladimir Sementsov-Ogievskiyvm.shutdown() 93