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