1#!/usr/bin/env python3 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2016 Intel Corporation 4# All rights reserved. 5# Copyright (c) 2022 Dell Inc, or its subsidiaries. 6# Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 7# 8 9import logging 10import argparse 11import importlib 12import os 13import sys 14import shlex 15import json 16 17try: 18 from shlex import quote 19except ImportError: 20 from pipes import quote 21 22sys.path.append(os.path.dirname(__file__) + '/../python') 23 24import spdk.rpc as rpc # noqa 25from spdk.rpc.client import print_dict, print_json, JSONRPCException # noqa 26from spdk.rpc.helpers import deprecated_aliases # noqa 27 28 29def print_array(a): 30 print(" ".join((quote(v) for v in a))) 31 32 33if __name__ == "__main__": 34 parser = argparse.ArgumentParser( 35 description='SPDK RPC command line interface', usage='%(prog)s [options]') 36 parser.add_argument('-s', dest='server_addr', 37 help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock') 38 parser.add_argument('-p', dest='port', 39 help='RPC port number (if server_addr is IP address)', 40 default=5260, type=int) 41 parser.add_argument('-t', dest='timeout', 42 help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0', 43 default=60.0, type=float) 44 parser.add_argument('-r', dest='conn_retries', 45 help='Retry connecting to the RPC server N times with 0.2s interval. Default: 0', 46 default=0, type=int) 47 parser.add_argument('-v', dest='verbose', action='store_const', const="INFO", 48 help='Set verbose mode to INFO', default="ERROR") 49 parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'], 50 help="""Set verbose level. """) 51 parser.add_argument('--dry-run', dest='dry_run', action='store_true', help="Display request and exit") 52 parser.set_defaults(dry_run=False) 53 parser.add_argument('--go-client', dest='go_client', action='store_true', help="Use Go client") 54 parser.set_defaults(go_client=False) 55 parser.add_argument('--server', dest='is_server', action='store_true', 56 help="Start listening on stdin, parse each line as a regular rpc.py execution and create \ 57 a separate connection for each command. Each command's output ends with either \ 58 **STATUS=0 if the command succeeded or **STATUS=1 if it failed. --server is meant \ 59 to be used in conjunction with bash coproc, where stdin and stdout are connected to \ 60 pipes and can be used as a faster way to send RPC commands. If enabled, rpc.py \ 61 must be executed without any other parameters.") 62 parser.set_defaults(is_server=False) 63 parser.add_argument('--plugin', dest='rpc_plugin', help='Module name of plugin with additional RPC commands') 64 subparsers = parser.add_subparsers(help='RPC methods', dest='called_rpc_name', metavar='') 65 66 def framework_start_init(args): 67 rpc.framework_start_init(args.client) 68 69 p = subparsers.add_parser('framework_start_init', help='Start initialization of subsystems') 70 p.set_defaults(func=framework_start_init) 71 72 def framework_wait_init(args): 73 rpc.framework_wait_init(args.client) 74 75 p = subparsers.add_parser('framework_wait_init', help='Block until subsystems have been initialized') 76 p.set_defaults(func=framework_wait_init) 77 78 def rpc_get_methods(args): 79 print_dict(rpc.rpc_get_methods(args.client, 80 current=args.current, 81 include_aliases=args.include_aliases)) 82 83 p = subparsers.add_parser('rpc_get_methods', help='Get list of supported RPC methods') 84 p.add_argument('-c', '--current', help='Get list of RPC methods only callable in the current state.', action='store_true') 85 p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true') 86 p.set_defaults(func=rpc_get_methods) 87 88 def spdk_get_version(args): 89 print_json(rpc.spdk_get_version(args.client)) 90 91 p = subparsers.add_parser('spdk_get_version', help='Get SPDK version') 92 p.set_defaults(func=spdk_get_version) 93 94 def save_config(args): 95 rpc.save_config(args.client, 96 sys.stdout, 97 indent=args.indent) 98 99 p = subparsers.add_parser('save_config', help="""Write current (live) configuration of SPDK subsystems and targets 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.set_defaults(func=save_config) 104 105 def load_config(args): 106 rpc.load_config(args.client, args.json_conf, 107 include_aliases=args.include_aliases) 108 109 p = subparsers.add_parser('load_config', help="""Configure SPDK subsystems and targets using JSON RPC.""") 110 p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true') 111 p.add_argument('-j', '--json-conf', help='Valid JSON configuration', default=sys.stdin) 112 p.set_defaults(func=load_config) 113 114 def save_subsystem_config(args): 115 rpc.save_subsystem_config(args.client, 116 sys.stdout, 117 indent=args.indent, 118 name=args.name) 119 120 p = subparsers.add_parser('save_subsystem_config', help="""Write current (live) configuration of SPDK subsystem to stdout. 121 """) 122 p.add_argument('-i', '--indent', help="""Indent level. Value less than 0 mean compact mode. Default indent level is 2. 123 """, type=int, default=2) 124 p.add_argument('-n', '--name', help='Name of subsystem', required=True) 125 p.set_defaults(func=save_subsystem_config) 126 127 def load_subsystem_config(args): 128 rpc.load_subsystem_config(args.client, 129 args.json_conf) 130 131 p = subparsers.add_parser('load_subsystem_config', help="""Configure SPDK subsystem using JSON RPC.""") 132 p.add_argument('-j', '--json-conf', help='Valid JSON configuration', default=sys.stdin) 133 p.set_defaults(func=load_subsystem_config) 134 135 # app 136 def spdk_kill_instance(args): 137 rpc.app.spdk_kill_instance(args.client, 138 sig_name=args.sig_name) 139 140 p = subparsers.add_parser('spdk_kill_instance', help='Send signal to instance') 141 p.add_argument('sig_name', help='signal will be sent to server.') 142 p.set_defaults(func=spdk_kill_instance) 143 144 def framework_monitor_context_switch(args): 145 enabled = None 146 if args.enable: 147 enabled = True 148 if args.disable: 149 enabled = False 150 print_dict(rpc.app.framework_monitor_context_switch(args.client, 151 enabled=enabled)) 152 153 p = subparsers.add_parser('framework_monitor_context_switch', 154 help='Control whether the context switch monitor is enabled') 155 p.add_argument('-e', '--enable', action='store_true', help='Enable context switch monitoring') 156 p.add_argument('-d', '--disable', action='store_true', help='Disable context switch monitoring') 157 p.set_defaults(func=framework_monitor_context_switch) 158 159 def framework_get_reactors(args): 160 print_dict(rpc.app.framework_get_reactors(args.client)) 161 162 p = subparsers.add_parser( 163 'framework_get_reactors', help='Display list of all reactors') 164 p.set_defaults(func=framework_get_reactors) 165 166 def framework_set_scheduler(args): 167 rpc.app.framework_set_scheduler(args.client, 168 name=args.name, 169 period=args.period, 170 load_limit=args.load_limit, 171 core_limit=args.core_limit, 172 core_busy=args.core_busy) 173 174 p = subparsers.add_parser( 175 'framework_set_scheduler', help='Select thread scheduler that will be activated and its period (experimental)') 176 p.add_argument('name', help="Name of a scheduler") 177 p.add_argument('-p', '--period', help="Scheduler period in microseconds", type=int) 178 p.add_argument('--load-limit', help="Scheduler load limit. Reserved for dynamic scheduler", type=int, required=False) 179 p.add_argument('--core-limit', help="Scheduler core limit. Reserved for dynamic scheduler", type=int, required=False) 180 p.add_argument('--core-busy', help="Scheduler core busy limit. Reserved for dynamic schedler", type=int, required=False) 181 p.set_defaults(func=framework_set_scheduler) 182 183 def framework_get_scheduler(args): 184 print_dict(rpc.app.framework_get_scheduler(args.client)) 185 186 p = subparsers.add_parser( 187 'framework_get_scheduler', help='Display currently set scheduler and its properties.') 188 p.set_defaults(func=framework_get_scheduler) 189 190 def framework_disable_cpumask_locks(args): 191 rpc.framework_disable_cpumask_locks(args.client) 192 193 p = subparsers.add_parser('framework_disable_cpumask_locks', 194 help='Disable CPU core lock files.') 195 p.set_defaults(func=framework_disable_cpumask_locks) 196 197 def framework_enable_cpumask_locks(args): 198 rpc.framework_enable_cpumask_locks(args.client) 199 200 p = subparsers.add_parser('framework_enable_cpumask_locks', 201 help='Enable CPU core lock files.') 202 p.set_defaults(func=framework_enable_cpumask_locks) 203 204 # bdev 205 def bdev_set_options(args): 206 rpc.bdev.bdev_set_options(args.client, 207 bdev_io_pool_size=args.bdev_io_pool_size, 208 bdev_io_cache_size=args.bdev_io_cache_size, 209 bdev_auto_examine=args.bdev_auto_examine, 210 iobuf_small_cache_size=args.iobuf_small_cache_size, 211 iobuf_large_cache_size=args.iobuf_large_cache_size) 212 213 p = subparsers.add_parser('bdev_set_options', 214 help="""Set options of bdev subsystem""") 215 p.add_argument('-p', '--bdev-io-pool-size', help='Number of bdev_io structures in shared buffer pool', type=int) 216 p.add_argument('-c', '--bdev-io-cache-size', help='Maximum number of bdev_io structures cached per thread', type=int) 217 group = p.add_mutually_exclusive_group() 218 group.add_argument('-e', '--enable-auto-examine', dest='bdev_auto_examine', help='Allow to auto examine', action='store_true') 219 group.add_argument('-d', '--disable-auto-examine', dest='bdev_auto_examine', help='Not allow to auto examine', action='store_false') 220 p.add_argument('--iobuf-small-cache-size', help='Size of the small iobuf per thread cache', type=int) 221 p.add_argument('--iobuf-large-cache-size', help='Size of the large iobuf per thread cache', type=int) 222 p.set_defaults(bdev_auto_examine=True) 223 p.set_defaults(func=bdev_set_options) 224 225 def bdev_examine(args): 226 rpc.bdev.bdev_examine(args.client, 227 name=args.name) 228 229 p = subparsers.add_parser('bdev_examine', 230 help="""examine a bdev if it exists, or will examine it after it is created""") 231 p.add_argument('-b', '--name', help='Name or alias of the bdev') 232 p.set_defaults(func=bdev_examine) 233 234 def bdev_wait_for_examine(args): 235 rpc.bdev.bdev_wait_for_examine(args.client) 236 237 p = subparsers.add_parser('bdev_wait_for_examine', 238 help="""Report when all bdevs have been examined""") 239 p.set_defaults(func=bdev_wait_for_examine) 240 241 def bdev_compress_create(args): 242 print_json(rpc.bdev.bdev_compress_create(args.client, 243 base_bdev_name=args.base_bdev_name, 244 pm_path=args.pm_path, 245 lb_size=args.lb_size)) 246 247 p = subparsers.add_parser('bdev_compress_create', help='Add a compress vbdev') 248 p.add_argument('-b', '--base-bdev-name', help="Name of the base bdev") 249 p.add_argument('-p', '--pm-path', help="Path to persistent memory") 250 p.add_argument('-l', '--lb-size', help="Compressed vol logical block size (optional, if used must be 512 or 4096)", type=int) 251 p.set_defaults(func=bdev_compress_create) 252 253 def bdev_compress_delete(args): 254 rpc.bdev.bdev_compress_delete(args.client, 255 name=args.name) 256 257 p = subparsers.add_parser('bdev_compress_delete', help='Delete a compress disk') 258 p.add_argument('name', help='compress bdev name') 259 p.set_defaults(func=bdev_compress_delete) 260 261 def bdev_compress_get_orphans(args): 262 print_dict(rpc.bdev.bdev_compress_get_orphans(args.client, 263 name=args.name)) 264 p = subparsers.add_parser( 265 'bdev_compress_get_orphans', help='Display list of orphaned compress bdevs.') 266 p.add_argument('-b', '--name', help="Name of a comp bdev. Example: COMP_Nvme0n1", required=False) 267 p.set_defaults(func=bdev_compress_get_orphans) 268 269 def bdev_crypto_create(args): 270 print_json(rpc.bdev.bdev_crypto_create(args.client, 271 base_bdev_name=args.base_bdev_name, 272 name=args.name, 273 crypto_pmd=args.crypto_pmd, 274 key=args.key, 275 cipher=args.cipher, 276 key2=args.key2, 277 key_name=args.key_name)) 278 p = subparsers.add_parser('bdev_crypto_create', help='Add a crypto vbdev') 279 p.add_argument('base_bdev_name', help="Name of the base bdev") 280 p.add_argument('name', help="Name of the crypto vbdev") 281 p.add_argument('-p', '--crypto-pmd', help="Name of the crypto device driver. Obsolete, see dpdk_cryptodev_set_driver", required=False) 282 p.add_argument('-k', '--key', help="Key. Obsolete, see accel_crypto_key_create", required=False) 283 p.add_argument('-c', '--cipher', help="cipher to use. Obsolete, see accel_crypto_key_create", required=False) 284 p.add_argument('-k2', '--key2', help="2nd key for cipher AES_XTS. Obsolete, see accel_crypto_key_create", default=None) 285 p.add_argument('-n', '--key-name', help="Key name to use, see accel_crypto_key_create", required=False) 286 p.set_defaults(func=bdev_crypto_create) 287 288 def bdev_crypto_delete(args): 289 rpc.bdev.bdev_crypto_delete(args.client, 290 name=args.name) 291 292 p = subparsers.add_parser('bdev_crypto_delete', help='Delete a crypto disk') 293 p.add_argument('name', help='crypto bdev name') 294 p.set_defaults(func=bdev_crypto_delete) 295 296 def bdev_ocf_create(args): 297 print_json(rpc.bdev.bdev_ocf_create(args.client, 298 name=args.name, 299 mode=args.mode, 300 cache_line_size=args.cache_line_size, 301 cache_bdev_name=args.cache_bdev_name, 302 core_bdev_name=args.core_bdev_name)) 303 p = subparsers.add_parser('bdev_ocf_create', help='Add an OCF block device') 304 p.add_argument('name', help='Name of resulting OCF bdev') 305 p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo']) 306 p.add_argument( 307 '--cache-line-size', 308 help='OCF cache line size. The unit is KiB', 309 type=int, 310 choices=[4, 8, 16, 32, 64], 311 required=False 312 ) 313 p.add_argument('cache_bdev_name', help='Name of underlying cache bdev') 314 p.add_argument('core_bdev_name', help='Name of underlying core bdev') 315 p.set_defaults(func=bdev_ocf_create) 316 317 def bdev_ocf_delete(args): 318 rpc.bdev.bdev_ocf_delete(args.client, 319 name=args.name) 320 321 p = subparsers.add_parser('bdev_ocf_delete', help='Delete an OCF block device') 322 p.add_argument('name', help='Name of OCF bdev') 323 p.set_defaults(func=bdev_ocf_delete) 324 325 def bdev_ocf_get_stats(args): 326 print_dict(rpc.bdev.bdev_ocf_get_stats(args.client, 327 name=args.name)) 328 p = subparsers.add_parser('bdev_ocf_get_stats', help='Get statistics of chosen OCF block device') 329 p.add_argument('name', help='Name of OCF bdev') 330 p.set_defaults(func=bdev_ocf_get_stats) 331 332 def bdev_ocf_reset_stats(args): 333 print_dict(rpc.bdev.bdev_ocf_reset_stats(args.client, 334 name=args.name)) 335 p = subparsers.add_parser('bdev_ocf_reset_stats', help='Reset statistics of chosen OCF block device') 336 p.add_argument('name', help='Name of OCF bdev') 337 p.set_defaults(func=bdev_ocf_reset_stats) 338 339 def bdev_ocf_get_bdevs(args): 340 print_dict(rpc.bdev.bdev_ocf_get_bdevs(args.client, 341 name=args.name)) 342 p = subparsers.add_parser('bdev_ocf_get_bdevs', help='Get list of OCF devices including unregistered ones') 343 p.add_argument('name', nargs='?', help='name of OCF vbdev or name of cache device or name of core device (optional)') 344 p.set_defaults(func=bdev_ocf_get_bdevs) 345 346 def bdev_ocf_set_cache_mode(args): 347 print_json(rpc.bdev.bdev_ocf_set_cache_mode(args.client, 348 name=args.name, 349 mode=args.mode)) 350 p = subparsers.add_parser('bdev_ocf_set_cache_mode', 351 help='Set cache mode of OCF block device') 352 p.add_argument('name', help='Name of OCF bdev') 353 p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo']) 354 p.set_defaults(func=bdev_ocf_set_cache_mode) 355 356 def bdev_ocf_set_seqcutoff(args): 357 rpc.bdev.bdev_ocf_set_seqcutoff(args.client, 358 name=args.name, 359 policy=args.policy, 360 threshold=args.threshold, 361 promotion_count=args.promotion_count) 362 p = subparsers.add_parser('bdev_ocf_set_seqcutoff', 363 help='Set sequential cutoff parameters on all cores for the given OCF cache device') 364 p.add_argument('name', help='Name of OCF cache bdev') 365 p.add_argument('-t', '--threshold', type=int, 366 help='Activation threshold [KiB]') 367 p.add_argument('-c', '--promotion-count', type=int, 368 help='Promotion request count') 369 p.add_argument('-p', '--policy', choices=['always', 'full', 'never'], required=True, 370 help='Sequential cutoff policy') 371 p.set_defaults(func=bdev_ocf_set_seqcutoff) 372 373 def bdev_ocf_flush_start(args): 374 rpc.bdev.bdev_ocf_flush_start(args.client, name=args.name) 375 p = subparsers.add_parser('bdev_ocf_flush_start', 376 help='Start flushing OCF cache device') 377 p.add_argument('name', help='Name of OCF bdev') 378 p.set_defaults(func=bdev_ocf_flush_start) 379 380 def bdev_ocf_flush_status(args): 381 print_json(rpc.bdev.bdev_ocf_flush_status(args.client, name=args.name)) 382 p = subparsers.add_parser('bdev_ocf_flush_status', 383 help='Get flush status of OCF cache device') 384 p.add_argument('name', help='Name of OCF bdev') 385 p.set_defaults(func=bdev_ocf_flush_status) 386 387 def bdev_malloc_create(args): 388 num_blocks = (args.total_size * 1024 * 1024) // args.block_size 389 print_json(rpc.bdev.bdev_malloc_create(args.client, 390 num_blocks=int(num_blocks), 391 block_size=args.block_size, 392 physical_block_size=args.physical_block_size, 393 name=args.name, 394 uuid=args.uuid, 395 optimal_io_boundary=args.optimal_io_boundary, 396 md_size=args.md_size, 397 md_interleave=args.md_interleave, 398 dif_type=args.dif_type, 399 dif_is_head_of_md=args.dif_is_head_of_md)) 400 p = subparsers.add_parser('bdev_malloc_create', help='Create a bdev with malloc backend') 401 p.add_argument('-b', '--name', help="Name of the bdev") 402 p.add_argument('-u', '--uuid', help="UUID of the bdev") 403 p.add_argument( 404 'total_size', help='Size of malloc bdev in MB (float > 0)', type=float) 405 p.add_argument('block_size', help='Data block size for this bdev', type=int) 406 p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int) 407 p.add_argument('-o', '--optimal-io-boundary', help="""Split on optimal IO boundary, in number of 408 blocks, default 0 (disabled)""", type=int) 409 p.add_argument('-m', '--md-size', type=int, 410 help='Metadata size for this bdev (0, 8, 16, 32, 64, or 128). Default is 0.') 411 p.add_argument('-i', '--md-interleave', action='store_true', 412 help='Metadata location, interleaved if set, and separated if omitted.') 413 p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3], 414 help='Protection information type. Parameter --md-size needs' 415 'to be set along --dif-type. Default=0 - no protection.') 416 p.add_argument('-d', '--dif-is-head-of-md', action='store_true', 417 help='Protection information is in the first 8 bytes of metadata. Default=false.') 418 p.set_defaults(func=bdev_malloc_create) 419 420 def bdev_malloc_delete(args): 421 rpc.bdev.bdev_malloc_delete(args.client, 422 name=args.name) 423 424 p = subparsers.add_parser('bdev_malloc_delete', help='Delete a malloc disk') 425 p.add_argument('name', help='malloc bdev name') 426 p.set_defaults(func=bdev_malloc_delete) 427 428 def bdev_null_create(args): 429 num_blocks = (args.total_size * 1024 * 1024) // args.block_size 430 if args.dif_type and not args.md_size: 431 print("ERROR: --md-size must be > 0 when --dif-type is > 0") 432 exit(1) 433 print_json(rpc.bdev.bdev_null_create(args.client, 434 num_blocks=num_blocks, 435 block_size=args.block_size, 436 physical_block_size=args.physical_block_size, 437 name=args.name, 438 uuid=args.uuid, 439 md_size=args.md_size, 440 dif_type=args.dif_type, 441 dif_is_head_of_md=args.dif_is_head_of_md)) 442 443 p = subparsers.add_parser('bdev_null_create', help='Add a bdev with null backend') 444 p.add_argument('name', help='Block device name') 445 p.add_argument('-u', '--uuid', help='UUID of the bdev') 446 p.add_argument('total_size', help='Size of null bdev in MB (int > 0). Includes only data blocks.', type=int) 447 p.add_argument('block_size', help='Data block size for this bdev.', type=int) 448 p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int) 449 p.add_argument('-m', '--md-size', type=int, 450 help='Metadata size for this bdev. Default=0.') 451 p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3], 452 help='Protection information type. Parameter --md-size needs' 453 'to be set along --dif-type. Default=0 - no protection.') 454 p.add_argument('-d', '--dif-is-head-of-md', action='store_true', 455 help='Protection information is in the first 8 bytes of metadata. Default=false.') 456 p.set_defaults(func=bdev_null_create) 457 458 def bdev_null_delete(args): 459 rpc.bdev.bdev_null_delete(args.client, 460 name=args.name) 461 462 p = subparsers.add_parser('bdev_null_delete', help='Delete a null bdev') 463 p.add_argument('name', help='null bdev name') 464 p.set_defaults(func=bdev_null_delete) 465 466 def bdev_null_resize(args): 467 print_json(rpc.bdev.bdev_null_resize(args.client, 468 name=args.name, 469 new_size=int(args.new_size))) 470 471 p = subparsers.add_parser('bdev_null_resize', 472 help='Resize a null bdev') 473 p.add_argument('name', help='null bdev name') 474 p.add_argument('new_size', help='new bdev size for resize operation. The unit is MiB') 475 p.set_defaults(func=bdev_null_resize) 476 477 def bdev_aio_create(args): 478 print_json(rpc.bdev.bdev_aio_create(args.client, 479 filename=args.filename, 480 name=args.name, 481 block_size=args.block_size, 482 readonly=args.readonly, 483 fallocate=args.fallocate)) 484 485 p = subparsers.add_parser('bdev_aio_create', help='Add a bdev with aio backend') 486 p.add_argument('filename', help='Path to device or file (ex: /dev/sda)') 487 p.add_argument('name', help='Block device name') 488 p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?') 489 p.add_argument("-r", "--readonly", action='store_true', help='Set this bdev as read-only') 490 p.add_argument("--fallocate", action='store_true', help='Support unmap/writezeros by fallocate') 491 p.set_defaults(func=bdev_aio_create) 492 493 def bdev_aio_rescan(args): 494 print_json(rpc.bdev.bdev_aio_rescan(args.client, 495 name=args.name)) 496 497 p = subparsers.add_parser('bdev_aio_rescan', help='Rescan a bdev size with aio backend') 498 p.add_argument('name', help='Block device name') 499 p.set_defaults(func=bdev_aio_rescan) 500 501 def bdev_aio_delete(args): 502 rpc.bdev.bdev_aio_delete(args.client, 503 name=args.name) 504 505 p = subparsers.add_parser('bdev_aio_delete', help='Delete an aio disk') 506 p.add_argument('name', help='aio bdev name') 507 p.set_defaults(func=bdev_aio_delete) 508 509 def bdev_uring_create(args): 510 print_json(rpc.bdev.bdev_uring_create(args.client, 511 filename=args.filename, 512 name=args.name, 513 block_size=args.block_size)) 514 515 p = subparsers.add_parser('bdev_uring_create', help='Create a bdev with io_uring backend') 516 p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)') 517 p.add_argument('name', help='bdev name') 518 p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?') 519 p.set_defaults(func=bdev_uring_create) 520 521 def bdev_uring_delete(args): 522 rpc.bdev.bdev_uring_delete(args.client, 523 name=args.name) 524 525 p = subparsers.add_parser('bdev_uring_delete', help='Delete a uring bdev') 526 p.add_argument('name', help='uring bdev name') 527 p.set_defaults(func=bdev_uring_delete) 528 529 def bdev_xnvme_create(args): 530 print_json(rpc.bdev.bdev_xnvme_create(args.client, 531 filename=args.filename, 532 name=args.name, 533 io_mechanism=args.io_mechanism)) 534 535 p = subparsers.add_parser('bdev_xnvme_create', help='Create a bdev with xNVMe backend') 536 p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)') 537 p.add_argument('name', help='name of xNVMe bdev to create') 538 p.add_argument('io_mechanism', help='IO mechanism to use (ex: libaio, io_uring, io_uring_cmd, etc.)') 539 p.add_argument('conserve_cpu', action='store_true', help='Whether or not to conserve CPU when polling') 540 p.set_defaults(func=bdev_xnvme_create) 541 542 def bdev_xnvme_delete(args): 543 rpc.bdev.bdev_xnvme_delete(args.client, 544 name=args.name) 545 546 p = subparsers.add_parser('bdev_xnvme_delete', help='Delete a xNVMe bdev') 547 p.add_argument('name', help='xNVMe bdev name') 548 p.set_defaults(func=bdev_xnvme_delete) 549 550 def bdev_nvme_set_options(args): 551 rpc.bdev.bdev_nvme_set_options(args.client, 552 action_on_timeout=args.action_on_timeout, 553 timeout_us=args.timeout_us, 554 timeout_admin_us=args.timeout_admin_us, 555 keep_alive_timeout_ms=args.keep_alive_timeout_ms, 556 retry_count=args.retry_count, 557 arbitration_burst=args.arbitration_burst, 558 low_priority_weight=args.low_priority_weight, 559 medium_priority_weight=args.medium_priority_weight, 560 high_priority_weight=args.high_priority_weight, 561 nvme_adminq_poll_period_us=args.nvme_adminq_poll_period_us, 562 nvme_ioq_poll_period_us=args.nvme_ioq_poll_period_us, 563 io_queue_requests=args.io_queue_requests, 564 delay_cmd_submit=args.delay_cmd_submit, 565 transport_retry_count=args.transport_retry_count, 566 bdev_retry_count=args.bdev_retry_count, 567 transport_ack_timeout=args.transport_ack_timeout, 568 ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec, 569 reconnect_delay_sec=args.reconnect_delay_sec, 570 fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec, 571 disable_auto_failback=args.disable_auto_failback, 572 generate_uuids=args.generate_uuids, 573 transport_tos=args.transport_tos, 574 nvme_error_stat=args.nvme_error_stat, 575 rdma_srq_size=args.rdma_srq_size, 576 io_path_stat=args.io_path_stat, 577 allow_accel_sequence=args.allow_accel_sequence, 578 rdma_max_cq_size=args.rdma_max_cq_size) 579 580 p = subparsers.add_parser('bdev_nvme_set_options', 581 help='Set options for the bdev nvme type. This is startup command.') 582 p.add_argument('-a', '--action-on-timeout', 583 help="Action to take on command time out. Valid values are: none, reset, abort") 584 p.add_argument('-t', '--timeout-us', 585 help="Timeout for each command, in microseconds. If 0, don't track timeouts.", type=int) 586 p.add_argument('--timeout-admin-us', 587 help="Timeout for each admin command, in microseconds. If 0, treat same as io timeouts.", type=int) 588 p.add_argument('-k', '--keep-alive-timeout-ms', 589 help="Keep alive timeout period in millisecond. If 0, disable keep-alive.", type=int) 590 p.add_argument('-n', '--retry-count', 591 help='the number of attempts per I/O when an I/O fails. (deprecated, please use --transport-retry-count.)', type=int) 592 p.add_argument('--arbitration-burst', 593 help='the value is expressed as a power of two', type=int) 594 p.add_argument('--low-priority-weight', 595 help='the maximum number of commands that the controller may launch at one time from a low priority queue', type=int) 596 p.add_argument('--medium-priority-weight', 597 help='the maximum number of commands that the controller may launch at one time from a medium priority queue', type=int) 598 p.add_argument('--high-priority-weight', 599 help='the maximum number of commands that the controller may launch at one time from a high priority queue', type=int) 600 p.add_argument('-p', '--nvme-adminq-poll-period-us', 601 help='How often the admin queue is polled for asynchronous events', type=int) 602 p.add_argument('-i', '--nvme-ioq-poll-period-us', 603 help='How often to poll I/O queues for completions', type=int) 604 p.add_argument('-s', '--io-queue-requests', 605 help='The number of requests allocated for each NVMe I/O queue. Default: 512', type=int) 606 p.add_argument('-d', '--disable-delay-cmd-submit', 607 help='Disable delaying NVMe command submission, i.e. no batching of multiple commands', 608 action='store_false', dest='delay_cmd_submit') 609 p.add_argument('-c', '--transport-retry-count', 610 help='the number of attempts per I/O in the transport layer when an I/O fails.', type=int) 611 p.add_argument('-r', '--bdev-retry-count', 612 help='the number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries.', type=int) 613 p.add_argument('-e', '--transport-ack-timeout', 614 help="""Time to wait ack until packet retransmission for RDMA or until closes connection for TCP. 615 Range 0-31 where 0 is driver-specific default value.""", type=int) 616 p.add_argument('-l', '--ctrlr-loss-timeout-sec', 617 help="""Time to wait until ctrlr is reconnected before deleting ctrlr. 618 -1 means infinite reconnect retries. 0 means no reconnect retry. 619 If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero. 620 If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than 621 reconnect_delay_sec. 622 This can be overridden by bdev_nvme_attach_controller.""", 623 type=int) 624 p.add_argument('-o', '--reconnect-delay-sec', 625 help="""Time to delay a reconnect retry. 626 If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero. 627 If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero. 628 If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and 629 less than ctrlr_loss_timeout_sec. 630 This can be overridden by bdev_nvme_attach_controller.""", 631 type=int) 632 p.add_argument('-u', '--fast-io-fail-timeout-sec', 633 help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr. 634 0 means no such timeout. 635 If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and 636 less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. 637 This can be overridden by bdev_nvme_attach_controller.""", 638 type=int) 639 p.add_argument('-f', '--disable-auto-failback', 640 help="""Disable automatic failback. bdev_nvme_set_preferred_path can be used to do manual failback. 641 By default, immediately failback to the preferred I/O path if it restored.""", 642 action='store_true') 643 p.add_argument('--generate-uuids', 644 help="""Enable generation of unique identifiers for NVMe bdevs only if they do 645 not provide UUID themselves. These strings are based on device serial number and 646 namespace ID and will always be the same for that device.""", action='store_true') 647 p.add_argument('--transport-tos', 648 help="""IPv4 Type of Service value. Only applicable for RDMA transports. 649 The default is 0 which means no TOS is applied.""", type=int) 650 p.add_argument('-m', '--nvme-error-stat', help="Enable collecting NVMe error counts.", action='store_true') 651 p.add_argument('-q', '--rdma-srq-size', 652 help='Set the size of a shared rdma receive queue. Default: 0 (disabled)', type=int) 653 p.add_argument('--io-path-stat', 654 help="""Enable collecting I/O path stat of each io path.""", 655 action='store_true') 656 p.add_argument('--allow-accel-sequence', 657 help='''Allow NVMe bdevs to advertise support for accel sequences if the 658 controller also supports them.''', action='store_true') 659 p.add_argument('--rdma-max-cq-size', 660 help='The maximum size of a rdma completion queue. Default: 0 (unlimited)', type=int) 661 662 p.set_defaults(func=bdev_nvme_set_options) 663 664 def bdev_nvme_set_hotplug(args): 665 rpc.bdev.bdev_nvme_set_hotplug(args.client, enable=args.enable, period_us=args.period_us) 666 667 p = subparsers.add_parser('bdev_nvme_set_hotplug', help='Set hotplug options for bdev nvme type.') 668 p.add_argument('-d', '--disable', dest='enable', default=False, action='store_false', help="Disable hotplug (default)") 669 p.add_argument('-e', '--enable', dest='enable', action='store_true', help="Enable hotplug") 670 p.add_argument('-r', '--period-us', 671 help='How often the hotplug is processed for insert and remove events', type=int) 672 p.set_defaults(func=bdev_nvme_set_hotplug) 673 674 def bdev_nvme_attach_controller(args): 675 print_array(rpc.bdev.bdev_nvme_attach_controller(args.client, 676 name=args.name, 677 trtype=args.trtype, 678 traddr=args.traddr, 679 adrfam=args.adrfam, 680 trsvcid=args.trsvcid, 681 priority=args.priority, 682 subnqn=args.subnqn, 683 hostnqn=args.hostnqn, 684 hostaddr=args.hostaddr, 685 hostsvcid=args.hostsvcid, 686 prchk_reftag=args.prchk_reftag, 687 prchk_guard=args.prchk_guard, 688 hdgst=args.hdgst, 689 ddgst=args.ddgst, 690 fabrics_timeout=args.fabrics_timeout, 691 multipath=args.multipath, 692 num_io_queues=args.num_io_queues, 693 ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec, 694 reconnect_delay_sec=args.reconnect_delay_sec, 695 fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec, 696 psk=args.psk, 697 max_bdevs=args.max_bdevs)) 698 699 p = subparsers.add_parser('bdev_nvme_attach_controller', help='Add bdevs with nvme backend') 700 p.add_argument('-b', '--name', help="Name of the NVMe controller, prefix for each bdev name", required=True) 701 p.add_argument('-t', '--trtype', 702 help='NVMe-oF target trtype: e.g., rdma, pcie', required=True) 703 p.add_argument('-a', '--traddr', 704 help='NVMe-oF target address: e.g., an ip address or BDF', required=True) 705 p.add_argument('-f', '--adrfam', 706 help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 707 p.add_argument('-s', '--trsvcid', 708 help='NVMe-oF target trsvcid: e.g., a port number') 709 p.add_argument('-p', '--priority', 710 help='NVMe-oF connection priority: e.g., a priority number') 711 p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn') 712 p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn') 713 p.add_argument('-i', '--hostaddr', 714 help='NVMe-oF host address: e.g., an ip address') 715 p.add_argument('-c', '--hostsvcid', 716 help='NVMe-oF host svcid: e.g., a port number') 717 p.add_argument('-r', '--prchk-reftag', 718 help='Enable checking of PI reference tag for I/O processing.', action='store_true') 719 p.add_argument('-g', '--prchk-guard', 720 help='Enable checking of PI guard for I/O processing.', action='store_true') 721 p.add_argument('-e', '--hdgst', 722 help='Enable TCP header digest.', action='store_true') 723 p.add_argument('-d', '--ddgst', 724 help='Enable TCP data digest.', action='store_true') 725 p.add_argument('--fabrics-timeout', type=int, help='Fabrics connect timeout in microseconds') 726 p.add_argument('-x', '--multipath', help='Set multipath behavior (disable, failover, multipath)') 727 p.add_argument('--num-io-queues', type=int, help='Set the number of IO queues to request during initialization.') 728 p.add_argument('-l', '--ctrlr-loss-timeout-sec', 729 help="""Time to wait until ctrlr is reconnected before deleting ctrlr. 730 -1 means infinite reconnect retries. 0 means no reconnect retry. 731 If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero. 732 If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than 733 reconnect_delay_sec.""", 734 type=int) 735 p.add_argument('-o', '--reconnect-delay-sec', 736 help="""Time to delay a reconnect retry. 737 If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero. 738 If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero. 739 If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and 740 less than ctrlr_loss_timeout_sec.""", 741 type=int) 742 p.add_argument('-u', '--fast-io-fail-timeout-sec', 743 help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr. 744 0 means no such timeout. 745 If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and 746 less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.""", 747 type=int) 748 p.add_argument('-k', '--psk', 749 help='Set PSK file path and enable TCP SSL socket implementation.') 750 p.add_argument('-m', '--max-bdevs', type=int, 751 help='The size of the name array for newly created bdevs. Default is 128',) 752 753 p.set_defaults(func=bdev_nvme_attach_controller) 754 755 def bdev_nvme_get_controllers(args): 756 print_dict(rpc.nvme.bdev_nvme_get_controllers(args.client, 757 name=args.name)) 758 759 p = subparsers.add_parser( 760 'bdev_nvme_get_controllers', help='Display current NVMe controllers list or required NVMe controller') 761 p.add_argument('-n', '--name', help="Name of the NVMe controller. Example: Nvme0", required=False) 762 p.set_defaults(func=bdev_nvme_get_controllers) 763 764 def bdev_nvme_detach_controller(args): 765 rpc.bdev.bdev_nvme_detach_controller(args.client, 766 name=args.name, 767 trtype=args.trtype, 768 traddr=args.traddr, 769 adrfam=args.adrfam, 770 trsvcid=args.trsvcid, 771 subnqn=args.subnqn, 772 hostaddr=args.hostaddr, 773 hostsvcid=args.hostsvcid) 774 775 p = subparsers.add_parser('bdev_nvme_detach_controller', 776 help='Detach an NVMe controller and delete any associated bdevs') 777 p.add_argument('name', help="Name of the controller") 778 p.add_argument('-t', '--trtype', 779 help='NVMe-oF target trtype: e.g., rdma, pcie') 780 p.add_argument('-a', '--traddr', 781 help='NVMe-oF target address: e.g., an ip address or BDF') 782 p.add_argument('-f', '--adrfam', 783 help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 784 p.add_argument('-s', '--trsvcid', 785 help='NVMe-oF target trsvcid: e.g., a port number') 786 p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn') 787 p.add_argument('-i', '--hostaddr', 788 help='NVMe-oF host address: e.g., an ip address') 789 p.add_argument('-c', '--hostsvcid', 790 help='NVMe-oF host svcid: e.g., a port number') 791 p.set_defaults(func=bdev_nvme_detach_controller) 792 793 def bdev_nvme_reset_controller(args): 794 rpc.bdev.bdev_nvme_reset_controller(args.client, 795 name=args.name, 796 cntlid=args.cntlid) 797 798 p = subparsers.add_parser('bdev_nvme_reset_controller', 799 help='Reset an NVMe controller or all NVMe controllers in an NVMe bdev controller') 800 p.add_argument('name', help="Name of the NVMe controller") 801 p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int) 802 p.set_defaults(func=bdev_nvme_reset_controller) 803 804 def bdev_nvme_enable_controller(args): 805 rpc.bdev.bdev_nvme_enable_controller(args.client, 806 name=args.name, 807 cntlid=args.cntlid) 808 809 p = subparsers.add_parser('bdev_nvme_enable_controller', 810 help='Enable an NVMe controller or all NVMe controllers in an NVMe bdev controller') 811 p.add_argument('name', help="Name of the NVMe controller") 812 p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int) 813 p.set_defaults(func=bdev_nvme_enable_controller) 814 815 def bdev_nvme_disable_controller(args): 816 rpc.bdev.bdev_nvme_disable_controller(args.client, 817 name=args.name, 818 cntlid=args.cntlid) 819 820 p = subparsers.add_parser('bdev_nvme_disable_controller', 821 help='Disable an NVMe controller or all NVMe controllers in an NVMe bdev controller') 822 p.add_argument('name', help="Name of the NVMe controller") 823 p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int) 824 p.set_defaults(func=bdev_nvme_disable_controller) 825 826 def bdev_nvme_start_discovery(args): 827 rpc.bdev.bdev_nvme_start_discovery(args.client, 828 name=args.name, 829 trtype=args.trtype, 830 traddr=args.traddr, 831 adrfam=args.adrfam, 832 trsvcid=args.trsvcid, 833 hostnqn=args.hostnqn, 834 wait_for_attach=args.wait_for_attach, 835 attach_timeout_ms=args.attach_timeout_ms, 836 ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec, 837 reconnect_delay_sec=args.reconnect_delay_sec, 838 fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec) 839 840 p = subparsers.add_parser('bdev_nvme_start_discovery', help='Start automatic discovery') 841 p.add_argument('-b', '--name', help="Name of the NVMe controller prefix for each bdev name", required=True) 842 p.add_argument('-t', '--trtype', 843 help='NVMe-oF target trtype: e.g., rdma, pcie', required=True) 844 p.add_argument('-a', '--traddr', 845 help='NVMe-oF target address: e.g., an ip address or BDF', required=True) 846 p.add_argument('-f', '--adrfam', 847 help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 848 p.add_argument('-s', '--trsvcid', 849 help='NVMe-oF target trsvcid: e.g., a port number') 850 p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn') 851 p.add_argument('-w', '--wait-for-attach', action='store_true', 852 help='Do not complete RPC until all discovered NVM subsystems are attached') 853 p.add_argument('-T', '--attach-timeout-ms', type=int, required=False, 854 help="""Time to wait until the discovery and all discovered NVM subsystems 855 are attached (default: 0, meaning wait indefinitely). Automatically 856 selects the --wait-for-attach option.""") 857 p.add_argument('-l', '--ctrlr-loss-timeout-sec', 858 help="""Time to wait until ctrlr is reconnected before deleting ctrlr. 859 -1 means infinite reconnect retries. 0 means no reconnect retry. 860 If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero. 861 If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than 862 reconnect_delay_sec.""", 863 type=int) 864 p.add_argument('-o', '--reconnect-delay-sec', 865 help="""Time to delay a reconnect retry. 866 If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero. 867 If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero. 868 If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and 869 less than ctrlr_loss_timeout_sec.""", 870 type=int) 871 p.add_argument('-u', '--fast-io-fail-timeout-sec', 872 help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr. 873 0 means no such timeout. 874 If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and 875 less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.""", 876 type=int) 877 p.set_defaults(func=bdev_nvme_start_discovery) 878 879 def bdev_nvme_stop_discovery(args): 880 rpc.bdev.bdev_nvme_stop_discovery(args.client, name=args.name) 881 882 p = subparsers.add_parser('bdev_nvme_stop_discovery', help='Stop automatic discovery') 883 p.add_argument('-b', '--name', help="Name of the service to stop", required=True) 884 p.set_defaults(func=bdev_nvme_stop_discovery) 885 886 def bdev_nvme_get_discovery_info(args): 887 print_dict(rpc.bdev.bdev_nvme_get_discovery_info(args.client)) 888 889 p = subparsers.add_parser('bdev_nvme_get_discovery_info', help='Get information about the automatic discovery') 890 p.set_defaults(func=bdev_nvme_get_discovery_info) 891 892 def bdev_nvme_get_io_paths(args): 893 print_dict(rpc.bdev.bdev_nvme_get_io_paths(args.client, name=args.name)) 894 895 p = subparsers.add_parser('bdev_nvme_get_io_paths', help='Display active I/O paths') 896 p.add_argument('-n', '--name', help="Name of the NVMe bdev", required=False) 897 p.set_defaults(func=bdev_nvme_get_io_paths) 898 899 def bdev_nvme_set_preferred_path(args): 900 rpc.bdev.bdev_nvme_set_preferred_path(args.client, 901 name=args.name, 902 cntlid=args.cntlid) 903 904 p = subparsers.add_parser('bdev_nvme_set_preferred_path', 905 help="""Set the preferred I/O path for an NVMe bdev when in multipath mode""") 906 p.add_argument('-b', '--name', help='Name of the NVMe bdev', required=True) 907 p.add_argument('-c', '--cntlid', help='NVMe-oF controller ID', type=int, required=True) 908 p.set_defaults(func=bdev_nvme_set_preferred_path) 909 910 def bdev_nvme_set_multipath_policy(args): 911 rpc.bdev.bdev_nvme_set_multipath_policy(args.client, 912 name=args.name, 913 policy=args.policy, 914 selector=args.selector, 915 rr_min_io=args.rr_min_io) 916 917 p = subparsers.add_parser('bdev_nvme_set_multipath_policy', 918 help="""Set multipath policy of the NVMe bdev""") 919 p.add_argument('-b', '--name', help='Name of the NVMe bdev', required=True) 920 p.add_argument('-p', '--policy', help='Multipath policy (active_passive or active_active)', required=True) 921 p.add_argument('-s', '--selector', help='Multipath selector (round_robin, queue_depth)', required=False) 922 p.add_argument('-r', '--rr-min-io', 923 help='Number of IO to route to a path before switching to another for round-robin', 924 type=int, required=False) 925 p.set_defaults(func=bdev_nvme_set_multipath_policy) 926 927 def bdev_nvme_get_path_iostat(args): 928 print_dict(rpc.bdev.bdev_nvme_get_path_iostat(args.client, 929 name=args.name)) 930 931 p = subparsers.add_parser('bdev_nvme_get_path_iostat', 932 help="""Display current I/O statistics of all the IO paths of the blockdev. It can be 933 called when io_path_stat is true.""") 934 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: NVMe0n1", required=True) 935 p.set_defaults(func=bdev_nvme_get_path_iostat) 936 937 def bdev_nvme_cuse_register(args): 938 rpc.bdev.bdev_nvme_cuse_register(args.client, 939 name=args.name) 940 941 p = subparsers.add_parser('bdev_nvme_cuse_register', 942 help='Register CUSE devices on NVMe controller') 943 p.add_argument('-n', '--name', 944 help='Name of the NVMe controller. Example: Nvme0', required=True) 945 p.set_defaults(func=bdev_nvme_cuse_register) 946 947 def bdev_nvme_cuse_unregister(args): 948 rpc.bdev.bdev_nvme_cuse_unregister(args.client, 949 name=args.name) 950 951 p = subparsers.add_parser('bdev_nvme_cuse_unregister', 952 help='Unregister CUSE devices on NVMe controller') 953 p.add_argument('-n', '--name', 954 help='Name of the NVMe controller. Example: Nvme0', required=True) 955 p.set_defaults(func=bdev_nvme_cuse_unregister) 956 957 def bdev_zone_block_create(args): 958 print_json(rpc.bdev.bdev_zone_block_create(args.client, 959 name=args.name, 960 base_bdev=args.base_bdev, 961 zone_capacity=args.zone_capacity, 962 optimal_open_zones=args.optimal_open_zones)) 963 964 p = subparsers.add_parser('bdev_zone_block_create', 965 help='Create virtual zone namespace device with block device backend') 966 p.add_argument('-b', '--name', help="Name of the zone device", required=True) 967 p.add_argument('-n', '--base-bdev', help='Name of underlying, non-zoned bdev', required=True) 968 p.add_argument('-z', '--zone-capacity', help='Surfaced zone capacity in blocks', type=int, required=True) 969 p.add_argument('-o', '--optimal-open-zones', help='Number of zones required to reach optimal write speed', type=int, required=True) 970 p.set_defaults(func=bdev_zone_block_create) 971 972 def bdev_zone_block_delete(args): 973 rpc.bdev.bdev_zone_block_delete(args.client, 974 name=args.name) 975 976 p = subparsers.add_parser('bdev_zone_block_delete', help='Delete a virtual zone namespace device') 977 p.add_argument('name', help='Virtual zone bdev name') 978 p.set_defaults(func=bdev_zone_block_delete) 979 980 def bdev_rbd_register_cluster(args): 981 config_param = None 982 if args.config_param: 983 config_param = {} 984 for entry in args.config_param: 985 parts = entry.split('=', 1) 986 if len(parts) != 2: 987 raise Exception('--config %s not in key=value form' % entry) 988 config_param[parts[0]] = parts[1] 989 print_json(rpc.bdev.bdev_rbd_register_cluster(args.client, 990 name=args.name, 991 user=args.user, 992 config_param=config_param, 993 config_file=args.config_file, 994 key_file=args.key_file, 995 core_mask=args.core_mask)) 996 997 p = subparsers.add_parser('bdev_rbd_register_cluster', 998 help='Add a Rados cluster with ceph rbd backend') 999 p.add_argument('name', help="Name of the Rados cluster only known to rbd bdev") 1000 p.add_argument('--user', help="Ceph user name (i.e. admin, not client.admin)", required=False) 1001 p.add_argument('--config-param', action='append', metavar='key=value', 1002 help="adds a key=value configuration option for rados_conf_set (default: rely on config file)") 1003 p.add_argument('--config-file', help="The file path of the Rados configuration file", required=False) 1004 p.add_argument('--key-file', help="The file path of the Rados keyring file", required=False) 1005 p.add_argument('--core-mask', help="Set core mask for librbd IO context threads", required=False) 1006 p.set_defaults(func=bdev_rbd_register_cluster) 1007 1008 def bdev_rbd_unregister_cluster(args): 1009 rpc.bdev.bdev_rbd_unregister_cluster(args.client, name=args.name) 1010 1011 p = subparsers.add_parser('bdev_rbd_unregister_cluster', 1012 help='Unregister a Rados cluster object') 1013 p.add_argument('name', help='Name of the Rados Cluster only known to rbd bdev') 1014 p.set_defaults(func=bdev_rbd_unregister_cluster) 1015 1016 def bdev_rbd_get_clusters_info(args): 1017 print_json(rpc.bdev.bdev_rbd_get_clusters_info(args.client, name=args.name)) 1018 1019 p = subparsers.add_parser('bdev_rbd_get_clusters_info', 1020 help='Display registered Rados Cluster names and related info') 1021 p.add_argument('-b', '--name', help="Name of the registered Rados Cluster Name. Example: Cluster1", required=False) 1022 p.set_defaults(func=bdev_rbd_get_clusters_info) 1023 1024 def bdev_rbd_create(args): 1025 config = None 1026 if args.config: 1027 config = {} 1028 for entry in args.config: 1029 parts = entry.split('=', 1) 1030 if len(parts) != 2: 1031 raise Exception('--config %s not in key=value form' % entry) 1032 config[parts[0]] = parts[1] 1033 print_json(rpc.bdev.bdev_rbd_create(args.client, 1034 name=args.name, 1035 user=args.user, 1036 config=config, 1037 pool_name=args.pool_name, 1038 rbd_name=args.rbd_name, 1039 block_size=args.block_size, 1040 cluster_name=args.cluster_name, 1041 uuid=args.uuid)) 1042 1043 p = subparsers.add_parser('bdev_rbd_create', help='Add a bdev with ceph rbd backend') 1044 p.add_argument('-b', '--name', help="Name of the bdev", required=False) 1045 p.add_argument('--user', help="Ceph user name (i.e. admin, not client.admin)", required=False) 1046 p.add_argument('--config', action='append', metavar='key=value', 1047 help="adds a key=value configuration option for rados_conf_set (default: rely on config file)") 1048 p.add_argument('pool_name', help='rbd pool name') 1049 p.add_argument('rbd_name', help='rbd image name') 1050 p.add_argument('block_size', help='rbd block size', type=int) 1051 p.add_argument('-c', '--cluster-name', help="cluster name to identify the Rados cluster", required=False) 1052 p.add_argument('-u', '--uuid', help="UUID of the bdev") 1053 p.set_defaults(func=bdev_rbd_create) 1054 1055 def bdev_rbd_delete(args): 1056 rpc.bdev.bdev_rbd_delete(args.client, 1057 name=args.name) 1058 1059 p = subparsers.add_parser('bdev_rbd_delete', help='Delete a rbd bdev') 1060 p.add_argument('name', help='rbd bdev name') 1061 p.set_defaults(func=bdev_rbd_delete) 1062 1063 def bdev_rbd_resize(args): 1064 print_json(rpc.bdev.bdev_rbd_resize(args.client, 1065 name=args.name, 1066 new_size=int(args.new_size))) 1067 1068 p = subparsers.add_parser('bdev_rbd_resize', 1069 help='Resize a rbd bdev') 1070 p.add_argument('name', help='rbd bdev name') 1071 p.add_argument('new_size', help='new bdev size for resize operation. The unit is MiB') 1072 p.set_defaults(func=bdev_rbd_resize) 1073 1074 def bdev_delay_create(args): 1075 print_json(rpc.bdev.bdev_delay_create(args.client, 1076 base_bdev_name=args.base_bdev_name, 1077 name=args.name, 1078 uuid=args.uuid, 1079 avg_read_latency=args.avg_read_latency, 1080 p99_read_latency=args.nine_nine_read_latency, 1081 avg_write_latency=args.avg_write_latency, 1082 p99_write_latency=args.nine_nine_write_latency)) 1083 1084 p = subparsers.add_parser('bdev_delay_create', 1085 help='Add a delay bdev on existing bdev') 1086 p.add_argument('-b', '--base-bdev-name', help="Name of the existing bdev", required=True) 1087 p.add_argument('-d', '--name', help="Name of the delay bdev", required=True) 1088 p.add_argument('-u', '--uuid', help='UUID of the bdev (optional)') 1089 p.add_argument('-r', '--avg-read-latency', 1090 help="Average latency to apply before completing read ops (in microseconds)", required=True, type=int) 1091 p.add_argument('-t', '--nine-nine-read-latency', 1092 help="latency to apply to 1 in 100 read ops (in microseconds)", required=True, type=int) 1093 p.add_argument('-w', '--avg-write-latency', 1094 help="Average latency to apply before completing write ops (in microseconds)", required=True, type=int) 1095 p.add_argument('-n', '--nine-nine-write-latency', 1096 help="latency to apply to 1 in 100 write ops (in microseconds)", required=True, type=int) 1097 p.set_defaults(func=bdev_delay_create) 1098 1099 def bdev_delay_delete(args): 1100 rpc.bdev.bdev_delay_delete(args.client, 1101 name=args.name) 1102 1103 p = subparsers.add_parser('bdev_delay_delete', help='Delete a delay bdev') 1104 p.add_argument('name', help='delay bdev name') 1105 p.set_defaults(func=bdev_delay_delete) 1106 1107 def bdev_delay_update_latency(args): 1108 print_json(rpc.bdev.bdev_delay_update_latency(args.client, 1109 delay_bdev_name=args.delay_bdev_name, 1110 latency_type=args.latency_type, 1111 latency_us=args.latency_us)) 1112 p = subparsers.add_parser('bdev_delay_update_latency', 1113 help='Update one of the latency values for a given delay bdev') 1114 p.add_argument('delay_bdev_name', help='The name of the given delay bdev') 1115 p.add_argument('latency_type', help='one of: avg_read, avg_write, p99_read, p99_write. No other values accepted.') 1116 p.add_argument('latency_us', help='new latency value in microseconds.', type=int) 1117 p.set_defaults(func=bdev_delay_update_latency) 1118 1119 def bdev_error_create(args): 1120 print_json(rpc.bdev.bdev_error_create(args.client, 1121 base_name=args.base_name, 1122 uuid=args.uuid)) 1123 1124 p = subparsers.add_parser('bdev_error_create', help='Add bdev with error injection backend') 1125 p.add_argument('base_name', help='base bdev name') 1126 p.add_argument('--uuid', help='UUID for this bdev', required=False) 1127 p.set_defaults(func=bdev_error_create) 1128 1129 def bdev_error_delete(args): 1130 rpc.bdev.bdev_error_delete(args.client, 1131 name=args.name) 1132 1133 p = subparsers.add_parser('bdev_error_delete', help='Delete an error bdev') 1134 p.add_argument('name', help='error bdev name') 1135 p.set_defaults(func=bdev_error_delete) 1136 1137 def bdev_iscsi_set_options(args): 1138 rpc.bdev.bdev_iscsi_set_options(args.client, 1139 timeout_sec=args.timeout_sec) 1140 1141 p = subparsers.add_parser('bdev_iscsi_set_options', help='Set options for the bdev iscsi type.') 1142 p.add_argument('-t', '--timeout-sec', help="Timeout for command, in seconds, if 0, don't track timeout.", type=int) 1143 p.set_defaults(func=bdev_iscsi_set_options) 1144 1145 def bdev_iscsi_create(args): 1146 print_json(rpc.bdev.bdev_iscsi_create(args.client, 1147 name=args.name, 1148 url=args.url, 1149 initiator_iqn=args.initiator_iqn)) 1150 1151 p = subparsers.add_parser('bdev_iscsi_create', 1152 help='Add bdev with iSCSI initiator backend') 1153 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 1154 p.add_argument('-i', '--initiator-iqn', help="Initiator IQN", required=True) 1155 p.add_argument('--url', help="iSCSI Lun URL", required=True) 1156 p.set_defaults(func=bdev_iscsi_create) 1157 1158 def bdev_iscsi_delete(args): 1159 rpc.bdev.bdev_iscsi_delete(args.client, 1160 name=args.name) 1161 1162 p = subparsers.add_parser('bdev_iscsi_delete', help='Delete an iSCSI bdev') 1163 p.add_argument('name', help='iSCSI bdev name') 1164 p.set_defaults(func=bdev_iscsi_delete) 1165 1166 def bdev_passthru_create(args): 1167 print_json(rpc.bdev.bdev_passthru_create(args.client, 1168 base_bdev_name=args.base_bdev_name, 1169 name=args.name, 1170 uuid=args.uuid)) 1171 1172 p = subparsers.add_parser('bdev_passthru_create', help='Add a pass through bdev on existing bdev') 1173 p.add_argument('-b', '--base-bdev-name', help="Name of the existing bdev", required=True) 1174 p.add_argument('-p', '--name', help="Name of the pass through bdev", required=True) 1175 p.add_argument('-u', '--uuid', help="UUID of the bdev") 1176 p.set_defaults(func=bdev_passthru_create) 1177 1178 def bdev_passthru_delete(args): 1179 rpc.bdev.bdev_passthru_delete(args.client, 1180 name=args.name) 1181 1182 p = subparsers.add_parser('bdev_passthru_delete', help='Delete a pass through bdev') 1183 p.add_argument('name', help='pass through bdev name') 1184 p.set_defaults(func=bdev_passthru_delete) 1185 1186 def bdev_get_bdevs(args): 1187 print_dict(rpc.bdev.bdev_get_bdevs(args.client, 1188 name=args.name, timeout=args.timeout_ms)) 1189 1190 p = subparsers.add_parser('bdev_get_bdevs', 1191 help='Display current blockdev list or required blockdev') 1192 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1", required=False) 1193 p.add_argument('-t', '--timeout-ms', help="""Time in ms to wait for the bdev to appear (only used 1194 with the -b|--name option). The default timeout is 0, meaning the RPC returns immediately 1195 whether the bdev exists or not.""", 1196 type=int, required=False) 1197 p.set_defaults(func=bdev_get_bdevs) 1198 1199 def bdev_get_iostat(args): 1200 print_dict(rpc.bdev.bdev_get_iostat(args.client, 1201 name=args.name, 1202 per_channel=args.per_channel)) 1203 1204 p = subparsers.add_parser('bdev_get_iostat', 1205 help='Display current I/O statistics of all the blockdevs or specified blockdev.') 1206 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1", required=False) 1207 p.add_argument('-c', '--per-channel', default=False, dest='per_channel', help='Display per channel IO stats for specified device', 1208 action='store_true', required=False) 1209 p.set_defaults(func=bdev_get_iostat) 1210 1211 def bdev_reset_iostat(args): 1212 rpc.bdev.bdev_reset_iostat(args.client, name=args.name, mode=args.mode) 1213 1214 p = subparsers.add_parser('bdev_reset_iostat', 1215 help='Reset I/O statistics of all the blockdevs or specified blockdev.') 1216 p.add_argument('-b', '--name', help="Name of the Blockdev. Example: Nvme0n1", required=False) 1217 p.add_argument('-m', '--mode', help="Mode to reset I/O statistics", choices=['all', 'maxmin'], required=False) 1218 p.set_defaults(func=bdev_reset_iostat) 1219 1220 def bdev_enable_histogram(args): 1221 rpc.bdev.bdev_enable_histogram(args.client, name=args.name, enable=args.enable) 1222 1223 p = subparsers.add_parser('bdev_enable_histogram', 1224 help='Enable or disable histogram for specified bdev') 1225 p.add_argument('-e', '--enable', default=True, dest='enable', action='store_true', help='Enable histograms on specified device') 1226 p.add_argument('-d', '--disable', dest='enable', action='store_false', help='Disable histograms on specified device') 1227 p.add_argument('name', help='bdev name') 1228 p.set_defaults(func=bdev_enable_histogram) 1229 1230 def bdev_get_histogram(args): 1231 print_dict(rpc.bdev.bdev_get_histogram(args.client, name=args.name)) 1232 1233 p = subparsers.add_parser('bdev_get_histogram', 1234 help='Get histogram for specified bdev') 1235 p.add_argument('name', help='bdev name') 1236 p.set_defaults(func=bdev_get_histogram) 1237 1238 def bdev_set_qd_sampling_period(args): 1239 rpc.bdev.bdev_set_qd_sampling_period(args.client, 1240 name=args.name, 1241 period=args.period) 1242 1243 p = subparsers.add_parser('bdev_set_qd_sampling_period', 1244 help="Enable or disable tracking of a bdev's queue depth.") 1245 p.add_argument('name', help='Blockdev name. Example: Malloc0') 1246 p.add_argument('period', help='Period with which to poll the block device queue depth in microseconds.' 1247 ' If set to 0, polling will be disabled.', 1248 type=int) 1249 p.set_defaults(func=bdev_set_qd_sampling_period) 1250 1251 def bdev_set_qos_limit(args): 1252 rpc.bdev.bdev_set_qos_limit(args.client, 1253 name=args.name, 1254 rw_ios_per_sec=args.rw_ios_per_sec, 1255 rw_mbytes_per_sec=args.rw_mbytes_per_sec, 1256 r_mbytes_per_sec=args.r_mbytes_per_sec, 1257 w_mbytes_per_sec=args.w_mbytes_per_sec) 1258 1259 p = subparsers.add_parser('bdev_set_qos_limit', 1260 help='Set QoS rate limit on a blockdev') 1261 p.add_argument('name', help='Blockdev name to set QoS. Example: Malloc0') 1262 p.add_argument('--rw-ios-per-sec', 1263 help='R/W IOs per second limit (>=1000, example: 20000). 0 means unlimited.', 1264 type=int, required=False) 1265 p.add_argument('--rw-mbytes-per-sec', 1266 help="R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.", 1267 type=int, required=False) 1268 p.add_argument('--r-mbytes-per-sec', 1269 help="Read megabytes per second limit (>=10, example: 100). 0 means unlimited.", 1270 type=int, required=False) 1271 p.add_argument('--w-mbytes-per-sec', 1272 help="Write megabytes per second limit (>=10, example: 100). 0 means unlimited.", 1273 type=int, required=False) 1274 p.set_defaults(func=bdev_set_qos_limit) 1275 1276 def bdev_error_inject_error(args): 1277 rpc.bdev.bdev_error_inject_error(args.client, 1278 name=args.name, 1279 io_type=args.io_type, 1280 error_type=args.error_type, 1281 num=args.num, 1282 queue_depth=args.queue_depth, 1283 corrupt_offset=args.corrupt_offset, 1284 corrupt_value=args.corrupt_value) 1285 1286 p = subparsers.add_parser('bdev_error_inject_error', help='bdev inject error') 1287 p.add_argument('name', help="""the name of the error injection bdev""") 1288 p.add_argument('io_type', help="""io_type: 'clear' 'read' 'write' 'unmap' 'flush' 'all'""") 1289 p.add_argument('error_type', help="""error_type: 'failure' 'pending' 'corrupt_data' 'nomem'""") 1290 p.add_argument( 1291 '-n', '--num', help='the number of commands you want to fail', type=int) 1292 p.add_argument( 1293 '-q', '--queue-depth', help='the queue depth at which to trigger the error', type=int) 1294 p.add_argument( 1295 '-o', '--corrupt-offset', help='the offset in bytes to xor with corrupt_value', type=int) 1296 p.add_argument( 1297 '-v', '--corrupt-value', help='the value for xor (1-255, 0 is invalid)', type=int) 1298 p.set_defaults(func=bdev_error_inject_error) 1299 1300 def bdev_nvme_apply_firmware(args): 1301 print_dict(rpc.bdev.bdev_nvme_apply_firmware(args.client, 1302 bdev_name=args.bdev_name, 1303 filename=args.filename)) 1304 1305 p = subparsers.add_parser('bdev_nvme_apply_firmware', help='Download and commit firmware to NVMe device') 1306 p.add_argument('filename', help='filename of the firmware to download') 1307 p.add_argument('bdev_name', help='name of the NVMe device') 1308 p.set_defaults(func=bdev_nvme_apply_firmware) 1309 1310 def bdev_nvme_get_transport_statistics(args): 1311 print_dict(rpc.bdev.bdev_nvme_get_transport_statistics(args.client)) 1312 1313 p = subparsers.add_parser('bdev_nvme_get_transport_statistics', 1314 help='Get bdev_nvme poll group transport statistics') 1315 p.set_defaults(func=bdev_nvme_get_transport_statistics) 1316 1317 def bdev_nvme_get_controller_health_info(args): 1318 print_dict(rpc.bdev.bdev_nvme_get_controller_health_info(args.client, 1319 name=args.name)) 1320 1321 p = subparsers.add_parser('bdev_nvme_get_controller_health_info', 1322 help='Display health log of the required NVMe bdev controller.') 1323 p.add_argument('-c', '--name', help="Name of the NVMe bdev controller. Example: Nvme0", required=True) 1324 p.set_defaults(func=bdev_nvme_get_controller_health_info) 1325 1326 # iSCSI 1327 def iscsi_set_options(args): 1328 rpc.iscsi.iscsi_set_options( 1329 args.client, 1330 auth_file=args.auth_file, 1331 node_base=args.node_base, 1332 nop_timeout=args.nop_timeout, 1333 nop_in_interval=args.nop_in_interval, 1334 disable_chap=args.disable_chap, 1335 require_chap=args.require_chap, 1336 mutual_chap=args.mutual_chap, 1337 chap_group=args.chap_group, 1338 max_sessions=args.max_sessions, 1339 max_queue_depth=args.max_queue_depth, 1340 max_connections_per_session=args.max_connections_per_session, 1341 default_time2wait=args.default_time2wait, 1342 default_time2retain=args.default_time2retain, 1343 first_burst_length=args.first_burst_length, 1344 immediate_data=args.immediate_data, 1345 error_recovery_level=args.error_recovery_level, 1346 allow_duplicated_isid=args.allow_duplicated_isid, 1347 max_large_datain_per_connection=args.max_large_datain_per_connection, 1348 max_r2t_per_connection=args.max_r2t_per_connection, 1349 pdu_pool_size=args.pdu_pool_size, 1350 immediate_data_pool_size=args.immediate_data_pool_size, 1351 data_out_pool_size=args.data_out_pool_size) 1352 1353 p = subparsers.add_parser('iscsi_set_options', 1354 help="""Set options of iSCSI subsystem""") 1355 p.add_argument('-f', '--auth-file', help='Path to CHAP shared secret file') 1356 p.add_argument('-b', '--node-base', help='Prefix of the name of iSCSI target node') 1357 p.add_argument('-o', '--nop-timeout', help='Timeout in seconds to nop-in request to the initiator', type=int) 1358 p.add_argument('-n', '--nop-in-interval', help='Time interval in secs between nop-in requests by the target', type=int) 1359 p.add_argument('-d', '--disable-chap', help="""CHAP for discovery session should be disabled. 1360 *** Mutually exclusive with --require-chap""", action='store_true') 1361 p.add_argument('-r', '--require-chap', help="""CHAP for discovery session should be required. 1362 *** Mutually exclusive with --disable-chap""", action='store_true') 1363 p.add_argument('-m', '--mutual-chap', help='CHAP for discovery session should be mutual', action='store_true') 1364 p.add_argument('-g', '--chap-group', help="""Authentication group ID for discovery session. 1365 *** Authentication group must be precreated ***""", type=int) 1366 p.add_argument('-a', '--max-sessions', help='Maximum number of sessions in the host.', type=int) 1367 p.add_argument('-q', '--max-queue-depth', help='Max number of outstanding I/Os per queue.', type=int) 1368 p.add_argument('-c', '--max-connections-per-session', help='Negotiated parameter, MaxConnections.', type=int) 1369 p.add_argument('-w', '--default-time2wait', help='Negotiated parameter, DefaultTime2Wait.', type=int) 1370 p.add_argument('-v', '--default-time2retain', help='Negotiated parameter, DefaultTime2Retain.', type=int) 1371 p.add_argument('-s', '--first-burst-length', help='Negotiated parameter, FirstBurstLength.', type=int) 1372 p.add_argument('-i', '--immediate-data', help='Negotiated parameter, ImmediateData.', action='store_true') 1373 p.add_argument('-l', '--error-recovery-level', help='Negotiated parameter, ErrorRecoveryLevel', type=int) 1374 p.add_argument('-p', '--allow-duplicated-isid', help='Allow duplicated initiator session ID.', action='store_true') 1375 p.add_argument('-x', '--max-large-datain-per-connection', help='Max number of outstanding split read I/Os per connection', type=int) 1376 p.add_argument('-k', '--max-r2t-per-connection', help='Max number of outstanding R2Ts per connection', type=int) 1377 p.add_argument('-u', '--pdu-pool-size', help='Number of PDUs in the pool', type=int) 1378 p.add_argument('-j', '--immediate-data-pool-size', help='Number of immediate data buffers in the pool', type=int) 1379 p.add_argument('-z', '--data-out-pool-size', help='Number of data out buffers in the pool', type=int) 1380 p.set_defaults(func=iscsi_set_options) 1381 1382 def iscsi_set_discovery_auth(args): 1383 rpc.iscsi.iscsi_set_discovery_auth( 1384 args.client, 1385 disable_chap=args.disable_chap, 1386 require_chap=args.require_chap, 1387 mutual_chap=args.mutual_chap, 1388 chap_group=args.chap_group) 1389 1390 p = subparsers.add_parser('iscsi_set_discovery_auth', 1391 help="""Set CHAP authentication for discovery session.""") 1392 p.add_argument('-d', '--disable-chap', help="""CHAP for discovery session should be disabled. 1393 *** Mutually exclusive with --require-chap""", action='store_true') 1394 p.add_argument('-r', '--require-chap', help="""CHAP for discovery session should be required. 1395 *** Mutually exclusive with --disable-chap""", action='store_true') 1396 p.add_argument('-m', '--mutual-chap', help='CHAP for discovery session should be mutual', action='store_true') 1397 p.add_argument('-g', '--chap-group', help="""Authentication group ID for discovery session. 1398 *** Authentication group must be precreated ***""", type=int) 1399 p.set_defaults(func=iscsi_set_discovery_auth) 1400 1401 def iscsi_create_auth_group(args): 1402 secrets = None 1403 if args.secrets: 1404 secrets = [dict(u.split(":") for u in a.split(" ")) for a in args.secrets.split(",")] 1405 1406 rpc.iscsi.iscsi_create_auth_group(args.client, tag=args.tag, secrets=secrets) 1407 1408 p = subparsers.add_parser('iscsi_create_auth_group', 1409 help='Create authentication group for CHAP authentication.') 1410 p.add_argument('tag', help='Authentication group tag (unique, integer > 0).', type=int) 1411 p.add_argument('-c', '--secrets', help="""Comma-separated list of CHAP secrets 1412<user:user_name secret:chap_secret muser:mutual_user_name msecret:mutual_chap_secret> enclosed in quotes. 1413Format: 'user:u1 secret:s1 muser:mu1 msecret:ms1,user:u2 secret:s2 muser:mu2 msecret:ms2'""", required=False) 1414 p.set_defaults(func=iscsi_create_auth_group) 1415 1416 def iscsi_delete_auth_group(args): 1417 rpc.iscsi.iscsi_delete_auth_group(args.client, tag=args.tag) 1418 1419 p = subparsers.add_parser('iscsi_delete_auth_group', 1420 help='Delete an authentication group.') 1421 p.add_argument('tag', help='Authentication group tag', type=int) 1422 p.set_defaults(func=iscsi_delete_auth_group) 1423 1424 def iscsi_auth_group_add_secret(args): 1425 rpc.iscsi.iscsi_auth_group_add_secret( 1426 args.client, 1427 tag=args.tag, 1428 user=args.user, 1429 secret=args.secret, 1430 muser=args.muser, 1431 msecret=args.msecret) 1432 1433 p = subparsers.add_parser('iscsi_auth_group_add_secret', 1434 help='Add a secret to an authentication group.') 1435 p.add_argument('tag', help='Authentication group tag', type=int) 1436 p.add_argument('-u', '--user', help='User name for one-way CHAP authentication', required=True) 1437 p.add_argument('-s', '--secret', help='Secret for one-way CHAP authentication', required=True) 1438 p.add_argument('-m', '--muser', help='User name for mutual CHAP authentication') 1439 p.add_argument('-r', '--msecret', help='Secret for mutual CHAP authentication') 1440 p.set_defaults(func=iscsi_auth_group_add_secret) 1441 1442 def iscsi_auth_group_remove_secret(args): 1443 rpc.iscsi.iscsi_auth_group_remove_secret(args.client, tag=args.tag, user=args.user) 1444 1445 p = subparsers.add_parser('iscsi_auth_group_remove_secret', 1446 help='Remove a secret from an authentication group.') 1447 p.add_argument('tag', help='Authentication group tag', type=int) 1448 p.add_argument('-u', '--user', help='User name for one-way CHAP authentication', required=True) 1449 p.set_defaults(func=iscsi_auth_group_remove_secret) 1450 1451 def iscsi_get_auth_groups(args): 1452 print_dict(rpc.iscsi.iscsi_get_auth_groups(args.client)) 1453 1454 p = subparsers.add_parser('iscsi_get_auth_groups', 1455 help='Display current authentication group configuration') 1456 p.set_defaults(func=iscsi_get_auth_groups) 1457 1458 def iscsi_get_portal_groups(args): 1459 print_dict(rpc.iscsi.iscsi_get_portal_groups(args.client)) 1460 1461 p = subparsers.add_parser('iscsi_get_portal_groups', help='Display current portal group configuration') 1462 p.set_defaults(func=iscsi_get_portal_groups) 1463 1464 def iscsi_get_initiator_groups(args): 1465 print_dict(rpc.iscsi.iscsi_get_initiator_groups(args.client)) 1466 1467 p = subparsers.add_parser('iscsi_get_initiator_groups', 1468 help='Display current initiator group configuration') 1469 p.set_defaults(func=iscsi_get_initiator_groups) 1470 1471 def iscsi_get_target_nodes(args): 1472 print_dict(rpc.iscsi.iscsi_get_target_nodes(args.client)) 1473 1474 p = subparsers.add_parser('iscsi_get_target_nodes', help='Display target nodes') 1475 p.set_defaults(func=iscsi_get_target_nodes) 1476 1477 def iscsi_create_target_node(args): 1478 luns = [] 1479 for u in args.bdev_name_id_pairs.strip().split(" "): 1480 bdev_name, lun_id = u.split(":") 1481 luns.append({"bdev_name": bdev_name, "lun_id": int(lun_id)}) 1482 1483 pg_ig_maps = [] 1484 for u in args.pg_ig_mappings.strip().split(" "): 1485 pg, ig = u.split(":") 1486 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 1487 1488 rpc.iscsi.iscsi_create_target_node( 1489 args.client, 1490 luns=luns, 1491 pg_ig_maps=pg_ig_maps, 1492 name=args.name, 1493 alias_name=args.alias_name, 1494 queue_depth=args.queue_depth, 1495 chap_group=args.chap_group, 1496 disable_chap=args.disable_chap, 1497 require_chap=args.require_chap, 1498 mutual_chap=args.mutual_chap, 1499 header_digest=args.header_digest, 1500 data_digest=args.data_digest) 1501 1502 p = subparsers.add_parser('iscsi_create_target_node', help='Add a target node') 1503 p.add_argument('name', help='Target node name (ASCII)') 1504 p.add_argument('alias_name', help='Target node alias name (ASCII)') 1505 p.add_argument('bdev_name_id_pairs', help="""Whitespace-separated list of <bdev name:LUN ID> pairs enclosed 1506 in quotes. Format: 'bdev_name0:id0 bdev_name1:id1' etc 1507 Example: 'Malloc0:0 Malloc1:1 Malloc5:2' 1508 *** The bdevs must pre-exist *** 1509 *** LUN0 (id = 0) is required *** 1510 *** bdevs names cannot contain space or colon characters ***""") 1511 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 1512 Whitespace separated, quoted, mapping defined with colon 1513 separated list of "tags" (int > 0) 1514 Example: '1:1 2:2 2:1' 1515 *** The Portal/Initiator Groups must be precreated ***""") 1516 p.add_argument('queue_depth', help='Desired target queue depth', type=int) 1517 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this target node. 1518 *** Authentication group must be precreated ***""", type=int) 1519 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this target node. 1520 *** Mutually exclusive with --require-chap ***""", action='store_true') 1521 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this target node. 1522 *** Mutually exclusive with --disable-chap ***""", action='store_true') 1523 p.add_argument( 1524 '-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', action='store_true') 1525 p.add_argument('-H', '--header-digest', 1526 help='Header Digest should be required for this target node.', action='store_true') 1527 p.add_argument('-D', '--data-digest', 1528 help='Data Digest should be required for this target node.', action='store_true') 1529 p.set_defaults(func=iscsi_create_target_node) 1530 1531 def iscsi_target_node_add_lun(args): 1532 rpc.iscsi.iscsi_target_node_add_lun( 1533 args.client, 1534 name=args.name, 1535 bdev_name=args.bdev_name, 1536 lun_id=args.lun_id) 1537 1538 p = subparsers.add_parser('iscsi_target_node_add_lun', 1539 help='Add LUN to the target node') 1540 p.add_argument('name', help='Target node name (ASCII)') 1541 p.add_argument('bdev_name', help="""bdev name enclosed in quotes. 1542 *** bdev name cannot contain space or colon characters ***""") 1543 p.add_argument('-i', dest='lun_id', help="""LUN ID (integer >= 0) 1544 *** If LUN ID is omitted or -1, the lowest free one is assigned ***""", type=int, required=False) 1545 p.set_defaults(func=iscsi_target_node_add_lun) 1546 1547 def iscsi_target_node_set_auth(args): 1548 rpc.iscsi.iscsi_target_node_set_auth( 1549 args.client, 1550 name=args.name, 1551 chap_group=args.chap_group, 1552 disable_chap=args.disable_chap, 1553 require_chap=args.require_chap, 1554 mutual_chap=args.mutual_chap) 1555 1556 p = subparsers.add_parser('iscsi_target_node_set_auth', 1557 help='Set CHAP authentication for the target node') 1558 p.add_argument('name', help='Target node name (ASCII)') 1559 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this target node. 1560 *** Authentication group must be precreated ***""", type=int) 1561 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this target node. 1562 *** Mutually exclusive with --require-chap ***""", action='store_true') 1563 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this target node. 1564 *** Mutually exclusive with --disable-chap ***""", action='store_true') 1565 p.add_argument('-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', 1566 action='store_true') 1567 p.set_defaults(func=iscsi_target_node_set_auth) 1568 1569 def iscsi_target_node_add_pg_ig_maps(args): 1570 pg_ig_maps = [] 1571 for u in args.pg_ig_mappings.strip().split(" "): 1572 pg, ig = u.split(":") 1573 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 1574 rpc.iscsi.iscsi_target_node_add_pg_ig_maps( 1575 args.client, 1576 pg_ig_maps=pg_ig_maps, 1577 name=args.name) 1578 1579 p = subparsers.add_parser('iscsi_target_node_add_pg_ig_maps', 1580 help='Add PG-IG maps to the target node') 1581 p.add_argument('name', help='Target node name (ASCII)') 1582 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 1583 Whitespace separated, quoted, mapping defined with colon 1584 separated list of "tags" (int > 0) 1585 Example: '1:1 2:2 2:1' 1586 *** The Portal/Initiator Groups must be precreated ***""") 1587 p.set_defaults(func=iscsi_target_node_add_pg_ig_maps) 1588 1589 def iscsi_target_node_remove_pg_ig_maps(args): 1590 pg_ig_maps = [] 1591 for u in args.pg_ig_mappings.strip().split(" "): 1592 pg, ig = u.split(":") 1593 pg_ig_maps.append({"pg_tag": int(pg), "ig_tag": int(ig)}) 1594 rpc.iscsi.iscsi_target_node_remove_pg_ig_maps( 1595 args.client, pg_ig_maps=pg_ig_maps, name=args.name) 1596 1597 p = subparsers.add_parser('iscsi_target_node_remove_pg_ig_maps', 1598 help='Delete PG-IG maps from the target node') 1599 p.add_argument('name', help='Target node name (ASCII)') 1600 p.add_argument('pg_ig_mappings', help="""List of (Portal_Group_Tag:Initiator_Group_Tag) mappings 1601 Whitespace separated, quoted, mapping defined with colon 1602 separated list of "tags" (int > 0) 1603 Example: '1:1 2:2 2:1' 1604 *** The Portal/Initiator Groups must be precreated ***""") 1605 p.set_defaults(func=iscsi_target_node_remove_pg_ig_maps) 1606 1607 def iscsi_target_node_set_redirect(args): 1608 rpc.iscsi.iscsi_target_node_set_redirect( 1609 args.client, 1610 name=args.name, 1611 pg_tag=args.pg_tag, 1612 redirect_host=args.redirect_host, 1613 redirect_port=args.redirect_port) 1614 1615 p = subparsers.add_parser('iscsi_target_node_set_redirect', 1616 help="""Update redirect portal of the public portal group for the target node. 1617 Omit redirect host and port to clear previously set redirect settings.""") 1618 p.add_argument('name', help='Target node name (ASCII)') 1619 p.add_argument('pg_tag', help='Portal group tag (unique, integer > 0)', type=int) 1620 p.add_argument('-a', '--redirect-host', help='Numeric IP address for redirect portal', required=False) 1621 p.add_argument('-p', '--redirect-port', help='Numeric TCP port for redirect portal', required=False) 1622 p.set_defaults(func=iscsi_target_node_set_redirect) 1623 1624 def iscsi_target_node_request_logout(args): 1625 rpc.iscsi.iscsi_target_node_request_logout( 1626 args.client, 1627 name=args.name, 1628 pg_tag=args.pg_tag) 1629 1630 p = subparsers.add_parser('iscsi_target_node_request_logout', 1631 help="""For the target node, request connections whose portal group tag 1632 match to logout, or request all connections if portal group tag is omitted.""") 1633 p.add_argument('name', help='Target node name (ASCII)') 1634 p.add_argument('-t', '--pg-tag', help='Portal group tag (unique, integer > 0)', type=int, required=False) 1635 p.set_defaults(func=iscsi_target_node_request_logout) 1636 1637 def iscsi_create_portal_group(args): 1638 portals = [] 1639 for p in args.portal_list.strip().split(' '): 1640 ip, separator, port_cpumask = p.rpartition(':') 1641 split_port_cpumask = port_cpumask.split('@') 1642 if len(split_port_cpumask) == 1: 1643 port = port_cpumask 1644 portals.append({'host': ip, 'port': port}) 1645 else: 1646 port = split_port_cpumask[0] 1647 cpumask = split_port_cpumask[1] 1648 portals.append({'host': ip, 'port': port}) 1649 print("WARNING: Specifying a portal group with a CPU mask is no longer supported. Ignoring it.") 1650 rpc.iscsi.iscsi_create_portal_group( 1651 args.client, 1652 portals=portals, 1653 tag=args.tag, 1654 private=args.private, 1655 wait=args.wait) 1656 1657 p = subparsers.add_parser('iscsi_create_portal_group', 1658 help='Add a portal group') 1659 p.add_argument( 1660 'tag', help='Portal group tag (unique, integer > 0)', type=int) 1661 p.add_argument('portal_list', help="""List of portals in host:port format, separated by whitespace 1662 Example: '192.168.100.100:3260 192.168.100.100:3261 192.168.100.100:3262""") 1663 p.add_argument('-p', '--private', help="""Public (false) or private (true) portal group. 1664 Private portal groups do not have their portals returned by a discovery session. A public 1665 portal group may optionally specify a redirect portal for non-discovery logins. This redirect 1666 portal must be from a private portal group.""", action='store_true') 1667 p.add_argument('-w', '--wait', help="""Do not listening on portals until it is started explicitly. 1668 One major iSCSI initiator may not retry login once it failed. Hence for such initiator, listening 1669 on portals should be allowed after all associated target nodes are created.""", action='store_true') 1670 p.set_defaults(func=iscsi_create_portal_group) 1671 1672 def iscsi_start_portal_group(args): 1673 rpc.iscsi.iscsi_start_portal_group(args.client, tag=args.tag) 1674 1675 p = subparsers.add_parser('iscsi_start_portal_group', 1676 help='Start listening on portals if it is not started yet.') 1677 p.add_argument( 1678 'tag', help='Portal group tag (unique, integer > 0)', type=int) 1679 p.set_defaults(func=iscsi_start_portal_group) 1680 1681 def iscsi_create_initiator_group(args): 1682 initiators = [] 1683 netmasks = [] 1684 for i in args.initiator_list.strip().split(' '): 1685 initiators.append(i) 1686 for n in args.netmask_list.strip().split(' '): 1687 netmasks.append(n) 1688 rpc.iscsi.iscsi_create_initiator_group( 1689 args.client, 1690 tag=args.tag, 1691 initiators=initiators, 1692 netmasks=netmasks) 1693 1694 p = subparsers.add_parser('iscsi_create_initiator_group', 1695 help='Add an initiator group') 1696 p.add_argument( 1697 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1698 p.add_argument('initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1699 enclosed in quotes. Example: 'ANY' or 'iqn.2016-06.io.spdk:host1 iqn.2016-06.io.spdk:host2'""") 1700 p.add_argument('netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1701 Example: '255.255.0.0 255.248.0.0' etc""") 1702 p.set_defaults(func=iscsi_create_initiator_group) 1703 1704 def iscsi_initiator_group_add_initiators(args): 1705 initiators = None 1706 netmasks = None 1707 if args.initiator_list: 1708 initiators = [] 1709 for i in args.initiator_list.strip().split(' '): 1710 initiators.append(i) 1711 if args.netmask_list: 1712 netmasks = [] 1713 for n in args.netmask_list.strip().split(' '): 1714 netmasks.append(n) 1715 rpc.iscsi.iscsi_initiator_group_add_initiators( 1716 args.client, 1717 tag=args.tag, 1718 initiators=initiators, 1719 netmasks=netmasks) 1720 1721 p = subparsers.add_parser('iscsi_initiator_group_add_initiators', 1722 help='Add initiators to an existing initiator group') 1723 p.add_argument( 1724 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1725 p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1726 enclosed in quotes. This parameter can be omitted. Example: 'ANY' or 1727 'iqn.2016-06.io.spdk:host1 iqn.2016-06.io.spdk:host2'""", required=False) 1728 p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1729 This parameter can be omitted. Example: '255.255.0.0 255.248.0.0' etc""", required=False) 1730 p.set_defaults(func=iscsi_initiator_group_add_initiators) 1731 1732 def iscsi_initiator_group_remove_initiators(args): 1733 initiators = None 1734 netmasks = None 1735 if args.initiator_list: 1736 initiators = [] 1737 for i in args.initiator_list.strip().split(' '): 1738 initiators.append(i) 1739 if args.netmask_list: 1740 netmasks = [] 1741 for n in args.netmask_list.strip().split(' '): 1742 netmasks.append(n) 1743 rpc.iscsi.iscsi_initiator_group_remove_initiators( 1744 args.client, 1745 tag=args.tag, 1746 initiators=initiators, 1747 netmasks=netmasks) 1748 1749 p = subparsers.add_parser('iscsi_initiator_group_remove_initiators', 1750 help='Delete initiators from an existing initiator group') 1751 p.add_argument( 1752 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1753 p.add_argument('-n', dest='initiator_list', help="""Whitespace-separated list of initiator hostnames or IP addresses, 1754 enclosed in quotes. This parameter can be omitted. Example: 'ANY' or 1755 'iqn.2016-06.io.spdk:host1 iqn.2016-06.io.spdk:host2'""", required=False) 1756 p.add_argument('-m', dest='netmask_list', help="""Whitespace-separated list of initiator netmasks enclosed in quotes. 1757 This parameter can be omitted. Example: '255.255.0.0 255.248.0.0' etc""", required=False) 1758 p.set_defaults(func=iscsi_initiator_group_remove_initiators) 1759 1760 def iscsi_delete_target_node(args): 1761 rpc.iscsi.iscsi_delete_target_node( 1762 args.client, target_node_name=args.target_node_name) 1763 1764 p = subparsers.add_parser('iscsi_delete_target_node', 1765 help='Delete a target node') 1766 p.add_argument('target_node_name', 1767 help='Target node name to be deleted. Example: iqn.2016-06.io.spdk:disk1.') 1768 p.set_defaults(func=iscsi_delete_target_node) 1769 1770 def iscsi_delete_portal_group(args): 1771 rpc.iscsi.iscsi_delete_portal_group(args.client, tag=args.tag) 1772 1773 p = subparsers.add_parser('iscsi_delete_portal_group', 1774 help='Delete a portal group') 1775 p.add_argument( 1776 'tag', help='Portal group tag (unique, integer > 0)', type=int) 1777 p.set_defaults(func=iscsi_delete_portal_group) 1778 1779 def iscsi_delete_initiator_group(args): 1780 rpc.iscsi.iscsi_delete_initiator_group(args.client, tag=args.tag) 1781 1782 p = subparsers.add_parser('iscsi_delete_initiator_group', 1783 help='Delete an initiator group') 1784 p.add_argument( 1785 'tag', help='Initiator group tag (unique, integer > 0)', type=int) 1786 p.set_defaults(func=iscsi_delete_initiator_group) 1787 1788 def iscsi_portal_group_set_auth(args): 1789 rpc.iscsi.iscsi_portal_group_set_auth( 1790 args.client, 1791 tag=args.tag, 1792 chap_group=args.chap_group, 1793 disable_chap=args.disable_chap, 1794 require_chap=args.require_chap, 1795 mutual_chap=args.mutual_chap) 1796 1797 p = subparsers.add_parser('iscsi_portal_group_set_auth', 1798 help='Set CHAP authentication for discovery sessions specific for the portal group') 1799 p.add_argument('tag', help='Portal group tag (unique, integer > 0)', type=int) 1800 p.add_argument('-g', '--chap-group', help="""Authentication group ID for this portal group. 1801 *** Authentication group must be precreated ***""", type=int) 1802 p.add_argument('-d', '--disable-chap', help="""CHAP authentication should be disabled for this portal group. 1803 *** Mutually exclusive with --require-chap ***""", action='store_true') 1804 p.add_argument('-r', '--require-chap', help="""CHAP authentication should be required for this portal group. 1805 *** Mutually exclusive with --disable-chap ***""", action='store_true') 1806 p.add_argument('-m', '--mutual-chap', help='CHAP authentication should be mutual/bidirectional.', 1807 action='store_true') 1808 p.set_defaults(func=iscsi_portal_group_set_auth) 1809 1810 def iscsi_get_connections(args): 1811 print_dict(rpc.iscsi.iscsi_get_connections(args.client)) 1812 1813 p = subparsers.add_parser('iscsi_get_connections', 1814 help='Display iSCSI connections') 1815 p.set_defaults(func=iscsi_get_connections) 1816 1817 def iscsi_get_options(args): 1818 print_dict(rpc.iscsi.iscsi_get_options(args.client)) 1819 1820 p = subparsers.add_parser('iscsi_get_options', 1821 help='Display iSCSI global parameters') 1822 p.set_defaults(func=iscsi_get_options) 1823 1824 def scsi_get_devices(args): 1825 print_dict(rpc.iscsi.scsi_get_devices(args.client)) 1826 1827 p = subparsers.add_parser('scsi_get_devices', help='Display SCSI devices') 1828 p.set_defaults(func=scsi_get_devices) 1829 1830 # trace 1831 def trace_enable_tpoint_group(args): 1832 rpc.trace.trace_enable_tpoint_group(args.client, name=args.name) 1833 1834 p = subparsers.add_parser('trace_enable_tpoint_group', 1835 help='enable trace on a specific tpoint group') 1836 p.add_argument( 1837 'name', help="""trace group name we want to enable in tpoint_group_mask. 1838 (for example "bdev" for bdev trace group, "all" for all trace groups).""") 1839 p.set_defaults(func=trace_enable_tpoint_group) 1840 1841 def trace_disable_tpoint_group(args): 1842 rpc.trace.trace_disable_tpoint_group(args.client, name=args.name) 1843 1844 p = subparsers.add_parser('trace_disable_tpoint_group', 1845 help='disable trace on a specific tpoint group') 1846 p.add_argument( 1847 'name', help="""trace group name we want to disable in tpoint_group_mask. 1848 (for example "bdev" for bdev trace group, "all" for all trace groups).""") 1849 p.set_defaults(func=trace_disable_tpoint_group) 1850 1851 def trace_set_tpoint_mask(args): 1852 rpc.trace.trace_set_tpoint_mask(args.client, name=args.name, tpoint_mask=args.tpoint_mask) 1853 1854 p = subparsers.add_parser('trace_set_tpoint_mask', 1855 help='enable tracepoint mask on a specific tpoint group') 1856 p.add_argument( 1857 'name', help="""trace group name we want to enable in tpoint_group_mask. 1858 (for example "bdev" for bdev trace group)""") 1859 p.add_argument( 1860 'tpoint_mask', help="""tracepoints to be enabled inside a given trace group. 1861 (for example value of "0x3" will enable only the first two tpoints in this group)""", 1862 type=lambda m: int(m, 16)) 1863 p.set_defaults(func=trace_set_tpoint_mask) 1864 1865 def trace_clear_tpoint_mask(args): 1866 rpc.trace.trace_clear_tpoint_mask(args.client, name=args.name, tpoint_mask=args.tpoint_mask) 1867 1868 p = subparsers.add_parser('trace_clear_tpoint_mask', 1869 help='disable tracepoint mask on a specific tpoint group') 1870 p.add_argument( 1871 'name', help="""trace group name we want to disable in tpoint_group_mask. 1872 (for example "bdev" for bdev trace group)""") 1873 p.add_argument( 1874 'tpoint_mask', help="""tracepoints to be disabled inside a given trace group. 1875 (for example value of "0x3" will disable the first two tpoints in this group)""", 1876 type=lambda m: int(m, 16)) 1877 p.set_defaults(func=trace_clear_tpoint_mask) 1878 1879 def trace_get_tpoint_group_mask(args): 1880 print_dict(rpc.trace.trace_get_tpoint_group_mask(args.client)) 1881 1882 p = subparsers.add_parser('trace_get_tpoint_group_mask', help='get trace point group mask') 1883 p.set_defaults(func=trace_get_tpoint_group_mask) 1884 1885 def trace_get_info(args): 1886 print_dict(rpc.trace.trace_get_info(args.client)) 1887 1888 p = subparsers.add_parser('trace_get_info', 1889 help='get name of shared memory file and list of the available trace point groups') 1890 p.set_defaults(func=trace_get_info) 1891 1892 # log 1893 def log_set_flag(args): 1894 rpc.log.log_set_flag(args.client, flag=args.flag) 1895 1896 p = subparsers.add_parser('log_set_flag', help='set log flag') 1897 p.add_argument( 1898 'flag', help='log flag we want to set. (for example "nvme").') 1899 p.set_defaults(func=log_set_flag) 1900 1901 def log_clear_flag(args): 1902 rpc.log.log_clear_flag(args.client, flag=args.flag) 1903 1904 p = subparsers.add_parser('log_clear_flag', help='clear log flag') 1905 p.add_argument( 1906 'flag', help='log flag we want to clear. (for example "nvme").') 1907 p.set_defaults(func=log_clear_flag) 1908 1909 def log_get_flags(args): 1910 print_dict(rpc.log.log_get_flags(args.client)) 1911 1912 p = subparsers.add_parser('log_get_flags', help='get log flags') 1913 p.set_defaults(func=log_get_flags) 1914 1915 def log_set_level(args): 1916 rpc.log.log_set_level(args.client, level=args.level) 1917 1918 p = subparsers.add_parser('log_set_level', help='set log level') 1919 p.add_argument('level', help='log level we want to set. (for example "DEBUG").') 1920 p.set_defaults(func=log_set_level) 1921 1922 def log_get_level(args): 1923 print_dict(rpc.log.log_get_level(args.client)) 1924 1925 p = subparsers.add_parser('log_get_level', help='get log level') 1926 p.set_defaults(func=log_get_level) 1927 1928 def log_set_print_level(args): 1929 rpc.log.log_set_print_level(args.client, level=args.level) 1930 1931 p = subparsers.add_parser('log_set_print_level', help='set log print level') 1932 p.add_argument('level', help='log print level we want to set. (for example "DEBUG").') 1933 p.set_defaults(func=log_set_print_level) 1934 1935 def log_get_print_level(args): 1936 print_dict(rpc.log.log_get_print_level(args.client)) 1937 1938 p = subparsers.add_parser('log_get_print_level', help='get log print level') 1939 p.set_defaults(func=log_get_print_level) 1940 1941 # lvol 1942 def bdev_lvol_create_lvstore(args): 1943 print_json(rpc.lvol.bdev_lvol_create_lvstore(args.client, 1944 bdev_name=args.bdev_name, 1945 lvs_name=args.lvs_name, 1946 cluster_sz=args.cluster_sz, 1947 clear_method=args.clear_method, 1948 num_md_pages_per_cluster_ratio=args.md_pages_per_cluster_ratio)) 1949 1950 p = subparsers.add_parser('bdev_lvol_create_lvstore', help='Add logical volume store on base bdev') 1951 p.add_argument('bdev_name', help='base bdev name') 1952 p.add_argument('lvs_name', help='name for lvol store') 1953 p.add_argument('-c', '--cluster-sz', help='size of cluster (in bytes)', type=int, required=False) 1954 p.add_argument('--clear-method', help="""Change clear method for data region. 1955 Available: none, unmap, write_zeroes""", required=False) 1956 p.add_argument('-m', '--md-pages-per-cluster-ratio', help='reserved metadata pages for each cluster', type=int, required=False) 1957 p.set_defaults(func=bdev_lvol_create_lvstore) 1958 1959 def bdev_lvol_rename_lvstore(args): 1960 rpc.lvol.bdev_lvol_rename_lvstore(args.client, 1961 old_name=args.old_name, 1962 new_name=args.new_name) 1963 1964 p = subparsers.add_parser('bdev_lvol_rename_lvstore', help='Change logical volume store name') 1965 p.add_argument('old_name', help='old name') 1966 p.add_argument('new_name', help='new name') 1967 p.set_defaults(func=bdev_lvol_rename_lvstore) 1968 1969 def bdev_lvol_grow_lvstore(args): 1970 print_dict(rpc.lvol.bdev_lvol_grow_lvstore(args.client, 1971 uuid=args.uuid, 1972 lvs_name=args.lvs_name)) 1973 1974 p = subparsers.add_parser('bdev_lvol_grow_lvstore', 1975 help='Grow the lvstore size to the underlying bdev size') 1976 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 1977 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 1978 p.set_defaults(func=bdev_lvol_grow_lvstore) 1979 1980 def bdev_lvol_create(args): 1981 print_json(rpc.lvol.bdev_lvol_create(args.client, 1982 lvol_name=args.lvol_name, 1983 size_in_mib=args.size_in_mib, 1984 thin_provision=args.thin_provision, 1985 clear_method=args.clear_method, 1986 uuid=args.uuid, 1987 lvs_name=args.lvs_name)) 1988 1989 p = subparsers.add_parser('bdev_lvol_create', help='Add a bdev with an logical volume backend') 1990 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 1991 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 1992 p.add_argument('-t', '--thin-provision', action='store_true', help='create lvol bdev as thin provisioned') 1993 p.add_argument('-c', '--clear-method', help="""Change default data clusters clear method. 1994 Available: none, unmap, write_zeroes""", required=False) 1995 p.add_argument('lvol_name', help='name for this lvol') 1996 p.add_argument('size_in_mib', help='size in MiB for this bdev', type=int) 1997 p.set_defaults(func=bdev_lvol_create) 1998 1999 def bdev_lvol_snapshot(args): 2000 print_json(rpc.lvol.bdev_lvol_snapshot(args.client, 2001 lvol_name=args.lvol_name, 2002 snapshot_name=args.snapshot_name)) 2003 2004 p = subparsers.add_parser('bdev_lvol_snapshot', help='Create a snapshot of an lvol bdev') 2005 p.add_argument('lvol_name', help='lvol bdev name') 2006 p.add_argument('snapshot_name', help='lvol snapshot name') 2007 p.set_defaults(func=bdev_lvol_snapshot) 2008 2009 def bdev_lvol_clone(args): 2010 print_json(rpc.lvol.bdev_lvol_clone(args.client, 2011 snapshot_name=args.snapshot_name, 2012 clone_name=args.clone_name)) 2013 2014 p = subparsers.add_parser('bdev_lvol_clone', help='Create a clone of an lvol snapshot') 2015 p.add_argument('snapshot_name', help='lvol snapshot name') 2016 p.add_argument('clone_name', help='lvol clone name') 2017 p.set_defaults(func=bdev_lvol_clone) 2018 2019 def bdev_lvol_clone_bdev(args): 2020 print_json(rpc.lvol.bdev_lvol_clone_bdev(args.client, 2021 bdev=args.bdev, 2022 lvs_name=args.lvs_name, 2023 clone_name=args.clone_name)) 2024 2025 p = subparsers.add_parser('bdev_lvol_clone_bdev', 2026 help='Create a clone of a non-lvol bdev') 2027 p.add_argument('bdev', help='bdev to clone') 2028 p.add_argument('lvs_name', help='logical volume store name') 2029 p.add_argument('clone_name', help='lvol clone name') 2030 p.set_defaults(func=bdev_lvol_clone_bdev) 2031 2032 def bdev_lvol_rename(args): 2033 rpc.lvol.bdev_lvol_rename(args.client, 2034 old_name=args.old_name, 2035 new_name=args.new_name) 2036 2037 p = subparsers.add_parser('bdev_lvol_rename', help='Change lvol bdev name') 2038 p.add_argument('old_name', help='lvol bdev name') 2039 p.add_argument('new_name', help='new lvol name') 2040 p.set_defaults(func=bdev_lvol_rename) 2041 2042 def bdev_lvol_inflate(args): 2043 rpc.lvol.bdev_lvol_inflate(args.client, 2044 name=args.name) 2045 2046 p = subparsers.add_parser('bdev_lvol_inflate', help='Make thin provisioned lvol a thick provisioned lvol') 2047 p.add_argument('name', help='lvol bdev name') 2048 p.set_defaults(func=bdev_lvol_inflate) 2049 2050 def bdev_lvol_decouple_parent(args): 2051 rpc.lvol.bdev_lvol_decouple_parent(args.client, 2052 name=args.name) 2053 2054 p = subparsers.add_parser('bdev_lvol_decouple_parent', help='Decouple parent of lvol') 2055 p.add_argument('name', help='lvol bdev name') 2056 p.set_defaults(func=bdev_lvol_decouple_parent) 2057 2058 def bdev_lvol_resize(args): 2059 rpc.lvol.bdev_lvol_resize(args.client, 2060 name=args.name, 2061 size_in_mib=args.size_in_mib) 2062 2063 p = subparsers.add_parser('bdev_lvol_resize', help='Resize existing lvol bdev') 2064 p.add_argument('name', help='lvol bdev name') 2065 p.add_argument('size_in_mib', help='new size in MiB for this bdev', type=int) 2066 p.set_defaults(func=bdev_lvol_resize) 2067 2068 def bdev_lvol_set_read_only(args): 2069 rpc.lvol.bdev_lvol_set_read_only(args.client, 2070 name=args.name) 2071 2072 p = subparsers.add_parser('bdev_lvol_set_read_only', help='Mark lvol bdev as read only') 2073 p.add_argument('name', help='lvol bdev name') 2074 p.set_defaults(func=bdev_lvol_set_read_only) 2075 2076 def bdev_lvol_delete(args): 2077 rpc.lvol.bdev_lvol_delete(args.client, 2078 name=args.name) 2079 2080 p = subparsers.add_parser('bdev_lvol_delete', help='Destroy a logical volume') 2081 p.add_argument('name', help='lvol bdev name') 2082 p.set_defaults(func=bdev_lvol_delete) 2083 2084 def bdev_lvol_delete_lvstore(args): 2085 rpc.lvol.bdev_lvol_delete_lvstore(args.client, 2086 uuid=args.uuid, 2087 lvs_name=args.lvs_name) 2088 2089 p = subparsers.add_parser('bdev_lvol_delete_lvstore', help='Destroy an logical volume store') 2090 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 2091 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 2092 p.set_defaults(func=bdev_lvol_delete_lvstore) 2093 2094 def bdev_lvol_get_lvstores(args): 2095 print_dict(rpc.lvol.bdev_lvol_get_lvstores(args.client, 2096 uuid=args.uuid, 2097 lvs_name=args.lvs_name)) 2098 2099 p = subparsers.add_parser('bdev_lvol_get_lvstores', help='Display current logical volume store list') 2100 p.add_argument('-u', '--uuid', help='lvol store UUID', required=False) 2101 p.add_argument('-l', '--lvs-name', help='lvol store name', required=False) 2102 p.set_defaults(func=bdev_lvol_get_lvstores) 2103 2104 def bdev_lvol_get_lvols(args): 2105 print_dict(rpc.lvol.bdev_lvol_get_lvols(args.client, 2106 lvs_uuid=args.lvs_uuid, 2107 lvs_name=args.lvs_name)) 2108 2109 p = subparsers.add_parser('bdev_lvol_get_lvols', help='Display current logical volume list') 2110 p.add_argument('-u', '--lvs-uuid', help='only lvols in lvol store UUID', required=False) 2111 p.add_argument('-l', '--lvs-name', help='only lvols in lvol store name', required=False) 2112 p.set_defaults(func=bdev_lvol_get_lvols) 2113 2114 def bdev_raid_set_options(args): 2115 rpc.bdev.bdev_raid_set_options(args.client, 2116 process_window_size_kb=args.process_window_size_kb) 2117 2118 p = subparsers.add_parser('bdev_raid_set_options', 2119 help='Set options for bdev raid.') 2120 p.add_argument('-w', '--process-window-size-kb', type=int, 2121 help="Background process (e.g. rebuild) window size in KiB") 2122 2123 p.set_defaults(func=bdev_raid_set_options) 2124 2125 def bdev_raid_get_bdevs(args): 2126 print_json(rpc.bdev.bdev_raid_get_bdevs(args.client, 2127 category=args.category)) 2128 2129 p = subparsers.add_parser('bdev_raid_get_bdevs', 2130 help="""This is used to list all the raid bdev details based on the input category 2131 requested. Category should be one of 'all', 'online', 'configuring' or 'offline'. 'all' means all the raid bdevs whether 2132 they are online or configuring or offline. 'online' is the raid bdev which is registered with bdev layer. 'configuring' 2133 is the raid bdev which does not have full configuration discovered yet. 'offline' is the raid bdev which is not registered 2134 with bdev as of now and it has encountered any error or user has requested to offline the raid bdev""") 2135 p.add_argument('category', help='all or online or configuring or offline') 2136 p.set_defaults(func=bdev_raid_get_bdevs) 2137 2138 def bdev_raid_create(args): 2139 base_bdevs = [] 2140 for u in args.base_bdevs.strip().split(" "): 2141 base_bdevs.append(u) 2142 2143 rpc.bdev.bdev_raid_create(args.client, 2144 name=args.name, 2145 strip_size_kb=args.strip_size_kb, 2146 raid_level=args.raid_level, 2147 base_bdevs=base_bdevs, 2148 uuid=args.uuid, 2149 superblock=args.superblock) 2150 p = subparsers.add_parser('bdev_raid_create', help='Create new raid bdev') 2151 p.add_argument('-n', '--name', help='raid bdev name', required=True) 2152 p.add_argument('-z', '--strip-size-kb', help='strip size in KB', type=int) 2153 p.add_argument('-r', '--raid-level', help='raid level, raid0, raid1 and a special level concat are supported', required=True) 2154 p.add_argument('-b', '--base-bdevs', help='base bdevs name, whitespace separated list in quotes', required=True) 2155 p.add_argument('--uuid', help='UUID for this raid bdev', required=False) 2156 p.add_argument('-s', '--superblock', help='information about raid bdev will be stored in superblock on each base bdev, ' 2157 'disabled by default due to backward compatibility', action='store_true') 2158 p.set_defaults(func=bdev_raid_create) 2159 2160 def bdev_raid_delete(args): 2161 rpc.bdev.bdev_raid_delete(args.client, 2162 name=args.name) 2163 p = subparsers.add_parser('bdev_raid_delete', help='Delete existing raid bdev') 2164 p.add_argument('name', help='raid bdev name') 2165 p.set_defaults(func=bdev_raid_delete) 2166 2167 def bdev_raid_add_base_bdev(args): 2168 rpc.bdev.bdev_raid_add_base_bdev(args.client, 2169 raid_bdev=args.raid_bdev, 2170 base_bdev=args.base_bdev) 2171 p = subparsers.add_parser('bdev_raid_add_base_bdev', help='Add base bdev to existing raid bdev') 2172 p.add_argument('raid_bdev', help='raid bdev name') 2173 p.add_argument('base_bdev', help='base bdev name') 2174 p.set_defaults(func=bdev_raid_add_base_bdev) 2175 2176 def bdev_raid_remove_base_bdev(args): 2177 rpc.bdev.bdev_raid_remove_base_bdev(args.client, 2178 name=args.name) 2179 p = subparsers.add_parser('bdev_raid_remove_base_bdev', help='Remove base bdev from existing raid bdev') 2180 p.add_argument('name', help='base bdev name') 2181 p.set_defaults(func=bdev_raid_remove_base_bdev) 2182 2183 # split 2184 def bdev_split_create(args): 2185 print_array(rpc.bdev.bdev_split_create(args.client, 2186 base_bdev=args.base_bdev, 2187 split_count=args.split_count, 2188 split_size_mb=args.split_size_mb)) 2189 2190 p = subparsers.add_parser('bdev_split_create', 2191 help="""Add given disk name to split config. If bdev with base_name 2192 name exist the split bdevs will be created right away, if not split bdevs will be created when base bdev became 2193 available (during examination process).""") 2194 p.add_argument('base_bdev', help='base bdev name') 2195 p.add_argument('-s', '--split-size-mb', help='size in MiB for each bdev', type=int) 2196 p.add_argument('split_count', help="""Optional - number of split bdevs to create. Total size * split_count must not 2197 exceed the base bdev size.""", type=int) 2198 p.set_defaults(func=bdev_split_create) 2199 2200 def bdev_split_delete(args): 2201 rpc.bdev.bdev_split_delete(args.client, 2202 base_bdev=args.base_bdev) 2203 2204 p = subparsers.add_parser('bdev_split_delete', help="""Delete split config with all created splits.""") 2205 p.add_argument('base_bdev', help='base bdev name') 2206 p.set_defaults(func=bdev_split_delete) 2207 2208 # ftl 2209 def bdev_ftl_create(args): 2210 print_dict(rpc.bdev.bdev_ftl_create(args.client, 2211 name=args.name, 2212 base_bdev=args.base_bdev, 2213 uuid=args.uuid, 2214 cache=args.cache, 2215 overprovisioning=args.overprovisioning, 2216 l2p_dram_limit=args.l2p_dram_limit, 2217 core_mask=args.core_mask, 2218 fast_shutdown=args.fast_shutdown)) 2219 2220 p = subparsers.add_parser('bdev_ftl_create', help='Add FTL bdev') 2221 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2222 p.add_argument('-d', '--base-bdev', help='Name of bdev used as underlying device', 2223 required=True) 2224 p.add_argument('-u', '--uuid', help='UUID of restored bdev (not applicable when creating new ' 2225 'instance): e.g. b286d19a-0059-4709-abcd-9f7732b1567d (optional)') 2226 p.add_argument('-c', '--cache', help='Name of the bdev to be used as a write buffer cache', 2227 required=True) 2228 p.add_argument('--overprovisioning', help='Percentage of device used for relocation, not exposed' 2229 ' to user (optional); default 20', type=int) 2230 p.add_argument('--l2p-dram-limit', help='l2p size that could reside in DRAM (optional); default 2048', 2231 type=int) 2232 p.add_argument('--core-mask', help='CPU core mask - which cores will be used for ftl core thread, ' 2233 'by default core thread will be set to the main application core (optional)') 2234 p.add_argument('-f', '--fast-shutdown', help="Enable fast shutdown", action='store_true') 2235 p.set_defaults(func=bdev_ftl_create) 2236 2237 def bdev_ftl_load(args): 2238 print_dict(rpc.bdev.bdev_ftl_load(args.client, 2239 name=args.name, 2240 base_bdev=args.base_bdev, 2241 uuid=args.uuid, 2242 cache=args.cache, 2243 overprovisioning=args.overprovisioning, 2244 l2p_dram_limit=args.l2p_dram_limit, 2245 core_mask=args.core_mask, 2246 fast_shutdown=args.fast_shutdown)) 2247 2248 p = subparsers.add_parser('bdev_ftl_load', help='Load FTL bdev') 2249 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2250 p.add_argument('-d', '--base-bdev', help='Name of bdev used as underlying device', 2251 required=True) 2252 p.add_argument('-u', '--uuid', help='UUID of restored bdev', required=True) 2253 p.add_argument('-c', '--cache', help='Name of the bdev to be used as a write buffer cache', 2254 required=True) 2255 p.add_argument('--overprovisioning', help='Percentage of device used for relocation, not exposed' 2256 ' to user (optional); default 20', type=int) 2257 p.add_argument('--l2p-dram-limit', help='l2p size that could reside in DRAM (optional); default 2048', 2258 type=int) 2259 p.add_argument('--core-mask', help='CPU core mask - which cores will be used for ftl core thread, ' 2260 'by default core thread will be set to the main application core (optional)') 2261 p.add_argument('-f', '--fast-shutdown', help="Enable fast shutdown", action='store_true') 2262 p.set_defaults(func=bdev_ftl_load) 2263 2264 def bdev_ftl_unload(args): 2265 print_dict(rpc.bdev.bdev_ftl_unload(args.client, name=args.name, fast_shutdown=args.fast_shutdown)) 2266 2267 p = subparsers.add_parser('bdev_ftl_unload', help='Unload FTL bdev') 2268 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2269 p.add_argument('-f', '--fast-shutdown', help="Fast shutdown", action='store_true') 2270 p.set_defaults(func=bdev_ftl_unload) 2271 2272 def bdev_ftl_delete(args): 2273 print_dict(rpc.bdev.bdev_ftl_delete(args.client, name=args.name, fast_shutdown=args.fast_shutdown)) 2274 2275 p = subparsers.add_parser('bdev_ftl_delete', help='Delete FTL bdev') 2276 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2277 p.add_argument('-f', '--fast-shutdown', help="Fast shutdown", action='store_true') 2278 p.set_defaults(func=bdev_ftl_delete) 2279 2280 def bdev_ftl_unmap(args): 2281 print_dict(rpc.bdev.bdev_ftl_unmap(args.client, name=args.name, 2282 lba=args.lba, 2283 num_blocks=args.num_blocks)) 2284 2285 p = subparsers.add_parser('bdev_ftl_unmap', help='FTL unmap') 2286 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2287 p.add_argument('--lba', help='start LBA', required=True, type=int) 2288 p.add_argument('--num-blocks', help='num blocks', required=True, type=int) 2289 p.set_defaults(func=bdev_ftl_unmap) 2290 2291 def bdev_ftl_get_stats(args): 2292 print_dict(rpc.bdev.bdev_ftl_get_stats(args.client, name=args.name)) 2293 2294 p = subparsers.add_parser('bdev_ftl_get_stats', help='print ftl stats') 2295 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2296 p.set_defaults(func=bdev_ftl_get_stats) 2297 2298 def bdev_ftl_get_properties(args): 2299 print_dict(rpc.bdev.bdev_ftl_get_properties(args.client, name=args.name)) 2300 2301 p = subparsers.add_parser('bdev_ftl_get_properties', help='Print FTL properties') 2302 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2303 p.set_defaults(func=bdev_ftl_get_properties) 2304 2305 def bdev_ftl_set_property(args): 2306 print_dict(rpc.bdev.bdev_ftl_set_property(args.client, name=args.name, 2307 ftl_property=args.property, 2308 value=args.value)) 2309 2310 p = subparsers.add_parser('bdev_ftl_set_property', help='Set FTL property') 2311 p.add_argument('-b', '--name', help="Name of the bdev", required=True) 2312 p.add_argument('-p', '--property', help="Name of the property to be set", required=True) 2313 p.add_argument('-v', '--value', help="Value of the property", required=True) 2314 p.set_defaults(func=bdev_ftl_set_property) 2315 2316 # vmd 2317 def vmd_enable(args): 2318 print_dict(rpc.vmd.vmd_enable(args.client)) 2319 2320 p = subparsers.add_parser('vmd_enable', aliases=['enable_vmd'], help='Enable VMD enumeration') 2321 p.set_defaults(func=vmd_enable) 2322 2323 def vmd_remove_device(args): 2324 print_dict(rpc.vmd.vmd_remove_device(args.client, addr=args.addr)) 2325 2326 p = subparsers.add_parser('vmd_remove_device', help='Remove a device behind VMD') 2327 p.add_argument('addr', help='Address of the device to remove', type=str) 2328 p.set_defaults(func=vmd_remove_device) 2329 2330 def vmd_rescan(args): 2331 print_dict(rpc.vmd.vmd_rescan(args.client)) 2332 2333 p = subparsers.add_parser('vmd_rescan', help='Force a rescan of the devices behind VMD') 2334 p.set_defaults(func=vmd_rescan) 2335 2336 # ublk 2337 def ublk_create_target(args): 2338 rpc.ublk.ublk_create_target(args.client, 2339 cpumask=args.cpumask) 2340 p = subparsers.add_parser('ublk_create_target', 2341 help='Create spdk ublk target for ublk dev') 2342 p.add_argument('-m', '--cpumask', help='cpu mask for ublk dev') 2343 p.set_defaults(func=ublk_create_target) 2344 2345 def ublk_destroy_target(args): 2346 rpc.ublk.ublk_destroy_target(args.client) 2347 p = subparsers.add_parser('ublk_destroy_target', 2348 help='Destroy spdk ublk target for ublk dev') 2349 p.set_defaults(func=ublk_destroy_target) 2350 2351 def ublk_start_disk(args): 2352 print(rpc.ublk.ublk_start_disk(args.client, 2353 bdev_name=args.bdev_name, 2354 ublk_id=args.ublk_id, 2355 num_queues=args.num_queues, 2356 queue_depth=args.queue_depth)) 2357 2358 p = subparsers.add_parser('ublk_start_disk', 2359 help='Export a bdev as a ublk device') 2360 p.add_argument('bdev_name', help='Blockdev name to be exported. Example: Malloc0.') 2361 p.add_argument('ublk_id', help='ublk device id to be assigned. Example: 1.', type=int) 2362 p.add_argument('-q', '--num-queues', help="the total number of queues. Example: 1", type=int, required=False) 2363 p.add_argument('-d', '--queue-depth', help="queue depth. Example: 128", type=int, required=False) 2364 p.set_defaults(func=ublk_start_disk) 2365 2366 def ublk_stop_disk(args): 2367 rpc.ublk.ublk_stop_disk(args.client, 2368 ublk_id=args.ublk_id) 2369 2370 p = subparsers.add_parser('ublk_stop_disk', 2371 help='Stop a ublk device') 2372 p.add_argument('ublk_id', help='ublk device id to be deleted. Example: 1.', type=int) 2373 p.set_defaults(func=ublk_stop_disk) 2374 2375 def ublk_recover_disk(args): 2376 print(rpc.ublk.ublk_recover_disk(args.client, 2377 bdev_name=args.bdev_name, 2378 ublk_id=args.ublk_id)) 2379 2380 p = subparsers.add_parser('ublk_recover_disk', 2381 help='Recover ublk device') 2382 p.add_argument('bdev_name', help='Blockdev name to be recovered. Example: Malloc0.') 2383 p.add_argument('ublk_id', help='ublk device id to be recovered. Example: 1.', type=int) 2384 p.set_defaults(func=ublk_recover_disk) 2385 2386 def ublk_get_disks(args): 2387 print_dict(rpc.ublk.ublk_get_disks(args.client, 2388 ublk_id=args.ublk_id)) 2389 2390 p = subparsers.add_parser('ublk_get_disks', 2391 help='Display full or specified ublk device list') 2392 p.add_argument('-n', '--ublk-id', help="ublk device id. Example: 1", type=int, required=False) 2393 p.set_defaults(func=ublk_get_disks) 2394 2395 # nbd 2396 def nbd_start_disk(args): 2397 print(rpc.nbd.nbd_start_disk(args.client, 2398 bdev_name=args.bdev_name, 2399 nbd_device=args.nbd_device)) 2400 2401 p = subparsers.add_parser('nbd_start_disk', 2402 help='Export a bdev as an nbd disk') 2403 p.add_argument('bdev_name', help='Blockdev name to be exported. Example: Malloc0.') 2404 p.add_argument('nbd_device', help='Nbd device name to be assigned. Example: /dev/nbd0.', nargs='?') 2405 p.set_defaults(func=nbd_start_disk) 2406 2407 def nbd_stop_disk(args): 2408 rpc.nbd.nbd_stop_disk(args.client, 2409 nbd_device=args.nbd_device) 2410 2411 p = subparsers.add_parser('nbd_stop_disk', 2412 help='Stop an nbd disk') 2413 p.add_argument('nbd_device', help='Nbd device name to be stopped. Example: /dev/nbd0.') 2414 p.set_defaults(func=nbd_stop_disk) 2415 2416 def nbd_get_disks(args): 2417 print_dict(rpc.nbd.nbd_get_disks(args.client, 2418 nbd_device=args.nbd_device)) 2419 2420 p = subparsers.add_parser('nbd_get_disks', 2421 help='Display full or specified nbd device list') 2422 p.add_argument('-n', '--nbd-device', help="Path of the nbd device. Example: /dev/nbd0", required=False) 2423 p.set_defaults(func=nbd_get_disks) 2424 2425 # NVMe-oF 2426 def nvmf_set_max_subsystems(args): 2427 rpc.nvmf.nvmf_set_max_subsystems(args.client, 2428 max_subsystems=args.max_subsystems) 2429 2430 p = subparsers.add_parser('nvmf_set_max_subsystems', 2431 help='Set the maximum number of NVMf target subsystems') 2432 p.add_argument('-x', '--max-subsystems', help='Max number of NVMf subsystems', type=int, required=True) 2433 p.set_defaults(func=nvmf_set_max_subsystems) 2434 2435 def nvmf_set_config(args): 2436 rpc.nvmf.nvmf_set_config(args.client, 2437 passthru_identify_ctrlr=args.passthru_identify_ctrlr, 2438 poll_groups_mask=args.poll_groups_mask, 2439 discovery_filter=args.discovery_filter) 2440 2441 p = subparsers.add_parser('nvmf_set_config', help='Set NVMf target config') 2442 p.add_argument('-i', '--passthru-identify-ctrlr', help="""Passthrough fields like serial number and model number 2443 when the controller has a single namespace that is an NVMe bdev""", action='store_true') 2444 p.add_argument('-m', '--poll-groups-mask', help='Set cpumask for NVMf poll groups (optional)', type=str) 2445 p.add_argument('-d', '--discovery-filter', help="""Set discovery filter (optional), possible values are: `match_any` (default) or 2446 comma separated values: `transport`, `address`, `svcid`""", type=str) 2447 p.set_defaults(func=nvmf_set_config) 2448 2449 def nvmf_create_transport(args): 2450 rpc.nvmf.nvmf_create_transport(**vars(args)) 2451 2452 p = subparsers.add_parser('nvmf_create_transport', help='Create NVMf transport') 2453 p.add_argument('-t', '--trtype', help='Transport type (ex. RDMA)', type=str, required=True) 2454 p.add_argument('-g', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2455 p.add_argument('-q', '--max-queue-depth', help='Max number of outstanding I/O per queue', type=int) 2456 p.add_argument('-m', '--max-io-qpairs-per-ctrlr', help='Max number of IO qpairs per controller', type=int) 2457 p.add_argument('-c', '--in-capsule-data-size', help='Max number of in-capsule data size', type=int) 2458 p.add_argument('-i', '--max-io-size', help='Max I/O size (bytes)', type=int) 2459 p.add_argument('-u', '--io-unit-size', help='I/O unit size (bytes)', type=int) 2460 p.add_argument('-a', '--max-aq-depth', help='Max number of admin cmds per AQ', type=int) 2461 p.add_argument('-n', '--num-shared-buffers', help='The number of pooled data buffers available to the transport', type=int) 2462 p.add_argument('-b', '--buf-cache-size', help='The number of shared buffers to reserve for each poll group', type=int) 2463 p.add_argument('-z', '--zcopy', action='store_true', help='''Use zero-copy operations if the 2464 underlying bdev supports them''') 2465 p.add_argument('-d', '--num-cqe', help="""The number of CQ entries. Only used when no_srq=true. 2466 Relevant only for RDMA transport""", type=int) 2467 p.add_argument('-s', '--max-srq-depth', help='Max number of outstanding I/O per SRQ. Relevant only for RDMA transport', type=int) 2468 p.add_argument('-r', '--no-srq', action='store_true', help='Disable per-thread shared receive queue. Relevant only for RDMA transport') 2469 p.add_argument('-o', '--c2h-success', action='store_false', help='Disable C2H success optimization. Relevant only for TCP transport') 2470 p.add_argument('-f', '--dif-insert-or-strip', action='store_true', help='Enable DIF insert/strip. Relevant only for TCP transport') 2471 p.add_argument('-y', '--sock-priority', help='The sock priority of the tcp connection. Relevant only for TCP transport', type=int) 2472 p.add_argument('-l', '--acceptor-backlog', help='Pending connections allowed at one time. Relevant only for RDMA transport', type=int) 2473 p.add_argument('-x', '--abort-timeout-sec', help='Abort execution timeout value, in seconds', type=int) 2474 p.add_argument('-w', '--no-wr-batching', action='store_true', help='Disable work requests batching. Relevant only for RDMA transport') 2475 p.add_argument('-e', '--control-msg-num', help="""The number of control messages per poll group. 2476 Relevant only for TCP transport""", type=int) 2477 p.add_argument('-M', '--disable-mappable-bar0', action='store_true', help="""Disable mmap() of BAR0. 2478 Relevant only for VFIO-USER transport""") 2479 p.add_argument('-I', '--disable-adaptive-irq', action='store_true', help="""Disable adaptive interrupt feature. 2480 Relevant only for VFIO-USER transport""") 2481 p.add_argument('-S', '--disable-shadow-doorbells', action='store_true', help="""Disable shadow doorbell support. 2482 Relevant only for VFIO-USER transport""") 2483 p.add_argument('--acceptor-poll-rate', help='Polling interval of the acceptor for incoming connections (usec)', type=int) 2484 p.set_defaults(func=nvmf_create_transport) 2485 2486 def nvmf_get_transports(args): 2487 print_dict(rpc.nvmf.nvmf_get_transports(args.client, trtype=args.trtype, tgt_name=args.tgt_name)) 2488 2489 p = subparsers.add_parser('nvmf_get_transports', help='Display nvmf transports or required transport') 2490 p.add_argument('--trtype', help='Transport type (optional)') 2491 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2492 p.set_defaults(func=nvmf_get_transports) 2493 2494 def nvmf_get_subsystems(args): 2495 print_dict(rpc.nvmf.nvmf_get_subsystems(args.client, nqn=args.nqn, tgt_name=args.tgt_name)) 2496 2497 p = subparsers.add_parser('nvmf_get_subsystems', help='Display nvmf subsystems or required subsystem') 2498 p.add_argument('nqn', help='Subsystem NQN (optional)', nargs="?") 2499 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2500 p.set_defaults(func=nvmf_get_subsystems) 2501 2502 def nvmf_create_subsystem(args): 2503 rpc.nvmf.nvmf_create_subsystem(args.client, 2504 nqn=args.nqn, 2505 tgt_name=args.tgt_name, 2506 serial_number=args.serial_number, 2507 model_number=args.model_number, 2508 allow_any_host=args.allow_any_host, 2509 max_namespaces=args.max_namespaces, 2510 ana_reporting=args.ana_reporting, 2511 min_cntlid=args.min_cntlid, 2512 max_cntlid=args.max_cntlid, 2513 max_discard_size_kib=args.max_discard_size, 2514 max_write_zeroes_size_kib=args.max_write_zeroes_size) 2515 2516 p = subparsers.add_parser('nvmf_create_subsystem', help='Create an NVMe-oF subsystem') 2517 p.add_argument('nqn', help='Subsystem NQN (ASCII)') 2518 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2519 p.add_argument("-s", "--serial-number", help=""" 2520 Format: 'sn' etc 2521 Example: 'SPDK00000000000001'""") 2522 p.add_argument("-d", "--model-number", help=""" 2523 Format: 'mn' etc 2524 Example: 'SPDK Controller'""") 2525 p.add_argument("-a", "--allow-any-host", action='store_true', help="Allow any host to connect (don't enforce allowed host NQN list)") 2526 p.add_argument("-m", "--max-namespaces", help="Maximum number of namespaces allowed", 2527 type=int) 2528 p.add_argument("-r", "--ana-reporting", action='store_true', help="Enable ANA reporting feature") 2529 p.add_argument("-i", "--min_cntlid", help="Minimum controller ID", type=int) 2530 p.add_argument("-I", "--max_cntlid", help="Maximum controller ID", type=int) 2531 p.add_argument("--max-discard-size", help="Maximum discard size (Kib)", type=int) 2532 p.add_argument("--max-write-zeroes-size", help="Maximum write_zeroes size (Kib)", type=int) 2533 p.set_defaults(func=nvmf_create_subsystem) 2534 2535 def nvmf_delete_subsystem(args): 2536 rpc.nvmf.nvmf_delete_subsystem(args.client, 2537 nqn=args.subsystem_nqn, 2538 tgt_name=args.tgt_name) 2539 2540 p = subparsers.add_parser('nvmf_delete_subsystem', help='Delete a nvmf subsystem') 2541 p.add_argument('subsystem_nqn', 2542 help='subsystem nqn to be deleted. Example: nqn.2016-06.io.spdk:cnode1.') 2543 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2544 p.set_defaults(func=nvmf_delete_subsystem) 2545 2546 def nvmf_subsystem_add_listener(args): 2547 rpc.nvmf.nvmf_subsystem_add_listener(**vars(args)) 2548 2549 p = subparsers.add_parser('nvmf_subsystem_add_listener', help='Add a listener to an NVMe-oF subsystem') 2550 p.add_argument('nqn', help='NVMe-oF subsystem NQN (\'discovery\' can be used as shortcut for discovery NQN)') 2551 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 2552 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 2553 p.add_argument('-p', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2554 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 2555 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number (required for RDMA or TCP)') 2556 p.add_argument('-k', '--secure-channel', help='Immediately establish a secure channel', action="store_true") 2557 p.add_argument('-n', '--ana-state', help='ANA state to set: optimized, non_optimized, or inaccessible', type=str, required=False) 2558 p.set_defaults(func=nvmf_subsystem_add_listener) 2559 2560 def nvmf_subsystem_remove_listener(args): 2561 rpc.nvmf.nvmf_subsystem_remove_listener(args.client, 2562 nqn=args.nqn, 2563 trtype=args.trtype, 2564 traddr=args.traddr, 2565 tgt_name=args.tgt_name, 2566 adrfam=args.adrfam, 2567 trsvcid=args.trsvcid) 2568 2569 p = subparsers.add_parser('nvmf_subsystem_remove_listener', help='Remove a listener from an NVMe-oF subsystem') 2570 p.add_argument('nqn', help='NVMe-oF subsystem NQN (\'discovery\' can be used as shortcut for discovery NQN)') 2571 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 2572 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 2573 p.add_argument('-p', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2574 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 2575 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number (required for TCP and RDMA transport types)') 2576 p.set_defaults(func=nvmf_subsystem_remove_listener) 2577 2578 def nvmf_subsystem_listener_set_ana_state(args): 2579 rpc.nvmf.nvmf_subsystem_listener_set_ana_state(args.client, 2580 nqn=args.nqn, 2581 ana_state=args.ana_state, 2582 trtype=args.trtype, 2583 traddr=args.traddr, 2584 tgt_name=args.tgt_name, 2585 adrfam=args.adrfam, 2586 trsvcid=args.trsvcid, 2587 anagrpid=args.anagrpid) 2588 2589 p = subparsers.add_parser('nvmf_subsystem_listener_set_ana_state', help='Set ANA state of a listener for an NVMe-oF subsystem') 2590 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2591 p.add_argument('-n', '--ana-state', help='ANA state to set: optimized, non_optimized, or inaccessible', required=True) 2592 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 2593 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 2594 p.add_argument('-p', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2595 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 2596 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number') 2597 p.add_argument('-g', '--anagrpid', help='ANA group ID (optional)', type=int) 2598 p.set_defaults(func=nvmf_subsystem_listener_set_ana_state) 2599 2600 def nvmf_discovery_add_referral(args): 2601 rpc.nvmf.nvmf_discovery_add_referral(**vars(args)) 2602 2603 p = subparsers.add_parser('nvmf_discovery_add_referral', help='Add a discovery service referral to an NVMe-oF target') 2604 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 2605 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 2606 p.add_argument('-p', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2607 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 2608 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number (required for RDMA or TCP)') 2609 p.add_argument('-k', '--secure-channel', help='The connection to that discovery subsystem requires a secure channel', 2610 action="store_true") 2611 p.add_argument('-n', '--subnqn', help='Subsystem NQN') 2612 p.set_defaults(func=nvmf_discovery_add_referral) 2613 2614 def nvmf_discovery_remove_referral(args): 2615 rpc.nvmf.nvmf_discovery_remove_referral(args.client, 2616 trtype=args.trtype, 2617 traddr=args.traddr, 2618 tgt_name=args.tgt_name, 2619 adrfam=args.adrfam, 2620 trsvcid=args.trsvcid, 2621 subnqn=args.subnqn) 2622 2623 p = subparsers.add_parser('nvmf_discovery_remove_referral', help='Remove a discovery service referral from an NVMe-oF target') 2624 p.add_argument('-t', '--trtype', help='NVMe-oF transport type: e.g., rdma', required=True) 2625 p.add_argument('-a', '--traddr', help='NVMe-oF transport address: e.g., an ip address', required=True) 2626 p.add_argument('-p', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2627 p.add_argument('-f', '--adrfam', help='NVMe-oF transport adrfam: e.g., ipv4, ipv6, ib, fc, intra_host') 2628 p.add_argument('-s', '--trsvcid', help='NVMe-oF transport service id: e.g., a port number (required for TCP and RDMA transport types)') 2629 p.add_argument('-n', '--subnqn', help='Subsystem NQN') 2630 p.set_defaults(func=nvmf_discovery_remove_referral) 2631 2632 def nvmf_discovery_get_referrals(args): 2633 print_dict(rpc.nvmf.nvmf_discovery_get_referrals(args.client, 2634 tgt_name=args.tgt_name)) 2635 2636 p = subparsers.add_parser('nvmf_discovery_get_referrals', 2637 help='Display discovery subsystem referrals of an NVMe-oF target') 2638 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2639 p.set_defaults(func=nvmf_discovery_get_referrals) 2640 2641 def nvmf_subsystem_add_ns(args): 2642 rpc.nvmf.nvmf_subsystem_add_ns(args.client, 2643 nqn=args.nqn, 2644 bdev_name=args.bdev_name, 2645 tgt_name=args.tgt_name, 2646 ptpl_file=args.ptpl_file, 2647 nsid=args.nsid, 2648 nguid=args.nguid, 2649 eui64=args.eui64, 2650 uuid=args.uuid, 2651 anagrpid=args.anagrpid) 2652 2653 p = subparsers.add_parser('nvmf_subsystem_add_ns', help='Add a namespace to an NVMe-oF subsystem') 2654 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2655 p.add_argument('bdev_name', help='The name of the bdev that will back this namespace') 2656 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2657 p.add_argument('-p', '--ptpl-file', help='The persistent reservation storage location (optional)', type=str) 2658 p.add_argument('-n', '--nsid', help='The requested NSID (optional)', type=int) 2659 p.add_argument('-g', '--nguid', help='Namespace globally unique identifier (optional)') 2660 p.add_argument('-e', '--eui64', help='Namespace EUI-64 identifier (optional)') 2661 p.add_argument('-u', '--uuid', help='Namespace UUID (optional)') 2662 p.add_argument('-a', '--anagrpid', help='ANA group ID (optional)', type=int) 2663 p.set_defaults(func=nvmf_subsystem_add_ns) 2664 2665 def nvmf_subsystem_remove_ns(args): 2666 rpc.nvmf.nvmf_subsystem_remove_ns(args.client, 2667 nqn=args.nqn, 2668 nsid=args.nsid, 2669 tgt_name=args.tgt_name) 2670 2671 p = subparsers.add_parser('nvmf_subsystem_remove_ns', help='Remove a namespace to an NVMe-oF subsystem') 2672 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2673 p.add_argument('nsid', help='The requested NSID', type=int) 2674 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2675 p.set_defaults(func=nvmf_subsystem_remove_ns) 2676 2677 def nvmf_subsystem_add_host(args): 2678 rpc.nvmf.nvmf_subsystem_add_host(args.client, 2679 nqn=args.nqn, 2680 host=args.host, 2681 tgt_name=args.tgt_name, 2682 psk=args.psk) 2683 2684 p = subparsers.add_parser('nvmf_subsystem_add_host', help='Add a host to an NVMe-oF subsystem') 2685 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2686 p.add_argument('host', help='Host NQN to allow') 2687 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2688 p.add_argument('--psk', help='Path to PSK file for TLS authentication (optional). Only applicable for TCP transport.', type=str) 2689 p.set_defaults(func=nvmf_subsystem_add_host) 2690 2691 def nvmf_subsystem_remove_host(args): 2692 rpc.nvmf.nvmf_subsystem_remove_host(args.client, 2693 nqn=args.nqn, 2694 host=args.host, 2695 tgt_name=args.tgt_name) 2696 2697 p = subparsers.add_parser('nvmf_subsystem_remove_host', help='Remove a host from an NVMe-oF subsystem') 2698 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2699 p.add_argument('host', help='Host NQN to remove') 2700 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2701 p.set_defaults(func=nvmf_subsystem_remove_host) 2702 2703 def nvmf_subsystem_allow_any_host(args): 2704 rpc.nvmf.nvmf_subsystem_allow_any_host(args.client, 2705 nqn=args.nqn, 2706 disable=args.disable, 2707 tgt_name=args.tgt_name) 2708 2709 p = subparsers.add_parser('nvmf_subsystem_allow_any_host', help='Allow any host to connect to the subsystem') 2710 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2711 p.add_argument('-e', '--enable', action='store_true', help='Enable allowing any host') 2712 p.add_argument('-d', '--disable', action='store_true', help='Disable allowing any host') 2713 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2714 p.set_defaults(func=nvmf_subsystem_allow_any_host) 2715 2716 def nvmf_subsystem_get_controllers(args): 2717 print_dict(rpc.nvmf.nvmf_subsystem_get_controllers(args.client, 2718 nqn=args.nqn, 2719 tgt_name=args.tgt_name)) 2720 2721 p = subparsers.add_parser('nvmf_subsystem_get_controllers', 2722 help='Display controllers of an NVMe-oF subsystem.') 2723 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2724 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2725 p.set_defaults(func=nvmf_subsystem_get_controllers) 2726 2727 def nvmf_subsystem_get_qpairs(args): 2728 print_dict(rpc.nvmf.nvmf_subsystem_get_qpairs(args.client, 2729 nqn=args.nqn, 2730 tgt_name=args.tgt_name)) 2731 2732 p = subparsers.add_parser('nvmf_subsystem_get_qpairs', 2733 help='Display queue pairs of an NVMe-oF subsystem.') 2734 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2735 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2736 p.set_defaults(func=nvmf_subsystem_get_qpairs) 2737 2738 def nvmf_subsystem_get_listeners(args): 2739 print_dict(rpc.nvmf.nvmf_subsystem_get_listeners(args.client, 2740 nqn=args.nqn, 2741 tgt_name=args.tgt_name)) 2742 2743 p = subparsers.add_parser('nvmf_subsystem_get_listeners', 2744 help='Display listeners of an NVMe-oF subsystem.') 2745 p.add_argument('nqn', help='NVMe-oF subsystem NQN') 2746 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2747 p.set_defaults(func=nvmf_subsystem_get_listeners) 2748 2749 def nvmf_get_stats(args): 2750 print_dict(rpc.nvmf.nvmf_get_stats(args.client, tgt_name=args.tgt_name)) 2751 2752 p = subparsers.add_parser( 2753 'nvmf_get_stats', help='Display current statistics for NVMf subsystem') 2754 p.add_argument('-t', '--tgt-name', help='The name of the parent NVMe-oF target (optional)', type=str) 2755 p.set_defaults(func=nvmf_get_stats) 2756 2757 def nvmf_set_crdt(args): 2758 print_dict(rpc.nvmf.nvmf_set_crdt(args.client, args.crdt1, args.crdt2, args.crdt3)) 2759 2760 p = subparsers.add_parser( 2761 'nvmf_set_crdt', 2762 help="""Set the 3 crdt (Command Retry Delay Time) values for NVMf subsystem. All 2763 values are in units of 100 milliseconds (same as the NVM Express specification).""") 2764 p.add_argument('-t1', '--crdt1', help='Command Retry Delay Time 1, in units of 100 milliseconds', type=int) 2765 p.add_argument('-t2', '--crdt2', help='Command Retry Delay Time 2, in units of 100 milliseconds', type=int) 2766 p.add_argument('-t3', '--crdt3', help='Command Retry Delay Time 3, in units of 100 milliseconds', type=int) 2767 p.set_defaults(func=nvmf_set_crdt) 2768 2769 # subsystem 2770 def framework_get_subsystems(args): 2771 print_dict(rpc.subsystem.framework_get_subsystems(args.client)) 2772 2773 p = subparsers.add_parser('framework_get_subsystems', 2774 help="""Print subsystems array in initialization order. Each subsystem 2775 entry contain (unsorted) array of subsystems it depends on.""") 2776 p.set_defaults(func=framework_get_subsystems) 2777 2778 def framework_get_config(args): 2779 print_dict(rpc.subsystem.framework_get_config(args.client, args.name)) 2780 2781 p = subparsers.add_parser('framework_get_config', help="""Print subsystem configuration""") 2782 p.add_argument('name', help='Name of subsystem to query') 2783 p.set_defaults(func=framework_get_config) 2784 2785 # vhost 2786 def vhost_controller_set_coalescing(args): 2787 rpc.vhost.vhost_controller_set_coalescing(args.client, 2788 ctrlr=args.ctrlr, 2789 delay_base_us=args.delay_base_us, 2790 iops_threshold=args.iops_threshold) 2791 2792 p = subparsers.add_parser('vhost_controller_set_coalescing', help='Set vhost controller coalescing') 2793 p.add_argument('ctrlr', help='controller name') 2794 p.add_argument('delay_base_us', help='Base delay time', type=int) 2795 p.add_argument('iops_threshold', help='IOPS threshold when coalescing is enabled', type=int) 2796 p.set_defaults(func=vhost_controller_set_coalescing) 2797 2798 def virtio_blk_create_transport(args): 2799 rpc.vhost.virtio_blk_create_transport(**vars(args)) 2800 2801 p = subparsers.add_parser('virtio_blk_create_transport', 2802 help='Create virtio blk transport') 2803 p.add_argument('name', help='transport name') 2804 p.set_defaults(func=virtio_blk_create_transport) 2805 2806 def virtio_blk_get_transports(args): 2807 print_dict(rpc.vhost.virtio_blk_get_transports(args.client, name=args.name)) 2808 2809 p = subparsers.add_parser('virtio_blk_get_transports', help='Display virtio-blk transports or requested transport') 2810 p.add_argument('--name', help='Transport name (optional)', type=str) 2811 p.set_defaults(func=virtio_blk_get_transports) 2812 2813 def vhost_create_scsi_controller(args): 2814 rpc.vhost.vhost_create_scsi_controller(args.client, 2815 ctrlr=args.ctrlr, 2816 cpumask=args.cpumask, 2817 delay=args.delay) 2818 2819 p = subparsers.add_parser('vhost_create_scsi_controller', help='Add new vhost controller') 2820 p.add_argument('ctrlr', help='controller name') 2821 p.add_argument('--cpumask', help='cpu mask for this controller') 2822 p.add_argument("--delay", action='store_true', help='whether delay starting controller or not') 2823 p.set_defaults(func=vhost_create_scsi_controller) 2824 2825 def vhost_start_scsi_controller(args): 2826 rpc.vhost.vhost_start_scsi_controller(args.client, 2827 ctrlr=args.ctrlr) 2828 2829 p = subparsers.add_parser('vhost_start_scsi_controller', help='Start vhost scsi controller') 2830 p.add_argument('ctrlr', help='controller name') 2831 p.set_defaults(func=vhost_start_scsi_controller) 2832 2833 def vhost_scsi_controller_add_target(args): 2834 print_json(rpc.vhost.vhost_scsi_controller_add_target(args.client, 2835 ctrlr=args.ctrlr, 2836 scsi_target_num=args.scsi_target_num, 2837 bdev_name=args.bdev_name)) 2838 2839 p = subparsers.add_parser('vhost_scsi_controller_add_target', help='Add lun to vhost controller') 2840 p.add_argument('ctrlr', help='controller name where add lun') 2841 p.add_argument('scsi_target_num', help='scsi_target_num', type=int) 2842 p.add_argument('bdev_name', help='bdev name') 2843 p.set_defaults(func=vhost_scsi_controller_add_target) 2844 2845 def vhost_scsi_controller_remove_target(args): 2846 rpc.vhost.vhost_scsi_controller_remove_target(args.client, 2847 ctrlr=args.ctrlr, 2848 scsi_target_num=args.scsi_target_num) 2849 2850 p = subparsers.add_parser('vhost_scsi_controller_remove_target', 2851 help='Remove target from vhost controller') 2852 p.add_argument('ctrlr', help='controller name to remove target from') 2853 p.add_argument('scsi_target_num', help='scsi_target_num', type=int) 2854 p.set_defaults(func=vhost_scsi_controller_remove_target) 2855 2856 def vhost_create_blk_controller(args): 2857 rpc.vhost.vhost_create_blk_controller(**vars(args)) 2858 2859 p = subparsers.add_parser('vhost_create_blk_controller', help='Add a new vhost block controller') 2860 p.add_argument('ctrlr', help='controller name') 2861 p.add_argument('dev_name', help='device name') 2862 p.add_argument('--cpumask', help='cpu mask for this controller') 2863 p.add_argument('--transport', help='virtio blk transport name (default: vhost_user_blk)') 2864 p.add_argument("-r", "--readonly", action='store_true', help='Set controller as read-only') 2865 p.add_argument("-p", "--packed_ring", action='store_true', help='Set controller as packed ring supported') 2866 p.set_defaults(func=vhost_create_blk_controller) 2867 2868 def vhost_get_controllers(args): 2869 print_dict(rpc.vhost.vhost_get_controllers(args.client, args.name)) 2870 2871 p = subparsers.add_parser('vhost_get_controllers', help='List all or specific vhost controller(s)') 2872 p.add_argument('-n', '--name', help="Name of vhost controller", required=False) 2873 p.set_defaults(func=vhost_get_controllers) 2874 2875 def vhost_delete_controller(args): 2876 rpc.vhost.vhost_delete_controller(args.client, 2877 ctrlr=args.ctrlr) 2878 2879 p = subparsers.add_parser('vhost_delete_controller', help='Delete a vhost controller') 2880 p.add_argument('ctrlr', help='controller name') 2881 p.set_defaults(func=vhost_delete_controller) 2882 2883 def bdev_virtio_attach_controller(args): 2884 print_array(rpc.vhost.bdev_virtio_attach_controller(args.client, 2885 name=args.name, 2886 trtype=args.trtype, 2887 traddr=args.traddr, 2888 dev_type=args.dev_type, 2889 vq_count=args.vq_count, 2890 vq_size=args.vq_size)) 2891 2892 p = subparsers.add_parser('bdev_virtio_attach_controller', 2893 help="""Attach virtio controller using provided 2894 transport type and device type. This will also create bdevs for any block devices connected to the 2895 controller (for example, SCSI devices for a virtio-scsi controller). 2896 Result is array of added bdevs.""") 2897 p.add_argument('name', help="Use this name as base for new created bdevs") 2898 p.add_argument('-t', '--trtype', 2899 help='Virtio target transport type: pci or user', required=True) 2900 p.add_argument('-a', '--traddr', 2901 help='Transport type specific target address: e.g. UNIX domain socket path or BDF', required=True) 2902 p.add_argument('-d', '--dev-type', 2903 help='Device type: blk or scsi', required=True) 2904 p.add_argument('--vq-count', help='Number of virtual queues to be used.', type=int) 2905 p.add_argument('--vq-size', help='Size of each queue', type=int) 2906 p.set_defaults(func=bdev_virtio_attach_controller) 2907 2908 def bdev_virtio_scsi_get_devices(args): 2909 print_dict(rpc.vhost.bdev_virtio_scsi_get_devices(args.client)) 2910 2911 p = subparsers.add_parser('bdev_virtio_scsi_get_devices', help='List all Virtio-SCSI devices.') 2912 p.set_defaults(func=bdev_virtio_scsi_get_devices) 2913 2914 def bdev_virtio_detach_controller(args): 2915 rpc.vhost.bdev_virtio_detach_controller(args.client, 2916 name=args.name) 2917 2918 p = subparsers.add_parser('bdev_virtio_detach_controller', help="""Remove a Virtio device 2919 This will delete all bdevs exposed by this device""") 2920 p.add_argument('name', help='Virtio device name. E.g. VirtioUser0') 2921 p.set_defaults(func=bdev_virtio_detach_controller) 2922 2923 def bdev_virtio_blk_set_hotplug(args): 2924 rpc.vhost.bdev_virtio_blk_set_hotplug(args.client, enable=args.enable, period_us=args.period_us) 2925 2926 p = subparsers.add_parser('bdev_virtio_blk_set_hotplug', help='Set hotplug options for bdev virtio_blk type.') 2927 p.add_argument('-d', '--disable', dest='enable', default=False, action='store_false', help="Disable hotplug (default)") 2928 p.add_argument('-e', '--enable', dest='enable', action='store_true', help="Enable hotplug") 2929 p.add_argument('-r', '--period-us', 2930 help='How often the hotplug is processed for insert and remove events', type=int) 2931 p.set_defaults(func=bdev_virtio_blk_set_hotplug) 2932 2933 # vfio-user target 2934 def vfu_tgt_set_base_path(args): 2935 rpc.vfio_user.vfu_tgt_set_base_path(args.client, path=args.path) 2936 2937 p = subparsers.add_parser('vfu_tgt_set_base_path', help='Set socket base path.') 2938 p.add_argument('path', help='socket base path') 2939 p.set_defaults(func=vfu_tgt_set_base_path) 2940 2941 def vfu_virtio_delete_endpoint(args): 2942 rpc.vfio_user.vfu_virtio_delete_endpoint(args.client, name=args.name) 2943 2944 p = subparsers.add_parser('vfu_virtio_delete_endpoint', help='Delete the PCI device via endpoint name.') 2945 p.add_argument('name', help='Endpoint name') 2946 p.set_defaults(func=vfu_virtio_delete_endpoint) 2947 2948 def vfu_virtio_create_blk_endpoint(args): 2949 rpc.vfio_user.vfu_virtio_create_blk_endpoint(args.client, 2950 name=args.name, 2951 bdev_name=args.bdev_name, 2952 cpumask=args.cpumask, 2953 num_queues=args.num_queues, 2954 qsize=args.qsize, 2955 packed_ring=args.packed_ring) 2956 2957 p = subparsers.add_parser('vfu_virtio_create_blk_endpoint', help='Create virtio-blk endpoint.') 2958 p.add_argument('name', help='Name of the endpoint') 2959 p.add_argument('--bdev-name', help='block device name', type=str, required=True) 2960 p.add_argument('--cpumask', help='CPU masks') 2961 p.add_argument('--num-queues', help='number of vrings', type=int, default=0) 2962 p.add_argument('--qsize', help='number of element for each vring', type=int, default=0) 2963 p.add_argument("--packed-ring", action='store_true', help='Enable packed ring') 2964 p.set_defaults(func=vfu_virtio_create_blk_endpoint) 2965 2966 def vfu_virtio_scsi_add_target(args): 2967 rpc.vfio_user.vfu_virtio_scsi_add_target(args.client, 2968 name=args.name, 2969 scsi_target_num=args.scsi_target_num, 2970 bdev_name=args.bdev_name) 2971 2972 p = subparsers.add_parser('vfu_virtio_scsi_add_target', help='Attach a block device to SCSI target of PCI endpoint.') 2973 p.add_argument('name', help='Name of the endpoint') 2974 p.add_argument('--scsi-target-num', help='number of SCSI Target', type=int, required=True) 2975 p.add_argument('--bdev-name', help='block device name', type=str, required=True) 2976 p.set_defaults(func=vfu_virtio_scsi_add_target) 2977 2978 def vfu_virtio_scsi_remove_target(args): 2979 rpc.vfio_user.vfu_virtio_scsi_remove_target(args.client, 2980 name=args.name, 2981 scsi_target_num=args.scsi_target_num) 2982 2983 p = subparsers.add_parser('vfu_virtio_scsi_remove_target', help='Remove the specified SCSI target of PCI endpoint.') 2984 p.add_argument('name', help='Name of the endpoint') 2985 p.add_argument('--scsi-target-num', help='number of SCSI Target', type=int, required=True) 2986 p.set_defaults(func=vfu_virtio_scsi_remove_target) 2987 2988 def vfu_virtio_create_scsi_endpoint(args): 2989 rpc.vfio_user.vfu_virtio_create_scsi_endpoint(args.client, 2990 name=args.name, 2991 cpumask=args.cpumask, 2992 num_io_queues=args.num_io_queues, 2993 qsize=args.qsize, 2994 packed_ring=args.packed_ring) 2995 2996 p = subparsers.add_parser('vfu_virtio_create_scsi_endpoint', help='Create virtio-scsi endpoint.') 2997 p.add_argument('name', help='Name of the endpoint') 2998 p.add_argument('--cpumask', help='CPU masks') 2999 p.add_argument('--num-io-queues', help='number of IO vrings', type=int, default=0) 3000 p.add_argument('--qsize', help='number of element for each vring', type=int, default=0) 3001 p.add_argument("--packed-ring", action='store_true', help='Enable packed ring') 3002 p.set_defaults(func=vfu_virtio_create_scsi_endpoint) 3003 3004 # accel_fw 3005 def accel_get_opc_assignments(args): 3006 print_dict(rpc.accel.accel_get_opc_assignments(args.client)) 3007 3008 p = subparsers.add_parser('accel_get_opc_assignments', help='Get list of opcode name to module assignments.') 3009 p.set_defaults(func=accel_get_opc_assignments) 3010 3011 def accel_get_module_info(args): 3012 print_dict(rpc.accel.accel_get_module_info(args.client)) 3013 3014 p = subparsers.add_parser('accel_get_module_info', aliases=['accel_get_engine_info'], 3015 help='Get list of valid module names and their operations.') 3016 p.set_defaults(func=accel_get_module_info) 3017 3018 def accel_assign_opc(args): 3019 rpc.accel.accel_assign_opc(args.client, opname=args.opname, module=args.module) 3020 3021 p = subparsers.add_parser('accel_assign_opc', help='Manually assign an operation to a module.') 3022 p.add_argument('-o', '--opname', help='opname') 3023 p.add_argument('-m', '--module', help='name of module') 3024 p.set_defaults(func=accel_assign_opc) 3025 3026 def accel_crypto_key_create(args): 3027 print_dict(rpc.accel.accel_crypto_key_create(args.client, 3028 cipher=args.cipher, 3029 key=args.key, 3030 key2=args.key2, 3031 tweak_mode=args.tweak_mode, 3032 name=args.name)) 3033 3034 p = subparsers.add_parser('accel_crypto_key_create', help='Create encryption key') 3035 p.add_argument('-c', '--cipher', help='cipher', required=True) 3036 p.add_argument('-k', '--key', help='key', required=True) 3037 p.add_argument('-e', '--key2', help='key2', required=False, default=None) 3038 p.add_argument('-t', '--tweak-mode', help='tweak mode', required=False, default=None) 3039 p.add_argument('-n', '--name', help='key name', required=True) 3040 p.set_defaults(func=accel_crypto_key_create) 3041 3042 def accel_crypto_key_destroy(args): 3043 print_dict(rpc.accel.accel_crypto_key_destroy(args.client, 3044 key_name=args.name)) 3045 3046 p = subparsers.add_parser('accel_crypto_key_destroy', help='Destroy encryption key') 3047 p.add_argument('-n', '--name', help='key name', required=True, type=str) 3048 p.set_defaults(func=accel_crypto_key_destroy) 3049 3050 def accel_crypto_keys_get(args): 3051 print_dict(rpc.accel.accel_crypto_keys_get(args.client, 3052 key_name=args.key_name)) 3053 3054 p = subparsers.add_parser('accel_crypto_keys_get', help='Get a list of the crypto keys') 3055 p.add_argument('-k', '--key-name', help='Get information about a specific key', type=str) 3056 p.set_defaults(func=accel_crypto_keys_get) 3057 3058 def accel_set_driver(args): 3059 rpc.accel.accel_set_driver(args.client, name=args.name) 3060 3061 p = subparsers.add_parser('accel_set_driver', help='Select accel platform driver to execute ' + 3062 'operation chains') 3063 p.add_argument('name', help='name of the platform driver') 3064 p.set_defaults(func=accel_set_driver) 3065 3066 def accel_set_options(args): 3067 rpc.accel.accel_set_options(args.client, args.small_cache_size, args.large_cache_size, 3068 args.task_count, args.sequence_count, args.buf_count) 3069 3070 p = subparsers.add_parser('accel_set_options', help='Set accel framework\'s options') 3071 p.add_argument('--small-cache-size', type=int, help='Size of the small iobuf cache') 3072 p.add_argument('--large-cache-size', type=int, help='Size of the large iobuf cache') 3073 p.add_argument('--task-count', type=int, help='Maximum number of tasks per IO channel') 3074 p.add_argument('--sequence-count', type=int, help='Maximum number of sequences per IO channel') 3075 p.add_argument('--buf-count', type=int, help='Maximum number of buffers per IO channel') 3076 p.set_defaults(func=accel_set_options) 3077 3078 def accel_get_stats(args): 3079 print_dict(rpc.accel.accel_get_stats(args.client)) 3080 3081 p = subparsers.add_parser('accel_get_stats', help='Display accel framework\'s statistics') 3082 p.set_defaults(func=accel_get_stats) 3083 3084 # ioat 3085 def ioat_scan_accel_module(args): 3086 rpc.ioat.ioat_scan_accel_module(args.client) 3087 3088 p = subparsers.add_parser('ioat_scan_accel_module', aliases=['ioat_scan_accel_engine'], 3089 help='Enable IOAT accel module offload.') 3090 p.set_defaults(func=ioat_scan_accel_module) 3091 3092 # dpdk compressdev 3093 def compressdev_scan_accel_module(args): 3094 rpc.compressdev.compressdev_scan_accel_module(args.client, pmd=args.pmd) 3095 3096 p = subparsers.add_parser('compressdev_scan_accel_module', help='Scan and enable compressdev module and set pmd option.') 3097 p.add_argument('-p', '--pmd', type=int, help='0 = auto-select, 1= QAT only, 2 = mlx5_pci only') 3098 p.set_defaults(func=compressdev_scan_accel_module) 3099 3100 # dsa 3101 def dsa_scan_accel_module(args): 3102 rpc.dsa.dsa_scan_accel_module(args.client, config_kernel_mode=args.config_kernel_mode) 3103 3104 p = subparsers.add_parser('dsa_scan_accel_module', aliases=['dsa_scan_accel_engine'], 3105 help='Set config and enable dsa accel module offload.') 3106 p.add_argument('-k', '--config-kernel-mode', help='Use Kernel mode dsa', 3107 action='store_true', dest='config_kernel_mode') 3108 p.set_defaults(func=dsa_scan_accel_module, config_kernel_mode=None) 3109 3110 # iaa 3111 def iaa_scan_accel_module(args): 3112 rpc.iaa.iaa_scan_accel_module(args.client) 3113 3114 p = subparsers.add_parser('iaa_scan_accel_module', aliases=['iaa_scan_accel_engine'], 3115 help='Set config and enable iaa accel module offload.') 3116 p.set_defaults(func=iaa_scan_accel_module) 3117 3118 def dpdk_cryptodev_scan_accel_module(args): 3119 rpc.dpdk_cryptodev.dpdk_cryptodev_scan_accel_module(args.client) 3120 3121 p = subparsers.add_parser('dpdk_cryptodev_scan_accel_module', 3122 help='Enable dpdk_cryptodev accel module offload.') 3123 p.set_defaults(func=dpdk_cryptodev_scan_accel_module) 3124 3125 def dpdk_cryptodev_set_driver(args): 3126 rpc.dpdk_cryptodev.dpdk_cryptodev_set_driver(args.client, 3127 driver_name=args.driver_name) 3128 3129 p = subparsers.add_parser('dpdk_cryptodev_set_driver', 3130 help='Set the DPDK cryptodev driver.') 3131 p.add_argument('-d', '--driver-name', help='The driver, can be one of crypto_aesni_mb, crypto_qat or mlx5_pci', type=str) 3132 p.set_defaults(func=dpdk_cryptodev_set_driver) 3133 3134 def dpdk_cryptodev_get_driver(args): 3135 print_dict(rpc.dpdk_cryptodev.dpdk_cryptodev_get_driver(args.client)) 3136 3137 p = subparsers.add_parser('dpdk_cryptodev_get_driver', help='Get the DPDK cryptodev driver') 3138 p.set_defaults(func=dpdk_cryptodev_get_driver) 3139 3140 # mlx5 3141 def mlx5_scan_accel_module(args): 3142 rpc.mlx5.mlx5_scan_accel_module(args.client, 3143 qp_size=args.qp_size, 3144 num_requests=args.num_requests) 3145 3146 p = subparsers.add_parser('mlx5_scan_accel_module', help='Enable mlx5 accel module.') 3147 p.add_argument('-q', '--qp-size', type=int, help='QP size') 3148 p.add_argument('-r', '--num-requests', type=int, help='Size of the shared requests pool') 3149 p.set_defaults(func=mlx5_scan_accel_module) 3150 3151 # accel_error 3152 def accel_error_inject_error(args): 3153 rpc.accel.accel_error_inject_error(args.client, opcode=args.opcode, 3154 type=args.type, count=args.count, 3155 interval=args.interval, errcode=args.errcode) 3156 3157 p = subparsers.add_parser('accel_error_inject_error', 3158 help='Inject an error to processing accel operation') 3159 p.add_argument('-o', '--opcode', help='Opcode') 3160 p.add_argument('-t', '--type', 3161 help='Error type ("corrupt": corrupt the data, "failure": fail the operation, "disable": disable error injection)') 3162 p.add_argument('-c', '--count', type=int, 3163 help='Number of errors to inject on each IO channel (0 to disable error injection)') 3164 p.add_argument('-i', '--interval', type=int, help='Interval between injections') 3165 p.add_argument('--errcode', type=int, help='Error code to inject (only relevant for type=failure)') 3166 p.set_defaults(func=accel_error_inject_error) 3167 3168 # opal 3169 def bdev_nvme_opal_init(args): 3170 rpc.nvme.bdev_nvme_opal_init(args.client, 3171 nvme_ctrlr_name=args.nvme_ctrlr_name, 3172 password=args.password) 3173 3174 p = subparsers.add_parser('bdev_nvme_opal_init', help='take ownership and activate') 3175 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name') 3176 p.add_argument('-p', '--password', help='password for admin') 3177 p.set_defaults(func=bdev_nvme_opal_init) 3178 3179 def bdev_nvme_opal_revert(args): 3180 rpc.nvme.bdev_nvme_opal_revert(args.client, 3181 nvme_ctrlr_name=args.nvme_ctrlr_name, 3182 password=args.password) 3183 p = subparsers.add_parser('bdev_nvme_opal_revert', help='Revert to default factory settings') 3184 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name') 3185 p.add_argument('-p', '--password', help='password') 3186 p.set_defaults(func=bdev_nvme_opal_revert) 3187 3188 def bdev_opal_create(args): 3189 print_json(rpc.bdev.bdev_opal_create(args.client, 3190 nvme_ctrlr_name=args.nvme_ctrlr_name, 3191 nsid=args.nsid, 3192 locking_range_id=args.locking_range_id, 3193 range_start=args.range_start, 3194 range_length=args.range_length, 3195 password=args.password)) 3196 3197 p = subparsers.add_parser('bdev_opal_create', help="""Create opal bdev on specified NVMe controller""") 3198 p.add_argument('-b', '--nvme-ctrlr-name', help='nvme ctrlr name', required=True) 3199 p.add_argument('-n', '--nsid', help='namespace ID (only support nsid=1 for now)', type=int, required=True) 3200 p.add_argument('-i', '--locking-range-id', help='locking range id', type=int, required=True) 3201 p.add_argument('-s', '--range-start', help='locking range start LBA', type=int, required=True) 3202 p.add_argument('-l', '--range-length', help='locking range length (in blocks)', type=int, required=True) 3203 p.add_argument('-p', '--password', help='admin password', required=True) 3204 p.set_defaults(func=bdev_opal_create) 3205 3206 def bdev_opal_get_info(args): 3207 print_dict(rpc.bdev.bdev_opal_get_info(args.client, 3208 bdev_name=args.bdev_name, 3209 password=args.password)) 3210 3211 p = subparsers.add_parser('bdev_opal_get_info', help='get opal locking range info for this bdev') 3212 p.add_argument('-b', '--bdev-name', help='opal bdev') 3213 p.add_argument('-p', '--password', help='password') 3214 p.set_defaults(func=bdev_opal_get_info) 3215 3216 def bdev_opal_delete(args): 3217 rpc.bdev.bdev_opal_delete(args.client, 3218 bdev_name=args.bdev_name, 3219 password=args.password) 3220 3221 p = subparsers.add_parser('bdev_opal_delete', help="""delete a virtual opal bdev""") 3222 p.add_argument('-b', '--bdev-name', help='opal virtual bdev', required=True) 3223 p.add_argument('-p', '--password', help='admin password', required=True) 3224 p.set_defaults(func=bdev_opal_delete) 3225 3226 def bdev_opal_new_user(args): 3227 rpc.bdev.bdev_opal_new_user(args.client, 3228 bdev_name=args.bdev_name, 3229 admin_password=args.admin_password, 3230 user_id=args.user_id, 3231 user_password=args.user_password) 3232 3233 p = subparsers.add_parser('bdev_opal_new_user', help="""Add a user to opal bdev who can set lock state for this bdev""") 3234 p.add_argument('-b', '--bdev-name', help='opal bdev', required=True) 3235 p.add_argument('-p', '--admin-password', help='admin password', required=True) 3236 p.add_argument('-i', '--user-id', help='ID for new user', type=int, required=True) 3237 p.add_argument('-u', '--user-password', help='password set for this user', required=True) 3238 p.set_defaults(func=bdev_opal_new_user) 3239 3240 def bdev_opal_set_lock_state(args): 3241 rpc.bdev.bdev_opal_set_lock_state(args.client, 3242 bdev_name=args.bdev_name, 3243 user_id=args.user_id, 3244 password=args.password, 3245 lock_state=args.lock_state) 3246 3247 p = subparsers.add_parser('bdev_opal_set_lock_state', help="""set lock state for an opal bdev""") 3248 p.add_argument('-b', '--bdev-name', help='opal bdev', required=True) 3249 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', 3250 type=int, required=True) 3251 p.add_argument('-p', '--password', help='password of this user', required=True) 3252 p.add_argument('-l', '--lock-state', help='lock state to set, choose from {readwrite, readonly, rwlock}', required=True) 3253 p.set_defaults(func=bdev_opal_set_lock_state) 3254 3255 # bdev_nvme_send_cmd 3256 def bdev_nvme_send_cmd(args): 3257 print_dict(rpc.nvme.bdev_nvme_send_cmd(args.client, 3258 name=args.nvme_name, 3259 cmd_type=args.cmd_type, 3260 data_direction=args.data_direction, 3261 cmdbuf=args.cmdbuf, 3262 data=args.data, 3263 metadata=args.metadata, 3264 data_len=args.data_length, 3265 metadata_len=args.metadata_length, 3266 timeout_ms=args.timeout_ms)) 3267 3268 p = subparsers.add_parser('bdev_nvme_send_cmd', help='NVMe passthrough cmd.') 3269 p.add_argument('-n', '--nvme-name', help="""Name of the operating NVMe controller""") 3270 p.add_argument('-t', '--cmd-type', help="""Type of nvme cmd. Valid values are: admin, io""") 3271 p.add_argument('-r', '--data-direction', help="""Direction of data transfer. Valid values are: c2h, h2c""") 3272 p.add_argument('-c', '--cmdbuf', help="""NVMe command encoded by base64 urlsafe""") 3273 p.add_argument('-d', '--data', help="""Data transferring to controller from host, encoded by base64 urlsafe""") 3274 p.add_argument('-m', '--metadata', help="""Metadata transferring to controller from host, encoded by base64 urlsafe""") 3275 p.add_argument('-D', '--data-length', help="""Data length required to transfer from controller to host""", type=int) 3276 p.add_argument('-M', '--metadata-length', help="""Metadata length required to transfer from controller to host""", type=int) 3277 p.add_argument('-T', '--timeout-ms', 3278 help="""Command execution timeout value, in milliseconds, if 0, don't track timeout""", type=int) 3279 p.set_defaults(func=bdev_nvme_send_cmd) 3280 3281 # Notifications 3282 def notify_get_types(args): 3283 print_dict(rpc.notify.notify_get_types(args.client)) 3284 3285 p = subparsers.add_parser('notify_get_types', help='List available notifications that user can subscribe to.') 3286 p.set_defaults(func=notify_get_types) 3287 3288 def notify_get_notifications(args): 3289 ret = rpc.notify.notify_get_notifications(args.client, 3290 id=args.id, 3291 max=args.max) 3292 print_dict(ret) 3293 3294 p = subparsers.add_parser('notify_get_notifications', help='Get notifications') 3295 p.add_argument('-i', '--id', help="""First ID to start fetching from""", type=int) 3296 p.add_argument('-n', '--max', help="""Maximum number of notifications to return in response""", type=int) 3297 p.set_defaults(func=notify_get_notifications) 3298 3299 def thread_get_stats(args): 3300 print_dict(rpc.app.thread_get_stats(args.client)) 3301 3302 p = subparsers.add_parser( 3303 'thread_get_stats', help='Display current statistics of all the threads') 3304 p.set_defaults(func=thread_get_stats) 3305 3306 def thread_set_cpumask(args): 3307 ret = rpc.app.thread_set_cpumask(args.client, 3308 id=args.id, 3309 cpumask=args.cpumask) 3310 p = subparsers.add_parser('thread_set_cpumask', 3311 help="""set the cpumask of the thread whose ID matches to the 3312 specified value. The thread may be migrated to one of the specified CPUs.""") 3313 p.add_argument('-i', '--id', type=int, help='thread ID') 3314 p.add_argument('-m', '--cpumask', help='cpumask for this thread') 3315 p.set_defaults(func=thread_set_cpumask) 3316 3317 def log_enable_timestamps(args): 3318 ret = rpc.app.log_enable_timestamps(args.client, 3319 enabled=args.enabled) 3320 p = subparsers.add_parser('log_enable_timestamps', 3321 help='Enable or disable timestamps.') 3322 p.add_argument('-d', '--disable', dest='enabled', default=False, action='store_false', help="Disable timestamps") 3323 p.add_argument('-e', '--enable', dest='enabled', action='store_true', help="Enable timestamps") 3324 p.set_defaults(func=log_enable_timestamps) 3325 3326 def thread_get_pollers(args): 3327 print_dict(rpc.app.thread_get_pollers(args.client)) 3328 3329 p = subparsers.add_parser( 3330 'thread_get_pollers', help='Display current pollers of all the threads') 3331 p.set_defaults(func=thread_get_pollers) 3332 3333 def thread_get_io_channels(args): 3334 print_dict(rpc.app.thread_get_io_channels(args.client)) 3335 3336 p = subparsers.add_parser( 3337 'thread_get_io_channels', help='Display current IO channels of all the threads') 3338 p.set_defaults(func=thread_get_io_channels) 3339 3340 def env_dpdk_get_mem_stats(args): 3341 print_dict(rpc.env_dpdk.env_dpdk_get_mem_stats(args.client)) 3342 3343 p = subparsers.add_parser( 3344 'env_dpdk_get_mem_stats', help='write the dpdk memory stats to a file.') 3345 p.set_defaults(func=env_dpdk_get_mem_stats) 3346 3347 # blobfs 3348 def blobfs_detect(args): 3349 print(rpc.blobfs.blobfs_detect(args.client, 3350 bdev_name=args.bdev_name)) 3351 3352 p = subparsers.add_parser('blobfs_detect', help='Detect whether a blobfs exists on bdev') 3353 p.add_argument('bdev_name', help='Blockdev name to detect blobfs. Example: Malloc0.') 3354 p.set_defaults(func=blobfs_detect) 3355 3356 def blobfs_create(args): 3357 print(rpc.blobfs.blobfs_create(args.client, 3358 bdev_name=args.bdev_name, 3359 cluster_sz=args.cluster_sz)) 3360 3361 p = subparsers.add_parser('blobfs_create', help='Build a blobfs on bdev') 3362 p.add_argument('bdev_name', help='Blockdev name to build blobfs. Example: Malloc0.') 3363 p.add_argument('-c', '--cluster-sz', 3364 help="""Size of cluster in bytes (Optional). Must be multiple of 4KB page size. Default and minimal value is 1M.""") 3365 p.set_defaults(func=blobfs_create) 3366 3367 def blobfs_mount(args): 3368 print(rpc.blobfs.blobfs_mount(args.client, 3369 bdev_name=args.bdev_name, 3370 mountpoint=args.mountpoint)) 3371 3372 p = subparsers.add_parser('blobfs_mount', help='Mount a blobfs on bdev to host path by FUSE') 3373 p.add_argument('bdev_name', help='Blockdev name where the blobfs is. Example: Malloc0.') 3374 p.add_argument('mountpoint', help='Mountpoint path in host to mount blobfs. Example: /mnt/.') 3375 p.set_defaults(func=blobfs_mount) 3376 3377 def blobfs_set_cache_size(args): 3378 print(rpc.blobfs.blobfs_set_cache_size(args.client, 3379 size_in_mb=args.size_in_mb)) 3380 3381 p = subparsers.add_parser('blobfs_set_cache_size', help='Set cache size for blobfs') 3382 p.add_argument('size_in_mb', help='Cache size for blobfs in megabytes.', type=int) 3383 p.set_defaults(func=blobfs_set_cache_size) 3384 3385 # sock 3386 def sock_impl_get_options(args): 3387 print_json(rpc.sock.sock_impl_get_options(args.client, 3388 impl_name=args.impl)) 3389 3390 p = subparsers.add_parser('sock_impl_get_options', help="""Get options of socket layer implementation""") 3391 p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True) 3392 p.set_defaults(func=sock_impl_get_options) 3393 3394 def sock_impl_set_options(args): 3395 rpc.sock.sock_impl_set_options(args.client, 3396 impl_name=args.impl, 3397 recv_buf_size=args.recv_buf_size, 3398 send_buf_size=args.send_buf_size, 3399 enable_recv_pipe=args.enable_recv_pipe, 3400 enable_quickack=args.enable_quickack, 3401 enable_placement_id=args.enable_placement_id, 3402 enable_zerocopy_send_server=args.enable_zerocopy_send_server, 3403 enable_zerocopy_send_client=args.enable_zerocopy_send_client, 3404 zerocopy_threshold=args.zerocopy_threshold, 3405 tls_version=args.tls_version, 3406 enable_ktls=args.enable_ktls) 3407 3408 p = subparsers.add_parser('sock_impl_set_options', help="""Set options of socket layer implementation""") 3409 p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True) 3410 p.add_argument('-r', '--recv-buf-size', help='Size of receive buffer on socket in bytes', type=int) 3411 p.add_argument('-s', '--send-buf-size', help='Size of send buffer on socket in bytes', type=int) 3412 p.add_argument('-p', '--enable-placement-id', help='Option for placement-id. 0:disable,1:incoming_napi,2:incoming_cpu', type=int) 3413 p.add_argument('--enable-recv-pipe', help='Enable receive pipe', 3414 action='store_true', dest='enable_recv_pipe') 3415 p.add_argument('--disable-recv-pipe', help='Disable receive pipe', 3416 action='store_false', dest='enable_recv_pipe') 3417 p.add_argument('--enable-quickack', help='Enable quick ACK', 3418 action='store_true', dest='enable_quickack') 3419 p.add_argument('--disable-quickack', help='Disable quick ACK', 3420 action='store_false', dest='enable_quickack') 3421 p.add_argument('--enable-zerocopy-send-server', help='Enable zerocopy on send for server sockets', 3422 action='store_true', dest='enable_zerocopy_send_server') 3423 p.add_argument('--disable-zerocopy-send-server', help='Disable zerocopy on send for server sockets', 3424 action='store_false', dest='enable_zerocopy_send_server') 3425 p.add_argument('--enable-zerocopy-send-client', help='Enable zerocopy on send for client sockets', 3426 action='store_true', dest='enable_zerocopy_send_client') 3427 p.add_argument('--disable-zerocopy-send-client', help='Disable zerocopy on send for client sockets', 3428 action='store_false', dest='enable_zerocopy_send_client') 3429 p.add_argument('--zerocopy-threshold', help='Set zerocopy_threshold in bytes', type=int) 3430 p.add_argument('--tls-version', help='TLS protocol version', type=int) 3431 p.add_argument('--enable-ktls', help='Enable Kernel TLS', 3432 action='store_true', dest='enable_ktls') 3433 p.add_argument('--disable-ktls', help='Disable Kernel TLS', 3434 action='store_false', dest='enable_ktls') 3435 p.set_defaults(func=sock_impl_set_options, enable_recv_pipe=None, enable_quickack=None, 3436 enable_placement_id=None, enable_zerocopy_send_server=None, enable_zerocopy_send_client=None, 3437 zerocopy_threshold=None, tls_version=None, enable_ktls=None) 3438 3439 def sock_set_default_impl(args): 3440 print_json(rpc.sock.sock_set_default_impl(args.client, 3441 impl_name=args.impl)) 3442 3443 p = subparsers.add_parser('sock_set_default_impl', help="""Set the default sock implementation""") 3444 p.add_argument('-i', '--impl', help='Socket implementation name, e.g. posix', required=True) 3445 p.set_defaults(func=sock_set_default_impl) 3446 3447 def framework_get_pci_devices(args): 3448 def splitbuf(buf, step): 3449 return [buf[i:i+step] for i in range(0, len(buf), step)] 3450 3451 devices = rpc.subsystem.framework_get_pci_devices(args.client) 3452 if not args.format_lspci: 3453 print_json(devices) 3454 else: 3455 for devid, dev in enumerate(devices): 3456 print('{} device #{}'.format(dev['address'], devid)) 3457 for lineid, line in enumerate(splitbuf(dev['config_space'], 32)): 3458 print('{:02x}: {}'.format(lineid * 16, ' '.join(splitbuf(line.lower(), 2)))) 3459 print() 3460 3461 p = subparsers.add_parser('framework_get_pci_devices', help='''Get a list of attached PCI devices''') 3462 p.add_argument('--format-lspci', help='Format the output in a way to be consumed by lspci -F', 3463 action='store_true') 3464 p.set_defaults(func=framework_get_pci_devices) 3465 3466 # bdev_nvme_add_error_injection 3467 def bdev_nvme_add_error_injection(args): 3468 print_dict(rpc.nvme.bdev_nvme_add_error_injection(args.client, 3469 name=args.nvme_name, 3470 cmd_type=args.cmd_type, 3471 opc=args.opc, 3472 do_not_submit=args.do_not_submit, 3473 timeout_in_us=args.timeout_in_us, 3474 err_count=args.err_count, 3475 sct=args.sct, 3476 sc=args.sc)) 3477 p = subparsers.add_parser('bdev_nvme_add_error_injection', 3478 help='Add a NVMe command error injection.') 3479 p.add_argument('-n', '--nvme-name', help="""Name of the operating NVMe controller""", required=True) 3480 p.add_argument('-t', '--cmd-type', help="""Type of NVMe command. Valid values are: admin, io""", required=True) 3481 p.add_argument('-o', '--opc', help="""Opcode of the NVMe command.""", required=True, type=int) 3482 p.add_argument('-s', '--do-not-submit', 3483 help="""Set to true if request should not be submitted to the controller""", 3484 dest="do_not_submit", action='store_true') 3485 p.add_argument('-w', '--timeout-in-us', help="""Wait specified microseconds when do_not_submit is true""", type=int) 3486 p.add_argument('-e', '--err-count', help="""Number of matching NVMe commands to inject errors""", type=int) 3487 p.add_argument('-u', '--sct', help="""Status code type""", type=int) 3488 p.add_argument('-c', '--sc', help="""Status code""", type=int) 3489 p.set_defaults(func=bdev_nvme_add_error_injection) 3490 3491 # bdev_nvme_remove_error_injection 3492 def bdev_nvme_remove_error_injection(args): 3493 print_dict(rpc.nvme.bdev_nvme_remove_error_injection(args.client, 3494 name=args.nvme_name, 3495 cmd_type=args.cmd_type, 3496 opc=args.opc)) 3497 p = subparsers.add_parser('bdev_nvme_remove_error_injection', 3498 help='Removes a NVMe command error injection.') 3499 p.add_argument('-n', '--nvme-name', help="""Name of the operating NVMe controller""", required=True) 3500 p.add_argument('-t', '--cmd-type', help="""Type of nvme cmd. Valid values are: admin, io""", required=True) 3501 p.add_argument('-o', '--opc', help="""Opcode of the nvme cmd.""", required=True, type=int) 3502 p.set_defaults(func=bdev_nvme_remove_error_injection) 3503 3504 def bdev_daos_create(args): 3505 num_blocks = (args.total_size * 1024 * 1024) // args.block_size 3506 print_json(rpc.bdev.bdev_daos_create(args.client, 3507 num_blocks=int(num_blocks), 3508 block_size=args.block_size, 3509 name=args.name, 3510 uuid=args.uuid, 3511 pool=args.pool, 3512 cont=args.cont, 3513 oclass=args.oclass)) 3514 p = subparsers.add_parser('bdev_daos_create', 3515 help='Create a bdev with DAOS backend') 3516 p.add_argument('name', help="Name of the bdev") 3517 p.add_argument('pool', help="UUID of the DAOS pool") 3518 p.add_argument('cont', help="UUID of the DAOS container") 3519 p.add_argument( 3520 'total_size', help='Size of DAOS bdev in MB (float > 0)', type=float) 3521 p.add_argument('block_size', help='Block size for this bdev', type=int) 3522 p.add_argument('-u', '--uuid', help="UUID of the bdev") 3523 p.add_argument('-o', '--oclass', help="DAOS object class") 3524 p.set_defaults(func=bdev_daos_create) 3525 3526 def bdev_daos_delete(args): 3527 rpc.bdev.bdev_daos_delete(args.client, 3528 name=args.name) 3529 3530 p = subparsers.add_parser('bdev_daos_delete', 3531 help='Delete a DAOS disk') 3532 p.add_argument('name', help='DAOS bdev name') 3533 p.set_defaults(func=bdev_daos_delete) 3534 3535 def bdev_daos_resize(args): 3536 print_json(rpc.bdev.bdev_daos_resize(args.client, 3537 name=args.name, 3538 new_size=int(args.new_size))) 3539 3540 p = subparsers.add_parser('bdev_daos_resize', 3541 help='Resize a DAOS bdev') 3542 p.add_argument('name', help='DAOS bdev name') 3543 p.add_argument('new_size', help='new bdev size for resize operation. The unit is MiB') 3544 p.set_defaults(func=bdev_daos_resize) 3545 3546 def iobuf_set_options(args): 3547 rpc.iobuf.iobuf_set_options(args.client, 3548 small_pool_count=args.small_pool_count, 3549 large_pool_count=args.large_pool_count, 3550 small_bufsize=args.small_bufsize, 3551 large_bufsize=args.large_bufsize) 3552 p = subparsers.add_parser('iobuf_set_options', help='Set iobuf pool options') 3553 p.add_argument('--small-pool-count', help='number of small buffers in the global pool', type=int) 3554 p.add_argument('--large-pool-count', help='number of large buffers in the global pool', type=int) 3555 p.add_argument('--small-bufsize', help='size of a small buffer', type=int) 3556 p.add_argument('--large-bufsize', help='size of a large buffer', type=int) 3557 p.set_defaults(func=iobuf_set_options) 3558 3559 def iobuf_get_stats(args): 3560 print_dict(rpc.iobuf.iobuf_get_stats(args.client)) 3561 3562 p = subparsers.add_parser('iobuf_get_stats', help='Display iobuf statistics') 3563 p.set_defaults(func=iobuf_get_stats) 3564 3565 def bdev_nvme_start_mdns_discovery(args): 3566 rpc.bdev.bdev_nvme_start_mdns_discovery(args.client, 3567 name=args.name, 3568 svcname=args.svcname, 3569 hostnqn=args.hostnqn) 3570 3571 p = subparsers.add_parser('bdev_nvme_start_mdns_discovery', help='Start mdns based automatic discovery') 3572 p.add_argument('-b', '--name', help="Name of the NVMe controller prefix for each bdev name", required=True) 3573 p.add_argument('-s', '--svcname', help='Service type to discover: e.g., _nvme-disc._tcp', required=True) 3574 p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn') 3575 p.set_defaults(func=bdev_nvme_start_mdns_discovery) 3576 3577 def bdev_nvme_stop_mdns_discovery(args): 3578 rpc.bdev.bdev_nvme_stop_mdns_discovery(args.client, name=args.name) 3579 3580 p = subparsers.add_parser('bdev_nvme_stop_mdns_discovery', help='Stop automatic mdns discovery') 3581 p.add_argument('-b', '--name', help="Name of the service to stop", required=True) 3582 p.set_defaults(func=bdev_nvme_stop_mdns_discovery) 3583 3584 def bdev_nvme_get_mdns_discovery_info(args): 3585 print_dict(rpc.bdev.bdev_nvme_get_mdns_discovery_info(args.client)) 3586 3587 p = subparsers.add_parser('bdev_nvme_get_mdns_discovery_info', help='Get information about the automatic mdns discovery') 3588 p.set_defaults(func=bdev_nvme_get_mdns_discovery_info) 3589 3590 def check_called_name(name): 3591 if name in deprecated_aliases: 3592 print("{} is deprecated, use {} instead.".format(name, deprecated_aliases[name]), file=sys.stderr) 3593 3594 class dry_run_client: 3595 def call(self, method, params=None): 3596 print("Request:\n" + json.dumps({"method": method, "params": params}, indent=2)) 3597 3598 def null_print(arg): 3599 pass 3600 3601 def call_rpc_func(args): 3602 args.func(args) 3603 check_called_name(args.called_rpc_name) 3604 3605 def execute_script(parser, client, fd): 3606 executed_rpc = "" 3607 for rpc_call in map(str.rstrip, fd): 3608 if not rpc_call.strip(): 3609 continue 3610 executed_rpc = "\n".join([executed_rpc, rpc_call]) 3611 rpc_args = shlex.split(rpc_call) 3612 if rpc_args[0][0] == '#': 3613 # Ignore lines starting with # - treat them as comments 3614 continue 3615 args = parser.parse_args(rpc_args) 3616 args.client = client 3617 try: 3618 call_rpc_func(args) 3619 except JSONRPCException as ex: 3620 print("Exception:") 3621 print(executed_rpc.strip() + " <<<") 3622 print(ex.message) 3623 exit(1) 3624 3625 def load_plugin(args): 3626 # Create temporary parser, pull out the plugin parameter, load the module, and then run the real argument parser 3627 plugin_parser = argparse.ArgumentParser(add_help=False) 3628 plugin_parser.add_argument('--plugin', dest='rpc_plugin', help='Module name of plugin with additional RPC commands') 3629 3630 rpc_module = plugin_parser.parse_known_args()[0].rpc_plugin 3631 if args is not None: 3632 rpc_module = plugin_parser.parse_known_args(args)[0].rpc_plugin 3633 3634 if rpc_module in plugins: 3635 return 3636 3637 if rpc_module is not None: 3638 try: 3639 rpc_plugin = importlib.import_module(rpc_module) 3640 try: 3641 rpc_plugin.spdk_rpc_plugin_initialize(subparsers) 3642 plugins.append(rpc_module) 3643 except AttributeError: 3644 print("Module %s does not contain 'spdk_rpc_plugin_initialize' function" % rpc_module) 3645 except ModuleNotFoundError: 3646 print("Module %s not found" % rpc_module) 3647 3648 def replace_arg_underscores(args): 3649 # All option names are defined with dashes only - for example: --tgt-name 3650 # But if user used underscores, convert them to dashes (--tgt_name => --tgt-name) 3651 # SPDK was inconsistent previously and had some options with underscores, so 3652 # doing this conversion ensures backward compatibility with older scripts. 3653 for i in range(len(args)): 3654 arg = args[i] 3655 if arg.startswith('--') and "_" in arg: 3656 opt, *vals = arg.split('=') 3657 args[i] = '='.join([opt.replace('_', '-'), *vals]) 3658 3659 plugins = [] 3660 load_plugin(None) 3661 3662 replace_arg_underscores(sys.argv) 3663 3664 args = parser.parse_args() 3665 3666 try: 3667 use_go_client = int(os.getenv('SPDK_JSONRPC_GO_CLIENT', 0)) == 1 3668 except ValueError: 3669 use_go_client = False 3670 3671 if sys.stdin.isatty() and not hasattr(args, 'func'): 3672 # No arguments and no data piped through stdin 3673 parser.print_help() 3674 exit(1) 3675 if args.is_server: 3676 for input in sys.stdin: 3677 cmd = shlex.split(input) 3678 replace_arg_underscores(cmd) 3679 try: 3680 load_plugin(cmd) 3681 tmp_args = parser.parse_args(cmd) 3682 except SystemExit as ex: 3683 print("**STATUS=1", flush=True) 3684 continue 3685 3686 try: 3687 if use_go_client: 3688 tmp_args.client = rpc.client.JSONRPCGoClient(tmp_args.server_addr, 3689 log_level=getattr(logging, tmp_args.verbose.upper())) 3690 else: 3691 tmp_args.client = rpc.client.JSONRPCClient( 3692 tmp_args.server_addr, tmp_args.port, tmp_args.timeout, 3693 log_level=getattr(logging, tmp_args.verbose.upper()), conn_retries=tmp_args.conn_retries) 3694 call_rpc_func(tmp_args) 3695 print("**STATUS=0", flush=True) 3696 except JSONRPCException as ex: 3697 print(ex.message) 3698 print("**STATUS=1", flush=True) 3699 exit(0) 3700 elif args.dry_run: 3701 args.client = dry_run_client() 3702 print_dict = null_print 3703 print_json = null_print 3704 print_array = null_print 3705 elif args.go_client or use_go_client: 3706 try: 3707 args.client = rpc.client.JSONRPCGoClient(args.server_addr, 3708 log_level=getattr(logging, args.verbose.upper())) 3709 except JSONRPCException as ex: 3710 print(ex.message) 3711 exit(1) 3712 else: 3713 try: 3714 args.client = rpc.client.JSONRPCClient(args.server_addr, args.port, args.timeout, 3715 log_level=getattr(logging, args.verbose.upper()), 3716 conn_retries=args.conn_retries) 3717 except JSONRPCException as ex: 3718 print(ex.message) 3719 exit(1) 3720 3721 if hasattr(args, 'func'): 3722 try: 3723 call_rpc_func(args) 3724 except JSONRPCException as ex: 3725 print(ex.message) 3726 exit(1) 3727 else: 3728 execute_script(parser, args.client, sys.stdin) 3729