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