xref: /openbmc/qemu/tests/qemu-iotests/277 (revision ec77662e60fa12802fd5c1bdc0e4d147a8b78e95)
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