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