17140c2f7STomasz Zawadzki#!/usr/bin/env python3 2*17538bdcSpaul luse# SPDX-License-Identifier: BSD-3-Clause 3*17538bdcSpaul luse# Copyright (C) 2019 Intel Corporation 4*17538bdcSpaul luse# All rights reserved. 5*17538bdcSpaul luse# 6*17538bdcSpaul luse 77140c2f7STomasz Zawadzkiimport logging 87140c2f7STomasz Zawadzkiimport argparse 97140c2f7STomasz Zawadzkiimport sys 107140c2f7STomasz Zawadzkiimport shlex 117140c2f7STomasz Zawadzki 127140c2f7STomasz Zawadzkitry: 137610bc38SKonrad Sztyber from spdk.rpc.client import print_dict, JSONRPCException 147610bc38SKonrad Sztyber import spdk.rpc as rpc 1514034200STomasz Zawadzkiexcept ImportError: 166e8e184bSKonrad Sztyber print("SPDK RPC library missing. Please add spdk/python directory to PYTHONPATH:") 176e8e184bSKonrad Sztyber print("'export PYTHONPATH=$PYTHONPATH:spdk/python'") 1814034200STomasz Zawadzki exit(1) 1914034200STomasz Zawadzki 2014034200STomasz Zawadzkitry: 217140c2f7STomasz Zawadzki from shlex import quote 227140c2f7STomasz Zawadzkiexcept ImportError: 237140c2f7STomasz Zawadzki from pipes import quote 247140c2f7STomasz Zawadzki 257140c2f7STomasz Zawadzki 267140c2f7STomasz Zawadzkidef print_array(a): 277140c2f7STomasz Zawadzki print(" ".join((quote(v) for v in a))) 287140c2f7STomasz Zawadzki 297140c2f7STomasz Zawadzki 307140c2f7STomasz Zawadzkidef perform_tests_func(client, name=None): 317140c2f7STomasz Zawadzki """ 327140c2f7STomasz Zawadzki 337140c2f7STomasz Zawadzki Args: 347140c2f7STomasz Zawadzki name: bdev name to perform bdevio tests on (optional; if omitted, test all bdevs) 357140c2f7STomasz Zawadzki 367140c2f7STomasz Zawadzki Returns: 377140c2f7STomasz Zawadzki Number of failures in tests. 0 means no errors found. 387140c2f7STomasz Zawadzki """ 397140c2f7STomasz Zawadzki params = {} 407140c2f7STomasz Zawadzki if name: 417140c2f7STomasz Zawadzki params['name'] = name 427140c2f7STomasz Zawadzki return client.call('perform_tests', params) 437140c2f7STomasz Zawadzki 447140c2f7STomasz Zawadzki 457140c2f7STomasz Zawadzkiif __name__ == "__main__": 467140c2f7STomasz Zawadzki parser = argparse.ArgumentParser( 476e8e184bSKonrad Sztyber description='SPDK RPC command line interface. NOTE: spdk/python is expected in PYTHONPATH') 487140c2f7STomasz Zawadzki parser.add_argument('-s', dest='server_addr', 497140c2f7STomasz Zawadzki help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock') 507140c2f7STomasz Zawadzki parser.add_argument('-p', dest='port', 517140c2f7STomasz Zawadzki help='RPC port number (if server_addr is IP address)', 527140c2f7STomasz Zawadzki default=5260, type=int) 537140c2f7STomasz Zawadzki parser.add_argument('-t', dest='timeout', 547140c2f7STomasz Zawadzki help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', 557140c2f7STomasz Zawadzki default=60.0, type=float) 567140c2f7STomasz Zawadzki parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", 577140c2f7STomasz Zawadzki help='Set verbose mode to INFO', default="ERROR") 587140c2f7STomasz Zawadzki parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], 597140c2f7STomasz Zawadzki help="""Set verbose level. """) 607140c2f7STomasz Zawadzki subparsers = parser.add_subparsers(help='RPC methods') 617140c2f7STomasz Zawadzki 627140c2f7STomasz Zawadzki def perform_tests(args): 637140c2f7STomasz Zawadzki print_dict(perform_tests_func(args.client, name=args.name)) 647140c2f7STomasz Zawadzki 657140c2f7STomasz Zawadzki p = subparsers.add_parser('perform_tests', help='Perform all bdevio tests on select bdev') 667140c2f7STomasz Zawadzki p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1") 677140c2f7STomasz Zawadzki p.set_defaults(func=perform_tests) 687140c2f7STomasz Zawadzki 697140c2f7STomasz Zawadzki def call_rpc_func(args): 707140c2f7STomasz Zawadzki try: 717140c2f7STomasz Zawadzki args.func(args) 727140c2f7STomasz Zawadzki except JSONRPCException as ex: 737140c2f7STomasz Zawadzki print(ex.message) 747140c2f7STomasz Zawadzki exit(1) 757140c2f7STomasz Zawadzki 767140c2f7STomasz Zawadzki def execute_script(parser, client, fd): 777140c2f7STomasz Zawadzki for rpc_call in map(str.rstrip, fd): 787140c2f7STomasz Zawadzki if not rpc_call.strip(): 797140c2f7STomasz Zawadzki continue 807140c2f7STomasz Zawadzki args = parser.parse_args(shlex.split(rpc_call)) 817140c2f7STomasz Zawadzki args.client = client 827140c2f7STomasz Zawadzki call_rpc_func(args) 837140c2f7STomasz Zawadzki 847140c2f7STomasz Zawadzki args = parser.parse_args() 857140c2f7STomasz Zawadzki args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) 867140c2f7STomasz Zawadzki if hasattr(args, 'func'): 877140c2f7STomasz Zawadzki call_rpc_func(args) 887140c2f7STomasz Zawadzki elif sys.stdin.isatty(): 897140c2f7STomasz Zawadzki # No arguments and no data piped through stdin 907140c2f7STomasz Zawadzki parser.print_help() 917140c2f7STomasz Zawadzki exit(1) 927140c2f7STomasz Zawadzki else: 937140c2f7STomasz Zawadzki execute_script(parser, args.client, sys.stdin) 94