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