Philippe Mathieu-Daudé | 7c47752 | 2020-01-30 17:32:30 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Vladimir Sementsov-Ogievskiy | 9dd003a | 2021-01-16 16:44:19 +0300 | [diff] [blame] | 2 | # group: rw quick |
Andrey Shinkevich | a4d925f | 2019-11-12 06:39:36 +0300 | [diff] [blame] | 3 | # |
| 4 | # Test NBD client reconnection |
| 5 | # |
| 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 | |
| 22 | import os |
| 23 | import subprocess |
| 24 | import iotests |
| 25 | from iotests import file_path, log |
| 26 | |
John Snow | 7d81405 | 2020-03-30 20:00:11 -0400 | [diff] [blame] | 27 | iotests.script_initialize() |
| 28 | |
Andrey Shinkevich | a4d925f | 2019-11-12 06:39:36 +0300 | [diff] [blame] | 29 | |
| 30 | nbd_sock, conf_file = file_path('nbd-sock', 'nbd-fault-injector.conf') |
| 31 | |
| 32 | |
| 33 | def make_conf_file(event): |
| 34 | """ |
| 35 | Create configuration file for the nbd-fault-injector.py |
| 36 | |
| 37 | :param event: which event the server should close a connection on |
| 38 | """ |
| 39 | with open(conf_file, 'w') as conff: |
| 40 | conff.write('[inject-error]\nevent={}\nwhen=after'.format(event)) |
| 41 | |
| 42 | |
| 43 | def start_server_NBD(event): |
| 44 | make_conf_file(event) |
| 45 | |
Vladimir Sementsov-Ogievskiy | ec77662 | 2021-01-16 16:44:14 +0300 | [diff] [blame] | 46 | srv = subprocess.Popen(['./nbd-fault-injector.py', '--classic-negotiation', |
Andrey Shinkevich | a4d925f | 2019-11-12 06:39:36 +0300 | [diff] [blame] | 47 | nbd_sock, conf_file], stdout=subprocess.PIPE, |
| 48 | stderr=subprocess.STDOUT, universal_newlines=True) |
| 49 | line = srv.stdout.readline() |
| 50 | if 'Listening on ' in line: |
| 51 | log('NBD server: started') |
| 52 | else: |
| 53 | log('NBD server: ' + line.rstrip()) |
| 54 | |
| 55 | return srv |
| 56 | |
| 57 | |
| 58 | def start_client_NBD(): |
| 59 | log('NBD client: QEMU-IO write') |
| 60 | args = iotests.qemu_io_args_no_fmt + \ |
| 61 | ['-c', 'write -P 0x7 0 3M', '--image-opts', |
| 62 | 'driver=nbd,server.type=unix,server.path={},' |
| 63 | 'reconnect-delay=7'.format(nbd_sock)] |
| 64 | clt = subprocess.Popen(args, stdout=subprocess.PIPE, |
| 65 | stderr=subprocess.STDOUT, |
| 66 | universal_newlines=True) |
| 67 | return clt |
| 68 | |
| 69 | |
| 70 | def check_proc_NBD(proc, connector): |
| 71 | try: |
| 72 | outs, errs = proc.communicate(timeout=10) |
| 73 | |
| 74 | if proc.returncode < 0: |
| 75 | log('NBD {}: EXIT SIGNAL {}\n'.format(connector, proc.returncode)) |
| 76 | log(outs) |
| 77 | else: |
| 78 | msg = outs.split('\n', 1) |
| 79 | log('NBD {}: {}'.format(connector, msg[0])) |
| 80 | |
| 81 | except subprocess.TimeoutExpired: |
| 82 | proc.kill() |
| 83 | log('NBD {}: ERROR timeout expired'.format(connector)) |
| 84 | finally: |
| 85 | if connector == 'server': |
| 86 | os.remove(nbd_sock) |
| 87 | os.remove(conf_file) |
| 88 | |
| 89 | |
| 90 | srv = start_server_NBD('data') |
| 91 | clt = start_client_NBD() |
| 92 | # The server should close the connection after a client write request |
| 93 | check_proc_NBD(srv, 'server') |
| 94 | # Start the NBD server again |
| 95 | srv = start_server_NBD('reply') |
| 96 | # The client should reconnect and complete the write operation |
| 97 | check_proc_NBD(clt, 'client') |
| 98 | # Make it sure that server terminated |
| 99 | check_proc_NBD(srv, 'server') |