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