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