17c477526SPhilippe 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 267d814059SJohn Snowiotests.script_initialize() 277d814059SJohn Snow 28a4d925f8SAndrey Shinkevich 29a4d925f8SAndrey Shinkevichnbd_sock, conf_file = file_path('nbd-sock', 'nbd-fault-injector.conf') 30a4d925f8SAndrey Shinkevich 31a4d925f8SAndrey Shinkevich 32a4d925f8SAndrey Shinkevichdef make_conf_file(event): 33a4d925f8SAndrey Shinkevich """ 34a4d925f8SAndrey Shinkevich Create configuration file for the nbd-fault-injector.py 35a4d925f8SAndrey Shinkevich 36a4d925f8SAndrey Shinkevich :param event: which event the server should close a connection on 37a4d925f8SAndrey Shinkevich """ 38a4d925f8SAndrey Shinkevich with open(conf_file, 'w') as conff: 39a4d925f8SAndrey Shinkevich conff.write('[inject-error]\nevent={}\nwhen=after'.format(event)) 40a4d925f8SAndrey Shinkevich 41a4d925f8SAndrey Shinkevich 42a4d925f8SAndrey Shinkevichdef start_server_NBD(event): 43a4d925f8SAndrey Shinkevich make_conf_file(event) 44a4d925f8SAndrey Shinkevich 45*ec77662eSVladimir Sementsov-Ogievskiy srv = subprocess.Popen(['./nbd-fault-injector.py', '--classic-negotiation', 46a4d925f8SAndrey Shinkevich nbd_sock, conf_file], stdout=subprocess.PIPE, 47a4d925f8SAndrey Shinkevich stderr=subprocess.STDOUT, universal_newlines=True) 48a4d925f8SAndrey Shinkevich line = srv.stdout.readline() 49a4d925f8SAndrey Shinkevich if 'Listening on ' in line: 50a4d925f8SAndrey Shinkevich log('NBD server: started') 51a4d925f8SAndrey Shinkevich else: 52a4d925f8SAndrey Shinkevich log('NBD server: ' + line.rstrip()) 53a4d925f8SAndrey Shinkevich 54a4d925f8SAndrey Shinkevich return srv 55a4d925f8SAndrey Shinkevich 56a4d925f8SAndrey Shinkevich 57a4d925f8SAndrey Shinkevichdef start_client_NBD(): 58a4d925f8SAndrey Shinkevich log('NBD client: QEMU-IO write') 59a4d925f8SAndrey Shinkevich args = iotests.qemu_io_args_no_fmt + \ 60a4d925f8SAndrey Shinkevich ['-c', 'write -P 0x7 0 3M', '--image-opts', 61a4d925f8SAndrey Shinkevich 'driver=nbd,server.type=unix,server.path={},' 62a4d925f8SAndrey Shinkevich 'reconnect-delay=7'.format(nbd_sock)] 63a4d925f8SAndrey Shinkevich clt = subprocess.Popen(args, stdout=subprocess.PIPE, 64a4d925f8SAndrey Shinkevich stderr=subprocess.STDOUT, 65a4d925f8SAndrey Shinkevich universal_newlines=True) 66a4d925f8SAndrey Shinkevich return clt 67a4d925f8SAndrey Shinkevich 68a4d925f8SAndrey Shinkevich 69a4d925f8SAndrey Shinkevichdef check_proc_NBD(proc, connector): 70a4d925f8SAndrey Shinkevich try: 71a4d925f8SAndrey Shinkevich outs, errs = proc.communicate(timeout=10) 72a4d925f8SAndrey Shinkevich 73a4d925f8SAndrey Shinkevich if proc.returncode < 0: 74a4d925f8SAndrey Shinkevich log('NBD {}: EXIT SIGNAL {}\n'.format(connector, proc.returncode)) 75a4d925f8SAndrey Shinkevich log(outs) 76a4d925f8SAndrey Shinkevich else: 77a4d925f8SAndrey Shinkevich msg = outs.split('\n', 1) 78a4d925f8SAndrey Shinkevich log('NBD {}: {}'.format(connector, msg[0])) 79a4d925f8SAndrey Shinkevich 80a4d925f8SAndrey Shinkevich except subprocess.TimeoutExpired: 81a4d925f8SAndrey Shinkevich proc.kill() 82a4d925f8SAndrey Shinkevich log('NBD {}: ERROR timeout expired'.format(connector)) 83a4d925f8SAndrey Shinkevich finally: 84a4d925f8SAndrey Shinkevich if connector == 'server': 85a4d925f8SAndrey Shinkevich os.remove(nbd_sock) 86a4d925f8SAndrey Shinkevich os.remove(conf_file) 87a4d925f8SAndrey Shinkevich 88a4d925f8SAndrey Shinkevich 89a4d925f8SAndrey Shinkevichsrv = start_server_NBD('data') 90a4d925f8SAndrey Shinkevichclt = start_client_NBD() 91a4d925f8SAndrey Shinkevich# The server should close the connection after a client write request 92a4d925f8SAndrey Shinkevichcheck_proc_NBD(srv, 'server') 93a4d925f8SAndrey Shinkevich# Start the NBD server again 94a4d925f8SAndrey Shinkevichsrv = start_server_NBD('reply') 95a4d925f8SAndrey Shinkevich# The client should reconnect and complete the write operation 96a4d925f8SAndrey Shinkevichcheck_proc_NBD(clt, 'client') 97a4d925f8SAndrey Shinkevich# Make it sure that server terminated 98a4d925f8SAndrey Shinkevichcheck_proc_NBD(srv, 'server') 99