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