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