1*7c477526SPhilippe Mathieu-Daudé#!/usr/bin/env python3 2a4d925f8SAndrey Shinkevich# 3a4d925f8SAndrey Shinkevich# Test NBD client reconnection 4a4d925f8SAndrey Shinkevich# 5a4d925f8SAndrey Shinkevich# Copyright (c) 2019 Virtuozzo International GmbH 6a4d925f8SAndrey Shinkevich# 7a4d925f8SAndrey Shinkevich# This program is free software; you can redistribute it and/or modify 8a4d925f8SAndrey Shinkevich# it under the terms of the GNU General Public License as published by 9a4d925f8SAndrey Shinkevich# the Free Software Foundation; either version 2 of the License, or 10a4d925f8SAndrey Shinkevich# (at your option) any later version. 11a4d925f8SAndrey Shinkevich# 12a4d925f8SAndrey Shinkevich# This program is distributed in the hope that it will be useful, 13a4d925f8SAndrey Shinkevich# but WITHOUT ANY WARRANTY; without even the implied warranty of 14a4d925f8SAndrey Shinkevich# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a4d925f8SAndrey Shinkevich# GNU General Public License for more details. 16a4d925f8SAndrey Shinkevich# 17a4d925f8SAndrey Shinkevich# You should have received a copy of the GNU General Public License 18a4d925f8SAndrey Shinkevich# along with this program. If not, see <http://www.gnu.org/licenses/>. 19a4d925f8SAndrey Shinkevich# 20a4d925f8SAndrey Shinkevich 21a4d925f8SAndrey Shinkevichimport os 22a4d925f8SAndrey Shinkevichimport subprocess 23a4d925f8SAndrey Shinkevichimport iotests 24a4d925f8SAndrey Shinkevichfrom iotests import file_path, log 25a4d925f8SAndrey Shinkevich 26a4d925f8SAndrey Shinkevich 27a4d925f8SAndrey Shinkevichnbd_sock, conf_file = file_path('nbd-sock', 'nbd-fault-injector.conf') 28a4d925f8SAndrey Shinkevich 29a4d925f8SAndrey Shinkevich 30a4d925f8SAndrey Shinkevichdef make_conf_file(event): 31a4d925f8SAndrey Shinkevich """ 32a4d925f8SAndrey Shinkevich Create configuration file for the nbd-fault-injector.py 33a4d925f8SAndrey Shinkevich 34a4d925f8SAndrey Shinkevich :param event: which event the server should close a connection on 35a4d925f8SAndrey Shinkevich """ 36a4d925f8SAndrey Shinkevich with open(conf_file, 'w') as conff: 37a4d925f8SAndrey Shinkevich conff.write('[inject-error]\nevent={}\nwhen=after'.format(event)) 38a4d925f8SAndrey Shinkevich 39a4d925f8SAndrey Shinkevich 40a4d925f8SAndrey Shinkevichdef start_server_NBD(event): 41a4d925f8SAndrey Shinkevich make_conf_file(event) 42a4d925f8SAndrey Shinkevich 43a4d925f8SAndrey Shinkevich srv = subprocess.Popen(['nbd-fault-injector.py', '--classic-negotiation', 44a4d925f8SAndrey Shinkevich nbd_sock, conf_file], stdout=subprocess.PIPE, 45a4d925f8SAndrey Shinkevich stderr=subprocess.STDOUT, universal_newlines=True) 46a4d925f8SAndrey Shinkevich line = srv.stdout.readline() 47a4d925f8SAndrey Shinkevich if 'Listening on ' in line: 48a4d925f8SAndrey Shinkevich log('NBD server: started') 49a4d925f8SAndrey Shinkevich else: 50a4d925f8SAndrey Shinkevich log('NBD server: ' + line.rstrip()) 51a4d925f8SAndrey Shinkevich 52a4d925f8SAndrey Shinkevich return srv 53a4d925f8SAndrey Shinkevich 54a4d925f8SAndrey Shinkevich 55a4d925f8SAndrey Shinkevichdef start_client_NBD(): 56a4d925f8SAndrey Shinkevich log('NBD client: QEMU-IO write') 57a4d925f8SAndrey Shinkevich args = iotests.qemu_io_args_no_fmt + \ 58a4d925f8SAndrey Shinkevich ['-c', 'write -P 0x7 0 3M', '--image-opts', 59a4d925f8SAndrey Shinkevich 'driver=nbd,server.type=unix,server.path={},' 60a4d925f8SAndrey Shinkevich 'reconnect-delay=7'.format(nbd_sock)] 61a4d925f8SAndrey Shinkevich clt = subprocess.Popen(args, stdout=subprocess.PIPE, 62a4d925f8SAndrey Shinkevich stderr=subprocess.STDOUT, 63a4d925f8SAndrey Shinkevich universal_newlines=True) 64a4d925f8SAndrey Shinkevich return clt 65a4d925f8SAndrey Shinkevich 66a4d925f8SAndrey Shinkevich 67a4d925f8SAndrey Shinkevichdef check_proc_NBD(proc, connector): 68a4d925f8SAndrey Shinkevich try: 69a4d925f8SAndrey Shinkevich outs, errs = proc.communicate(timeout=10) 70a4d925f8SAndrey Shinkevich 71a4d925f8SAndrey Shinkevich if proc.returncode < 0: 72a4d925f8SAndrey Shinkevich log('NBD {}: EXIT SIGNAL {}\n'.format(connector, proc.returncode)) 73a4d925f8SAndrey Shinkevich log(outs) 74a4d925f8SAndrey Shinkevich else: 75a4d925f8SAndrey Shinkevich msg = outs.split('\n', 1) 76a4d925f8SAndrey Shinkevich log('NBD {}: {}'.format(connector, msg[0])) 77a4d925f8SAndrey Shinkevich 78a4d925f8SAndrey Shinkevich except subprocess.TimeoutExpired: 79a4d925f8SAndrey Shinkevich proc.kill() 80a4d925f8SAndrey Shinkevich log('NBD {}: ERROR timeout expired'.format(connector)) 81a4d925f8SAndrey Shinkevich finally: 82a4d925f8SAndrey Shinkevich if connector == 'server': 83a4d925f8SAndrey Shinkevich os.remove(nbd_sock) 84a4d925f8SAndrey Shinkevich os.remove(conf_file) 85a4d925f8SAndrey Shinkevich 86a4d925f8SAndrey Shinkevich 87a4d925f8SAndrey Shinkevichsrv = start_server_NBD('data') 88a4d925f8SAndrey Shinkevichclt = start_client_NBD() 89a4d925f8SAndrey Shinkevich# The server should close the connection after a client write request 90a4d925f8SAndrey Shinkevichcheck_proc_NBD(srv, 'server') 91a4d925f8SAndrey Shinkevich# Start the NBD server again 92a4d925f8SAndrey Shinkevichsrv = start_server_NBD('reply') 93a4d925f8SAndrey Shinkevich# The client should reconnect and complete the write operation 94a4d925f8SAndrey Shinkevichcheck_proc_NBD(clt, 'client') 95a4d925f8SAndrey Shinkevich# Make it sure that server terminated 96a4d925f8SAndrey Shinkevichcheck_proc_NBD(srv, 'server') 97