]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | #!/usr/bin/env python3 |
2 | ||
3 | from rpc.client import print_dict, JSONRPCException | |
4 | ||
5 | import logging | |
6 | import argparse | |
7 | import rpc | |
8 | import sys | |
9 | import shlex | |
10 | ||
11 | try: | |
12 | from shlex import quote | |
13 | except ImportError: | |
14 | from pipes import quote | |
15 | ||
16 | ||
17 | def print_array(a): | |
18 | print(" ".join((quote(v) for v in a))) | |
19 | ||
20 | ||
21 | def _fuzz_vhost_create_dev(client, socket, is_blk, use_bogus_buffer, use_valid_buffer, test_scsi_tmf, valid_lun): | |
22 | """Create a new device in the vhost fuzzer. | |
23 | ||
24 | Args: | |
25 | socket: A valid unix domain socket for the dev to bind to. | |
26 | is_blk: if set, create a virtio_blk device, otherwise use scsi. | |
27 | use_bogus_buffer: if set, pass an invalid memory address as a buffer accompanying requests. | |
28 | use_valid_buffer: if set, pass in a valid memory buffer with requests. Overrides use_bogus_buffer. | |
29 | test_scsi_tmf: Test scsi management commands on the given device. Valid if and only if is_blk is false. | |
30 | valid_lun: Supply only a valid lun number when submitting commands to the given device. Valid if and only if is_blk is false. | |
31 | ||
32 | Returns: | |
33 | True or False | |
34 | """ | |
35 | ||
36 | params = {"socket": socket, | |
37 | "is_blk": is_blk, | |
38 | "use_bogus_buffer": use_bogus_buffer, | |
39 | "use_valid_buffer": use_valid_buffer, | |
40 | "test_scsi_tmf": test_scsi_tmf, | |
41 | "valid_lun": valid_lun} | |
42 | ||
43 | return client.call("fuzz_vhost_create_dev", params) | |
44 | ||
45 | ||
46 | if __name__ == "__main__": | |
47 | parser = argparse.ArgumentParser( | |
48 | description='SPDK RPC command line interface. NOTE: spdk/scripts/ is expected in PYTHONPATH') | |
49 | parser.add_argument('-s', dest='server_addr', | |
50 | help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock') | |
51 | parser.add_argument('-p', dest='port', | |
52 | help='RPC port number (if server_addr is IP address)', | |
53 | default=5260, type=int) | |
54 | parser.add_argument('-t', dest='timeout', | |
55 | help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', | |
56 | default=60.0, type=float) | |
57 | parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", | |
58 | help='Set verbose mode to INFO', default="ERROR") | |
59 | parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], | |
60 | help="""Set verbose level. """) | |
61 | subparsers = parser.add_subparsers(help='RPC methods') | |
62 | ||
63 | def fuzz_vhost_create_dev(args): | |
64 | _fuzz_vhost_create_dev( | |
65 | args.client, | |
66 | args.socket, | |
67 | args.is_blk, | |
68 | args.use_bogus_buffer, | |
69 | args.use_valid_buffer, | |
70 | args.test_scsi_tmf, | |
71 | args.valid_lun) | |
72 | ||
73 | p = subparsers.add_parser('fuzz_vhost_create_dev', help="Add a new device to the vhost fuzzer.") | |
74 | p.add_argument('-s', '--socket', help="Path to a valid unix domain socket for dev binding.") | |
75 | p.add_argument('-b', '--is-blk', help='The specified socket corresponds to a vhost-blk dev.', action='store_true') | |
76 | p.add_argument('-u', '--use-bogus-buffer', help='Pass bogus buffer addresses with requests when fuzzing.', action='store_true') | |
77 | p.add_argument('-v', '--use-valid-buffer', help='Pass valid buffers when fuzzing. overrides use-bogus-buffer.', action='store_true') | |
78 | p.add_argument('-m', '--test-scsi-tmf', help='for a scsi device, test scsi management commands.', action='store_true') | |
79 | p.add_argument('-l', '--valid-lun', help='for a scsi device, test only using valid lun IDs.', action='store_true') | |
80 | p.set_defaults(func=fuzz_vhost_create_dev) | |
81 | ||
82 | def call_rpc_func(args): | |
83 | try: | |
84 | args.func(args) | |
85 | except JSONRPCException as ex: | |
86 | print(ex.message) | |
87 | exit(1) | |
88 | ||
89 | def execute_script(parser, client, fd): | |
90 | for rpc_call in map(str.rstrip, fd): | |
91 | if not rpc_call.strip(): | |
92 | continue | |
93 | args = parser.parse_args(shlex.split(rpc_call)) | |
94 | args.client = client | |
95 | call_rpc_func(args) | |
96 | ||
97 | args = parser.parse_args() | |
98 | args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) | |
99 | if hasattr(args, 'func'): | |
100 | call_rpc_func(args) | |
101 | elif sys.stdin.isatty(): | |
102 | # No arguments and no data piped through stdin | |
103 | parser.print_help() | |
104 | exit(1) | |
105 | else: | |
106 | execute_script(parser, args.client, sys.stdin) |