1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2019 Intel Corporation 4# All rights reserved. 5# 6 7import logging 8import argparse 9import sys 10import shlex 11 12try: 13 from spdk.rpc.client import print_dict, JSONRPCException 14 import spdk.rpc as rpc 15except ImportError: 16 print("SPDK RPC library missing. Please add spdk/python directory to PYTHONPATH:") 17 print("'export PYTHONPATH=$PYTHONPATH:spdk/python'") 18 exit(1) 19 20try: 21 from shlex import quote 22except ImportError: 23 from pipes import quote 24 25 26def print_array(a): 27 print(" ".join((quote(v) for v in a))) 28 29 30def perform_tests_func(client, name=None): 31 """ 32 33 Args: 34 name: bdev name to perform bdevio tests on (optional; if omitted, test all bdevs) 35 36 Returns: 37 Number of failures in tests. 0 means no errors found. 38 """ 39 params = {} 40 if name: 41 params['name'] = name 42 return client.call('perform_tests', params) 43 44 45if __name__ == "__main__": 46 parser = argparse.ArgumentParser( 47 description='SPDK RPC command line interface. NOTE: spdk/python is expected in PYTHONPATH') 48 parser.add_argument('-s', dest='server_addr', 49 help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock') 50 parser.add_argument('-p', dest='port', 51 help='RPC port number (if server_addr is IP address)', 52 default=5260, type=int) 53 parser.add_argument('-t', dest='timeout', 54 help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', 55 default=60.0, type=float) 56 parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", 57 help='Set verbose mode to INFO', default="ERROR") 58 parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], 59 help="""Set verbose level. """) 60 subparsers = parser.add_subparsers(help='RPC methods') 61 62 def perform_tests(args): 63 print_dict(perform_tests_func(args.client, name=args.name)) 64 65 p = subparsers.add_parser('perform_tests', help='Perform all bdevio tests on select bdev') 66 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1") 67 p.set_defaults(func=perform_tests) 68 69 def call_rpc_func(args): 70 try: 71 args.func(args) 72 except JSONRPCException as ex: 73 print(ex.message) 74 exit(1) 75 76 def execute_script(parser, client, fd): 77 for rpc_call in map(str.rstrip, fd): 78 if not rpc_call.strip(): 79 continue 80 args = parser.parse_args(shlex.split(rpc_call)) 81 args.client = client 82 call_rpc_func(args) 83 84 args = parser.parse_args() 85 args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) 86 if hasattr(args, 'func'): 87 call_rpc_func(args) 88 elif sys.stdin.isatty(): 89 # No arguments and no data piped through stdin 90 parser.print_help() 91 exit(1) 92 else: 93 execute_script(parser, args.client, sys.stdin) 94