1#!/usr/bin/env python3 2 3from rpc.client import print_dict, print_json, JSONRPCException 4from rpc.helpers import deprecated_aliases 5 6import logging 7import argparse 8import rpc 9import sys 10import shlex 11import json 12 13try: 14 from shlex import quote 15except ImportError: 16 from pipes import quote 17 18 19def print_array(a): 20 print(" ".join((quote(v) for v in a))) 21 22 23if __name__ == "__main__": 24 parser = argparse.ArgumentParser( 25 description='SPDK RPC command line interface') 26 parser.add_argument('-s', dest='server_addr', 27 help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock') 28 parser.add_argument('-p', dest='port', 29 help='RPC port number (if server_addr is IP address)', 30 default=5260, type=int) 31 parser.add_argument('-t', dest='timeout', 32 help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', 33 default=60.0, type=float) 34 parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", 35 help='Set verbose mode to INFO', default="ERROR") 36 parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], 37 help="""Set verbose level. """) 38 parser.add_argument('--dry_run', dest='dry_run', action='store_true', help="Display request and exit") 39 parser.set_defaults(dry_run=False) 40 subparsers = parser.add_subparsers(help='RPC methods', dest='called_rpc_name') 41 42 def framework_start_init(args): 43 rpc.framework_start_init(args.client) 44 45 p = subparsers.add_parser('framework_start_init', aliases=['start_subsystem_init'], 46 help='Start initialization of subsystems') 47 p.set_defaults(func=framework_start_init) 48 49 def framework_wait_init(args): 50 rpc.framework_wait_init(args.client) 51 52 p = subparsers.add_parser('framework_wait_init', aliases=['wait_subsystem_init'], 53 help='Block until subsystems have been initialized') 54 p.set_defaults(func=framework_wait_init) 55 56 def rpc_get_methods(args): 57 print_dict(rpc.rpc_get_methods(args.client, 58 current=args.current, 59 include_aliases=args.include_aliases)) 60 61 p = subparsers.add_parser('rpc_get_methods', aliases=['get_rpc_methods'], 62 help='Get list of supported RPC methods') 63 p.add_argument('-c', '--current', help='Get list of RPC methods only callable in the current state.', action='store_true') 64 p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true') 65 p.set_defaults(func=rpc_get_methods) 66 67 def spdk_get_version(args): 68 print_json(rpc.spdk_get_version(args.client)) 69 70 p = subparsers.add_parser('spdk_get_version', aliases=['get_spdk_version'], 71 help='Get SPDK version') 72 p.set_defaults(func=spdk_get_version) 73 74 def save_config(args): 75 rpc.save_config(args.client, 76 sys.stdout, 77 indent=args.indent) 78 79 p = subparsers.add_parser('save_config', help="""Write current (live) configuration of SPDK subsystems and targets to stdout. 80 """) 81 p.add_argument('-i', '--indent', help="""Indent level. Value less than 0 mean compact mode. Default indent level is 2. 82 """, type=int, default=2) 83 p.set_defaults(func=save_config) 84 85 def load_config(args): 86 rpc.load_config(args.client, sys.stdin, 87 include_aliases=args.include_aliases) 88 89 p = subparsers.add_parser('load_config', help="""Configure SPDK subsystems and targets using JSON RPC read from stdin.""") 90 p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true') 91 p.set_defaults(func=load_config) 92 93 def save_subsystem_config(args): 94 rpc.save_subsystem_config(args.client, 95 sys.stdout, 96 indent=args.indent, 97 name=args.name) 98 99 p = subparsers.add_parser('save_subsystem_config', help="""Write current (live) configuration of SPDK subsystem to stdout. 100 """) 101 p.add_argument('-i', '--indent', help="""Indent level. Value less than 0 mean compact mode. Default indent level is 2. 102 """, type=int, default=2) 103 p.add_argument('-n', '--name', help='Name of subsystem', required=True) 104 p.set_defaults(func=save_subsystem_config) 105 106 def load_subsystem_config(args): 107 rpc.load_subsystem_config(args.client, 108 sys.stdin) 109 110 p = subparsers.add_parser('load_subsystem_config', help="""Configure SPDK subsystem using JSON RPC read from stdin.""") 111 p.set_defaults(func=load_subsystem_config) 112 113 # app 114 def spdk_kill_instance(args): 115 rpc.app.spdk_kill_instance(args.client, 116 sig_name=args.sig_name) 117 118 p = subparsers.add_parser('spdk_kill_instance', aliases=['kill_instance'], 119 help='Send signal to instance') 120 p.add_argument('sig_name', help='signal will be sent to server.') 121 p.set_defaults(func=spdk_kill_instance) 122 123 def framework_monitor_context_switch(args): 124 enabled = None 125 if args.enable: 126 enabled = True 127 if args.disable: 128 enabled = False 129 print_dict(rpc.app.framework_monitor_context_switch(args.client, 130 enabled=enabled)) 131 132 p = subparsers.add_parser('framework_monitor_context_switch', aliases=['context_switch_monitor'], 133 help='Control whether the context switch monitor is enabled') 134 p.add_argument('-e', '--enable', action='store_true', help='Enable context switch monitoring') 135 p.add_argument('-d', '--disable', action='store_true', help='Disable context switch monitoring') 136 p.set_defaults(func=framework_monitor_context_switch) 137 138 def framework_get_reactors(args): 139 print_dict(rpc.app.framework_get_reactors(args.client)) 140 141 p = subparsers.add_parser( 142 'framework_get_reactors', help='Display list of all reactors') 143 p.set_defaults(func=framework_get_reactors) 144 145 # bdev 146 def bdev_set_options(args): 147 rpc.bdev.bdev_set_options(args.client, 148 bdev_io_pool_size=args.bdev_io_pool_size, 149 bdev_io_cache_size=args.bdev_io_cache_size) 150 151 p = subparsers.add_parser('bdev_set_options', aliases=['set_bdev_options'], 152 help="""Set options of bdev subsystem""") 153 p.add_argument('-p', '--bdev-io-pool-size', help='Number of bdev_io structures in shared buffer pool', type=int) 154 p.add_argument('-c', '--bdev-io-cache-size', help='Maximum number of bdev_io structures cached per thread', type=int) 155 p.set_defaults(func=bdev_set_options) 156 157 def bdev_compress_create(args): 158 print_json(rpc.bdev.bdev_compress_create(args.client, 159 base_bdev_name=args.base_bdev_name, 160 pm_path=args.pm_path)) 161 162 p = subparsers.add_parser('bdev_compress_create', aliases=['construct_compress_bdev'], 163 help='Add a compress vbdev') 164 p.add_argument('-b', '--base_bdev_name', help="Name of the base bdev") 165 p.add_argument('-p', '--pm_path', help="Path to persistent memory") 166 p.set_defaults(func=bdev_compress_create) 167 168 def bdev_compress_delete(args): 169 rpc.bdev.bdev_compress_delete(args.client, 170 name=args.name) 171 172 p = subparsers.add_parser('bdev_compress_delete', aliases=['delete_compress_bdev'], 173 help='Delete a compress disk') 174 p.add_argument('name', help='compress bdev name') 175 p.set_defaults(func=bdev_compress_delete) 176 177 def compress_set_pmd(args): 178 rpc.bdev.compress_set_pmd(args.client, 179 pmd=args.pmd) 180 p = subparsers.add_parser('compress_set_pmd', aliases=['set_compress_pmd'], 181 help='Set pmd option for a compress disk') 182 p.add_argument('-p', '--pmd', type=int, help='0 = auto-select, 1= QAT only, 2 = ISAL only') 183 p.set_defaults(func=compress_set_pmd) 184 185 def bdev_compress_get_orphans(args): 186 print_dict(rpc.bdev.bdev_compress_get_orphans(args.client, 187 name=args.name)) 188 p = subparsers.add_parser( 189 'bdev_compress_get_orphans', help='Display list of orphaned compress bdevs.') 190 p.add_argument('-b', '--name', help="Name of a comp bdev. Example: COMP_Nvme0n1", required=False) 191 p.set_defaults(func=bdev_compress_get_orphans) 192 193 def bdev_crypto_create(args): 194 print_json(rpc.bdev.bdev_crypto_create(args.client, 195 base_bdev_name=args.base_bdev_name, 196 name=args.name, 197 crypto_pmd=args.crypto_pmd, 198 key=args.key, 199 cipher=args.cipher, 200 key2=args.key2)) 201 p = subparsers.add_parser('bdev_crypto_create', aliases=['construct_crypto_bdev'], 202 help='Add a crypto vbdev') 203 p.add_argument('base_bdev_name', help="Name of the base bdev") 204 p.add_argument('name', help="Name of the crypto vbdev") 205 p.add_argument('crypto_pmd', help="Name of the crypto device driver") 206 p.add_argument('key', help="Key") 207 p.add_argument('-c', '--cipher', help="cipher to use, AES_CBC or AES_XTS (QAT only)", default="AES_CBC") 208 p.add_argument('-k2', '--key2', help="2nd key for cipher AET_XTS", default=None) 209 p.set_defaults(func=bdev_crypto_create) 210 211 def bdev_crypto_delete(args): 212 rpc.bdev.bdev_crypto_delete(args.client, 213 name=args.name) 214 215 p = subparsers.add_parser('bdev_crypto_delete', aliases=['delete_crypto_bdev'], 216 help='Delete a crypto disk') 217 p.add_argument('name', help='crypto bdev name') 218 p.set_defaults(func=bdev_crypto_delete) 219 220 def bdev_ocf_create(args): 221 print_json(rpc.bdev.bdev_ocf_create(args.client, 222 name=args.name, 223 mode=args.mode, 224 cache_bdev_name=args.cache_bdev_name, 225 core_bdev_name=args.core_bdev_name)) 226 p = subparsers.add_parser('bdev_ocf_create', aliases=['construct_ocf_bdev'], 227 help='Add an OCF block device') 228 p.add_argument('name', help='Name of resulting OCF bdev') 229 p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo']) 230 p.add_argument('cache_bdev_name', help='Name of underlying cache bdev') 231 p.add_argument('core_bdev_name', help='Name of unerlying core bdev') 232 p.set_defaults(func=bdev_ocf_create) 233 234 def bdev_ocf_delete(args): 235 rpc.bdev.bdev_ocf_delete(args.client, 236 name=args.name) 237 238 p = subparsers.add_parser('bdev_ocf_delete', aliases=['delete_ocf_bdev'], 239 help='Delete an OCF block device') 240 p.add_argument('name', help='Name of OCF bdev') 241 p.set_defaults(func=bdev_ocf_delete) 242 243 def bdev_ocf_get_stats(args): 244 print_dict(rpc.bdev.bdev_ocf_get_stats(args.client, 245 name=args.name)) 246 p = subparsers.add_parser('bdev_ocf_get_stats', aliases=['get_ocf_stats'], 247 help='Get statistics of chosen OCF block device') 248 p.add_argument('name', help='Name of OCF bdev') 249 p.set_defaults(func=bdev_ocf_get_stats) 250 251 def bdev_ocf_get_bdevs(args): 252 print_dict(rpc.bdev.bdev_ocf_get_bdevs(args.client, 253 name=args.name)) 254 p = subparsers.add_parser('bdev_ocf_get_bdevs', aliases=['get_ocf_bdevs'], 255 help='Get list of OCF devices including unregistered ones') 256 p.add_argument('name', nargs='?', default=None, help='name of OCF vbdev or name of cache device or name of core device (optional)') 257 p.set_defaults(func=bdev_ocf_get_bdevs) 258 259 def bdev_malloc_create(args): 260 num_blocks = (args.total_size * 1024 * 1024) // args.block_size 261 print_json(rpc.bdev.bdev_malloc_create(args.client, 262 num_blocks=int(num_blocks), 263 block_size=args.block_size, 264 name=args.name, 265 uuid=args.uuid)) 266 p = subparsers.add_parser('bdev_malloc_create', aliases=['construct_malloc_bdev'], 267 help='Create a bdev with malloc backend') 268 p.add_argument('-b', '--name', help="Name of the bdev") 269 p.add_argument('-u', '--uuid', help="UUID of the bdev") 270 p.add_argument( 271 'total_size', help='Size of malloc bdev in MB (float > 0)', type=float) 272 p.add_argument('block_size', help='Block size for this bdev', type=int) 273 p.set_defaults(func=bdev_malloc_create) 274 275 def bdev_malloc_delete(args): 276 rpc.bdev.bdev_malloc_delete(args.client, 277 name=args.name) 278 279 p = subparsers.add_parser('bdev_malloc_delete', aliases=['delete_malloc_bdev'], 280 help='Delete a malloc disk') 281 p.add_argument('name', help='malloc bdev name') 282 p.set_defaults(func=bdev_malloc_delete) 283 284 def bdev_null_create(args): 285 num_blocks = (args.total_size * 1024 * 1024) // args.block_size 286 print_json(rpc.bdev.bdev_null_create(args.client, 287 num_blocks=num_blocks, 288 block_size=args.block_size, 289 name=args.name, 290 uuid=args.uuid, 291 md_size=args.md_size, 292 dif_type=args.dif_type, 293 dif_is_head_of_md=args.dif_is_head_of_md)) 294 295 p = subparsers.add_parser('bdev_null_create', aliases=['construct_null_bdev'], 296 help='Add a bdev with null backend') 297 p.add_argument('name', help='Block device name') 298 p.add_argument('-u', '--uuid', help='UUID of the bdev') 299 p.add_argument( 300 'total_size', help='Size of null bdev in MB (int > 0)', type=int) 301 p.add_argument('block_size', help='Block size for this bdev', type=int) 302 p.add_argument('-m', '--md-size', type=int, 303 help='Metadata size for this bdev. Default 0') 304 p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3], 305 help='Protection information type. Default: 0 - no protection') 306 p.add_argument('-d', '--dif-is-head-of-md', action='store_true', 307 help='Protection information is in the first 8 bytes of metadata. Default: in the last 8 bytes') 308 p.set_defaults(func=bdev_null_create) 309 310 def bdev_null_delete(args): 311 rpc.bdev.bdev_null_delete(args.client, 312 name=args.name) 313 314 p = subparsers.add_parser('bdev_null_delete', aliases=['delete_null_bdev'], 315 help='Delete a null bdev') 316 p.add_argument('name', help='null bdev name') 317 p.set_defaults(func=bdev_null_delete) 318 319 def bdev_aio_create(args): 320 print_json(rpc.bdev.bdev_aio_create(args.client, 321 filename=args.filename, 322 name=args.name, 323 block_size=args.block_size)) 324 325 p = subparsers.add_parser('bdev_aio_create', aliases=['construct_aio_bdev'], 326 help='Add a bdev with aio backend') 327 p.add_argument('filename', help='Path to device or file (ex: /dev/sda)') 328 p.add_argument('name', help='Block device name') 329 p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?', default=0) 330 p.set_defaults(func=bdev_aio_create) 331 332 def bdev_aio_delete(args): 333 rpc.bdev.bdev_aio_delete(args.client, 334 name=args.name) 335 336 p = subparsers.add_parser('bdev_aio_delete', aliases=['delete_aio_bdev'], 337 help='Delete an aio disk') 338 p.add_argument('name', help='aio bdev name') 339 p.set_defaults(func=bdev_aio_delete) 340 341 def bdev_uring_create(args): 342 print_json(rpc.bdev.bdev_uring_create(args.client, 343 filename=args.filename, 344 name=args.name, 345 block_size=args.block_size)) 346 347 p = subparsers.add_parser('bdev_uring_create', help='Create a bdev with io_uring backend') 348 p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)') 349 p.add_argument('name', help='bdev name') 350 p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?', default=0) 351 p.set_defaults(func=bdev_uring_create) 352 353 def bdev_uring_delete(args): 354 rpc.bdev.bdev_uring_delete(args.client, 355 name=args.name) 356 357 p = subparsers.add_parser('bdev_uring_delete', help='Delete a uring bdev') 358 p.add_argument('name', help='uring bdev name') 359 p.set_defaults(func=bdev_uring_delete) 360 361 def bdev_nvme_set_options(args): 362 rpc.bdev.bdev_nvme_set_options(args.client, 363 action_on_timeout=args.action_on_timeout, 364 timeout_us=args.timeout_us, 365 retry_count=args.retry_count, 366 arbitration_burst=args.arbitration_burst, 367 low_priority_weight=args.low_priority_weight, 368 medium_priority_weight=args.medium_priority_weight, 369 high_priority_weight=args.high_priority_weight, 370 nvme_adminq_poll_period_us=args.nvme_adminq_poll_period_us, 371 nvme_ioq_poll_period_us=args.nvme_ioq_poll_period_us, 372 io_queue_requests=args.io_queue_requests, 373 delay_cmd_submit=args.delay_cmd_submit) 374 375 p = subparsers.add_parser('bdev_nvme_set_options', aliases=['set_bdev_nvme_options'], 376 help='Set options for the bdev nvme type. This is startup command.') 377 p.add_argument('-a', '--action-on-timeout', 378 help="Action to take on command time out. Valid valies are: none, reset, abort") 379 p.add_argument('-t', '--timeout-us', 380 help="Timeout for each command, in microseconds. If 0, don't track timeouts.", type=int) 381 p.add_argument('-n', '--retry-count', 382 help='the number of attempts per I/O when an I/O fails', type=int) 383 p.add_argument('--arbitration-burst', 384 help='the value is expressed as a power of two', type=int) 385 p.add_argument('--low-priority-weight', 386 help='the maximum number of commands that the controller may launch at one time from a low priority queue', type=int) 387 p.add_argument('--medium-priority-weight', 388 help='the maximum number of commands that the controller may launch at one time from a medium priority queue', type=int) 389 p.add_argument('--high-priority-weight', 390 help='the maximum number of commands that the controller may launch at one time from a high priority queue', type=int) 391 p.add_argument('-p', '--nvme-adminq-poll-period-us', 392 help='How often the admin queue is polled for asynchronous events', type=int) 393 p.add_argument('-i', '--nvme-ioq-poll-period-us', 394 help='How often to poll I/O queues for completions', type=int) 395 p.add_argument('-s', '--io-queue-requests', 396 help='The number of requests allocated for each NVMe I/O queue. Default: 512', type=int) 397 p.add_argument('-d', '--disable-delay-cmd-submit', 398 help='Disable delaying NVMe command submission, i.e. no batching of multiple commands', 399 action='store_false', dest='delay_cmd_submit', default=True) 400 p.set_defaults(func=bdev_nvme_set_options) 401 402 def bdev_nvme_set_hotplug(args): 403 rpc.bdev.bdev_nvme_set_hotplug(args.client, enable=args.enable, period_us=args.period_us) 404 405 p = subparsers.add_parser('bdev_nvme_set_hotplug', aliases=['set_bdev_nvme_hotplug'], 406 help='Set hotplug options for bdev nvme type.') 407 p.add_argument('-d', '--disable', dest='enable', default=False, action='store_false', help="Disable hotplug (default)") 408 p.add_argument('-e', '--enable', dest='enable', action='store_true', help="Enable hotplug") 409 p.add_argument('-r', '--period-us', 410 help='How often the hotplug is processed for insert and remove events', type=int) 411 p.set_defaults(func=bdev_nvme_set_hotplug) 412 413 def bdev_nvme_attach_controller(args): 414 print_array(rpc.bdev.bdev_nvme_attach_controller(args.client, 415 name=args.name, 416 trtype=args.trtype, 417 traddr=args.traddr, 418 adrfam=args.adrfam, 419 trsvcid=args.trsvcid, 420 subnqn=args.subnqn, 421 hostnqn=args.hostnqn, 422 hostaddr=args.hostaddr, 423 hostsvcid=args.hostsvcid, 424 prchk_reftag=args.prchk_reftag, 425 prchk_guard=args.prchk_guard)) 426 427 p = subparsers.add_parser('bdev_nvme_attach_controller', aliases=['construct_nvme_bdev'], 428 help='Add bdevs with nvme backend') 429 p.add_argument('-b', '--name', help="Name of the NVMe controller, prefix for each bdev name", required=True) 430 p.add_argument('-t', '--trtype', 431 help='NVMe-oF target trtype: e.g., rdma, pcie', required=True) 432 p.add_argument('-a', '--traddr', 433 help='NVMe-oF target address: e.g., an ip address or BDF', required=True) 434 p.add_argument('-f', '--adrfam', 435 help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 436 p.add_argument('-s', '--trsvcid', 437 help='NVMe-oF target trsvcid: e.g., a port number') 438 p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn') 439 p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn') 440 p.add_argument('-i', '--hostaddr', 441 help='NVMe-oF host address: e.g., an ip address') 442 p.add_argument('-c', '--hostsvcid', 443 help='NVMe-oF host svcid: e.g., a port number') 444 p.add_argument('-r', '--prchk-reftag', 445 help='Enable checking of PI reference tag for I/O processing.', action='store_true') 446 p.add_argument('-g', '--prchk-guard', 447 help='Enable checking of PI guard for I/O processing.', action='store_true') 448 p.set_defaults(func=bdev_nvme_attach_controller) 449 450 def bdev_nvme_get_controllers(args): 451 print_dict(rpc.nvme.bdev_nvme_get_controllers(args.client, 452 name=args.name)) 453 454 p = subparsers.add_parser( 455 'bdev_nvme_get_controllers', aliases=['get_nvme_controllers'], 456 help='Display current NVMe controllers list or required NVMe controller') 457 p.add_argument('-n', '--name', help="Name of the NVMe controller. Example: Nvme0", required=False) 458 p.set_defaults(func=bdev_nvme_get_controllers) 459 460 def bdev_nvme_detach_controller(args): 461 rpc.bdev.bdev_nvme_detach_controller(args.client, 462 name=args.name) 463 464 p = subparsers.add_parser('bdev_nvme_detach_controller', aliases=['delete_nvme_controller'], 465 help='Detach an NVMe controller and delete any associated bdevs') 466 p.add_argument('name', help="Name of the controller") 467 p.set_defaults(func=bdev_nvme_detach_controller) 468 469 def bdev_nvme_cuse_register(args): 470 rpc.bdev.bdev_nvme_cuse_register(args.client, 471 name=args.name) 472 473 p = subparsers.add_parser('bdev_nvme_cuse_register', 474 help='Register CUSE devices on NVMe controller') 475 p.add_argument('-n', '--name', 476 help='Name of the NVMe controller. Example: Nvme0', required=True) 477 p.set_defaults(func=bdev_nvme_cuse_register) 478 479 def bdev_nvme_cuse_unregister(args): 480 rpc.bdev.bdev_nvme_cuse_unregister(args.client, 481 name=args.name) 482 483 p = subparsers.add_parser('bdev_nvme_cuse_unregister', 484 help='Unregister CUSE devices on NVMe controller') 485 p.add_argument('-n', '--name', 486 help='Name of the NVMe controller. Example: Nvme0', required=True) 487 p.set_defaults(func=bdev_nvme_cuse_unregister) 488 489 def bdev_zone_block_create(args): 490 print_json(rpc.bdev.bdev_zone_block_create(args.client, 491 name=args.name, 492 base_bdev=args.base_bdev, 493 zone_capacity=args.zone_capacity, 494 optimal_open_zones=args.optimal_open_zones)) 495 496 p = subparsers.add_parser('bdev_zone_block_create', 497 help='Create virtual zone namespace device with block device backend') 498 p.add_argument('-b', '--name', help="Name of the zone device", required=True) 499 p.add_argument('-n', '--base-bdev', help='Name of underlying, non-zoned bdev', required=True) 500 p.add_argument('-z', '--zone-capacity', help='Surfaced zone capacity in blocks', type=int, required=True) 501 p.add_argument('-o', '--optimal-open-zones', help='Number of zones required to reach optimal write speed', type=int, required=True) 502 p.set_defaults(func=bdev_zone_block_create) 503 504 def bdev_zone_block_delete(args): 505 rpc.bdev.bdev_zone_block_delete(args.client, 506 name=args.name) 507 508 p = subparsers.add_parser('bdev_zone_block_delete', help='Delete a virtual zone namespace device') 509 p.add_argument('name', help='Virtual zone bdev name') 510 p.set_defaults(func=bdev_zone_block_delete) 511 512 def bdev_rbd_create(args): 513 config = None 514 if args.config: 515 config = {} 516 for entry in args.config: 517 parts = entry.split('=', 1) 518 if len(parts) != 2: 519 raise Exception('--config %s not in key=value form' % entry) 520 config[parts[0]] = parts[1] 521 print_json(rpc.bdev.bdev_rbd_create(args.client, 522 name=args.name, 523 user=args.user, 524 config=config, 525 pool_name=args.pool_name, 526 rbd_name=args.rbd_name, 527 block_size=args.block_size)) 528 529 p = subparsers.add_parser('bdev_rbd_create', aliases=['construct_rbd_bdev'], 530 help='Add a bdev with ceph rbd backend') 531 p.add_argument('-b', '--name', help="Name of the bdev", required=False) 532 p.add_argument('--user', help="Ceph user name (i.e. admin, not client.admin)", required=False) 533 p.add_argument('--config', action='append', metavar='key=value', 534 help="adds a key=value configuration option for rados_conf_set (default: rely on config file)") 535 p.add_argument('pool_name', help='rbd pool name') 536 p.add_argument('rbd_name', help='rbd image name') 537 p.add_argument('block_size', help='rbd block size', type=int) 538 p.set_defaults(func=bdev_rbd_create) 539 540 def bdev_rbd_delete(args): 541 rpc.bdev.bdev_rbd_delete(args.client, 542 name=args.name) 543 544 p = subparsers.add_parser('bdev_rbd_delete', aliases=['delete_rbd_bdev'], 545 help='Delete a rbd bdev') 546 p.add_argument('name', help='rbd bdev name') 547 p.set_defaults(func=bdev_rbd_delete) 548 549 def bdev_delay_create(args): 550 print_json(rpc.bdev.bdev_delay_create(args.client, 551 base_bdev_name=args.base_bdev_name, 552 name=args.name, 553 avg_read_latency=args.avg_read_latency, 554 p99_read_latency=args.nine_nine_read_latency, 555 avg_write_latency=args.avg_write_latency, 556 p99_write_latency=args.nine_nine_write_latency)) 557 558 p = subparsers.add_parser('bdev_delay_create', 559 help='Add a delay bdev on existing bdev') 560 p.add_argument('-b', '--base-bdev-name', help="Name of the existing bdev", required=True) 561 p.add_argument('-d', '--name', help="Name of the delay bdev", required=True) 562 p.add_argument('-r', '--avg-read-latency', 563 help="Average latency to apply before completing read ops (in microseconds)", required=True, type=int) 564 p.add_argument('-t', '--nine-nine-read-latency', 565 help="latency to apply to 1 in 100 read ops (in microseconds)", required=True, type=int) 566 p.add_argument('-w', '--avg-write-latency', 567 help="Average latency to apply before completing write ops (in microseconds)", required=True, type=int) 568 p.add_argument('-n', '--nine-nine-write-latency', 569 help="latency to apply to 1 in 100 write ops (in microseconds)", required=True, type=int) 570 p.set_defaults(func=bdev_delay_create) 571 572 def bdev_delay_delete(args): 573 rpc.bdev.bdev_delay_delete(args.client, 574 name=args.name) 575 576 p = subparsers.add_parser('bdev_delay_delete', help='Delete a delay bdev') 577 p.add_argument('name', help='delay bdev name') 578 p.set_defaults(func=bdev_delay_delete) 579 580 def bdev_delay_update_latency(args): 581 print_json(rpc.bdev.bdev_delay_update_latency(args.client, 582 delay_bdev_name=args.delay_bdev_name, 583 latency_type=args.latency_type, 584 latency_us=args.latency_us)) 585 p = subparsers.add_parser('bdev_delay_update_latency', 586 help='Update one of the latency values for a given delay bdev') 587 p.add_argument('delay_bdev_name', help='The name of the given delay bdev') 588 p.add_argument('latency_type', help='one of: avg_read, avg_write, p99_read, p99_write. No other values accepted.') 589 p.add_argument('latency_us', help='new latency value in microseconds.', type=int) 590 p.set_defaults(func=bdev_delay_update_latency) 591 592 def bdev_error_create(args): 593 print_json(rpc.bdev.bdev_error_create(args.client, 594 base_name=args.base_name)) 595 596 p = subparsers.add_parser('bdev_error_create', aliases=['construct_error_bdev'], 597 help='Add bdev with error injection backend') 598 p.add_argument('base_name', help='base bdev name') 599 p.set_defaults(func=bdev_error_create) 600 601 def bdev_error_delete(args): 602 rpc.bdev.bdev_error_delete(args.client, 603 name=args.name) 604 605 p = subparsers.add_parser('bdev_error_delete', aliases=['delete_error_bdev'], 606 help='Delete an error bdev') 607 p.add_argument('name', help='error bdev name') 608 p.set_defaults(func=bdev_error_delete) 609 610 def bdev_iscsi_create(args): 611 print_json(rpc.bdev.bdev_iscsi_create(args.client, 612 name=args.name, 613 url=args.url, 614 initiator_iqn=args.initiator_iqn)) 615 616 p = subparsers.add_parser('bdev_iscsi_create', aliases=['construct_iscsi_bdev'], 617 help='Add bdev with iSCSI initiator backend') 618 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 619 p.add_argument('-i', '--initiator-iqn', help="Initiator IQN", required=True) 620 p.add_argument('--url', help="iSCSI Lun URL", required=True) 621 p.set_defaults(func=bdev_iscsi_create) 622 623 def bdev_iscsi_delete(args): 624 rpc.bdev.bdev_iscsi_delete(args.client, 625 name=args.name) 626 627 p = subparsers.add_parser('bdev_iscsi_delete', aliases=['delete_iscsi_bdev'], 628 help='Delete an iSCSI bdev') 629 p.add_argument('name', help='iSCSI bdev name') 630 p.set_defaults(func=bdev_iscsi_delete) 631 632 def bdev_pmem_create(args): 633 print_json(rpc.bdev.bdev_pmem_create(args.client, 634 pmem_file=args.pmem_file, 635 name=args.name)) 636 637 p = subparsers.add_parser('bdev_pmem_create', aliases=['construct_pmem_bdev'], 638 help='Add a bdev with pmem backend') 639 p.add_argument('pmem_file', help='Path to pmemblk pool file') 640 p.add_argument('-n', '--name', help='Block device name', required=True) 641 p.set_defaults(func=bdev_pmem_create) 642 643 def bdev_pmem_delete(args): 644 rpc.bdev.bdev_pmem_delete(args.client, 645 name=args.name) 646 647 p = subparsers.add_parser('bdev_pmem_delete', aliases=['delete_pmem_bdev'], 648 help='Delete a pmem bdev') 649 p.add_argument('name', help='pmem bdev name') 650 p.set_defaults(func=bdev_pmem_delete) 651 652 def bdev_passthru_create(args): 653 print_json(rpc.bdev.bdev_passthru_create(args.client, 654 base_bdev_name=args.base_bdev_name, 655 name=args.name)) 656 657 p = subparsers.add_parser('bdev_passthru_create', aliases=['construct_passthru_bdev'], 658 help='Add a pass through bdev on existing bdev') 659 p.add_argument('-b', '--base-bdev-name', help="Name of the existing bdev", required=True) 660 p.add_argument('-p', '--name', help="Name of the pass through bdev", required=True) 661 p.set_defaults(func=bdev_passthru_create) 662 663 def bdev_passthru_delete(args): 664 rpc.bdev.bdev_passthru_delete(args.client, 665 name=args.name) 666 667 p = subparsers.add_parser('bdev_passthru_delete', aliases=['delete_passthru_bdev'], 668 help='Delete a pass through bdev') 669 p.add_argument('name', help='pass through bdev name') 670 p.set_defaults(func=bdev_passthru_delete) 671 672 def bdev_get_bdevs(args): 673 print_dict(rpc.bdev.bdev_get_bdevs(args.client, 674 name=args.name)) 675 676 p = subparsers.add_parser('bdev_get_bdevs', aliases=['get_bdevs'], 677 help='Display current blockdev list or required blockdev') 678 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1", required=False) 679 p.set_defaults(func=bdev_get_bdevs) 680 681 def bdev_get_iostat(args): 682 print_dict(rpc.bdev.bdev_get_iostat(args.client, 683 name=args.name)) 684 685 p = subparsers.add_parser('bdev_get_iostat', aliases=['get_bdevs_iostat'], 686 help='Display current I/O statistics of all the blockdevs or required blockdev.') 687 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1", required=False) 688 p.set_defaults(func=bdev_get_iostat) 689 690 def bdev_enable_histogram(args): 691 rpc.bdev.bdev_enable_histogram(args.client, name=args.name, enable=args.enable) 692 693 p = subparsers.add_parser('bdev_enable_histogram', aliases=['enable_bdev_histogram'], 694 help='Enable or disable histogram for specified bdev') 695 p.add_argument('-e', '--enable', default=True, dest='enable', action='store_true', help='Enable histograms on specified device') 696 p.add_argument('-d', '--disable', dest='enable', action='store_false', help='Disable histograms on specified device') 697 p.add_argument('name', help='bdev name') 698 p.set_defaults(func=bdev_enable_histogram) 699 700 def bdev_get_histogram(args): 701 print_dict(rpc.bdev.bdev_get_histogram(args.client, name=args.name)) 702 703 p = subparsers.add_parser('bdev_get_histogram', aliases=['get_bdev_histogram'], 704 help='Get histogram for specified bdev') 705 p.add_argument('name', help='bdev name') 706 p.set_defaults(func=bdev_get_histogram) 707 708 def bdev_set_qd_sampling_period(args): 709 rpc.bdev.bdev_set_qd_sampling_period(args.client, 710 name=args.name, 711 period=args.period) 712 713 p = subparsers.add_parser('bdev_set_qd_sampling_period', aliases=['set_bdev_qd_sampling_period'], 714 help="Enable or disable tracking of a bdev's queue depth.") 715 p.add_argument('name', help='Blockdev name. Example: Malloc0') 716 p.add_argument('period', help='Period with which to poll the block device queue depth in microseconds.' 717 ' If set to 0, polling will be disabled.', 718 type=int) 719 p.set_defaults(func=bdev_set_qd_sampling_period) 720 721 def bdev_set_qos_limit(args): 722 rpc.bdev.bdev_set_qos_limit(args.client, 723 name=args.name, 724 rw_ios_per_sec=args.rw_ios_per_sec, 725 rw_mbytes_per_sec=args.rw_mbytes_per_sec, 726 r_mbytes_per_sec=args.r_mbytes_per_sec, 727 w_mbytes_per_sec=args.w_mbytes_per_sec) 728 729 p = subparsers.add_parser('bdev_set_qos_limit', aliases=['set_bdev_qos_limit'], 730 help='Set QoS rate limit on a blockdev') 731 p.add_argument('name', help='Blockdev name to set QoS. Example: Malloc0') 732 p.add_argument('--rw_ios_per_sec', 733 help='R/W IOs per second limit (>=10000, example: 20000). 0 means unlimited.', 734 type=int, required=False) 735 p.add_argument('--rw_mbytes_per_sec', 736 help="R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.", 737 type=int, required=False) 738 p.add_argument('--r_mbytes_per_sec', 739 help="Read megabytes per second limit (>=10, example: 100). 0 means unlimited.", 740 type=int, required=False) 741 p.add_argument('--w_mbytes_per_sec', 742 help="Write megabytes per second limit (>=10, example: 100). 0 means unlimited.", 743 type=int, required=False) 744 p.set_defaults(func=bdev_set_qos_limit) 745 746 def bdev_error_inject_error(args): 747 rpc.bdev.bdev_error_inject_error(args.client, 748 name=args.name, 749 io_type=args.io_type, 750 error_type=args.error_type, 751 num=args.num) 752 753 p = subparsers.add_parser('bdev_error_inject_error', aliases=['bdev_inject_error'], 754 help='bdev inject error') 755 p.add_argument('name', help="""the name of the error injection bdev""") 756 p.add_argument('io_type', help="""io_type: 'clear' 'read' 'write' 'unmap' 'flush' 'all'""") 757 p.add_argument('error_type', help="""error_type: 'failure' 'pending'""") 758 p.add_argument( 759 '-n', '--num', help='the number of commands you want to fail', type=int, default=1) 760 p.set_defaults(func=bdev_error_inject_error) 761 762 def bdev_nvme_apply_firmware(args): 763 print_dict(rpc.bdev.bdev_nvme_apply_firmware(args.client, 764 bdev_name=args.bdev_name, 765 filename=args.filename)) 766 767 p = subparsers.add_parser('bdev_nvme_apply_firmware', aliases=['apply_firmware'], 768 help='Download and commit firmware to NVMe device') 769 p.add_argument('filename', help='filename of the firmware to download') 770 p.add_argument('bdev_name', help='name of the NVMe device') 771 p.set_defaults(func=bdev_nvme_apply_firmware) 772 773 # iSCSI 774 def iscsi_set_options(args): 775 rpc.iscsi.iscsi_set_options( 776 args.client, 777 auth_file=args.auth_file, 778 node_base=args.node_base, 779 nop_timeout=args.nop_timeout, 780 nop_in_interval=args.nop_in_interval, 781 disable_chap=args.disable_chap, 782 require_chap=args.require_chap, 783 mutual_chap=args.mutual_chap, 784 chap_group=args.chap_group, 785 max_sessions=args.max_sessions, 786 max_queue_depth=args.max_queue_depth, 787 max_connections_per_session=args.max_connections_per_session, 788 default_time2wait=args.default_time2wait, 789 default_time2retain=args.default_time2retain, 790 first_burst_length=args.first_burst_length, 791 immediate_data=args.immediate_data, 792 error_recovery_level=args.error_recovery_level, 793 allow_duplicated_isid=args.allow_duplicated_isid) 794 795 p = subparsers.add_parser('iscsi_set_options', aliases=['set_iscsi_options'], 796 help="""Set options of iSCSI subsystem""") 797 p.add_argument('-f', '--auth-file', help='Path to CHAP shared secret file') 798 p.add_argument('-b', '--node-base', help='Prefix of the name of iSCSI target node') 799 p.add_argument('-o', '--nop-timeout', help='Timeout in seconds to nop-in request to the initiator', type=int) 800 p.add_argument('-n', '--nop-in-interval', help='Time interval in secs between nop-in requests by the target', type=int) 801 p.add_argument('-d', '--disable-chap', help="""CHAP for discovery session should be disabled. 802 *** Mutually exclusive with --require-chap""", action='store_true') 803 p.add_argument('-r', '--require-chap', help="""CHAP for discovery session should be required. 804 *** Mutually exclusive with --disable-chap""", action='store_true') 805 p.add_argument('-m', '--mutual-chap', help='CHAP for discovery session should be mutual', action='store_true') 806 p.add_argument('-g', '--chap-group', help="""Authentication group ID for discovery session. 807 *** Authentication group must be precreated ***""", type=int) 808 p.add_argument('-a', '--max-sessions', help='Maximum number of sessions in the host.', type=int) 809 p.add_argument('-q', '--max-queue-depth', help='Max number of outstanding I/Os per queue.', type=int) 810 p.add_argument('-c', '--max-connections-per-session', help='Negotiated parameter, MaxConnections.', type=int) 811 p.add_argument('-w', '--default-time2wait', help='Negotiated parameter, DefaultTime2Wait.', type=int) 812 p.add_argument('-v', '--default-time2retain', help='Negotiated parameter, DefaultTime2Retain.', type=int) 813 p.add_argument('-s', '--first-burst-length', help='Negotiated parameter, FirstBurstLength.', type=int) 814 p.add_argument('-i', '--immediate-data', help='Negotiated parameter, ImmediateData.', action='store_true') 815 p.add_argument('-l', '--error-recovery-level', help='Negotiated parameter, ErrorRecoveryLevel', type=int) 816 p.add_argument('-p', '--allow-duplicated-isid', help='Allow duplicated initiator session ID.', action='store_true') 817 p.set_defaults(func=iscsi_set_options) 818 819 def iscsi_set_discovery_auth(args): 820 rpc.iscsi.iscsi_set_discovery_auth( 821 args.client, 822 disable_chap=args.disable_chap, 823 require_chap=args.require_chap, 824 mutual_chap=args.mutual_chap, 825 chap_group=args.chap_group) 826 827 p = subparsers.add_parser('iscsi_set_discovery_auth', aliases=['set_iscsi_discovery_auth'], 828 help="""Set CHAP authentication for discovery session.""") 829 p.add_argument('-d', '--disable-chap', help="""CHAP for discovery session should be disabled. 830 *** Mutually exclusive with --require-chap""", action='store_true') 831 p.add_argument('-r', '--require-chap', help="""CHAP for discovery session should be required. 832 *** Mutually exclusive with --disable-chap""", action='store_true') 833 p.add_argument('-m', '--mutual-chap', help='CHAP for discovery session should be mutual', action='store_true') 834 p.add_argument('-g', '--chap-group', help="""Authentication group ID for discovery session. 835 *** Authentication group must be precreated ***""", type=int) 836 p.set_defaults(func=iscsi_set_discovery_auth) 837 838 def iscsi_create_auth_group(args): 839 secrets = None 840 if args.secrets: 841 secrets = [dict(u.split(":") for u in a.split(" ")) for a in args.secrets.split(",")] 842 843 rpc.iscsi.iscsi_create_auth_group(args.client, tag=args.tag, secrets=secrets) 844 845 p = subparsers.add_parser('iscsi_create_auth_group', aliases=['add_iscsi_auth_group'], 846 help='Create authentication group for CHAP authentication.') 847 p.add_argument('tag', help='Authentication group tag (unique, integer > 0).', type=int) 848 p.add_argument('-c', '--secrets', help="""Comma-separated list of CHAP secrets 849<user:user_name secret:chap_secret muser:mutual_user_name msecret:mutual_chap_secret> enclosed in quotes. 850Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 msecret:ms2'""", required=False) 851 p.set_defaults(func=iscsi_create_auth_group) 852 853 def iscsi_delete_auth_group(args): 854 rpc.iscsi.iscsi_delete_auth_group(args.client, tag=args.tag) 855 856 p = subparsers.add_parser('iscsi_delete_auth_group', aliases=['delete_iscsi_auth_group'], 857 help='Delete an authentication group.') 858 p.add_argument('tag', help='Authentication group tag', type=int) 859 p.set_defaults(func=iscsi_delete_auth_group) 860 861 def iscsi_auth_group_add_secret(args): 862 rpc.iscsi.iscsi_auth_group_add_secret( 863 args.client, 864 tag=args.tag, 865 user=args.user, 866 secret=args.secret, 867 muser=args.muser, 868 msecret=args.msecret) 869 870 p = subparsers.add_parser('iscsi_auth_group_add_secret', aliases=['add_secret_to_iscsi_auth_group'], 871 help='Add a secret to an authentication group.') 872 p.add_argument('tag', help='Authentication group tag', type=int) 873 p.add_argument('-u', '--user', help='User name for one-way CHAP authentication', required=True) 874 p.add_argument('-s', '--secret', help='Secret for one-way CHAP authentication', required=True) 875 p.add_argument('-m', '--muser', help='User name for mutual CHAP authentication') 876 p.add_argument('-r', '--msecret', help='Secret for mutual CHAP authentication') 877 p.set_defaults(func=iscsi_auth_group_add_secret) 878 879 def iscsi_auth_group_remove_secret(args): 880 rpc.iscsi.iscsi_auth_group_remove_secret(args.client, tag=args.tag, user=args.user) 881 882 p = subparsers.add_parser('iscsi_auth_group_remove_secret', aliases=['delete_secret_from_iscsi_auth_group'], 883 help='Remove a secret from an authentication group.') 884 p.add_argument('tag', help='Authentication group tag', type=int) 885 p.add_argument('-u', '--user', help='User name for one-way CHAP authentication', required=True) 886 p.set_defaults(func=iscsi_auth_group_remove_secret) 887 888 def iscsi_get_auth_groups(args): 889 print_dict(rpc.iscsi.iscsi_get_auth_groups(args.client)) 890 891 p = subparsers.add_parser('iscsi_get_auth_groups', aliases=['get_iscsi_auth_groups'], 892 help='Display current authentication group configuration') 893 p.set_defaults(func=iscsi_get_auth_groups) 894 895 def iscsi_get_portal_groups(args): 896 print_dict(rpc.iscsi.iscsi_get_portal_groups(args.client)) 897 898 p = subparsers.add_parser( 899 'iscsi_get_portal_groups', aliases=['get_portal_groups'], 900 help='Display current portal group configuration') 901 p.set_defaults(func=iscsi_get_portal_groups) 902 903 def iscsi_get_initiator_groups(args): 904 print_dict(rpc.iscsi.iscsi_get_initiator_groups(args.client)) 905 906 p = subparsers.add_parser('iscsi_get_initiator_groups', 907 aliases=['get_initiator_groups'], 908 help='Display current initiator group configuration') 909 p.set_defaults(func=iscsi_get_initiator_groups) 910 911 def iscsi_get_target_nodes(args): 912 print_dict(rpc.iscsi.iscsi_get_target_nodes(args.client)) 913 914 p = subparsers.add_parser('iscsi_get_target_nodes', aliases=['get_target_nodes'], 915 help='Display target nodes') 916 p.set_defaults(func=iscsi_get_target_nodes) 917 918 def iscsi_create_target_node(args): 919 luns = [] 920 for u in args.bdev_name_id_pairs.strip().split(" "): 921 bdev_name, lun_id = u.split(":") 922 luns.append({"bdev_name": bdev_name, "lun_id": int(lun_id)}) 923 924 pg_ig_maps = [] 925 for u in args.pg_ig_mappings.strip().split(" "): 926 pg, ig = u.split(":") 927 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 928 929 rpc.iscsi.iscsi_create_target_node( 930 args.client, 931 luns=luns, 932 pg_ig_maps=pg_ig_maps, 933 name=args.name, 934 alias_name=args.alias_name, 935 queue_depth=args.queue_depth, 936 chap_group=args.chap_group, 937 disable_chap=args.disable_chap, 938 require_chap=args.require_chap, 939 mutual_chap=args.mutual_chap, 940 header_digest=args.header_digest, 941 data_digest=args.data_digest) 942 943 p = subparsers.add_parser('iscsi_create_target_node', aliases=['construct_target_node'], 944 help='Add a target node') 945 p.add_argument('name', help='Target node name (ASCII)') 946 p.add_argument('alias_name', help='Target node alias name (ASCII)') 947 p.add_argument('bdev_name_id_pairs', help="""Whitespace-separated list of <bdev name:LUN ID> pairs enclosed 948 in quotes. Format: 'bdev_name0:id0 bdev_name1:id1' etc 949 Example: 'Malloc0:0 Malloc1:1 Malloc5:2' 950 *** The bdevs must pre-exist *** 951 *** LUN0 (id = 0) is required *** 952 *** bdevs names cannot contain space or colon characters ***""") 953 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 954 Whitespace separated, quoted, mapping defined with colon 955 separated list of "tags" (int > 0) 956 Example: '1:1 2:2 2:1' 957 *** The Portal/Initiator Groups must be precreated ***""") 958 p.add_argument('queue_depth', help='Desired target queue depth', type=int) 959 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this target node. 960 *** Authentication group must be precreated ***""", type=int, default=0) 961 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this target node. 962 *** Mutually exclusive with --require-chap ***""", action='store_true') 963 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this target node. 964 *** Mutually exclusive with --disable-chap ***""", action='store_true') 965 p.add_argument( 966 '-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', action='store_true') 967 p.add_argument('-H', '--header-digest', 968 help='Header Digest should be required for this target node.', action='store_true') 969 p.add_argument('-D', '--data-digest', 970 help='Data Digest should be required for this target node.', action='store_true') 971 p.set_defaults(func=iscsi_create_target_node) 972 973 def iscsi_target_node_add_lun(args): 974 rpc.iscsi.iscsi_target_node_add_lun( 975 args.client, 976 name=args.name, 977 bdev_name=args.bdev_name, 978 lun_id=args.lun_id) 979 980 p = subparsers.add_parser('iscsi_target_node_add_lun', aliases=['target_node_add_lun'], 981 help='Add LUN to the target node') 982 p.add_argument('name', help='Target node name (ASCII)') 983 p.add_argument('bdev_name', help="""bdev name enclosed in quotes. 984 *** bdev name cannot contain space or colon characters ***""") 985 p.add_argument('-i', dest='lun_id', help="""LUN ID (integer >= 0) 986 *** If LUN ID is omitted or -1, the lowest free one is assigned ***""", type=int, required=False) 987 p.set_defaults(func=iscsi_target_node_add_lun) 988 989 def iscsi_target_node_set_auth(args): 990 rpc.iscsi.iscsi_target_node_set_auth( 991 args.client, 992 name=args.name, 993 chap_group=args.chap_group, 994 disable_chap=args.disable_chap, 995 require_chap=args.require_chap, 996 mutual_chap=args.mutual_chap) 997 998 p = subparsers.add_parser('iscsi_target_node_set_auth', aliases=['set_iscsi_target_node_auth'], 999 help='Set CHAP authentication for the target node') 1000 p.add_argument('name', help='Target node name (ASCII)') 1001 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this target node. 1002 *** Authentication group must be precreated ***""", type=int, default=0) 1003 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this target node. 1004 *** Mutually exclusive with --require-chap ***""", action='store_true') 1005 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this target node. 1006 *** Mutually exclusive with --disable-chap ***""", action='store_true') 1007 p.add_argument('-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', 1008 action='store_true') 1009 p.set_defaults(func=iscsi_target_node_set_auth) 1010 1011 def iscsi_target_node_add_pg_ig_maps(args): 1012 pg_ig_maps = [] 1013 for u in args.pg_ig_mappings.strip().split(" "): 1014 pg, ig = u.split(":") 1015 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 1016 rpc.iscsi.iscsi_target_node_add_pg_ig_maps( 1017 args.client, 1018 pg_ig_maps=pg_ig_maps, 1019 name=args.name) 1020 1021 p = subparsers.add_parser('iscsi_target_node_add_pg_ig_maps', 1022 aliases=['add_pg_ig_maps'], 1023 help='Add PG-IG maps to the target node') 1024 p.add_argument('name', help='Target node name (ASCII)') 1025 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 1026 Whitespace separated, quoted, mapping defined with colon 1027 separated list of "tags" (int > 0) 1028 Example: '1:1 2:2 2:1' 1029 *** The Portal/Initiator Groups must be precreated ***""") 1030 p.set_defaults(func=iscsi_target_node_add_pg_ig_maps) 1031 1032 def iscsi_target_node_remove_pg_ig_maps(args): 1033 pg_ig_maps = [] 1034 for u in args.pg_ig_mappings.strip().split(" "): 1035 pg, ig = u.split(":") 1036 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 1037 rpc.iscsi.iscsi_target_node_remove_pg_ig_maps( 1038 args.client, pg_ig_maps=pg_ig_maps, name=args.name) 1039 1040 p = subparsers.add_parser('iscsi_target_node_remove_pg_ig_maps', 1041 aliases=['delete_pg_ig_maps'], 1042 help='Delete PG-IG maps from the target node') 1043 p.add_argument('name', help='Target node name (ASCII)') 1044 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 1045 Whitespace separated, quoted, mapping defined with colon 1046 separated list of "tags" (int > 0) 1047 Example: '1:1 2:2 2:1' 1048 *** The Portal/Initiator Groups must be precreated ***""") 1049 p.set_defaults(func=iscsi_target_node_remove_pg_ig_maps) 1050 1051 def iscsi_create_portal_group(args): 1052 portals = [] 1053 for p in args.portal_list.strip().split(' '): 1054 ip, separator, port_cpumask = p.rpartition(':') 1055 split_port_cpumask = port_cpumask.split('@') 1056 if len(split_port_cpumask) == 1: 1057 port = port_cpumask 1058 portals.append({'host': ip, 'port': port}) 1059 else: 1060 port = split_port_cpumask[0] 1061 cpumask = split_port_cpumask[1] 1062 portals.append({'host': ip, 'port': port}) 1063 print("WARNING: Specifying a portal group with a CPU mask is no longer supported. Ignoring it.") 1064 rpc.iscsi.iscsi_create_portal_group( 1065 args.client, 1066 portals=portals, 1067 tag=args.tag) 1068 1069 p = subparsers.add_parser('iscsi_create_portal_group', aliases=['add_portal_group'], 1070 help='Add a portal group') 1071 p.add_argument( 1072 'tag', help='Portal group tag (unique, integer > 0)', type=int) 1073 p.add_argument('portal_list', help="""List of portals in host:port format, separated by whitespace 1074 Example: '192.168.100.100:3260 192.168.100.100:3261 192.168.100.100:3262""") 1075 p.set_defaults(func=iscsi_create_portal_group) 1076 1077 def iscsi_create_initiator_group(args): 1078 initiators = [] 1079 netmasks = [] 1080 for i in args.initiator_list.strip().split(' '): 1081 initiators.append(i) 1082 for n in args.netmask_list.strip().split(' '): 1083 netmasks.append(n) 1084 rpc.iscsi.iscsi_create_initiator_group( 1085 args.client, 1086 tag=args.tag, 1087 initiators=initiators, 1088 netmasks=netmasks) 1089 1090 p = subparsers.add_parser('iscsi_create_initiator_group', aliases=['add_initiator_group'], 1091 help='Add an initiator group') 1092 p.add_argument( 1093 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1094 p.add_argument('initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1095 enclosed in quotes. Example: 'ANY' or '127.0.0.1 192.168.200.100'""") 1096 p.add_argument('netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1097 Example: '255.255.0.0 255.248.0.0' etc""") 1098 p.set_defaults(func=iscsi_create_initiator_group) 1099 1100 def iscsi_initiator_group_add_initiators(args): 1101 initiators = None 1102 netmasks = None 1103 if args.initiator_list: 1104 initiators = [] 1105 for i in args.initiator_list.strip().split(' '): 1106 initiators.append(i) 1107 if args.netmask_list: 1108 netmasks = [] 1109 for n in args.netmask_list.strip().split(' '): 1110 netmasks.append(n) 1111 rpc.iscsi.iscsi_initiator_group_add_initiators( 1112 args.client, 1113 tag=args.tag, 1114 initiators=initiators, 1115 netmasks=netmasks) 1116 1117 p = subparsers.add_parser('iscsi_initiator_group_add_initiators', 1118 aliases=['add_initiators_to_initiator_group'], 1119 help='Add initiators to an existing initiator group') 1120 p.add_argument( 1121 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1122 p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1123 enclosed in quotes. This parameter can be omitted. Example: 'ANY' or '127.0.0.1 192.168.200.100'""", required=False) 1124 p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1125 This parameter can be omitted. Example: '255.255.0.0 255.248.0.0' etc""", required=False) 1126 p.set_defaults(func=iscsi_initiator_group_add_initiators) 1127 1128 def iscsi_initiator_group_remove_initiators(args): 1129 initiators = None 1130 netmasks = None 1131 if args.initiator_list: 1132 initiators = [] 1133 for i in args.initiator_list.strip().split(' '): 1134 initiators.append(i) 1135 if args.netmask_list: 1136 netmasks = [] 1137 for n in args.netmask_list.strip().split(' '): 1138 netmasks.append(n) 1139 rpc.iscsi.iscsi_initiator_group_remove_initiators( 1140 args.client, 1141 tag=args.tag, 1142 initiators=initiators, 1143 netmasks=netmasks) 1144 1145 p = subparsers.add_parser('iscsi_initiator_group_remove_initiators', 1146 aliases=['delete_initiators_from_initiator_group'], 1147 help='Delete initiators from an existing initiator group') 1148 p.add_argument( 1149 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1150 p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1151 enclosed in quotes. This parameter can be omitted. Example: 'ANY' or '127.0.0.1 192.168.200.100'""", required=False) 1152 p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1153 This parameter can be omitted. Example: '255.255.0.0 255.248.0.0' etc""", required=False) 1154 p.set_defaults(func=iscsi_initiator_group_remove_initiators) 1155 1156 def iscsi_delete_target_node(args): 1157 rpc.iscsi.iscsi_delete_target_node( 1158 args.client, target_node_name=args.target_node_name) 1159 1160 p = subparsers.add_parser('iscsi_delete_target_node', aliases=['delete_target_node'], 1161 help='Delete a target node') 1162 p.add_argument('target_node_name', 1163 help='Target node name to be deleted. Example: iqn.2016-06.io.spdk:disk1.') 1164 p.set_defaults(func=iscsi_delete_target_node) 1165 1166 def iscsi_delete_portal_group(args): 1167 rpc.iscsi.iscsi_delete_portal_group(args.client, tag=args.tag) 1168 1169 p = subparsers.add_parser('iscsi_delete_portal_group', 1170 aliases=['delete_portal_group'], 1171 help='Delete a portal group') 1172 p.add_argument( 1173 'tag', help='Portal group tag (unique, integer > 0)', type=int) 1174 p.set_defaults(func=iscsi_delete_portal_group) 1175 1176 def iscsi_delete_initiator_group(args): 1177 rpc.iscsi.iscsi_delete_initiator_group(args.client, tag=args.tag) 1178 1179 p = subparsers.add_parser('iscsi_delete_initiator_group', 1180 aliases=['delete_initiator_group'], 1181 help='Delete an initiator group') 1182 p.add_argument( 1183 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1184 p.set_defaults(func=iscsi_delete_initiator_group) 1185 1186 def iscsi_portal_group_set_auth(args): 1187 rpc.iscsi.iscsi_portal_group_set_auth( 1188 args.client, 1189 tag=args.tag, 1190 chap_group=args.chap_group, 1191 disable_chap=args.disable_chap, 1192 require_chap=args.require_chap, 1193 mutual_chap=args.mutual_chap) 1194 1195 p = subparsers.add_parser('iscsi_portal_group_set_auth', 1196 help='Set CHAP authentication for discovery sessions specific for the portal group') 1197 p.add_argument('tag', help='Portal group tag (unique, integer > 0)', type=int) 1198 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this portal group. 1199 *** Authentication group must be precreated ***""", type=int, default=0) 1200 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this portal group. 1201 *** Mutually exclusive with --require-chap ***""", action='store_true') 1202 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this portal group. 1203 *** Mutually exclusive with --disable-chap ***""", action='store_true') 1204 p.add_argument('-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', 1205 action='store_true') 1206 p.set_defaults(func=iscsi_portal_group_set_auth) 1207 1208 def iscsi_get_connections(args): 1209 print_dict(rpc.iscsi.iscsi_get_connections(args.client)) 1210 1211 p = subparsers.add_parser('iscsi_get_connections', aliases=['get_iscsi_connections'], 1212 help='Display iSCSI connections') 1213 p.set_defaults(func=iscsi_get_connections) 1214 1215 def iscsi_get_options(args): 1216 print_dict(rpc.iscsi.iscsi_get_options(args.client)) 1217 1218 p = subparsers.add_parser('iscsi_get_options', aliases=['get_iscsi_global_params'], 1219 help='Display iSCSI global parameters') 1220 p.set_defaults(func=iscsi_get_options) 1221 1222 def scsi_get_devices(args): 1223 print_dict(rpc.iscsi.scsi_get_devices(args.client)) 1224 1225 p = subparsers.add_parser('scsi_get_devices', aliases=['get_scsi_devices'], 1226 help='Display SCSI devices') 1227 p.set_defaults(func=scsi_get_devices) 1228 1229 # trace 1230 def trace_enable_tpoint_group(args): 1231 rpc.trace.trace_enable_tpoint_group(args.client, name=args.name) 1232 1233 p = subparsers.add_parser('trace_enable_tpoint_group', aliases=['enable_tpoint_group'], 1234 help='enable trace on a specific tpoint group') 1235 p.add_argument( 1236 'name', help="""trace group name we want to enable in tpoint_group_mask. 1237 (for example "bdev" for bdev trace group, "all" for all trace groups).""") 1238 p.set_defaults(func=trace_enable_tpoint_group) 1239 1240 def trace_disable_tpoint_group(args): 1241 rpc.trace.trace_disable_tpoint_group(args.client, name=args.name) 1242 1243 p = subparsers.add_parser('trace_disable_tpoint_group', aliases=['disable_tpoint_group'], 1244 help='disable trace on a specific tpoint group') 1245 p.add_argument( 1246 'name', help="""trace group name we want to disable in tpoint_group_mask. 1247 (for example "bdev" for bdev trace group, "all" for all trace groups).""") 1248 p.set_defaults(func=trace_disable_tpoint_group) 1249 1250 def trace_get_tpoint_group_mask(args): 1251 print_dict(rpc.trace.trace_get_tpoint_group_mask(args.client)) 1252 1253 p = subparsers.add_parser('trace_get_tpoint_group_mask', aliases=['get_tpoint_group_mask'], 1254 help='get trace point group mask') 1255 p.set_defaults(func=trace_get_tpoint_group_mask) 1256 1257 # log 1258 def log_set_flag(args): 1259 rpc.log.log_set_flag(args.client, flag=args.flag) 1260 1261 p = subparsers.add_parser('log_set_flag', help='set log flag', aliases=['set_log_flag']) 1262 p.add_argument( 1263 'flag', help='log flag we want to set. (for example "nvme").') 1264 p.set_defaults(func=log_set_flag) 1265 1266 def log_clear_flag(args): 1267 rpc.log.log_clear_flag(args.client, flag=args.flag) 1268 1269 p = subparsers.add_parser('log_clear_flag', help='clear log flag', aliases=['clear_log_flag']) 1270 p.add_argument( 1271 'flag', help='log flag we want to clear. (for example "nvme").') 1272 p.set_defaults(func=log_clear_flag) 1273 1274 def log_get_flags(args): 1275 print_dict(rpc.log.log_get_flags(args.client)) 1276 1277 p = subparsers.add_parser('log_get_flags', help='get log flags', aliases=['get_log_flags']) 1278 p.set_defaults(func=log_get_flags) 1279 1280 def log_set_level(args): 1281 rpc.log.log_set_level(args.client, level=args.level) 1282 1283 p = subparsers.add_parser('log_set_level', aliases=['set_log_level'], 1284 help='set log level') 1285 p.add_argument('level', help='log level we want to set. (for example "DEBUG").') 1286 p.set_defaults(func=log_set_level) 1287 1288 def log_get_level(args): 1289 print_dict(rpc.log.log_get_level(args.client)) 1290 1291 p = subparsers.add_parser('log_get_level', aliases=['get_log_level'], 1292 help='get log level') 1293 p.set_defaults(func=log_get_level) 1294 1295 def log_set_print_level(args): 1296 rpc.log.log_set_print_level(args.client, level=args.level) 1297 1298 p = subparsers.add_parser('log_set_print_level', aliases=['set_log_print_level'], 1299 help='set log print level') 1300 p.add_argument('level', help='log print level we want to set. (for example "DEBUG").') 1301 p.set_defaults(func=log_set_print_level) 1302 1303 def log_get_print_level(args): 1304 print_dict(rpc.log.log_get_print_level(args.client)) 1305 1306 p = subparsers.add_parser('log_get_print_level', aliases=['get_log_print_level'], 1307 help='get log print level') 1308 p.set_defaults(func=log_get_print_level) 1309 1310 # lvol 1311 def bdev_lvol_create_lvstore(args): 1312 print_json(rpc.lvol.bdev_lvol_create_lvstore(args.client, 1313 bdev_name=args.bdev_name, 1314 lvs_name=args.lvs_name, 1315 cluster_sz=args.cluster_sz, 1316 clear_method=args.clear_method)) 1317 1318 p = subparsers.add_parser('bdev_lvol_create_lvstore', aliases=['construct_lvol_store'], 1319 help='Add logical volume store on base bdev') 1320 p.add_argument('bdev_name', help='base bdev name') 1321 p.add_argument('lvs_name', help='name for lvol store') 1322 p.add_argument('-c', '--cluster-sz', help='size of cluster (in bytes)', type=int, required=False) 1323 p.add_argument('--clear-method', help="""Change clear method for data region. 1324 Available: none, unmap, write_zeroes""", required=False) 1325 p.set_defaults(func=bdev_lvol_create_lvstore) 1326 1327 def bdev_lvol_rename_lvstore(args): 1328 rpc.lvol.bdev_lvol_rename_lvstore(args.client, 1329 old_name=args.old_name, 1330 new_name=args.new_name) 1331 1332 p = subparsers.add_parser('bdev_lvol_rename_lvstore', aliases=['rename_lvol_store'], 1333 help='Change logical volume store name') 1334 p.add_argument('old_name', help='old name') 1335 p.add_argument('new_name', help='new name') 1336 p.set_defaults(func=bdev_lvol_rename_lvstore) 1337 1338 def bdev_lvol_create(args): 1339 print_json(rpc.lvol.bdev_lvol_create(args.client, 1340 lvol_name=args.lvol_name, 1341 size=args.size * 1024 * 1024, 1342 thin_provision=args.thin_provision, 1343 clear_method=args.clear_method, 1344 uuid=args.uuid, 1345 lvs_name=args.lvs_name)) 1346 1347 p = subparsers.add_parser('bdev_lvol_create', aliases=['construct_lvol_bdev'], 1348 help='Add a bdev with an logical volume backend') 1349 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 1350 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 1351 p.add_argument('-t', '--thin-provision', action='store_true', help='create lvol bdev as thin provisioned') 1352 p.add_argument('-c', '--clear-method', help="""Change default data clusters clear method. 1353 Available: none, unmap, write_zeroes""", required=False) 1354 p.add_argument('lvol_name', help='name for this lvol') 1355 p.add_argument('size', help='size in MiB for this bdev', type=int) 1356 p.set_defaults(func=bdev_lvol_create) 1357 1358 def bdev_lvol_snapshot(args): 1359 print_json(rpc.lvol.bdev_lvol_snapshot(args.client, 1360 lvol_name=args.lvol_name, 1361 snapshot_name=args.snapshot_name)) 1362 1363 p = subparsers.add_parser('bdev_lvol_snapshot', aliases=['snapshot_lvol_bdev'], 1364 help='Create a snapshot of an lvol bdev') 1365 p.add_argument('lvol_name', help='lvol bdev name') 1366 p.add_argument('snapshot_name', help='lvol snapshot name') 1367 p.set_defaults(func=bdev_lvol_snapshot) 1368 1369 def bdev_lvol_clone(args): 1370 print_json(rpc.lvol.bdev_lvol_clone(args.client, 1371 snapshot_name=args.snapshot_name, 1372 clone_name=args.clone_name)) 1373 1374 p = subparsers.add_parser('bdev_lvol_clone', aliases=['clone_lvol_bdev'], 1375 help='Create a clone of an lvol snapshot') 1376 p.add_argument('snapshot_name', help='lvol snapshot name') 1377 p.add_argument('clone_name', help='lvol clone name') 1378 p.set_defaults(func=bdev_lvol_clone) 1379 1380 def bdev_lvol_rename(args): 1381 rpc.lvol.bdev_lvol_rename(args.client, 1382 old_name=args.old_name, 1383 new_name=args.new_name) 1384 1385 p = subparsers.add_parser('bdev_lvol_rename', aliases=['rename_lvol_bdev'], 1386 help='Change lvol bdev name') 1387 p.add_argument('old_name', help='lvol bdev name') 1388 p.add_argument('new_name', help='new lvol name') 1389 p.set_defaults(func=bdev_lvol_rename) 1390 1391 def bdev_lvol_inflate(args): 1392 rpc.lvol.bdev_lvol_inflate(args.client, 1393 name=args.name) 1394 1395 p = subparsers.add_parser('bdev_lvol_inflate', aliases=['inflate_lvol_bdev'], 1396 help='Make thin provisioned lvol a thick provisioned lvol') 1397 p.add_argument('name', help='lvol bdev name') 1398 p.set_defaults(func=bdev_lvol_inflate) 1399 1400 def bdev_lvol_decouple_parent(args): 1401 rpc.lvol.bdev_lvol_decouple_parent(args.client, 1402 name=args.name) 1403 1404 p = subparsers.add_parser('bdev_lvol_decouple_parent', aliases=['decouple_parent_lvol_bdev'], 1405 help='Decouple parent of lvol') 1406 p.add_argument('name', help='lvol bdev name') 1407 p.set_defaults(func=bdev_lvol_decouple_parent) 1408 1409 def bdev_lvol_resize(args): 1410 rpc.lvol.bdev_lvol_resize(args.client, 1411 name=args.name, 1412 size=args.size * 1024 * 1024) 1413 1414 p = subparsers.add_parser('bdev_lvol_resize', aliases=['resize_lvol_bdev'], 1415 help='Resize existing lvol bdev') 1416 p.add_argument('name', help='lvol bdev name') 1417 p.add_argument('size', help='new size in MiB for this bdev', type=int) 1418 p.set_defaults(func=bdev_lvol_resize) 1419 1420 def bdev_lvol_set_read_only(args): 1421 rpc.lvol.bdev_lvol_set_read_only(args.client, 1422 name=args.name) 1423 1424 p = subparsers.add_parser('bdev_lvol_set_read_only', aliases=['set_read_only_lvol_bdev'], 1425 help='Mark lvol bdev as read only') 1426 p.add_argument('name', help='lvol bdev name') 1427 p.set_defaults(func=bdev_lvol_set_read_only) 1428 1429 def bdev_lvol_delete(args): 1430 rpc.lvol.bdev_lvol_delete(args.client, 1431 name=args.name) 1432 1433 p = subparsers.add_parser('bdev_lvol_delete', aliases=['destroy_lvol_bdev'], 1434 help='Destroy a logical volume') 1435 p.add_argument('name', help='lvol bdev name') 1436 p.set_defaults(func=bdev_lvol_delete) 1437 1438 def bdev_lvol_delete_lvstore(args): 1439 rpc.lvol.bdev_lvol_delete_lvstore(args.client, 1440 uuid=args.uuid, 1441 lvs_name=args.lvs_name) 1442 1443 p = subparsers.add_parser('bdev_lvol_delete_lvstore', aliases=['destroy_lvol_store'], 1444 help='Destroy an logical volume store') 1445 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 1446 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 1447 p.set_defaults(func=bdev_lvol_delete_lvstore) 1448 1449 def bdev_lvol_get_lvstores(args): 1450 print_dict(rpc.lvol.bdev_lvol_get_lvstores(args.client, 1451 uuid=args.uuid, 1452 lvs_name=args.lvs_name)) 1453 1454 p = subparsers.add_parser('bdev_lvol_get_lvstores', aliases=['get_lvol_stores'], 1455 help='Display current logical volume store list') 1456 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 1457 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 1458 p.set_defaults(func=bdev_lvol_get_lvstores) 1459 1460 def bdev_raid_get_bdevs(args): 1461 print_array(rpc.bdev.bdev_raid_get_bdevs(args.client, 1462 category=args.category)) 1463 1464 p = subparsers.add_parser('bdev_raid_get_bdevs', aliases=['get_raid_bdevs'], 1465 help="""This is used to list all the raid bdev names based on the input category 1466 requested. Category should be one of 'all', 'online', 'configuring' or 'offline'. 'all' means all the raid bdevs whether 1467 they are online or configuring or offline. 'online' is the raid bdev which is registered with bdev layer. 'configuring' 1468 is the raid bdev which does not have full configuration discovered yet. 'offline' is the raid bdev which is not registered 1469 with bdev as of now and it has encountered any error or user has requested to offline the raid bdev""") 1470 p.add_argument('category', help='all or online or configuring or offline') 1471 p.set_defaults(func=bdev_raid_get_bdevs) 1472 1473 def bdev_raid_create(args): 1474 base_bdevs = [] 1475 for u in args.base_bdevs.strip().split(" "): 1476 base_bdevs.append(u) 1477 1478 rpc.bdev.bdev_raid_create(args.client, 1479 name=args.name, 1480 strip_size=args.strip_size, 1481 strip_size_kb=args.strip_size_kb, 1482 raid_level=args.raid_level, 1483 base_bdevs=base_bdevs) 1484 p = subparsers.add_parser('bdev_raid_create', aliases=['construct_raid_bdev'], 1485 help='Create new raid bdev') 1486 p.add_argument('-n', '--name', help='raid bdev name', required=True) 1487 p.add_argument('-s', '--strip-size', help='strip size in KB (deprecated)', type=int) 1488 p.add_argument('-z', '--strip-size_kb', help='strip size in KB', type=int) 1489 p.add_argument('-r', '--raid-level', help='raid level, only raid level 0 is supported', required=True) 1490 p.add_argument('-b', '--base-bdevs', help='base bdevs name, whitespace separated list in quotes', required=True) 1491 p.set_defaults(func=bdev_raid_create) 1492 1493 def bdev_raid_delete(args): 1494 rpc.bdev.bdev_raid_delete(args.client, 1495 name=args.name) 1496 p = subparsers.add_parser('bdev_raid_delete', aliases=['destroy_raid_bdev'], 1497 help='Delete existing raid bdev') 1498 p.add_argument('name', help='raid bdev name') 1499 p.set_defaults(func=bdev_raid_delete) 1500 1501 # split 1502 def bdev_split_create(args): 1503 print_array(rpc.bdev.bdev_split_create(args.client, 1504 base_bdev=args.base_bdev, 1505 split_count=args.split_count, 1506 split_size_mb=args.split_size_mb)) 1507 1508 p = subparsers.add_parser('bdev_split_create', aliases=['construct_split_vbdev'], 1509 help="""Add given disk name to split config. If bdev with base_name 1510 name exist the split bdevs will be created right away, if not split bdevs will be created when base bdev became 1511 available (during examination process).""") 1512 p.add_argument('base_bdev', help='base bdev name') 1513 p.add_argument('-s', '--split-size-mb', help='size in MiB for each bdev', type=int, default=0) 1514 p.add_argument('split_count', help="""Optional - number of split bdevs to create. Total size * split_count must not 1515 exceed the base bdev size.""", type=int) 1516 p.set_defaults(func=bdev_split_create) 1517 1518 def bdev_split_delete(args): 1519 rpc.bdev.bdev_split_delete(args.client, 1520 base_bdev=args.base_bdev) 1521 1522 p = subparsers.add_parser('bdev_split_delete', aliases=['destruct_split_vbdev'], 1523 help="""Delete split config with all created splits.""") 1524 p.add_argument('base_bdev', help='base bdev name') 1525 p.set_defaults(func=bdev_split_delete) 1526 1527 # ftl 1528 ftl_valid_limits = ('crit', 'high', 'low', 'start') 1529 1530 def bdev_ftl_create(args): 1531 def parse_limits(limits, arg_dict, key_suffix=''): 1532 for limit in limits.split(','): 1533 key, value = limit.split(':', 1) 1534 if key in ftl_valid_limits: 1535 arg_dict['limit_' + key + key_suffix] = int(value) 1536 else: 1537 raise ValueError('Limit {} is not supported'.format(key)) 1538 1539 arg_limits = {} 1540 if args.limit_threshold: 1541 parse_limits(args.limit_threshold, arg_limits, '_threshold') 1542 1543 if args.limit: 1544 parse_limits(args.limit, arg_limits) 1545 1546 print_dict(rpc.bdev.bdev_ftl_create(args.client, 1547 name=args.name, 1548 base_bdev=args.base_bdev, 1549 uuid=args.uuid, 1550 cache=args.cache, 1551 allow_open_bands=args.allow_open_bands, 1552 overprovisioning=args.overprovisioning, 1553 use_append=args.use_append, 1554 **arg_limits)) 1555 1556 p = subparsers.add_parser('bdev_ftl_create', aliases=['construct_ftl_bdev'], help='Add FTL bdev') 1557 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 1558 p.add_argument('-d', '--base_bdev', help='Name of zoned bdev used as underlying device', 1559 required=True) 1560 p.add_argument('-u', '--uuid', help='UUID of restored bdev (not applicable when creating new ' 1561 'instance): e.g. b286d19a-0059-4709-abcd-9f7732b1567d (optional)') 1562 p.add_argument('-c', '--cache', help='Name of the bdev to be used as a write buffer cache (optional)') 1563 p.add_argument('-o', '--allow_open_bands', help='Restoring after dirty shutdown without cache will' 1564 ' result in partial data recovery, instead of error', action='store_true') 1565 p.add_argument('--overprovisioning', help='Percentage of device used for relocation, not exposed' 1566 ' to user (optional)', type=int) 1567 p.add_argument('--use_append', help='Use appends instead of writes', action='store_true') 1568 1569 limits = p.add_argument_group('Defrag limits', 'Configures defrag limits and thresholds for' 1570 ' levels ' + str(ftl_valid_limits)[1:-1]) 1571 limits.add_argument('--limit', help='Percentage of allowed user versus internal writes at given' 1572 ' levels, e.g. crit:0,high:20,low:80') 1573 limits.add_argument('--limit-threshold', help='Number of free bands triggering a given level of' 1574 ' write limiting e.g. crit:1,high:2,low:3,start:4') 1575 p.set_defaults(func=bdev_ftl_create) 1576 1577 def bdev_ftl_delete(args): 1578 print_dict(rpc.bdev.bdev_ftl_delete(args.client, name=args.name)) 1579 1580 p = subparsers.add_parser('bdev_ftl_delete', aliases=['delete_ftl_bdev'], 1581 help='Delete FTL bdev') 1582 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 1583 p.set_defaults(func=bdev_ftl_delete) 1584 1585 # vmd 1586 def enable_vmd(args): 1587 print_dict(rpc.vmd.enable_vmd(args.client)) 1588 1589 p = subparsers.add_parser('enable_vmd', help='Enable VMD enumeration') 1590 p.set_defaults(func=enable_vmd) 1591 1592 # nbd 1593 def nbd_start_disk(args): 1594 print(rpc.nbd.nbd_start_disk(args.client, 1595 bdev_name=args.bdev_name, 1596 nbd_device=args.nbd_device)) 1597 1598 p = subparsers.add_parser('nbd_start_disk', aliases=['start_nbd_disk'], 1599 help='Export a bdev as an nbd disk') 1600 p.add_argument('bdev_name', help='Blockdev name to be exported. Example: Malloc0.') 1601 p.add_argument('nbd_device', help='Nbd device name to be assigned. Example: /dev/nbd0.', nargs='?') 1602 p.set_defaults(func=nbd_start_disk) 1603 1604 def nbd_stop_disk(args): 1605 rpc.nbd.nbd_stop_disk(args.client, 1606 nbd_device=args.nbd_device) 1607 1608 p = subparsers.add_parser('nbd_stop_disk', aliases=['stop_nbd_disk'], 1609 help='Stop an nbd disk') 1610 p.add_argument('nbd_device', help='Nbd device name to be stopped. Example: /dev/nbd0.') 1611 p.set_defaults(func=nbd_stop_disk) 1612 1613 def nbd_get_disks(args): 1614 print_dict(rpc.nbd.nbd_get_disks(args.client, 1615 nbd_device=args.nbd_device)) 1616 1617 p = subparsers.add_parser('nbd_get_disks', aliases=['get_nbd_disks'], 1618 help='Display full or specified nbd device list') 1619 p.add_argument('-n', '--nbd-device', help="Path of the nbd device. Example: /dev/nbd0", required=False) 1620 p.set_defaults(func=nbd_get_disks) 1621 1622 # net 1623 def net_interface_add_ip_address(args): 1624 rpc.net.net_interface_add_ip_address(args.client, ifc_index=args.ifc_index, ip_addr=args.ip_addr) 1625 1626 p = subparsers.add_parser('net_interface_add_ip_address', aliases=['add_ip_address'], 1627 help='Add IP address') 1628 p.add_argument('ifc_index', help='ifc index of the nic device.', type=int) 1629 p.add_argument('ip_addr', help='ip address will be added.') 1630 p.set_defaults(func=net_interface_add_ip_address) 1631 1632 def net_interface_delete_ip_address(args): 1633 rpc.net.net_interface_delete_ip_address(args.client, ifc_index=args.ifc_index, ip_addr=args.ip_addr) 1634 1635 p = subparsers.add_parser('net_interface_delete_ip_address', aliases=['delete_ip_address'], 1636 help='Delete IP address') 1637 p.add_argument('ifc_index', help='ifc index of the nic device.', type=int) 1638 p.add_argument('ip_addr', help='ip address will be deleted.') 1639 p.set_defaults(func=net_interface_delete_ip_address) 1640 1641 def net_get_interfaces(args): 1642 print_dict(rpc.net.net_get_interfaces(args.client)) 1643 1644 p = subparsers.add_parser( 1645 'net_get_interfaces', aliases=['get_interfaces'], help='Display current interface list') 1646 p.set_defaults(func=net_get_interfaces) 1647 1648 # NVMe-oF 1649 def nvmf_set_max_subsystems(args): 1650 rpc.nvmf.nvmf_set_max_subsystems(args.client, 1651 max_subsystems=args.max_subsystems) 1652 1653 p = subparsers.add_parser('nvmf_set_max_subsystems', aliases=['set_nvmf_target_max_subsystems'], 1654 help='Set the maximum number of NVMf target subsystems') 1655 p.add_argument('-x', '--max-subsystems', help='Max number of NVMf subsystems', type=int, required=True) 1656 p.set_defaults(func=nvmf_set_max_subsystems) 1657 1658 def nvmf_set_config(args): 1659 rpc.nvmf.nvmf_set_config(args.client, 1660 acceptor_poll_rate=args.acceptor_poll_rate, 1661 conn_sched=args.conn_sched, 1662 passthru_identify_ctrlr=args.passthru_identify_ctrlr) 1663 1664 p = subparsers.add_parser('nvmf_set_config', aliases=['set_nvmf_target_config'], 1665 help='Set NVMf target config') 1666 p.add_argument('-r', '--acceptor-poll-rate', help='Polling interval of the acceptor for incoming connections (usec)', type=int) 1667 p.add_argument('-s', '--conn-sched', help="""'roundrobin' - Schedule the incoming connections from any host 1668 on the cores in a round robin manner (Default). 'hostip' - Schedule all the incoming connections from a 1669 specific host IP on to the same core. Connections from different IP will be assigned to cores in a round 1670 robin manner. 'transport' - Schedule the connection according to the transport characteristics.""") 1671 p.add_argument('-i', '--passthru-identify-ctrlr', help="""Passthrough fields like serial number and model number 1672 when the controller has a single namespace that is an NVMe bdev""", action='store_true') 1673 p.set_defaults(func=nvmf_set_config) 1674 1675 def nvmf_create_transport(args): 1676 rpc.nvmf.nvmf_create_transport(args.client, 1677 trtype=args.trtype, 1678 tgt_name=args.tgt_name, 1679 max_queue_depth=args.max_queue_depth, 1680 max_qpairs_per_ctrlr=args.max_qpairs_per_ctrlr, 1681 in_capsule_data_size=args.in_capsule_data_size, 1682 max_io_size=args.max_io_size, 1683 io_unit_size=args.io_unit_size, 1684 max_aq_depth=args.max_aq_depth, 1685 num_shared_buffers=args.num_shared_buffers, 1686 buf_cache_size=args.buf_cache_size, 1687 max_srq_depth=args.max_srq_depth, 1688 no_srq=args.no_srq, 1689 c2h_success=args.c2h_success, 1690 dif_insert_or_strip=args.dif_insert_or_strip, 1691 sock_priority=args.sock_priority) 1692 1693 p = subparsers.add_parser('nvmf_create_transport', help='Create NVMf transport') 1694 p.add_argument('-t', '--trtype', help='Transport type (ex. RDMA)', type=str, required=True) 1695 p.add_argument('-g', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1696 p.add_argument('-q', '--max-queue-depth', help='Max number of outstanding I/O per queue', type=int) 1697 p.add_argument('-p', '--max-qpairs-per-ctrlr', help='Max number of SQ and CQ per controller', type=int) 1698 p.add_argument('-c', '--in-capsule-data-size', help='Max number of in-capsule data size', type=int) 1699 p.add_argument('-i', '--max-io-size', help='Max I/O size (bytes)', type=int) 1700 p.add_argument('-u', '--io-unit-size', help='I/O unit size (bytes)', type=int) 1701 p.add_argument('-a', '--max-aq-depth', help='Max number of admin cmds per AQ', type=int) 1702 p.add_argument('-n', '--num-shared-buffers', help='The number of pooled data buffers available to the transport', type=int) 1703 p.add_argument('-b', '--buf-cache-size', help='The number of shared buffers to reserve for each poll group', type=int) 1704 p.add_argument('-s', '--max-srq-depth', help='Max number of outstanding I/O per SRQ. Relevant only for RDMA transport', type=int) 1705 p.add_argument('-r', '--no-srq', action='store_true', help='Disable per-thread shared receive queue. Relevant only for RDMA transport') 1706 p.add_argument('-o', '--c2h-success', action='store_false', help='Disable C2H success optimization. Relevant only for TCP transport') 1707 p.add_argument('-f', '--dif-insert-or-strip', action='store_true', help='Enable DIF insert/strip. Relevant only for TCP transport') 1708 p.add_argument('-y', '--sock-priority', help='The sock priority of the tcp connection. Relevant only for TCP transport', type=int) 1709 p.set_defaults(func=nvmf_create_transport) 1710 1711 def nvmf_get_transports(args): 1712 print_dict(rpc.nvmf.nvmf_get_transports(args.client, tgt_name=args.tgt_name)) 1713 1714 p = subparsers.add_parser('nvmf_get_transports', aliases=['get_nvmf_transports'], 1715 help='Display nvmf transports') 1716 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1717 p.set_defaults(func=nvmf_get_transports) 1718 1719 def nvmf_get_subsystems(args): 1720 print_dict(rpc.nvmf.nvmf_get_subsystems(args.client, tgt_name=args.tgt_name)) 1721 1722 p = subparsers.add_parser('nvmf_get_subsystems', aliases=['get_nvmf_subsystems'], 1723 help='Display nvmf subsystems') 1724 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1725 p.set_defaults(func=nvmf_get_subsystems) 1726 1727 def nvmf_create_subsystem(args): 1728 rpc.nvmf.nvmf_create_subsystem(args.client, 1729 nqn=args.nqn, 1730 tgt_name=args.tgt_name, 1731 serial_number=args.serial_number, 1732 model_number=args.model_number, 1733 allow_any_host=args.allow_any_host, 1734 max_namespaces=args.max_namespaces) 1735 1736 p = subparsers.add_parser('nvmf_create_subsystem', aliases=['nvmf_subsystem_create'], 1737 help='Create an NVMe-oF subsystem') 1738 p.add_argument('nqn', help='Subsystem NQN (ASCII)') 1739 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1740 p.add_argument("-s", "--serial-number", help=""" 1741 Format: 'sn' etc 1742 Example: 'SPDK00000000000001'""", default='00000000000000000000') 1743 p.add_argument("-d", "--model-number", help=""" 1744 Format: 'mn' etc 1745 Example: 'SPDK Controller'""", default='SPDK bdev Controller') 1746 p.add_argument("-a", "--allow-any-host", action='store_true', help="Allow any host to connect (don't enforce host NQN whitelist)") 1747 p.add_argument("-m", "--max-namespaces", help="Maximum number of namespaces allowed", 1748 type=int, default=0) 1749 p.set_defaults(func=nvmf_create_subsystem) 1750 1751 def nvmf_delete_subsystem(args): 1752 rpc.nvmf.nvmf_delete_subsystem(args.client, 1753 nqn=args.subsystem_nqn, 1754 tgt_name=args.tgt_name) 1755 1756 p = subparsers.add_parser('nvmf_delete_subsystem', aliases=['delete_nvmf_subsystem'], 1757 help='Delete a nvmf subsystem') 1758 p.add_argument('subsystem_nqn', 1759 help='subsystem nqn to be deleted. Example: nqn.2016-06.io.spdk:cnode1.') 1760 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1761 p.set_defaults(func=nvmf_delete_subsystem) 1762 1763 def nvmf_subsystem_add_listener(args): 1764 rpc.nvmf.nvmf_subsystem_add_listener(args.client, 1765 nqn=args.nqn, 1766 trtype=args.trtype, 1767 traddr=args.traddr, 1768 tgt_name=args.tgt_name, 1769 adrfam=args.adrfam, 1770 trsvcid=args.trsvcid) 1771 1772 p = subparsers.add_parser('nvmf_subsystem_add_listener', help='Add a listener to an NVMe-oF subsystem') 1773 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1774 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 1775 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 1776 p.add_argument('-p', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1777 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 1778 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number') 1779 p.set_defaults(func=nvmf_subsystem_add_listener) 1780 1781 def nvmf_subsystem_remove_listener(args): 1782 rpc.nvmf.nvmf_subsystem_remove_listener(args.client, 1783 nqn=args.nqn, 1784 trtype=args.trtype, 1785 traddr=args.traddr, 1786 tgt_name=args.tgt_name, 1787 adrfam=args.adrfam, 1788 trsvcid=args.trsvcid) 1789 1790 p = subparsers.add_parser('nvmf_subsystem_remove_listener', help='Remove a listener from an NVMe-oF subsystem') 1791 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1792 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 1793 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 1794 p.add_argument('-p', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1795 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 1796 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number') 1797 p.set_defaults(func=nvmf_subsystem_remove_listener) 1798 1799 def nvmf_subsystem_add_ns(args): 1800 rpc.nvmf.nvmf_subsystem_add_ns(args.client, 1801 nqn=args.nqn, 1802 bdev_name=args.bdev_name, 1803 tgt_name=args.tgt_name, 1804 ptpl_file=args.ptpl_file, 1805 nsid=args.nsid, 1806 nguid=args.nguid, 1807 eui64=args.eui64, 1808 uuid=args.uuid) 1809 1810 p = subparsers.add_parser('nvmf_subsystem_add_ns', help='Add a namespace to an NVMe-oF subsystem') 1811 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1812 p.add_argument('bdev_name', help='The name of the bdev that will back this namespace') 1813 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1814 p.add_argument('-p', '--ptpl-file', help='The persistent reservation storage location (optional)', type=str) 1815 p.add_argument('-n', '--nsid', help='The requested NSID (optional)', type=int) 1816 p.add_argument('-g', '--nguid', help='Namespace globally unique identifier (optional)') 1817 p.add_argument('-e', '--eui64', help='Namespace EUI-64 identifier (optional)') 1818 p.add_argument('-u', '--uuid', help='Namespace UUID (optional)') 1819 p.set_defaults(func=nvmf_subsystem_add_ns) 1820 1821 def nvmf_subsystem_remove_ns(args): 1822 rpc.nvmf.nvmf_subsystem_remove_ns(args.client, 1823 nqn=args.nqn, 1824 nsid=args.nsid, 1825 tgt_name=args.tgt_name) 1826 1827 p = subparsers.add_parser('nvmf_subsystem_remove_ns', help='Remove a namespace to an NVMe-oF subsystem') 1828 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1829 p.add_argument('nsid', help='The requested NSID', type=int) 1830 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1831 p.set_defaults(func=nvmf_subsystem_remove_ns) 1832 1833 def nvmf_subsystem_add_host(args): 1834 rpc.nvmf.nvmf_subsystem_add_host(args.client, 1835 nqn=args.nqn, 1836 host=args.host, 1837 tgt_name=args.tgt_name) 1838 1839 p = subparsers.add_parser('nvmf_subsystem_add_host', help='Add a host to an NVMe-oF subsystem') 1840 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1841 p.add_argument('host', help='Host NQN to allow') 1842 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1843 p.set_defaults(func=nvmf_subsystem_add_host) 1844 1845 def nvmf_subsystem_remove_host(args): 1846 rpc.nvmf.nvmf_subsystem_remove_host(args.client, 1847 nqn=args.nqn, 1848 host=args.host, 1849 tgt_name=args.tgt_name) 1850 1851 p = subparsers.add_parser('nvmf_subsystem_remove_host', help='Remove a host from an NVMe-oF subsystem') 1852 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1853 p.add_argument('host', help='Host NQN to remove') 1854 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1855 p.set_defaults(func=nvmf_subsystem_remove_host) 1856 1857 def nvmf_subsystem_allow_any_host(args): 1858 rpc.nvmf.nvmf_subsystem_allow_any_host(args.client, 1859 nqn=args.nqn, 1860 disable=args.disable, 1861 tgt_name=args.tgt_name) 1862 1863 p = subparsers.add_parser('nvmf_subsystem_allow_any_host', help='Allow any host to connect to the subsystem') 1864 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 1865 p.add_argument('-e', '--enable', action='store_true', help='Enable allowing any host') 1866 p.add_argument('-d', '--disable', action='store_true', help='Disable allowing any host') 1867 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1868 p.set_defaults(func=nvmf_subsystem_allow_any_host) 1869 1870 def nvmf_get_stats(args): 1871 print_dict(rpc.nvmf.nvmf_get_stats(args.client, tgt_name=args.tgt_name)) 1872 1873 p = subparsers.add_parser( 1874 'nvmf_get_stats', help='Display current statistics for NVMf subsystem') 1875 p.add_argument('-t', '--tgt_name', help='The name of the parent NVMe-oF target (optional)', type=str) 1876 p.set_defaults(func=nvmf_get_stats) 1877 1878 # pmem 1879 def bdev_pmem_create_pool(args): 1880 num_blocks = int((args.total_size * 1024 * 1024) / args.block_size) 1881 rpc.pmem.bdev_pmem_create_pool(args.client, 1882 pmem_file=args.pmem_file, 1883 num_blocks=num_blocks, 1884 block_size=args.block_size) 1885 1886 p = subparsers.add_parser('bdev_pmem_create_pool', aliases=['create_pmem_pool'], 1887 help='Create pmem pool') 1888 p.add_argument('pmem_file', help='Path to pmemblk pool file') 1889 p.add_argument('total_size', help='Size of malloc bdev in MB (int > 0)', type=int) 1890 p.add_argument('block_size', help='Block size for this pmem pool', type=int) 1891 p.set_defaults(func=bdev_pmem_create_pool) 1892 1893 def bdev_pmem_get_pool_info(args): 1894 print_dict(rpc.pmem.bdev_pmem_get_pool_info(args.client, 1895 pmem_file=args.pmem_file)) 1896 1897 p = subparsers.add_parser('bdev_pmem_get_pool_info', aliases=['pmem_pool_info'], 1898 help='Display pmem pool info and check consistency') 1899 p.add_argument('pmem_file', help='Path to pmemblk pool file') 1900 p.set_defaults(func=bdev_pmem_get_pool_info) 1901 1902 def bdev_pmem_delete_pool(args): 1903 rpc.pmem.bdev_pmem_delete_pool(args.client, 1904 pmem_file=args.pmem_file) 1905 1906 p = subparsers.add_parser('bdev_pmem_delete_pool', aliases=['delete_pmem_pool'], 1907 help='Delete pmem pool') 1908 p.add_argument('pmem_file', help='Path to pmemblk pool file') 1909 p.set_defaults(func=bdev_pmem_delete_pool) 1910 1911 # subsystem 1912 def framework_get_subsystems(args): 1913 print_dict(rpc.subsystem.framework_get_subsystems(args.client)) 1914 1915 p = subparsers.add_parser('framework_get_subsystems', aliases=['get_subsystems'], 1916 help="""Print subsystems array in initialization order. Each subsystem 1917 entry contain (unsorted) array of subsystems it depends on.""") 1918 p.set_defaults(func=framework_get_subsystems) 1919 1920 def framework_get_config(args): 1921 print_dict(rpc.subsystem.framework_get_config(args.client, args.name)) 1922 1923 p = subparsers.add_parser('framework_get_config', aliases=['get_subsystem_config'], 1924 help="""Print subsystem configuration""") 1925 p.add_argument('name', help='Name of subsystem to query') 1926 p.set_defaults(func=framework_get_config) 1927 1928 # vhost 1929 def vhost_controller_set_coalescing(args): 1930 rpc.vhost.vhost_controller_set_coalescing(args.client, 1931 ctrlr=args.ctrlr, 1932 delay_base_us=args.delay_base_us, 1933 iops_threshold=args.iops_threshold) 1934 1935 p = subparsers.add_parser('vhost_controller_set_coalescing', aliases=['set_vhost_controller_coalescing'], 1936 help='Set vhost controller coalescing') 1937 p.add_argument('ctrlr', help='controller name') 1938 p.add_argument('delay_base_us', help='Base delay time', type=int) 1939 p.add_argument('iops_threshold', help='IOPS threshold when coalescing is enabled', type=int) 1940 p.set_defaults(func=vhost_controller_set_coalescing) 1941 1942 def vhost_create_scsi_controller(args): 1943 rpc.vhost.vhost_create_scsi_controller(args.client, 1944 ctrlr=args.ctrlr, 1945 cpumask=args.cpumask) 1946 1947 p = subparsers.add_parser( 1948 'vhost_create_scsi_controller', aliases=['construct_vhost_scsi_controller'], 1949 help='Add new vhost controller') 1950 p.add_argument('ctrlr', help='controller name') 1951 p.add_argument('--cpumask', help='cpu mask for this controller') 1952 p.set_defaults(func=vhost_create_scsi_controller) 1953 1954 def vhost_scsi_controller_add_target(args): 1955 print_json(rpc.vhost.vhost_scsi_controller_add_target(args.client, 1956 ctrlr=args.ctrlr, 1957 scsi_target_num=args.scsi_target_num, 1958 bdev_name=args.bdev_name)) 1959 1960 p = subparsers.add_parser('vhost_scsi_controller_add_target', 1961 aliases=['add_vhost_scsi_lun'], 1962 help='Add lun to vhost controller') 1963 p.add_argument('ctrlr', help='conntroller name where add lun') 1964 p.add_argument('scsi_target_num', help='scsi_target_num', type=int) 1965 p.add_argument('bdev_name', help='bdev name') 1966 p.set_defaults(func=vhost_scsi_controller_add_target) 1967 1968 def vhost_scsi_controller_remove_target(args): 1969 rpc.vhost.vhost_scsi_controller_remove_target(args.client, 1970 ctrlr=args.ctrlr, 1971 scsi_target_num=args.scsi_target_num) 1972 1973 p = subparsers.add_parser('vhost_scsi_controller_remove_target', 1974 aliases=['remove_vhost_scsi_target'], 1975 help='Remove target from vhost controller') 1976 p.add_argument('ctrlr', help='controller name to remove target from') 1977 p.add_argument('scsi_target_num', help='scsi_target_num', type=int) 1978 p.set_defaults(func=vhost_scsi_controller_remove_target) 1979 1980 def vhost_create_blk_controller(args): 1981 rpc.vhost.vhost_create_blk_controller(args.client, 1982 ctrlr=args.ctrlr, 1983 dev_name=args.dev_name, 1984 cpumask=args.cpumask, 1985 readonly=args.readonly) 1986 1987 p = subparsers.add_parser('vhost_create_blk_controller', 1988 aliases=['construct_vhost_blk_controller'], 1989 help='Add a new vhost block controller') 1990 p.add_argument('ctrlr', help='controller name') 1991 p.add_argument('dev_name', help='device name') 1992 p.add_argument('--cpumask', help='cpu mask for this controller') 1993 p.add_argument("-r", "--readonly", action='store_true', help='Set controller as read-only') 1994 p.set_defaults(func=vhost_create_blk_controller) 1995 1996 def vhost_create_nvme_controller(args): 1997 rpc.vhost.vhost_create_nvme_controller(args.client, 1998 ctrlr=args.ctrlr, 1999 io_queues=args.io_queues, 2000 cpumask=args.cpumask) 2001 2002 p = subparsers.add_parser('vhost_create_nvme_controller', aliases=['vhost_create_nvme_controller'], 2003 help='Add new vhost controller') 2004 p.add_argument('ctrlr', help='controller name') 2005 p.add_argument('io_queues', help='number of IO queues for the controller', type=int) 2006 p.add_argument('--cpumask', help='cpu mask for this controller') 2007 p.set_defaults(func=vhost_create_nvme_controller) 2008 2009 def vhost_nvme_controller_add_ns(args): 2010 rpc.vhost.vhost_nvme_controller_add_ns(args.client, 2011 ctrlr=args.ctrlr, 2012 bdev_name=args.bdev_name) 2013 2014 p = subparsers.add_parser('vhost_nvme_controller_add_ns', aliases=['add_vhost_nvme_ns'], 2015 help='Add a Namespace to vhost controller') 2016 p.add_argument('ctrlr', help='conntroller name where add a Namespace') 2017 p.add_argument('bdev_name', help='block device name for a new Namespace') 2018 p.set_defaults(func=vhost_nvme_controller_add_ns) 2019 2020 def vhost_get_controllers(args): 2021 print_dict(rpc.vhost.vhost_get_controllers(args.client, args.name)) 2022 2023 p = subparsers.add_parser('vhost_get_controllers', aliases=['get_vhost_controllers'], 2024 help='List all or specific vhost controller(s)') 2025 p.add_argument('-n', '--name', help="Name of vhost controller", required=False) 2026 p.set_defaults(func=vhost_get_controllers) 2027 2028 def vhost_delete_controller(args): 2029 rpc.vhost.vhost_delete_controller(args.client, 2030 ctrlr=args.ctrlr) 2031 2032 p = subparsers.add_parser('vhost_delete_controller', aliases=['remove_vhost_controller'], 2033 help='Delete a vhost controller') 2034 p.add_argument('ctrlr', help='controller name') 2035 p.set_defaults(func=vhost_delete_controller) 2036 2037 def bdev_virtio_attach_controller(args): 2038 print_array(rpc.vhost.bdev_virtio_attach_controller(args.client, 2039 name=args.name, 2040 trtype=args.trtype, 2041 traddr=args.traddr, 2042 dev_type=args.dev_type, 2043 vq_count=args.vq_count, 2044 vq_size=args.vq_size)) 2045 2046 p = subparsers.add_parser('bdev_virtio_attach_controller', aliases=['construct_virtio_dev'], 2047 help="""Attach virtio controller using provided 2048 transport type and device type. This will also create bdevs for any block devices connected to the 2049 controller (for example, SCSI devices for a virtio-scsi controller). 2050 Result is array of added bdevs.""") 2051 p.add_argument('name', help="Use this name as base for new created bdevs") 2052 p.add_argument('-t', '--trtype', 2053 help='Virtio target transport type: pci or user', required=True) 2054 p.add_argument('-a', '--traddr', 2055 help='Transport type specific target address: e.g. UNIX domain socket path or BDF', required=True) 2056 p.add_argument('-d', '--dev-type', 2057 help='Device type: blk or scsi', required=True) 2058 p.add_argument('--vq-count', help='Number of virtual queues to be used.', type=int) 2059 p.add_argument('--vq-size', help='Size of each queue', type=int) 2060 p.set_defaults(func=bdev_virtio_attach_controller) 2061 2062 def bdev_virtio_scsi_get_devices(args): 2063 print_dict(rpc.vhost.bdev_virtio_scsi_get_devices(args.client)) 2064 2065 p = subparsers.add_parser('bdev_virtio_scsi_get_devices', aliases=['get_virtio_scsi_devs'], 2066 help='List all Virtio-SCSI devices.') 2067 p.set_defaults(func=bdev_virtio_scsi_get_devices) 2068 2069 def bdev_virtio_detach_controller(args): 2070 rpc.vhost.bdev_virtio_detach_controller(args.client, 2071 name=args.name) 2072 2073 p = subparsers.add_parser('bdev_virtio_detach_controller', aliases=['remove_virtio_bdev'], 2074 help="""Remove a Virtio device 2075 This will delete all bdevs exposed by this device""") 2076 p.add_argument('name', help='Virtio device name. E.g. VirtioUser0') 2077 p.set_defaults(func=bdev_virtio_detach_controller) 2078 2079 # OCSSD 2080 def bdev_ocssd_create(args): 2081 nsid = int(args.nsid) if args.nsid is not None else None 2082 print_json(rpc.bdev.bdev_ocssd_create(args.client, 2083 ctrlr_name=args.ctrlr_name, 2084 bdev_name=args.name, 2085 nsid=nsid, 2086 range=args.range)) 2087 2088 p = subparsers.add_parser('bdev_ocssd_create', 2089 help='Creates zoned bdev on specified Open Channel controller') 2090 p.add_argument('-c', '--ctrlr_name', help='Name of the OC NVMe controller', required=True) 2091 p.add_argument('-b', '--name', help='Name of the bdev to create', required=True) 2092 p.add_argument('-n', '--nsid', help='Namespace ID', required=False) 2093 p.add_argument('-r', '--range', help='Parallel unit range (in the form of BEGIN-END (inclusive))', 2094 required=False) 2095 p.set_defaults(func=bdev_ocssd_create) 2096 2097 def bdev_ocssd_delete(args): 2098 print_json(rpc.bdev.bdev_ocssd_delete(args.client, 2099 name=args.name)) 2100 2101 p = subparsers.add_parser('bdev_ocssd_delete', 2102 help='Deletes Open Channel bdev') 2103 p.add_argument('name', help='Name of the Open Channel bdev') 2104 p.set_defaults(func=bdev_ocssd_delete) 2105 2106 # accel framework 2107 def accel_set_module(args): 2108 rpc.accel.accel_set_module(args.client, 2109 module=args.module) 2110 2111 p = subparsers.add_parser('accel_set_module', 2112 help='Set module option for the accelerator framework') 2113 p.add_argument('-m', '--module', type=int, help='0 = auto-select, 1= Software, 2 = CBDMA') 2114 p.set_defaults(func=accel_set_module) 2115 2116 # ioat 2117 def ioat_scan_accel_engine(args): 2118 pci_whitelist = [] 2119 if args.pci_whitelist: 2120 for w in args.pci_whitelist.strip().split(" "): 2121 pci_whitelist.append(w) 2122 rpc.ioat.ioat_scan_accel_engine(args.client, pci_whitelist) 2123 2124 p = subparsers.add_parser('ioat_scan_accel_engine', 2125 aliases=['ioat_scan_copy_engine', 'scan_ioat_copy_engine'], 2126 help='Set scan and enable IOAT accel engine offload.') 2127 p.add_argument('-w', '--pci-whitelist', help="""Whitespace-separated list of PCI addresses in 2128 domain:bus:device.function format or domain.bus.device.function format""") 2129 p.set_defaults(func=ioat_scan_accel_engine) 2130 2131 # opal 2132 def bdev_nvme_opal_init(args): 2133 rpc.nvme.bdev_nvme_opal_init(args.client, 2134 nvme_ctrlr_name=args.nvme_ctrlr_name, 2135 password=args.password) 2136 2137 p = subparsers.add_parser('bdev_nvme_opal_init', help='take ownership and activate') 2138 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name') 2139 p.add_argument('-p', '--password', help='password for admin') 2140 p.set_defaults(func=bdev_nvme_opal_init) 2141 2142 def bdev_nvme_opal_revert(args): 2143 rpc.nvme.bdev_nvme_opal_revert(args.client, 2144 nvme_ctrlr_name=args.nvme_ctrlr_name, 2145 password=args.password) 2146 p = subparsers.add_parser('bdev_nvme_opal_revert', help='Revert to default factory settings') 2147 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name') 2148 p.add_argument('-p', '--password', help='password') 2149 p.set_defaults(func=bdev_nvme_opal_revert) 2150 2151 def bdev_opal_create(args): 2152 print_json(rpc.bdev.bdev_opal_create(args.client, 2153 nvme_ctrlr_name=args.nvme_ctrlr_name, 2154 nsid=args.nsid, 2155 locking_range_id=args.locking_range_id, 2156 range_start=args.range_start, 2157 range_length=args.range_length, 2158 password=args.password)) 2159 2160 p = subparsers.add_parser('bdev_opal_create', help="""Create opal bdev on specified NVMe controller""") 2161 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name', required=True) 2162 p.add_argument('-n', '--nsid', help='namespace ID (only support nsid=1 for now)', type=int, required=True) 2163 p.add_argument('-i', '--locking-range-id', help='locking range id', type=int, required=True) 2164 p.add_argument('-s', '--range-start', help='locking range start LBA', type=int, required=True) 2165 p.add_argument('-l', '--range-length', help='locking range length (in blocks)', type=int, required=True) 2166 p.add_argument('-p', '--password', help='admin password', required=True) 2167 p.set_defaults(func=bdev_opal_create) 2168 2169 def bdev_opal_get_info(args): 2170 print_dict(rpc.bdev.bdev_opal_get_info(args.client, 2171 bdev_name=args.bdev_name, 2172 password=args.password)) 2173 2174 p = subparsers.add_parser('bdev_opal_get_info', help='get opal locking range info for this bdev') 2175 p.add_argument('-b', '--bdev-name', help='opal bdev') 2176 p.add_argument('-p', '--password', help='password') 2177 p.set_defaults(func=bdev_opal_get_info) 2178 2179 def bdev_opal_delete(args): 2180 rpc.bdev.bdev_opal_delete(args.client, 2181 bdev_name=args.bdev_name, 2182 password=args.password) 2183 2184 p = subparsers.add_parser('bdev_opal_delete', help="""delete a virtual opal bdev""") 2185 p.add_argument('-b', '--bdev-name', help='opal virtual bdev', required=True) 2186 p.add_argument('-p', '--password', help='admin password', required=True) 2187 p.set_defaults(func=bdev_opal_delete) 2188 2189 def bdev_opal_new_user(args): 2190 rpc.bdev.bdev_opal_new_user(args.client, 2191 bdev_name=args.bdev_name, 2192 admin_password=args.admin_password, 2193 user_id=args.user_id, 2194 user_password=args.user_password) 2195 2196 p = subparsers.add_parser('bdev_opal_new_user', help="""Add a user to opal bdev who can set lock state for this bdev""") 2197 p.add_argument('-b', '--bdev-name', help='opal bdev', required=True) 2198 p.add_argument('-p', '--admin-password', help='admin password', required=True) 2199 p.add_argument('-i', '--user-id', help='ID for new user', type=int, required=True) 2200 p.add_argument('-u', '--user-password', help='password set for this user', required=True) 2201 p.set_defaults(func=bdev_opal_new_user) 2202 2203 def bdev_opal_set_lock_state(args): 2204 rpc.bdev.bdev_opal_set_lock_state(args.client, 2205 bdev_name=args.bdev_name, 2206 user_id=args.user_id, 2207 password=args.password, 2208 lock_state=args.lock_state) 2209 2210 p = subparsers.add_parser('bdev_opal_set_lock_state', help="""set lock state for an opal bdev""") 2211 p.add_argument('-b', '--bdev-name', help='opal bdev', required=True) 2212 p.add_argument('-i', '--user-id', help='ID of the user who want to set lock state, either admin or a user assigned to this bdev', 2213 type=int, required=True) 2214 p.add_argument('-p', '--password', help='password of this user', required=True) 2215 p.add_argument('-l', '--lock-state', help='lock state to set, choose from {readwrite, readonly, rwlock}', required=True) 2216 p.set_defaults(func=bdev_opal_set_lock_state) 2217 2218 # bdev_nvme_send_cmd 2219 def bdev_nvme_send_cmd(args): 2220 print_dict(rpc.nvme.bdev_nvme_send_cmd(args.client, 2221 name=args.nvme_name, 2222 cmd_type=args.cmd_type, 2223 data_direction=args.data_direction, 2224 cmdbuf=args.cmdbuf, 2225 data=args.data, 2226 metadata=args.metadata, 2227 data_len=args.data_length, 2228 metadata_len=args.metadata_length, 2229 timeout_ms=args.timeout_ms)) 2230 2231 p = subparsers.add_parser('bdev_nvme_send_cmd', aliases=['send_nvme_cmd'], 2232 help='NVMe passthrough cmd.') 2233 p.add_argument('-n', '--nvme-name', help="""Name of the operating NVMe controller""") 2234 p.add_argument('-t', '--cmd-type', help="""Type of nvme cmd. Valid values are: admin, io""") 2235 p.add_argument('-r', '--data-direction', help="""Direction of data transfer. Valid values are: c2h, h2c""") 2236 p.add_argument('-c', '--cmdbuf', help="""NVMe command encoded by base64 urlsafe""") 2237 p.add_argument('-d', '--data', help="""Data transferring to controller from host, encoded by base64 urlsafe""") 2238 p.add_argument('-m', '--metadata', help="""Metadata transferring to controller from host, encoded by base64 urlsafe""") 2239 p.add_argument('-D', '--data-length', help="""Data length required to transfer from controller to host""", type=int) 2240 p.add_argument('-M', '--metadata-length', help="""Metadata length required to transfer from controller to host""", type=int) 2241 p.add_argument('-T', '--timeout-ms', 2242 help="""Command execution timeout value, in milliseconds, if 0, don't track timeout""", type=int, default=0) 2243 p.set_defaults(func=bdev_nvme_send_cmd) 2244 2245 # Notifications 2246 def notify_get_types(args): 2247 print_dict(rpc.notify.notify_get_types(args.client)) 2248 2249 p = subparsers.add_parser('notify_get_types', aliases=['get_notification_types'], 2250 help='List available notifications that user can subscribe to.') 2251 p.set_defaults(func=notify_get_types) 2252 2253 def notify_get_notifications(args): 2254 ret = rpc.notify.notify_get_notifications(args.client, 2255 id=args.id, 2256 max=args.max) 2257 print_dict(ret) 2258 2259 p = subparsers.add_parser('notify_get_notifications', aliases=['get_notifications'], 2260 help='Get notifications') 2261 p.add_argument('-i', '--id', help="""First ID to start fetching from""", type=int) 2262 p.add_argument('-n', '--max', help="""Maximum number of notifications to return in response""", type=int) 2263 p.set_defaults(func=notify_get_notifications) 2264 2265 def thread_get_stats(args): 2266 print_dict(rpc.app.thread_get_stats(args.client)) 2267 2268 p = subparsers.add_parser( 2269 'thread_get_stats', help='Display current statistics of all the threads') 2270 p.set_defaults(func=thread_get_stats) 2271 2272 def thread_set_cpumask(args): 2273 ret = rpc.app.thread_set_cpumask(args.client, 2274 id=args.id, 2275 cpumask=args.cpumask) 2276 p = subparsers.add_parser('thread_set_cpumask', 2277 help="""set the cpumask of the thread whose ID matches to the 2278 specified value. The thread may be migrated to one of the specified CPUs.""") 2279 p.add_argument('-i', '--id', type=int, help='thread ID') 2280 p.add_argument('-m', '--cpumask', help='cpumask for this thread') 2281 p.set_defaults(func=thread_set_cpumask) 2282 2283 def env_dpdk_get_mem_stats(args): 2284 print_dict(rpc.env_dpdk.env_dpdk_get_mem_stats(args.client)) 2285 2286 p = subparsers.add_parser( 2287 'env_dpdk_get_mem_stats', help='write the dpdk memory stats to a file.') 2288 p.set_defaults(func=env_dpdk_get_mem_stats) 2289 2290 # blobfs 2291 def blobfs_detect(args): 2292 print(rpc.blobfs.blobfs_detect(args.client, 2293 bdev_name=args.bdev_name)) 2294 2295 p = subparsers.add_parser('blobfs_detect', help='Detect whether a blobfs exists on bdev') 2296 p.add_argument('bdev_name', help='Blockdev name to detect blobfs. Example: Malloc0.') 2297 p.set_defaults(func=blobfs_detect) 2298 2299 def blobfs_create(args): 2300 print(rpc.blobfs.blobfs_create(args.client, 2301 bdev_name=args.bdev_name, 2302 cluster_sz=args.cluster_sz)) 2303 2304 p = subparsers.add_parser('blobfs_create', help='Build a blobfs on bdev') 2305 p.add_argument('bdev_name', help='Blockdev name to build blobfs. Example: Malloc0.') 2306 p.add_argument('-c', '--cluster_sz', 2307 help="""Size of cluster in bytes (Optional). Must be multiple of 4KB page size. Default and minimal value is 1M.""") 2308 p.set_defaults(func=blobfs_create) 2309 2310 def blobfs_mount(args): 2311 print(rpc.blobfs.blobfs_mount(args.client, 2312 bdev_name=args.bdev_name, 2313 mountpoint=args.mountpoint)) 2314 2315 p = subparsers.add_parser('blobfs_mount', help='Mount a blobfs on bdev to host path by FUSE') 2316 p.add_argument('bdev_name', help='Blockdev name where the blobfs is. Example: Malloc0.') 2317 p.add_argument('mountpoint', help='Mountpoint path in host to mount blobfs. Example: /mnt/.') 2318 p.set_defaults(func=blobfs_mount) 2319 2320 def blobfs_set_cache_size(args): 2321 print(rpc.blobfs.blobfs_set_cache_size(args.client, 2322 size_in_mb=args.size_in_mb)) 2323 2324 p = subparsers.add_parser('blobfs_set_cache_size', help='Set cache size for blobfs') 2325 p.add_argument('size_in_mb', help='Cache size for blobfs in megabytes.', type=int) 2326 p.set_defaults(func=blobfs_set_cache_size) 2327 2328 def check_called_name(name): 2329 if name in deprecated_aliases: 2330 print("{} is deprecated, use {} instead.".format(name, deprecated_aliases[name]), file=sys.stderr) 2331 2332 class dry_run_client: 2333 def call(self, method, params=None): 2334 print("Request:\n" + json.dumps({"method": method, "params": params}, indent=2)) 2335 2336 def null_print(arg): 2337 pass 2338 2339 def call_rpc_func(args): 2340 args.func(args) 2341 check_called_name(args.called_rpc_name) 2342 2343 def execute_script(parser, client, fd): 2344 executed_rpc = "" 2345 for rpc_call in map(str.rstrip, fd): 2346 if not rpc_call.strip(): 2347 continue 2348 executed_rpc = "\n".join([executed_rpc, rpc_call]) 2349 args = parser.parse_args(shlex.split(rpc_call)) 2350 args.client = client 2351 try: 2352 call_rpc_func(args) 2353 except JSONRPCException as ex: 2354 print("Exception:") 2355 print(executed_rpc.strip() + " <<<") 2356 print(ex.message) 2357 exit(1) 2358 2359 args = parser.parse_args() 2360 if args.dry_run: 2361 args.client = dry_run_client() 2362 print_dict = null_print 2363 print_json = null_print 2364 print_array = null_print 2365 else: 2366 args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, log_level=getattr(logging, args.verbose.upper())) 2367 if hasattr(args, 'func'): 2368 try: 2369 call_rpc_func(args) 2370 except JSONRPCException as ex: 2371 print(ex.message) 2372 exit(1) 2373 elif sys.stdin.isatty(): 2374 # No arguments and no data piped through stdin 2375 parser.print_help() 2376 exit(1) 2377 else: 2378 execute_script(parser, args.client, sys.stdin) 2379