4 # Tests for qmp command nbd-server-remove.
6 # Copyright (c) 2017 Virtuozzo International GmbH
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.
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.
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/>.
26 from iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive
28 nbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock')
29 nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
30 disk = os.path.join(iotests.test_dir, 'disk')
33 class TestNbdServerRemove(iotests.QMPTestCase):
35 qemu_img_create('-f', iotests.imgfmt, disk, '1M')
37 self.vm = iotests.VM().add_drive(disk)
47 self.vm.cmd('nbd-server-start', addr=address)
48 self.vm.cmd('nbd-server-add', device='drive0', name='exp')
55 def remove_export(self, name, mode=None):
57 return self.vm.qmp('nbd-server-remove', name=name)
59 return self.vm.qmp('nbd-server-remove', name=name, mode=mode)
61 def assertExportNotFound(self, name):
62 result = self.vm.qmp('nbd-server-remove', name=name)
63 self.assert_qmp(result, 'error/desc', "Export 'exp' is not found")
65 def assertExistingClients(self, result):
66 self.assert_qmp(result, 'error/desc', "export 'exp' still in use")
68 def assertReadOk(self, qemu_io_output):
70 filter_qemu_io(qemu_io_output).strip(),
71 'read 512/512 bytes at offset 0\n' +
72 '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)')
74 def assertReadFailed(self, qemu_io_output):
75 self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
76 'read failed: Input/output error')
78 def assertConnectFailed(self, qemu_io_output):
79 self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
80 "qemu-io: can't open device " + nbd_uri +
81 ": Requested export not available\n"
82 "server reported: export 'exp' not present")
84 def do_test_connect_after_remove(self, mode=None):
85 args = ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri)
86 self.assertReadOk(qemu_io(*args).stdout)
88 result = self.remove_export('exp', mode)
89 self.assert_qmp(result, 'return', {})
91 self.assertExportNotFound('exp')
92 self.assertConnectFailed(qemu_io(*args, check=False).stdout)
94 def test_connect_after_remove_default(self):
95 self.do_test_connect_after_remove()
97 def test_connect_after_remove_safe(self):
98 self.do_test_connect_after_remove('safe')
100 def test_connect_after_remove_force(self):
101 self.do_test_connect_after_remove('hard')
103 def do_test_remove_during_connect_safe(self, mode=None):
104 qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
105 self.assertReadOk(qio.cmd('read 0 512'))
107 result = self.remove_export('exp', mode)
108 self.assertExistingClients(result)
110 self.assertReadOk(qio.cmd('read 0 512'))
114 result = self.remove_export('exp', mode)
115 self.assert_qmp(result, 'return', {})
117 self.assertExportNotFound('exp')
119 def test_remove_during_connect_default(self):
120 self.do_test_remove_during_connect_safe()
122 def test_remove_during_connect_safe(self):
123 self.do_test_remove_during_connect_safe('safe')
125 def test_remove_during_connect_hard(self):
126 qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
127 self.assertReadOk(qio.cmd('read 0 512'))
129 result = self.remove_export('exp', 'hard')
130 self.assert_qmp(result, 'return', {})
132 self.assertReadFailed(qio.cmd('read 0 512'))
133 self.assertExportNotFound('exp')
137 def test_remove_during_connect_safe_hard(self):
138 qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
139 self.assertReadOk(qio.cmd('read 0 512'))
141 result = self.remove_export('exp', 'safe')
142 self.assertExistingClients(result)
144 self.assertReadOk(qio.cmd('read 0 512'))
146 result = self.remove_export('exp', 'hard')
147 self.assert_qmp(result, 'return', {})
149 self.assertExportNotFound('exp')
150 self.assertReadFailed(qio.cmd('read 0 512'))
154 if __name__ == '__main__':
155 iotests.main(supported_fmts=['raw'],
156 supported_protocols=['nbd'])