-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
rpc.py
executable file
·4098 lines (3483 loc) · 224 KB
/
rpc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (C) 2016 Intel Corporation
# All rights reserved.
# Copyright (c) 2022 Dell Inc, or its subsidiaries.
# Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
import logging
import argparse
import importlib
import os
import sys
import shlex
import json
try:
from shlex import quote
except ImportError:
from pipes import quote
sys.path.append(os.path.dirname(__file__) + '/../python')
import spdk.rpc as rpc # noqa
from spdk.rpc.client import print_dict, print_json, JSONRPCException # noqa
from spdk.rpc.helpers import deprecated_aliases # noqa
def print_array(a):
print(" ".join((quote(v) for v in a)))
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description='SPDK RPC command line interface', usage='%(prog)s [options]')
parser.add_argument('-s', dest='server_addr',
help='RPC domain socket path or IP address', default='/var/tmp/spdk.sock')
parser.add_argument('-p', dest='port',
help='RPC port number (if server_addr is IP address)',
default=5260, type=int)
parser.add_argument('-t', dest='timeout',
help='Timeout as a floating point number expressed in seconds waiting for response. Default: 60.0',
default=None, type=float)
parser.add_argument('-r', dest='conn_retries',
help='Retry connecting to the RPC server N times with 0.2s interval. Default: 0',
default=0, type=int)
parser.add_argument('-v', dest='verbose', action='store_const', const="INFO",
help='Set verbose mode to INFO', default="ERROR")
parser.add_argument('--verbose', dest='verbose', choices=['DEBUG', 'INFO', 'ERROR'],
help="""Set verbose level. """)
parser.add_argument('--dry-run', dest='dry_run', action='store_true', help="Display request and exit")
parser.set_defaults(dry_run=False)
parser.add_argument('--go-client', dest='go_client', action='store_true', help="Use Go client")
parser.set_defaults(go_client=False)
parser.add_argument('--server', dest='is_server', action='store_true',
help="Start listening on stdin, parse each line as a regular rpc.py execution and create \
a separate connection for each command. Each command's output ends with either \
**STATUS=0 if the command succeeded or **STATUS=1 if it failed. --server is meant \
to be used in conjunction with bash coproc, where stdin and stdout are connected to \
pipes and can be used as a faster way to send RPC commands. If enabled, rpc.py \
must be executed without any other parameters.")
parser.set_defaults(is_server=False)
parser.add_argument('--plugin', dest='rpc_plugin', help='Module name of plugin with additional RPC commands')
subparsers = parser.add_subparsers(help='RPC methods', dest='called_rpc_name', metavar='')
def framework_start_init(args):
rpc.framework_start_init(args.client)
p = subparsers.add_parser('framework_start_init', help='Start initialization of subsystems')
p.set_defaults(func=framework_start_init)
def framework_wait_init(args):
rpc.framework_wait_init(args.client)
p = subparsers.add_parser('framework_wait_init', help='Block until subsystems have been initialized')
p.set_defaults(func=framework_wait_init)
def rpc_get_methods(args):
print_dict(rpc.rpc_get_methods(args.client,
current=args.current,
include_aliases=args.include_aliases))
p = subparsers.add_parser('rpc_get_methods', help='Get list of supported RPC methods')
p.add_argument('-c', '--current', help='Get list of RPC methods only callable in the current state.', action='store_true')
p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true')
p.set_defaults(func=rpc_get_methods)
def spdk_get_version(args):
print_json(rpc.spdk_get_version(args.client))
p = subparsers.add_parser('spdk_get_version', help='Get SPDK version')
p.set_defaults(func=spdk_get_version)
def save_config(args):
rpc.save_config(args.client,
sys.stdout,
indent=args.indent,
subsystems=args.subsystems)
p = subparsers.add_parser('save_config', help="""Write current (live) configuration of SPDK subsystems and targets to stdout.
""")
p.add_argument('-i', '--indent', help="""Indent level. Value less than 0 mean compact mode. Default indent level is 2.
""", type=int, default=2)
p.add_argument('-s', '--subsystems', help="""Comma-separated list of subsystems (and their dependencies) to save""")
p.set_defaults(func=save_config)
def load_config(args):
rpc.load_config(args.client, args.json_conf,
include_aliases=args.include_aliases)
p = subparsers.add_parser('load_config', help="""Configure SPDK subsystems and targets using JSON RPC.""")
p.add_argument('-i', '--include-aliases', help='include RPC aliases', action='store_true')
p.add_argument('-j', '--json-conf', help='Valid JSON configuration', default=sys.stdin)
p.set_defaults(func=load_config)
def save_subsystem_config(args):
rpc.save_subsystem_config(args.client,
sys.stdout,
indent=args.indent,
name=args.name)
p = subparsers.add_parser('save_subsystem_config', help="""Write current (live) configuration of SPDK subsystem to stdout.
""")
p.add_argument('-i', '--indent', help="""Indent level. Value less than 0 mean compact mode. Default indent level is 2.
""", type=int, default=2)
p.add_argument('-n', '--name', help='Name of subsystem', required=True)
p.set_defaults(func=save_subsystem_config)
def load_subsystem_config(args):
rpc.load_subsystem_config(args.client,
args.json_conf)
p = subparsers.add_parser('load_subsystem_config', help="""Configure SPDK subsystem using JSON RPC.""")
p.add_argument('-j', '--json-conf', help='Valid JSON configuration', default=sys.stdin)
p.set_defaults(func=load_subsystem_config)
# app
def spdk_kill_instance(args):
rpc.app.spdk_kill_instance(args.client,
sig_name=args.sig_name)
p = subparsers.add_parser('spdk_kill_instance', help='Send signal to instance')
p.add_argument('sig_name', help='signal will be sent to server.')
p.set_defaults(func=spdk_kill_instance)
def framework_monitor_context_switch(args):
enabled = None
if args.enable:
enabled = True
if args.disable:
enabled = False
print_dict(rpc.app.framework_monitor_context_switch(args.client,
enabled=enabled))
p = subparsers.add_parser('framework_monitor_context_switch',
help='Control whether the context switch monitor is enabled')
p.add_argument('-e', '--enable', action='store_true', help='Enable context switch monitoring')
p.add_argument('-d', '--disable', action='store_true', help='Disable context switch monitoring')
p.set_defaults(func=framework_monitor_context_switch)
def framework_get_reactors(args):
print_dict(rpc.app.framework_get_reactors(args.client))
p = subparsers.add_parser(
'framework_get_reactors', help='Display list of all reactors')
p.set_defaults(func=framework_get_reactors)
def framework_set_scheduler(args):
rpc.app.framework_set_scheduler(args.client,
name=args.name,
period=args.period,
load_limit=args.load_limit,
core_limit=args.core_limit,
core_busy=args.core_busy,
mappings=args.mappings)
p = subparsers.add_parser(
'framework_set_scheduler', help='Select thread scheduler that will be activated and its period (experimental)')
p.add_argument('name', help="Name of a scheduler")
p.add_argument('-p', '--period', help="Scheduler period in microseconds", type=int)
p.add_argument('--load-limit', help="Scheduler load limit. Reserved for dynamic scheduler", type=int)
p.add_argument('--core-limit', help="Scheduler core limit. Reserved for dynamic scheduler", type=int)
p.add_argument('--core-busy', help="Scheduler core busy limit. Reserved for dynamic scheduler", type=int)
p.add_argument('--mappings', help="Comma-separated list of thread:core mappings. Reserved for static scheduler")
p.set_defaults(func=framework_set_scheduler)
def framework_get_scheduler(args):
print_dict(rpc.app.framework_get_scheduler(args.client))
p = subparsers.add_parser(
'framework_get_scheduler', help='Display currently set scheduler and its properties.')
p.set_defaults(func=framework_get_scheduler)
def framework_get_governor(args):
print_dict(rpc.app.framework_get_governor(args.client))
p = subparsers.add_parser(
'framework_get_governor', help='Display currently set governor and the available, set CPU frequencies.')
p.set_defaults(func=framework_get_governor)
def scheduler_set_options(args):
rpc.app.scheduler_set_options(args.client,
isolated_core_mask=args.isolated_core_mask,
scheduling_core=args.scheduling_core)
p = subparsers.add_parser('scheduler_set_options', help='Set scheduler options')
p.add_argument('-i', '--isolated-core-mask', help="Mask of CPU cores to isolate from scheduling change", type=str)
p.add_argument('-s', '--scheduling-core', help="Scheduler scheduling core. Idle threads will move to scheduling core."
"Reserved for dynamic scheduler.", type=int)
p.set_defaults(func=scheduler_set_options)
def framework_disable_cpumask_locks(args):
rpc.framework_disable_cpumask_locks(args.client)
p = subparsers.add_parser('framework_disable_cpumask_locks',
help='Disable CPU core lock files.')
p.set_defaults(func=framework_disable_cpumask_locks)
def framework_enable_cpumask_locks(args):
rpc.framework_enable_cpumask_locks(args.client)
p = subparsers.add_parser('framework_enable_cpumask_locks',
help='Enable CPU core lock files.')
p.set_defaults(func=framework_enable_cpumask_locks)
# bdev
def bdev_set_options(args):
rpc.bdev.bdev_set_options(args.client,
bdev_io_pool_size=args.bdev_io_pool_size,
bdev_io_cache_size=args.bdev_io_cache_size,
bdev_auto_examine=args.bdev_auto_examine,
iobuf_small_cache_size=args.iobuf_small_cache_size,
iobuf_large_cache_size=args.iobuf_large_cache_size)
p = subparsers.add_parser('bdev_set_options',
help="""Set options of bdev subsystem""")
p.add_argument('-p', '--bdev-io-pool-size', help='Number of bdev_io structures in shared buffer pool', type=int)
p.add_argument('-c', '--bdev-io-cache-size', help='Maximum number of bdev_io structures cached per thread', type=int)
group = p.add_mutually_exclusive_group()
group.add_argument('-e', '--enable-auto-examine', dest='bdev_auto_examine', help='Allow to auto examine', action='store_true')
group.add_argument('-d', '--disable-auto-examine', dest='bdev_auto_examine', help='Not allow to auto examine', action='store_false')
p.add_argument('--iobuf-small-cache-size', help='Size of the small iobuf per thread cache', type=int)
p.add_argument('--iobuf-large-cache-size', help='Size of the large iobuf per thread cache', type=int)
p.set_defaults(bdev_auto_examine=True)
p.set_defaults(func=bdev_set_options)
def bdev_examine(args):
rpc.bdev.bdev_examine(args.client,
name=args.name)
p = subparsers.add_parser('bdev_examine',
help="""examine a bdev if it exists, or will examine it after it is created""")
p.add_argument('-b', '--name', help='Name or alias of the bdev')
p.set_defaults(func=bdev_examine)
def bdev_wait_for_examine(args):
rpc.bdev.bdev_wait_for_examine(args.client)
p = subparsers.add_parser('bdev_wait_for_examine',
help="""Report when all bdevs have been examined""")
p.set_defaults(func=bdev_wait_for_examine)
def bdev_compress_create(args):
print_json(rpc.bdev.bdev_compress_create(args.client,
base_bdev_name=args.base_bdev_name,
pm_path=args.pm_path,
lb_size=args.lb_size,
comp_algo=args.comp_algo,
comp_level=args.comp_level))
p = subparsers.add_parser('bdev_compress_create', help='Add a compress vbdev')
p.add_argument('-b', '--base-bdev-name', help="Name of the base bdev", required=True)
p.add_argument('-p', '--pm-path', help="Path to persistent memory", required=True)
p.add_argument('-l', '--lb-size', help="Compressed vol logical block size (optional, if used must be 512 or 4096)", type=int)
p.add_argument('-c', '--comp-algo', help='Compression algorithm, (deflate, lz4). Default is deflate')
p.add_argument('-L', '--comp-level',
help="""Compression algorithm level.
if algo == deflate, level ranges from 0 to 3.
if algo == lz4, level ranges from 1 to 65537""",
default=1, type=int)
p.set_defaults(func=bdev_compress_create)
def bdev_compress_delete(args):
rpc.bdev.bdev_compress_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_compress_delete', help='Delete a compress disk')
p.add_argument('name', help='compress bdev name')
p.set_defaults(func=bdev_compress_delete)
def bdev_compress_get_orphans(args):
print_dict(rpc.bdev.bdev_compress_get_orphans(args.client,
name=args.name))
p = subparsers.add_parser(
'bdev_compress_get_orphans', help='Display list of orphaned compress bdevs.')
p.add_argument('-b', '--name', help="Name of a comp bdev. Example: COMP_Nvme0n1")
p.set_defaults(func=bdev_compress_get_orphans)
def bdev_crypto_create(args):
print_json(rpc.bdev.bdev_crypto_create(args.client,
base_bdev_name=args.base_bdev_name,
name=args.name,
crypto_pmd=args.crypto_pmd,
key=args.key,
cipher=args.cipher,
key2=args.key2,
key_name=args.key_name))
p = subparsers.add_parser('bdev_crypto_create', help='Add a crypto vbdev')
p.add_argument('base_bdev_name', help="Name of the base bdev")
p.add_argument('name', help="Name of the crypto vbdev")
p.add_argument('-p', '--crypto-pmd', help="Name of the crypto device driver. Obsolete, see dpdk_cryptodev_set_driver")
p.add_argument('-k', '--key', help="Key. Obsolete, see accel_crypto_key_create")
p.add_argument('-c', '--cipher', help="cipher to use. Obsolete, see accel_crypto_key_create")
p.add_argument('-k2', '--key2', help="2nd key for cipher AES_XTS. Obsolete, see accel_crypto_key_create", default=None)
p.add_argument('-n', '--key-name', help="Key name to use, see accel_crypto_key_create")
p.set_defaults(func=bdev_crypto_create)
def bdev_crypto_delete(args):
rpc.bdev.bdev_crypto_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_crypto_delete', help='Delete a crypto disk')
p.add_argument('name', help='crypto bdev name')
p.set_defaults(func=bdev_crypto_delete)
def bdev_ocf_create(args):
print_json(rpc.bdev.bdev_ocf_create(args.client,
name=args.name,
mode=args.mode,
cache_line_size=args.cache_line_size,
cache_bdev_name=args.cache_bdev_name,
core_bdev_name=args.core_bdev_name))
p = subparsers.add_parser('bdev_ocf_create', help='Add an OCF block device')
p.add_argument('name', help='Name of resulting OCF bdev')
p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo'])
p.add_argument(
'--cache-line-size',
help='OCF cache line size. The unit is KiB',
type=int,
choices=[4, 8, 16, 32, 64]
)
p.add_argument('cache_bdev_name', help='Name of underlying cache bdev')
p.add_argument('core_bdev_name', help='Name of underlying core bdev')
p.set_defaults(func=bdev_ocf_create)
def bdev_ocf_delete(args):
rpc.bdev.bdev_ocf_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_ocf_delete', help='Delete an OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_delete)
def bdev_ocf_get_stats(args):
print_dict(rpc.bdev.bdev_ocf_get_stats(args.client,
name=args.name))
p = subparsers.add_parser('bdev_ocf_get_stats', help='Get statistics of chosen OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_get_stats)
def bdev_ocf_reset_stats(args):
print_dict(rpc.bdev.bdev_ocf_reset_stats(args.client,
name=args.name))
p = subparsers.add_parser('bdev_ocf_reset_stats', help='Reset statistics of chosen OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_reset_stats)
def bdev_ocf_get_bdevs(args):
print_dict(rpc.bdev.bdev_ocf_get_bdevs(args.client,
name=args.name))
p = subparsers.add_parser('bdev_ocf_get_bdevs', help='Get list of OCF devices including unregistered ones')
p.add_argument('name', nargs='?', help='name of OCF vbdev or name of cache device or name of core device (optional)')
p.set_defaults(func=bdev_ocf_get_bdevs)
def bdev_ocf_set_cache_mode(args):
print_json(rpc.bdev.bdev_ocf_set_cache_mode(args.client,
name=args.name,
mode=args.mode))
p = subparsers.add_parser('bdev_ocf_set_cache_mode',
help='Set cache mode of OCF block device')
p.add_argument('name', help='Name of OCF bdev')
p.add_argument('mode', help='OCF cache mode', choices=['wb', 'wt', 'pt', 'wa', 'wi', 'wo'])
p.set_defaults(func=bdev_ocf_set_cache_mode)
def bdev_ocf_set_seqcutoff(args):
rpc.bdev.bdev_ocf_set_seqcutoff(args.client,
name=args.name,
policy=args.policy,
threshold=args.threshold,
promotion_count=args.promotion_count)
p = subparsers.add_parser('bdev_ocf_set_seqcutoff',
help='Set sequential cutoff parameters on all cores for the given OCF cache device')
p.add_argument('name', help='Name of OCF cache bdev')
p.add_argument('-t', '--threshold', type=int,
help='Activation threshold [KiB]')
p.add_argument('-c', '--promotion-count', type=int,
help='Promotion request count')
p.add_argument('-p', '--policy', choices=['always', 'full', 'never'], required=True,
help='Sequential cutoff policy')
p.set_defaults(func=bdev_ocf_set_seqcutoff)
def bdev_ocf_flush_start(args):
rpc.bdev.bdev_ocf_flush_start(args.client, name=args.name)
p = subparsers.add_parser('bdev_ocf_flush_start',
help='Start flushing OCF cache device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_flush_start)
def bdev_ocf_flush_status(args):
print_json(rpc.bdev.bdev_ocf_flush_status(args.client, name=args.name))
p = subparsers.add_parser('bdev_ocf_flush_status',
help='Get flush status of OCF cache device')
p.add_argument('name', help='Name of OCF bdev')
p.set_defaults(func=bdev_ocf_flush_status)
def bdev_malloc_create(args):
num_blocks = (args.total_size * 1024 * 1024) // args.block_size
print_json(rpc.bdev.bdev_malloc_create(args.client,
num_blocks=int(num_blocks),
block_size=args.block_size,
physical_block_size=args.physical_block_size,
name=args.name,
uuid=args.uuid,
optimal_io_boundary=args.optimal_io_boundary,
md_size=args.md_size,
md_interleave=args.md_interleave,
dif_type=args.dif_type,
dif_is_head_of_md=args.dif_is_head_of_md,
dif_pi_format=args.dif_pi_format))
p = subparsers.add_parser('bdev_malloc_create', help='Create a bdev with malloc backend')
p.add_argument('-b', '--name', help="Name of the bdev")
p.add_argument('-u', '--uuid', help="UUID of the bdev (optional)")
p.add_argument(
'total_size', help='Size of malloc bdev in MB (float > 0)', type=float)
p.add_argument('block_size', help='Data block size for this bdev', type=int)
p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int)
p.add_argument('-o', '--optimal-io-boundary', help="""Split on optimal IO boundary, in number of
blocks, default 0 (disabled)""", type=int)
p.add_argument('-m', '--md-size', type=int,
help='Metadata size for this bdev (0, 8, 16, 32, 64, or 128). Default is 0.')
p.add_argument('-i', '--md-interleave', action='store_true',
help='Metadata location, interleaved if set, and separated if omitted.')
p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3],
help='Protection information type. Parameter --md-size needs'
'to be set along --dif-type. Default=0 - no protection.')
p.add_argument('-d', '--dif-is-head-of-md', action='store_true',
help='Protection information is in the first 8 bytes of metadata. Default=false.')
p.add_argument('-f', '--dif-pi-format', type=int, choices=[0, 1, 2],
help='Protection infromation format. Parameter --dif-type needs to be set together.'
'0=16b Guard PI, 1=32b Guard PI, 2=64b Guard PI. Default=0.')
p.set_defaults(func=bdev_malloc_create)
def bdev_malloc_delete(args):
rpc.bdev.bdev_malloc_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_malloc_delete', help='Delete a malloc disk')
p.add_argument('name', help='malloc bdev name')
p.set_defaults(func=bdev_malloc_delete)
def bdev_null_create(args):
num_blocks = (args.total_size * 1024 * 1024) // args.block_size
if args.dif_type and not args.md_size:
print("ERROR: --md-size must be > 0 when --dif-type is > 0")
exit(1)
print_json(rpc.bdev.bdev_null_create(args.client,
num_blocks=num_blocks,
block_size=args.block_size,
physical_block_size=args.physical_block_size,
name=args.name,
uuid=args.uuid,
md_size=args.md_size,
dif_type=args.dif_type,
dif_is_head_of_md=args.dif_is_head_of_md,
dif_pi_format=args.dif_pi_format))
p = subparsers.add_parser('bdev_null_create', help='Add a bdev with null backend')
p.add_argument('name', help='Block device name')
p.add_argument('-u', '--uuid', help='UUID of the bdev (optional)')
p.add_argument('total_size', help='Size of null bdev in MB (int > 0). Includes only data blocks.', type=int)
p.add_argument('block_size', help='Data block size for this bdev.', type=int)
p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int)
p.add_argument('-m', '--md-size', type=int,
help='Metadata size for this bdev. Default=0.')
p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3],
help='Protection information type. Parameter --md-size needs'
'to be set along --dif-type. Default=0 - no protection.')
p.add_argument('-d', '--dif-is-head-of-md', action='store_true',
help='Protection information is in the first 8 bytes of metadata. Default=false.')
p.add_argument('-f', '--dif-pi-format', type=int, choices=[0, 1, 2],
help='Protection infromation format. Parameter --dif-type needs to be set together.'
'0=16b Guard PI, 1=32b Guard PI, 2=64b Guard PI. Default=0.')
p.set_defaults(func=bdev_null_create)
def bdev_null_delete(args):
rpc.bdev.bdev_null_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_null_delete', help='Delete a null bdev')
p.add_argument('name', help='null bdev name')
p.set_defaults(func=bdev_null_delete)
def bdev_null_resize(args):
print_json(rpc.bdev.bdev_null_resize(args.client,
name=args.name,
new_size=int(args.new_size)))
p = subparsers.add_parser('bdev_null_resize',
help='Resize a null bdev')
p.add_argument('name', help='null bdev name')
p.add_argument('new_size', help='new bdev size for resize operation. The unit is MiB')
p.set_defaults(func=bdev_null_resize)
def bdev_aio_create(args):
print_json(rpc.bdev.bdev_aio_create(args.client,
filename=args.filename,
name=args.name,
block_size=args.block_size,
readonly=args.readonly,
fallocate=args.fallocate,
uuid=args.uuid))
p = subparsers.add_parser('bdev_aio_create', help='Add a bdev with aio backend')
p.add_argument('filename', help='Path to device or file (ex: /dev/sda)')
p.add_argument('name', help='Block device name')
p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?')
p.add_argument("-r", "--readonly", action='store_true', help='Set this bdev as read-only')
p.add_argument("--fallocate", action='store_true', help='Support unmap/writezeros by fallocate')
p.add_argument('-u', '--uuid', help="UUID of the bdev (optional)")
p.set_defaults(func=bdev_aio_create)
def bdev_aio_rescan(args):
print_json(rpc.bdev.bdev_aio_rescan(args.client,
name=args.name))
p = subparsers.add_parser('bdev_aio_rescan', help='Rescan a bdev size with aio backend')
p.add_argument('name', help='Block device name')
p.set_defaults(func=bdev_aio_rescan)
def bdev_aio_delete(args):
rpc.bdev.bdev_aio_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_aio_delete', help='Delete an aio disk')
p.add_argument('name', help='aio bdev name')
p.set_defaults(func=bdev_aio_delete)
def bdev_uring_create(args):
print_json(rpc.bdev.bdev_uring_create(args.client,
filename=args.filename,
name=args.name,
block_size=args.block_size,
uuid=args.uuid))
p = subparsers.add_parser('bdev_uring_create', help='Create a bdev with io_uring backend')
p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)')
p.add_argument('name', help='bdev name')
p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?')
p.add_argument('-u', '--uuid', help="UUID of the bdev")
p.set_defaults(func=bdev_uring_create)
def bdev_uring_rescan(args):
print_json(rpc.bdev.bdev_uring_rescan(args.client,
name=args.name))
p = subparsers.add_parser('bdev_uring_rescan', help='Rescan a bdev size with uring backend')
p.add_argument('name', help='Block device name')
p.set_defaults(func=bdev_uring_rescan)
def bdev_uring_delete(args):
rpc.bdev.bdev_uring_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_uring_delete', help='Delete a uring bdev')
p.add_argument('name', help='uring bdev name')
p.set_defaults(func=bdev_uring_delete)
def bdev_xnvme_create(args):
print_json(rpc.bdev.bdev_xnvme_create(args.client,
filename=args.filename,
name=args.name,
io_mechanism=args.io_mechanism,
conserve_cpu=args.conserve_cpu))
p = subparsers.add_parser('bdev_xnvme_create', help='Create a bdev with xNVMe backend')
p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)')
p.add_argument('name', help='name of xNVMe bdev to create')
p.add_argument('io_mechanism', help='IO mechanism to use (ex: libaio, io_uring, io_uring_cmd, etc.)')
p.add_argument('-c', '--conserve-cpu', action='store_true', help='Whether or not to conserve CPU when polling')
p.set_defaults(func=bdev_xnvme_create)
def bdev_xnvme_delete(args):
rpc.bdev.bdev_xnvme_delete(args.client,
name=args.name)
p = subparsers.add_parser('bdev_xnvme_delete', help='Delete a xNVMe bdev')
p.add_argument('name', help='xNVMe bdev name')
p.set_defaults(func=bdev_xnvme_delete)
def bdev_nvme_set_options(args):
rpc.bdev.bdev_nvme_set_options(args.client,
action_on_timeout=args.action_on_timeout,
timeout_us=args.timeout_us,
timeout_admin_us=args.timeout_admin_us,
keep_alive_timeout_ms=args.keep_alive_timeout_ms,
arbitration_burst=args.arbitration_burst,
low_priority_weight=args.low_priority_weight,
medium_priority_weight=args.medium_priority_weight,
high_priority_weight=args.high_priority_weight,
nvme_adminq_poll_period_us=args.nvme_adminq_poll_period_us,
nvme_ioq_poll_period_us=args.nvme_ioq_poll_period_us,
io_queue_requests=args.io_queue_requests,
delay_cmd_submit=args.delay_cmd_submit,
transport_retry_count=args.transport_retry_count,
bdev_retry_count=args.bdev_retry_count,
transport_ack_timeout=args.transport_ack_timeout,
ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec,
reconnect_delay_sec=args.reconnect_delay_sec,
fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec,
disable_auto_failback=args.disable_auto_failback,
generate_uuids=args.generate_uuids,
transport_tos=args.transport_tos,
nvme_error_stat=args.nvme_error_stat,
rdma_srq_size=args.rdma_srq_size,
io_path_stat=args.io_path_stat,
allow_accel_sequence=args.allow_accel_sequence,
rdma_max_cq_size=args.rdma_max_cq_size,
rdma_cm_event_timeout_ms=args.rdma_cm_event_timeout_ms,
dhchap_digests=args.dhchap_digests,
dhchap_dhgroups=args.dhchap_dhgroups,
rdma_umr_per_io=args.rdma_umr_per_io)
p = subparsers.add_parser('bdev_nvme_set_options',
help='Set options for the bdev nvme type. This is startup command.')
p.add_argument('-a', '--action-on-timeout',
help="Action to take on command time out. Valid values are: none, reset, abort")
p.add_argument('-t', '--timeout-us',
help="Timeout for each command, in microseconds. If 0, don't track timeouts.", type=int)
p.add_argument('--timeout-admin-us',
help="Timeout for each admin command, in microseconds. If 0, treat same as io timeouts.", type=int)
p.add_argument('-k', '--keep-alive-timeout-ms',
help="Keep alive timeout period in millisecond. If 0, disable keep-alive.", type=int)
p.add_argument('--arbitration-burst',
help='the value is expressed as a power of two', type=int)
p.add_argument('--low-priority-weight',
help='the maximum number of commands that the controller may launch at one time from a low priority queue', type=int)
p.add_argument('--medium-priority-weight',
help='the maximum number of commands that the controller may launch at one time from a medium priority queue', type=int)
p.add_argument('--high-priority-weight',
help='the maximum number of commands that the controller may launch at one time from a high priority queue', type=int)
p.add_argument('-p', '--nvme-adminq-poll-period-us',
help='How often the admin queue is polled for asynchronous events', type=int)
p.add_argument('-i', '--nvme-ioq-poll-period-us',
help='How often to poll I/O queues for completions', type=int)
p.add_argument('-s', '--io-queue-requests',
help='The number of requests allocated for each NVMe I/O queue. Default: 512', type=int)
p.add_argument('-d', '--disable-delay-cmd-submit',
help='Disable delaying NVMe command submission, i.e. no batching of multiple commands',
action='store_false', dest='delay_cmd_submit')
p.add_argument('-c', '--transport-retry-count',
help='the number of attempts per I/O in the transport layer when an I/O fails.', type=int)
p.add_argument('-r', '--bdev-retry-count',
help='the number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries.', type=int)
p.add_argument('-e', '--transport-ack-timeout',
help="""Time to wait ack until packet retransmission for RDMA or until closes connection for TCP.
Range 0-31 where 0 is driver-specific default value.""", type=int)
p.add_argument('-l', '--ctrlr-loss-timeout-sec',
help="""Time to wait until ctrlr is reconnected before deleting ctrlr.
-1 means infinite reconnect retries. 0 means no reconnect retry.
If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than
reconnect_delay_sec.
This can be overridden by bdev_nvme_attach_controller.""",
type=int)
p.add_argument('-o', '--reconnect-delay-sec',
help="""Time to delay a reconnect retry.
If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and
less than ctrlr_loss_timeout_sec.
This can be overridden by bdev_nvme_attach_controller.""",
type=int)
p.add_argument('-u', '--fast-io-fail-timeout-sec',
help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
0 means no such timeout.
If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and
less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.
This can be overridden by bdev_nvme_attach_controller.""",
type=int)
p.add_argument('-f', '--disable-auto-failback',
help="""Disable automatic failback. bdev_nvme_set_preferred_path can be used to do manual failback.
By default, immediately failback to the preferred I/O path if it restored.""",
action='store_true')
p.add_argument('--generate-uuids',
help="""Enable generation of unique identifiers for NVMe bdevs only if they do
not provide UUID themselves. These strings are based on device serial number and
namespace ID and will always be the same for that device.""", action='store_true')
p.add_argument('--transport-tos',
help="""IPv4 Type of Service value. Only applicable for RDMA transports.
The default is 0 which means no TOS is applied.""", type=int)
p.add_argument('-m', '--nvme-error-stat', help="Enable collecting NVMe error counts.", action='store_true')
p.add_argument('-q', '--rdma-srq-size',
help='Set the size of a shared rdma receive queue. Default: 0 (disabled)', type=int)
p.add_argument('--io-path-stat',
help="""Enable collecting I/O path stat of each io path.""",
action='store_true')
p.add_argument('--allow-accel-sequence',
help='''Allow NVMe bdevs to advertise support for accel sequences if the
controller also supports them.''', action='store_true')
p.add_argument('--rdma-max-cq-size',
help='The maximum size of a rdma completion queue. Default: 0 (unlimited)', type=int)
p.add_argument('--rdma-cm-event-timeout-ms',
help='Time to wait for RDMA CM event. Only applicable for RDMA transports.', type=int)
p.add_argument('--dhchap-digests', help='Comma-separated list of allowed DH-HMAC-CHAP digests',
type=lambda d: d.split(','))
p.add_argument('--dhchap-dhgroups', help='Comma-separated list of allowed DH-HMAC-CHAP DH groups',
type=lambda d: d.split(','))
p.add_argument('--enable-rdma-umr-per-io',
help='''Enable scatter-gather RDMA Memory Region per IO if supported by the system.''',
action='store_true', dest='rdma_umr_per_io')
p.add_argument('--disable-rdma-umr-per-io',
help='''Disable scatter-gather RDMA Memory Region per IO.''',
action='store_false', dest='rdma_umr_per_io')
p.set_defaults(func=bdev_nvme_set_options)
def bdev_nvme_set_hotplug(args):
rpc.bdev.bdev_nvme_set_hotplug(args.client, enable=args.enable, period_us=args.period_us)
p = subparsers.add_parser('bdev_nvme_set_hotplug', help='Set hotplug options for bdev nvme type.')
p.add_argument('-d', '--disable', dest='enable', default=False, action='store_false', help="Disable hotplug (default)")
p.add_argument('-e', '--enable', dest='enable', action='store_true', help="Enable hotplug")
p.add_argument('-r', '--period-us',
help='How often the hotplug is processed for insert and remove events', type=int)
p.set_defaults(func=bdev_nvme_set_hotplug)
def bdev_nvme_attach_controller(args):
print_array(rpc.bdev.bdev_nvme_attach_controller(args.client,
name=args.name,
trtype=args.trtype,
traddr=args.traddr,
adrfam=args.adrfam,
trsvcid=args.trsvcid,
priority=args.priority,
subnqn=args.subnqn,
hostnqn=args.hostnqn,
hostaddr=args.hostaddr,
hostsvcid=args.hostsvcid,
prchk_reftag=args.prchk_reftag,
prchk_guard=args.prchk_guard,
hdgst=args.hdgst,
ddgst=args.ddgst,
fabrics_connect_timeout_us=args.fabrics_connect_timeout_us,
multipath=args.multipath,
num_io_queues=args.num_io_queues,
ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec,
reconnect_delay_sec=args.reconnect_delay_sec,
fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec,
psk=args.psk,
max_bdevs=args.max_bdevs,
dhchap_key=args.dhchap_key,
dhchap_ctrlr_key=args.dhchap_ctrlr_key,
allow_unrecognized_csi=args.allow_unrecognized_csi))
p = subparsers.add_parser('bdev_nvme_attach_controller', help='Add bdevs with nvme backend')
p.add_argument('-b', '--name', help="Name of the NVMe controller, prefix for each bdev name", required=True)
p.add_argument('-t', '--trtype',
help='NVMe-oF target trtype: e.g., rdma, pcie', required=True)
p.add_argument('-a', '--traddr',
help='NVMe-oF target address: e.g., an ip address or BDF', required=True)
p.add_argument('-f', '--adrfam',
help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host')
p.add_argument('-s', '--trsvcid',
help='NVMe-oF target trsvcid: e.g., a port number')
p.add_argument('-p', '--priority',
help='NVMe-oF connection priority: e.g., a priority number')
p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn')
p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn')
p.add_argument('-i', '--hostaddr',
help='NVMe-oF host address: e.g., an ip address')
p.add_argument('-c', '--hostsvcid',
help='NVMe-oF host svcid: e.g., a port number')
p.add_argument('-r', '--prchk-reftag',
help='Enable checking of PI reference tag for I/O processing.', action='store_true')
p.add_argument('-g', '--prchk-guard',
help='Enable checking of PI guard for I/O processing.', action='store_true')
p.add_argument('-e', '--hdgst',
help='Enable TCP header digest.', action='store_true')
p.add_argument('-d', '--ddgst',
help='Enable TCP data digest.', action='store_true')
p.add_argument('--fabrics-timeout', type=int, help='Fabrics connect timeout in microseconds',
dest="fabrics_connect_timeout_us")
p.add_argument('-x', '--multipath', help='Set multipath behavior (disable, failover, multipath)')
p.add_argument('--num-io-queues', type=int, help='Set the number of IO queues to request during initialization.')
p.add_argument('-l', '--ctrlr-loss-timeout-sec',
help="""Time to wait until ctrlr is reconnected before deleting ctrlr.
-1 means infinite reconnect retries. 0 means no reconnect retry.
If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than
reconnect_delay_sec.""",
type=int)
p.add_argument('-o', '--reconnect-delay-sec',
help="""Time to delay a reconnect retry.
If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and
less than ctrlr_loss_timeout_sec.""",
type=int)
p.add_argument('-u', '--fast-io-fail-timeout-sec',
help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
0 means no such timeout.
If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and
less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.""",
type=int)
p.add_argument('-k', '--psk',
help="""Set PSK and enable TCP SSL socket implementation. The PSK can either be a
name of a key attached to the keyring or a path to a file containing the key. The
latter method is deprecated.""")
p.add_argument('-m', '--max-bdevs', type=int,
help='The size of the name array for newly created bdevs. Default is 128',)
p.add_argument('--dhchap-key', help='DH-HMAC-CHAP key name')
p.add_argument('--dhchap-ctrlr-key', help='DH-HMAC-CHAP controller key name')
p.add_argument('-U', '--allow-unrecognized-csi', help="""Allow attaching namespaces with unrecognized command set identifiers.
These will only support NVMe passthrough.""", action='store_true')
p.set_defaults(func=bdev_nvme_attach_controller)
def bdev_nvme_get_controllers(args):
print_dict(rpc.nvme.bdev_nvme_get_controllers(args.client,
name=args.name))
p = subparsers.add_parser(
'bdev_nvme_get_controllers', help='Display current NVMe controllers list or required NVMe controller')
p.add_argument('-n', '--name', help="Name of the NVMe controller. Example: Nvme0")
p.set_defaults(func=bdev_nvme_get_controllers)
def bdev_nvme_detach_controller(args):
rpc.bdev.bdev_nvme_detach_controller(args.client,
name=args.name,
trtype=args.trtype,
traddr=args.traddr,
adrfam=args.adrfam,
trsvcid=args.trsvcid,
subnqn=args.subnqn,
hostaddr=args.hostaddr,
hostsvcid=args.hostsvcid)
p = subparsers.add_parser('bdev_nvme_detach_controller',
help='Detach an NVMe controller and delete any associated bdevs')
p.add_argument('name', help="Name of the controller")
p.add_argument('-t', '--trtype',
help='NVMe-oF target trtype: e.g., rdma, pcie')
p.add_argument('-a', '--traddr',
help='NVMe-oF target address: e.g., an ip address or BDF')
p.add_argument('-f', '--adrfam',
help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host')
p.add_argument('-s', '--trsvcid',
help='NVMe-oF target trsvcid: e.g., a port number')
p.add_argument('-n', '--subnqn', help='NVMe-oF target subnqn')
p.add_argument('-i', '--hostaddr',
help='NVMe-oF host address: e.g., an ip address')
p.add_argument('-c', '--hostsvcid',
help='NVMe-oF host svcid: e.g., a port number')
p.set_defaults(func=bdev_nvme_detach_controller)
def bdev_nvme_reset_controller(args):
rpc.bdev.bdev_nvme_reset_controller(args.client,
name=args.name,
cntlid=args.cntlid)
p = subparsers.add_parser('bdev_nvme_reset_controller',
help='Reset an NVMe controller or all NVMe controllers in an NVMe bdev controller')
p.add_argument('name', help="Name of the NVMe controller")
p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int)
p.set_defaults(func=bdev_nvme_reset_controller)
def bdev_nvme_enable_controller(args):
rpc.bdev.bdev_nvme_enable_controller(args.client,
name=args.name,
cntlid=args.cntlid)
p = subparsers.add_parser('bdev_nvme_enable_controller',
help='Enable an NVMe controller or all NVMe controllers in an NVMe bdev controller')
p.add_argument('name', help="Name of the NVMe controller")
p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int)
p.set_defaults(func=bdev_nvme_enable_controller)
def bdev_nvme_disable_controller(args):
rpc.bdev.bdev_nvme_disable_controller(args.client,
name=args.name,
cntlid=args.cntlid)
p = subparsers.add_parser('bdev_nvme_disable_controller',
help='Disable an NVMe controller or all NVMe controllers in an NVMe bdev controller')
p.add_argument('name', help="Name of the NVMe controller")
p.add_argument('-c', '--cntlid', help="NVMe controller ID", type=int)
p.set_defaults(func=bdev_nvme_disable_controller)
def bdev_nvme_start_discovery(args):
rpc.bdev.bdev_nvme_start_discovery(args.client,
name=args.name,
trtype=args.trtype,
traddr=args.traddr,
adrfam=args.adrfam,
trsvcid=args.trsvcid,
hostnqn=args.hostnqn,
wait_for_attach=args.wait_for_attach,
attach_timeout_ms=args.attach_timeout_ms,
ctrlr_loss_timeout_sec=args.ctrlr_loss_timeout_sec,
reconnect_delay_sec=args.reconnect_delay_sec,
fast_io_fail_timeout_sec=args.fast_io_fail_timeout_sec)
p = subparsers.add_parser('bdev_nvme_start_discovery', help='Start automatic discovery')
p.add_argument('-b', '--name', help="Name of the NVMe controller prefix for each bdev name", required=True)
p.add_argument('-t', '--trtype',
help='NVMe-oF target trtype: e.g., rdma, pcie', required=True)
p.add_argument('-a', '--traddr',
help='NVMe-oF target address: e.g., an ip address or BDF', required=True)
p.add_argument('-f', '--adrfam',
help='NVMe-oF target adrfam: e.g., ipv4, ipv6, ib, fc, intra_host')
p.add_argument('-s', '--trsvcid',
help='NVMe-oF target trsvcid: e.g., a port number')
p.add_argument('-q', '--hostnqn', help='NVMe-oF host subnqn')
p.add_argument('-w', '--wait-for-attach', action='store_true',
help='Do not complete RPC until all discovered NVM subsystems are attached')
p.add_argument('-T', '--attach-timeout-ms', type=int,
help="""Time to wait until the discovery and all discovered NVM subsystems
are attached (default: 0, meaning wait indefinitely). Automatically
selects the --wait-for-attach option.""")
p.add_argument('-l', '--ctrlr-loss-timeout-sec',
help="""Time to wait until ctrlr is reconnected before deleting ctrlr.
-1 means infinite reconnect retries. 0 means no reconnect retry.
If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than
reconnect_delay_sec.""",
type=int)
p.add_argument('-o', '--reconnect-delay-sec',
help="""Time to delay a reconnect retry.
If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_delay_sec has to be non-zero and
less than ctrlr_loss_timeout_sec.""",
type=int)
p.add_argument('-u', '--fast-io-fail-timeout-sec',
help="""Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
0 means no such timeout.
If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and
less than ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.""",
type=int)
p.set_defaults(func=bdev_nvme_start_discovery)
def bdev_nvme_stop_discovery(args):
rpc.bdev.bdev_nvme_stop_discovery(args.client, name=args.name)
p = subparsers.add_parser('bdev_nvme_stop_discovery', help='Stop automatic discovery')
p.add_argument('-b', '--name', help="Name of the service to stop", required=True)
p.set_defaults(func=bdev_nvme_stop_discovery)
def bdev_nvme_get_discovery_info(args):
print_dict(rpc.bdev.bdev_nvme_get_discovery_info(args.client))
p = subparsers.add_parser('bdev_nvme_get_discovery_info', help='Get information about the automatic discovery')
p.set_defaults(func=bdev_nvme_get_discovery_info)
def bdev_nvme_get_io_paths(args):
print_dict(rpc.bdev.bdev_nvme_get_io_paths(args.client, name=args.name))
p = subparsers.add_parser('bdev_nvme_get_io_paths', help='Display active I/O paths')
p.add_argument('-n', '--name', help="Name of the NVMe bdev")
p.set_defaults(func=bdev_nvme_get_io_paths)
def bdev_nvme_set_preferred_path(args):
rpc.bdev.bdev_nvme_set_preferred_path(args.client,
name=args.name,
cntlid=args.cntlid)
p = subparsers.add_parser('bdev_nvme_set_preferred_path',
help="""Set the preferred I/O path for an NVMe bdev when in multipath mode""")
p.add_argument('-b', '--name', help='Name of the NVMe bdev', required=True)
p.add_argument('-c', '--cntlid', help='NVMe-oF controller ID', type=int, required=True)
p.set_defaults(func=bdev_nvme_set_preferred_path)
def bdev_nvme_set_multipath_policy(args):
rpc.bdev.bdev_nvme_set_multipath_policy(args.client,
name=args.name,
policy=args.policy,
selector=args.selector,
rr_min_io=args.rr_min_io)
p = subparsers.add_parser('bdev_nvme_set_multipath_policy',
help="""Set multipath policy of the NVMe bdev""")
p.add_argument('-b', '--name', help='Name of the NVMe bdev', required=True)
p.add_argument('-p', '--policy', help='Multipath policy (active_passive or active_active)', required=True)
p.add_argument('-s', '--selector', help='Multipath selector (round_robin, queue_depth)')
p.add_argument('-r', '--rr-min-io',
help='Number of IO to route to a path before switching to another for round-robin',
type=int)
p.set_defaults(func=bdev_nvme_set_multipath_policy)
def bdev_nvme_get_path_iostat(args):
print_dict(rpc.bdev.bdev_nvme_get_path_iostat(args.client,