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