xref: /spdk/python/spdk/rpc/bdev.py (revision e0d7428b482257aa6999b8b4cc44159dcc292df9)
1#  SPDX-License-Identifier: BSD-3-Clause
2#  Copyright (C) 2017 Intel Corporation.
3#  All rights reserved.
4#  Copyright (c) 2022 Dell Inc, or its subsidiaries.
5#  Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
6
7
8def bdev_set_options(client, bdev_io_pool_size=None, bdev_io_cache_size=None,
9                     bdev_auto_examine=None, iobuf_small_cache_size=None,
10                     iobuf_large_cache_size=None):
11    """Set parameters for the bdev subsystem.
12    Args:
13        bdev_io_pool_size: number of bdev_io structures in shared buffer pool (optional)
14        bdev_io_cache_size: maximum number of bdev_io structures cached per thread (optional)
15        bdev_auto_examine: if set to false, the bdev layer will not examine every disks automatically (optional)
16        iobuf_small_cache_size: size of the small iobuf per thread cache
17        iobuf_large_cache_size: size of the large iobuf per thread cache
18    """
19    params = dict()
20    if bdev_io_pool_size is not None:
21        params['bdev_io_pool_size'] = bdev_io_pool_size
22    if bdev_io_cache_size is not None:
23        params['bdev_io_cache_size'] = bdev_io_cache_size
24    if bdev_auto_examine is not None:
25        params['bdev_auto_examine'] = bdev_auto_examine
26    if iobuf_small_cache_size is not None:
27        params['iobuf_small_cache_size'] = iobuf_small_cache_size
28    if iobuf_large_cache_size is not None:
29        params['iobuf_large_cache_size'] = iobuf_large_cache_size
30    return client.call('bdev_set_options', params)
31
32
33def bdev_examine(client, name):
34    """Examine a bdev manually. If the bdev does not exist yet when this RPC is called,
35    it will be examined when it is created
36    Args:
37        name: name of the bdev
38    """
39    params = dict()
40    params['name'] = name
41    return client.call('bdev_examine', params)
42
43
44def bdev_wait_for_examine(client):
45    """Report when all bdevs have been examined
46    """
47    return client.call('bdev_wait_for_examine')
48
49
50def bdev_compress_create(client, base_bdev_name, pm_path, lb_size=None, comp_algo=None, comp_level=None):
51    """Construct a compress virtual block device.
52    Args:
53        base_bdev_name: name of the underlying base bdev
54        pm_path: path to persistent memory
55        lb_size: logical block size for the compressed vol in bytes.  Must be 4K or 512.
56        comp_algo: compression algorithm for the compressed vol. Default is deflate.
57        comp_level: compression algorithm level for the compressed vol. Default is 1.
58    Returns:
59        Name of created virtual block device.
60    """
61    params = dict()
62    params['base_bdev_name'] = base_bdev_name
63    params['pm_path'] = pm_path
64    if lb_size is not None:
65        params['lb_size'] = lb_size
66    if comp_algo is not None:
67        params['comp_algo'] = comp_algo
68    if comp_level is not None:
69        params['comp_level'] = comp_level
70    return client.call('bdev_compress_create', params)
71
72
73def bdev_compress_delete(client, name):
74    """Delete compress virtual block device.
75    Args:
76        name: name of compress vbdev to delete
77    """
78    params = dict()
79    params['name'] = name
80    return client.call('bdev_compress_delete', params)
81
82
83def bdev_compress_get_orphans(client, name=None):
84    """Get a list of comp bdevs that do not have a pmem file (aka orphaned).
85    Args:
86        name: comp bdev name to query (optional; if omitted, query all comp bdevs)
87    Returns:
88        List of comp bdev names.
89    """
90    params = dict()
91    if name is not None:
92        params['name'] = name
93    return client.call('bdev_compress_get_orphans', params)
94
95
96def bdev_crypto_create(client, base_bdev_name, name, crypto_pmd=None, key=None, cipher=None, key2=None, key_name=None):
97    """Construct a crypto virtual block device.
98    Args:
99        base_bdev_name: name of the underlying base bdev
100        name: name for the crypto vbdev
101        crypto_pmd: name of the DPDK crypto driver to use
102        key: key
103        cipher: crypto algorithm to use
104        key2: Optional second part of the key
105        key_name: The key name to use in crypto operations
106    Returns:
107        Name of created virtual block device.
108    """
109    params = dict()
110    params['base_bdev_name'] = base_bdev_name
111    params['name'] = name
112    if crypto_pmd is not None:
113        params['crypto_pmd'] = crypto_pmd
114    if key is not None:
115        params['key'] = key
116    if cipher is not None:
117        params['cipher'] = cipher
118    if key2 is not None:
119        params['key2'] = key2
120    if key_name is not None:
121        params['key_name'] = key_name
122    return client.call('bdev_crypto_create', params)
123
124
125def bdev_crypto_delete(client, name):
126    """Delete crypto virtual block device.
127    Args:
128        name: name of crypto vbdev to delete
129    """
130    params = dict()
131    params['name'] = name
132    return client.call('bdev_crypto_delete', params)
133
134
135def bdev_ocf_create(client, name, mode, cache_bdev_name, core_bdev_name, cache_line_size=None):
136    """Add an OCF block device
137    Args:
138        name: name of constructed OCF bdev
139        mode: OCF cache mode: {'wb', 'wt', 'pt', 'wa', 'wi', 'wo'}
140        cache_bdev_name: name of underlying cache bdev
141        core_bdev_name: name of underlying core bdev
142        cache_line_size: OCF cache line size. The unit is KiB: {4, 8, 16, 32, 64}
143    Returns:
144        Name of created block device
145    """
146    params = dict()
147    params['name'] = name
148    params['mode'] = mode
149    params['cache_bdev_name'] = cache_bdev_name
150    params['core_bdev_name'] = core_bdev_name
151    if cache_line_size is not None:
152        params['cache_line_size'] = cache_line_size
153    return client.call('bdev_ocf_create', params)
154
155
156def bdev_ocf_delete(client, name):
157    """Delete an OCF device
158    Args:
159        name: name of OCF bdev
160    """
161    params = dict()
162    params['name'] = name
163    return client.call('bdev_ocf_delete', params)
164
165
166def bdev_ocf_get_stats(client, name):
167    """Get statistics of chosen OCF block device
168    Args:
169        name: name of OCF bdev
170    Returns:
171        Statistics as json object
172    """
173    params = dict()
174    params['name'] = name
175    return client.call('bdev_ocf_get_stats', params)
176
177
178def bdev_ocf_reset_stats(client, name):
179    """Reset statistics of chosen OCF block device
180    Args:
181        name: name of OCF bdev
182    Returns:
183        None
184    """
185    params = dict()
186    params['name'] = name
187    return client.call('bdev_ocf_reset_stats', params)
188
189
190def bdev_ocf_get_bdevs(client, name=None):
191    """Get list of OCF devices including unregistered ones
192    Args:
193        name: name of OCF vbdev or name of cache device or name of core device (optional)
194    Returns:
195        Array of OCF devices with their current status
196    """
197    params = dict()
198    if name is not None:
199        params['name'] = name
200    return client.call('bdev_ocf_get_bdevs', params)
201
202
203def bdev_ocf_set_cache_mode(client, name, mode):
204    """Set cache mode of OCF block device
205    Args:
206        name: name of OCF bdev
207        mode: OCF cache mode: {'wb', 'wt', 'pt', 'wa', 'wi', 'wo'}
208    Returns:
209        New cache mode name
210    """
211    params = dict()
212    params['name'] = name
213    params['mode'] = mode
214    return client.call('bdev_ocf_set_cache_mode', params)
215
216
217def bdev_ocf_set_seqcutoff(client, name, policy, threshold=None, promotion_count=None):
218    """Set sequential cutoff parameters on all cores for the given OCF cache device
219    Args:
220        name: Name of OCF cache bdev
221        policy: Sequential cutoff policy
222        threshold: Activation threshold [KiB] (optional)
223        promotion_count: Promotion request count (optional)
224    """
225    params = dict()
226    params['name'] = name
227    params['policy'] = policy
228    if threshold is not None:
229        params['threshold'] = threshold
230    if promotion_count is not None:
231        params['promotion_count'] = promotion_count
232    return client.call('bdev_ocf_set_seqcutoff', params)
233
234
235def bdev_ocf_flush_start(client, name):
236    """Start flushing OCF cache device
237    Args:
238        name: name of OCF bdev
239    """
240    params = dict()
241    params['name'] = name
242    return client.call('bdev_ocf_flush_start', params)
243
244
245def bdev_ocf_flush_status(client, name):
246    """Get flush status of OCF cache device
247    Args:
248        name: name of OCF bdev
249    Returns:
250        Flush status
251    """
252    params = dict()
253    params['name'] = name
254    return client.call('bdev_ocf_flush_status', params)
255
256
257def bdev_malloc_create(client, num_blocks, block_size, physical_block_size=None, name=None, uuid=None, optimal_io_boundary=None,
258                       md_size=None, md_interleave=None, dif_type=None, dif_is_head_of_md=None, dif_pi_format=None):
259    """Construct a malloc block device.
260    Args:
261        num_blocks: size of block device in blocks
262        block_size: Data block size of device; must be a power of 2 and at least 512
263        physical_block_size: Physical block size of device; must be a power of 2 and at least 512 (optional)
264        name: name of block device (optional)
265        uuid: UUID of block device (optional)
266        optimal_io_boundary: Split on optimal IO boundary, in number of blocks, default 0 (disabled, optional)
267        md_size: metadata size of device (0, 8, 16, 32, 64, or 128), default 0 (optional)
268        md_interleave: metadata location, interleaved if set, and separated if omitted (optional)
269        dif_type: protection information type (optional)
270        dif_is_head_of_md: protection information is in the first 8 bytes of metadata (optional)
271        dif_pi_format: protection information format (optional)
272    Returns:
273        Name of created block device.
274    """
275    params = dict()
276    params['num_blocks'] = num_blocks
277    params['block_size'] = block_size
278    if physical_block_size is not None:
279        params['physical_block_size'] = physical_block_size
280    if name is not None:
281        params['name'] = name
282    if uuid is not None:
283        params['uuid'] = uuid
284    if optimal_io_boundary is not None:
285        params['optimal_io_boundary'] = optimal_io_boundary
286    if md_size is not None:
287        params['md_size'] = md_size
288    if md_interleave is not None:
289        params['md_interleave'] = md_interleave
290    if dif_type is not None:
291        params['dif_type'] = dif_type
292    if dif_is_head_of_md is not None:
293        params['dif_is_head_of_md'] = dif_is_head_of_md
294    if dif_pi_format is not None:
295        params['dif_pi_format'] = dif_pi_format
296    return client.call('bdev_malloc_create', params)
297
298
299def bdev_malloc_delete(client, name):
300    """Delete malloc block device.
301    Args:
302        bdev_name: name of malloc bdev to delete
303    """
304    params = dict()
305    params['name'] = name
306    return client.call('bdev_malloc_delete', params)
307
308
309def bdev_null_create(client, num_blocks, block_size, name, physical_block_size=None, uuid=None, md_size=None,
310                     dif_type=None, dif_is_head_of_md=None, dif_pi_format=None):
311    """Construct a null block device.
312    Args:
313        num_blocks: size of block device in blocks
314        block_size: block size of device; data part size must be a power of 2 and at least 512
315        name: name of block device
316        physical_block_size: physical block size of the device; data part size must be a power of 2 and at least 512 (optional)
317        uuid: UUID of block device (optional)
318        md_size: metadata size of device (optional)
319        dif_type: protection information type (optional)
320        dif_is_head_of_md: protection information is in the first 8 bytes of metadata (optional)
321        dif_pi_format: protection information format (optional)
322    Returns:
323        Name of created block device.
324    """
325    params = dict()
326    params['num_blocks'] = num_blocks
327    params['block_size'] = block_size
328    params['name'] = name
329    if physical_block_size is not None:
330        params['physical_block_size'] = physical_block_size
331    if uuid is not None:
332        params['uuid'] = uuid
333    if md_size is not None:
334        params['md_size'] = md_size
335    if dif_type is not None:
336        params['dif_type'] = dif_type
337    if dif_is_head_of_md is not None:
338        params['dif_is_head_of_md'] = dif_is_head_of_md
339    if dif_pi_format is not None:
340        params['dif_pi_format'] = dif_pi_format
341    return client.call('bdev_null_create', params)
342
343
344def bdev_null_delete(client, name):
345    """Remove null bdev from the system.
346    Args:
347        name: name of null bdev to delete
348    """
349    params = dict()
350    params['name'] = name
351    return client.call('bdev_null_delete', params)
352
353
354def bdev_null_resize(client, name, new_size):
355    """Resize null bdev in the system.
356    Args:
357        name: name of null bdev to resize
358        new_size: new bdev size of resize operation. The unit is MiB
359    """
360    params = dict()
361    params['name'] = name
362    params['new_size'] = new_size
363    return client.call('bdev_null_resize', params)
364
365
366def bdev_raid_set_options(client, process_window_size_kb=None, process_max_bandwidth_mb_sec=None):
367    """Set options for bdev raid.
368    Args:
369        process_window_size_kb: Background process (e.g. rebuild) window size in KiB
370        process_max_bandwidth_mb_sec: Background process (e.g. rebuild) maximum bandwidth in MiB/Sec
371    """
372    params = dict()
373    if process_window_size_kb is not None:
374        params['process_window_size_kb'] = process_window_size_kb
375
376    if process_max_bandwidth_mb_sec is not None:
377        params['process_max_bandwidth_mb_sec'] = process_max_bandwidth_mb_sec
378
379    return client.call('bdev_raid_set_options', params)
380
381
382def bdev_raid_get_bdevs(client, category):
383    """Get list of raid bdevs based on category
384    Args:
385        category: any one of all or online or configuring or offline
386    Returns:
387        List of raid bdev details
388    """
389    params = dict()
390    params['category'] = category
391    return client.call('bdev_raid_get_bdevs', params)
392
393
394def bdev_raid_create(client, name, raid_level, base_bdevs, strip_size_kb=None, uuid=None, superblock=None):
395    """Create raid bdev. Either strip size arg will work but one is required.
396    Args:
397        name: user defined raid bdev name
398        raid_level: raid level of raid bdev, supported values 0
399        base_bdevs: Space separated names of Nvme bdevs in double quotes, like "Nvme0n1 Nvme1n1 Nvme2n1"
400        strip_size_kb: strip size of raid bdev in KB, supported values like 8, 16, 32, 64, 128, 256, etc
401        uuid: UUID for this raid bdev (optional)
402        superblock: information about raid bdev will be stored in superblock on each base bdev,
403                    disabled by default due to backward compatibility
404    Returns:
405        None
406    """
407    params = dict()
408    params['name'] = name
409    params['raid_level'] = raid_level
410    params['base_bdevs'] = base_bdevs
411    if strip_size_kb is not None:
412        params['strip_size_kb'] = strip_size_kb
413    if uuid is not None:
414        params['uuid'] = uuid
415    if superblock is not None:
416        params['superblock'] = superblock
417    return client.call('bdev_raid_create', params)
418
419
420def bdev_raid_delete(client, name):
421    """Delete raid bdev
422    Args:
423        name: raid bdev name
424    Returns:
425        None
426    """
427    params = dict()
428    params['name'] = name
429    return client.call('bdev_raid_delete', params)
430
431
432def bdev_raid_add_base_bdev(client, base_bdev, raid_bdev):
433    """Add base bdev to existing raid bdev
434    Args:
435        base_bdev: base bdev name
436        raid_bdev: raid bdev name
437    Returns:
438        None
439    """
440    params = dict()
441    params['base_bdev'] = base_bdev
442    params['raid_bdev'] = raid_bdev
443    return client.call('bdev_raid_add_base_bdev', params)
444
445
446def bdev_raid_remove_base_bdev(client, name):
447    """Remove base bdev from existing raid bdev
448    Args:
449        name: base bdev name
450    Returns:
451        None
452    """
453    params = dict()
454    params['name'] = name
455    return client.call('bdev_raid_remove_base_bdev', params)
456
457
458def bdev_aio_create(client, filename, name, block_size=None, readonly=None, fallocate=None, uuid=None):
459    """Construct a Linux AIO block device.
460    Args:
461        filename: path to device or file (ex: /dev/sda)
462        name: name of block device
463        block_size: block size of device (optional; autodetected if omitted)
464        readonly: set aio bdev as read-only
465        fallocate: enable fallocate for UNMAP/WRITEZEROS support (note that fallocate syscall would block reactor)
466        uuid: UUID of the bdev (optional)
467    Returns:
468        Name of created block device.
469    """
470    params = dict()
471    params['filename'] = filename
472    params['name'] = name
473    if block_size is not None:
474        params['block_size'] = block_size
475    if readonly is not None:
476        params['readonly'] = readonly
477    if fallocate is not None:
478        params['fallocate'] = fallocate
479    if uuid is not None:
480        params['uuid'] = uuid
481    return client.call('bdev_aio_create', params)
482
483
484def bdev_aio_rescan(client, name):
485    """Rescan a Linux AIO block device.
486    Args:
487        name: name of aio bdev to rescan
488    """
489    params = dict()
490    params['name'] = name
491    return client.call('bdev_aio_rescan', params)
492
493
494def bdev_aio_delete(client, name):
495    """Remove aio bdev from the system.
496    Args:
497        name: name of aio bdev to delete
498    """
499    params = dict()
500    params['name'] = name
501    return client.call('bdev_aio_delete', params)
502
503
504def bdev_uring_create(client, filename, name, block_size=None, uuid=None):
505    """Create a bdev with Linux io_uring backend.
506    Args:
507        filename: path to device or file (ex: /dev/nvme0n1)
508        name: name of bdev
509        block_size: block size of device (optional; autodetected if omitted)
510        uuid: UUID of block device (optional)
511    Returns:
512        Name of created bdev.
513    """
514    params = dict()
515    params['filename'] = filename
516    params['name'] = name
517    if block_size is not None:
518        params['block_size'] = block_size
519    if uuid is not None:
520        params['uuid'] = uuid
521    return client.call('bdev_uring_create', params)
522
523
524def bdev_uring_rescan(client, name):
525    """Rescan a Linux URING block device.
526    Args:
527        name: name of uring bdev to rescan
528    """
529    params = dict()
530    params['name'] = name
531    return client.call('bdev_uring_rescan', params)
532
533
534def bdev_uring_delete(client, name):
535    """Delete a uring bdev.
536    Args:
537        name: name of uring bdev to delete
538    """
539    params = dict()
540    params['name'] = name
541    return client.call('bdev_uring_delete', params)
542
543
544def bdev_xnvme_create(client, filename, name, io_mechanism, conserve_cpu):
545    """Create a bdev with xNVMe backend.
546    Args:
547        filename: path to device or file (ex: /dev/nvme0n1)
548        name: name of xNVMe bdev to create
549        io_mechanism: I/O mechanism to use (ex: io_uring, io_uring_cmd, etc.)
550        conserve_cpu: Whether or not to conserve CPU when polling (default: False)
551    Returns:
552        Name of created bdev.
553    """
554    params = dict()
555    params['filename'] = filename
556    params['name'] = name
557    params['io_mechanism'] = io_mechanism
558    params['conserve_cpu'] = conserve_cpu
559    return client.call('bdev_xnvme_create', params)
560
561
562def bdev_xnvme_delete(client, name):
563    """Delete a xNVMe bdev.
564    Args:
565        name: name of xNVMe bdev to delete
566    """
567    params = dict()
568    params['name'] = name
569    return client.call('bdev_xnvme_delete', params)
570
571
572def bdev_nvme_set_options(client, action_on_timeout=None, timeout_us=None, timeout_admin_us=None,
573                          keep_alive_timeout_ms=None, arbitration_burst=None,
574                          low_priority_weight=None, medium_priority_weight=None, high_priority_weight=None,
575                          nvme_adminq_poll_period_us=None, nvme_ioq_poll_period_us=None, io_queue_requests=None,
576                          delay_cmd_submit=None, transport_retry_count=None, bdev_retry_count=None,
577                          transport_ack_timeout=None, ctrlr_loss_timeout_sec=None, reconnect_delay_sec=None,
578                          fast_io_fail_timeout_sec=None, disable_auto_failback=None, generate_uuids=None,
579                          transport_tos=None, nvme_error_stat=None, rdma_srq_size=None, io_path_stat=None,
580                          allow_accel_sequence=None, rdma_max_cq_size=None, rdma_cm_event_timeout_ms=None,
581                          dhchap_digests=None, dhchap_dhgroups=None):
582    """Set options for the bdev nvme. This is startup command.
583    Args:
584        action_on_timeout:  action to take on command time out. Valid values are: none, reset, abort (optional)
585        timeout_us: Timeout for each command, in microseconds. If 0, don't track timeouts (optional)
586        timeout_admin_us: Timeout for each admin command, in microseconds. If 0, treat same as io timeouts (optional)
587        keep_alive_timeout_ms: Keep alive timeout period in millisecond, default is 10s (optional)
588        arbitration_burst: The value is expressed as a power of two (optional)
589        low_priority_weight: The number of commands that may be executed from the low priority queue at one time (optional)
590        medium_priority_weight: The number of commands that may be executed from the medium priority queue at one time (optional)
591        high_priority_weight: The number of commands that may be executed from the high priority queue at one time (optional)
592        nvme_adminq_poll_period_us: How often the admin queue is polled for asynchronous events in microseconds (optional)
593        nvme_ioq_poll_period_us: How often to poll I/O queues for completions in microseconds (optional)
594        io_queue_requests: The number of requests allocated for each NVMe I/O queue. Default: 512 (optional)
595        delay_cmd_submit: Enable delayed NVMe command submission to allow batching of multiple commands (optional)
596        transport_retry_count: The number of attempts per I/O in the transport layer when an I/O fails (optional)
597        bdev_retry_count: The number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries. (optional)
598        transport_ack_timeout: Time to wait ack until packet retransmission for RDMA or until closes connection for TCP.
599        Range 0-31 where 0 is driver-specific default value (optional)
600        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
601        -1 means infinite reconnect retries. 0 means no reconnect retry.
602        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
603        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
604        This can be overridden by bdev_nvme_attach_controller. (optional)
605        reconnect_delay_sec: Time to delay a reconnect retry.
606        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
607        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
608        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
609        This can be overridden by bdev_nvme_attach_controller. (optional)
610        fast_io_fail_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
611        0 means no such timeout.
612        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
613        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.
614        This can be overridden by bdev_nvme_attach_controller. (optional)
615        disable_auto_failback: Disable automatic failback. bdev_nvme_set_preferred_path can be used to do manual failback.
616        By default, immediately failback to the preferred I/O path if it is restored. (optional)
617        generate_uuids: Enable generation of unique identifiers for NVMe bdevs only if they do not provide UUID themselves.
618        These strings are based on device serial number and namespace ID and will always be the same for that device.
619        transport_tos: IPv4 Type of Service value. Only applicable for RDMA transports.
620        The default is 0 which means no TOS is applied. (optional)
621        nvme_error_stat: Enable collecting NVMe error counts. (optional)
622        rdma_srq_size: Set the size of a shared rdma receive queue. Default: 0 (disabled) (optional)
623        io_path_stat: Enable collection I/O path stat of each io path. (optional)
624        allow_accel_sequence: Allow NVMe bdevs to advertise support for accel sequences if the
625        controller also supports them. (optional)
626        rdma_max_cq_size: The maximum size of a rdma completion queue. Default: 0 (unlimited) (optional)
627        rdma_cm_event_timeout_ms: Time to wait for RDMA CM event. Only applicable for RDMA transports.
628        dhchap_digests: List of allowed DH-HMAC-CHAP digests. (optional)
629        dhchap_dhgroups: List of allowed DH-HMAC-CHAP DH groups. (optional)
630    """
631    params = dict()
632    if action_on_timeout is not None:
633        params['action_on_timeout'] = action_on_timeout
634    if timeout_us is not None:
635        params['timeout_us'] = timeout_us
636    if timeout_admin_us is not None:
637        params['timeout_admin_us'] = timeout_admin_us
638    if keep_alive_timeout_ms is not None:
639        params['keep_alive_timeout_ms'] = keep_alive_timeout_ms
640    if arbitration_burst is not None:
641        params['arbitration_burst'] = arbitration_burst
642    if low_priority_weight is not None:
643        params['low_priority_weight'] = low_priority_weight
644    if medium_priority_weight is not None:
645        params['medium_priority_weight'] = medium_priority_weight
646    if high_priority_weight is not None:
647        params['high_priority_weight'] = high_priority_weight
648    if nvme_adminq_poll_period_us is not None:
649        params['nvme_adminq_poll_period_us'] = nvme_adminq_poll_period_us
650    if nvme_ioq_poll_period_us is not None:
651        params['nvme_ioq_poll_period_us'] = nvme_ioq_poll_period_us
652    if io_queue_requests is not None:
653        params['io_queue_requests'] = io_queue_requests
654    if delay_cmd_submit is not None:
655        params['delay_cmd_submit'] = delay_cmd_submit
656    if transport_retry_count is not None:
657        params['transport_retry_count'] = transport_retry_count
658    if bdev_retry_count is not None:
659        params['bdev_retry_count'] = bdev_retry_count
660    if transport_ack_timeout is not None:
661        params['transport_ack_timeout'] = transport_ack_timeout
662    if ctrlr_loss_timeout_sec is not None:
663        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
664    if reconnect_delay_sec is not None:
665        params['reconnect_delay_sec'] = reconnect_delay_sec
666    if fast_io_fail_timeout_sec is not None:
667        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
668    if disable_auto_failback is not None:
669        params['disable_auto_failback'] = disable_auto_failback
670    if generate_uuids is not None:
671        params['generate_uuids'] = generate_uuids
672    if transport_tos is not None:
673        params['transport_tos'] = transport_tos
674    if nvme_error_stat is not None:
675        params['nvme_error_stat'] = nvme_error_stat
676    if rdma_srq_size is not None:
677        params['rdma_srq_size'] = rdma_srq_size
678    if io_path_stat is not None:
679        params['io_path_stat'] = io_path_stat
680    if allow_accel_sequence is not None:
681        params['allow_accel_sequence'] = allow_accel_sequence
682    if rdma_max_cq_size is not None:
683        params['rdma_max_cq_size'] = rdma_max_cq_size
684    if rdma_cm_event_timeout_ms is not None:
685        params['rdma_cm_event_timeout_ms'] = rdma_cm_event_timeout_ms
686    if dhchap_digests is not None:
687        params['dhchap_digests'] = dhchap_digests
688    if dhchap_dhgroups is not None:
689        params['dhchap_dhgroups'] = dhchap_dhgroups
690    return client.call('bdev_nvme_set_options', params)
691
692
693def bdev_nvme_set_hotplug(client, enable, period_us=None):
694    """Set options for the bdev nvme. This is startup command.
695    Args:
696       enable: True to enable hotplug, False to disable.
697       period_us: how often the hotplug is processed for insert and remove events. Set 0 to reset to default. (optional)
698    """
699    params = dict()
700    params['enable'] = enable
701    if period_us is not None:
702        params['period_us'] = period_us
703    return client.call('bdev_nvme_set_hotplug', params)
704
705
706def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvcid=None,
707                                priority=None, subnqn=None, hostnqn=None, hostaddr=None,
708                                hostsvcid=None, prchk_reftag=None, prchk_guard=None,
709                                hdgst=None, ddgst=None, fabrics_connect_timeout_us=None,
710                                multipath=None, num_io_queues=None, ctrlr_loss_timeout_sec=None,
711                                reconnect_delay_sec=None, fast_io_fail_timeout_sec=None,
712                                psk=None, max_bdevs=None, dhchap_key=None, dhchap_ctrlr_key=None,
713                                allow_unrecognized_csi=None):
714    """Construct block device for each NVMe namespace in the attached controller.
715    Args:
716        name: bdev name prefix; "n" + namespace ID will be appended to create unique names
717        trtype: transport type ("PCIe", "RDMA", "FC", "TCP")
718        traddr: transport address (PCI BDF or IP address)
719        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
720        trsvcid: transport service ID (port number for IP-based addresses)
721        priority: transport connection priority (Sock priority for TCP-based transports; optional)
722        subnqn: subsystem NQN to connect to (optional)
723        hostnqn: NQN to connect from (optional)
724        hostaddr: host transport address (IP address for IP-based transports, NULL for PCIe or FC; optional)
725        hostsvcid: host transport service ID (port number for IP-based transports, NULL for PCIe or FC; optional)
726        prchk_reftag: Enable checking of PI reference tag for I/O processing (optional)
727        prchk_guard: Enable checking of PI guard for I/O processing (optional)
728        hdgst: Enable TCP header digest (optional)
729        ddgst: Enable TCP data digest (optional)
730        fabrics_connect_timeout_us: Fabrics connect timeout in us (optional)
731        multipath: The behavior when multiple paths are created ("disable", "failover", or "multipath"; failover if not specified)
732        num_io_queues: The number of IO queues to request during initialization. (optional)
733        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
734        -1 means infinite reconnect retries. 0 means no reconnect retry.
735        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
736        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
737        (optional)
738        reconnect_delay_sec: Time to delay a reconnect retry.
739        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
740        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
741        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
742        (optional)
743        fast_io_fail_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
744        0 means no such timeout.
745        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
746        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. (optional)
747        psk: Set PSK file path and enable TCP SSL socket implementation (optional)
748        max_bdevs: Size of the name array for newly created bdevs. Default is 128. (optional)
749        dhchap_key: DH-HMAC-CHAP key name.
750        dhchap_ctrlr_key: DH-HMAC-CHAP controller key name.
751        allow_unrecognized_csi: Allow attaching namespaces with unrecognized command set identifiers. These will only support NVMe
752        passthrough.
753    Returns:
754        Names of created block devices.
755    """
756    params = dict()
757    params['name'] = name
758    params['trtype'] = trtype
759    params['traddr'] = traddr
760    if adrfam is not None:
761        params['adrfam'] = adrfam
762    if trsvcid is not None:
763        params['trsvcid'] = trsvcid
764    if priority is not None:
765        params['priority'] = priority
766    if subnqn is not None:
767        params['subnqn'] = subnqn
768    if hostnqn is not None:
769        params['hostnqn'] = hostnqn
770    if hostaddr is not None:
771        params['hostaddr'] = hostaddr
772    if hostsvcid is not None:
773        params['hostsvcid'] = hostsvcid
774    if prchk_reftag is not None:
775        params['prchk_reftag'] = prchk_reftag
776    if prchk_guard is not None:
777        params['prchk_guard'] = prchk_guard
778    if hdgst is not None:
779        params['hdgst'] = hdgst
780    if ddgst is not None:
781        params['ddgst'] = ddgst
782    if fabrics_connect_timeout_us is not None:
783        params['fabrics_connect_timeout_us'] = fabrics_connect_timeout_us
784    if multipath is not None:
785        params['multipath'] = multipath
786    if num_io_queues is not None:
787        params['num_io_queues'] = num_io_queues
788    if ctrlr_loss_timeout_sec is not None:
789        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
790    if reconnect_delay_sec is not None:
791        params['reconnect_delay_sec'] = reconnect_delay_sec
792    if fast_io_fail_timeout_sec is not None:
793        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
794    if psk is not None:
795        params['psk'] = psk
796    if max_bdevs is not None:
797        params['max_bdevs'] = max_bdevs
798    if dhchap_key is not None:
799        params['dhchap_key'] = dhchap_key
800    if dhchap_ctrlr_key is not None:
801        params['dhchap_ctrlr_key'] = dhchap_ctrlr_key
802    if allow_unrecognized_csi is not None:
803        params['allow_unrecognized_csi'] = allow_unrecognized_csi
804    return client.call('bdev_nvme_attach_controller', params)
805
806
807def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
808                                adrfam=None, trsvcid=None, subnqn=None,
809                                hostaddr=None, hostsvcid=None):
810    """Detach NVMe controller and delete any associated bdevs. Optionally,
811       If all of the transport ID options are specified, only remove that
812       transport path from the specified controller. If that is the only
813       available path for the controller, this will also result in the
814       controller being detached and the associated bdevs being deleted.
815    Args:
816        name: controller name
817        trtype: transport type ("PCIe", "RDMA")
818        traddr: transport address (PCI BDF or IP address)
819        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
820        trsvcid: transport service ID (port number for IP-based addresses)
821        subnqn: subsystem NQN to connect to (optional)
822        hostaddr: Host address (IP address)
823        hostsvcid: transport service ID on host side (port number)
824    """
825    params = dict()
826    params['name'] = name
827    if trtype is not None:
828        params['trtype'] = trtype
829    if traddr is not None:
830        params['traddr'] = traddr
831    if adrfam is not None:
832        params['adrfam'] = adrfam
833    if trsvcid is not None:
834        params['trsvcid'] = trsvcid
835    if subnqn is not None:
836        params['subnqn'] = subnqn
837    if hostaddr is not None:
838        params['hostaddr'] = hostaddr
839    if hostsvcid is not None:
840        params['hostsvcid'] = hostsvcid
841    return client.call('bdev_nvme_detach_controller', params)
842
843
844def bdev_nvme_reset_controller(client, name, cntlid=None):
845    """Reset an NVMe controller or all NVMe controllers in an NVMe bdev controller.
846    Args:
847        name: controller name
848        cntlid: NVMe controller ID (optional)
849    """
850    params = dict()
851    params['name'] = name
852    if cntlid is not None:
853        params['cntlid'] = cntlid
854    return client.call('bdev_nvme_reset_controller', params)
855
856
857def bdev_nvme_enable_controller(client, name, cntlid=None):
858    """Enable an NVMe controller or all NVMe controllers in an NVMe bdev controller.
859    Args:
860        name: controller name
861        cntlid: NVMe controller ID (optional)
862    """
863    params = dict()
864    params['name'] = name
865    if cntlid is not None:
866        params['cntlid'] = cntlid
867    return client.call('bdev_nvme_enable_controller', params)
868
869
870def bdev_nvme_disable_controller(client, name, cntlid=None):
871    """Disable an NVMe controller or all NVMe controllers in an NVMe bdev controller.
872    Args:
873        name: controller name
874        cntlid: NVMe controller ID (optional)
875    """
876    params = dict()
877    params['name'] = name
878    if cntlid is not None:
879        params['cntlid'] = cntlid
880    return client.call('bdev_nvme_disable_controller', params)
881
882
883def bdev_nvme_start_discovery(client, name, trtype, traddr, adrfam=None, trsvcid=None,
884                              hostnqn=None, wait_for_attach=None, ctrlr_loss_timeout_sec=None,
885                              reconnect_delay_sec=None, fast_io_fail_timeout_sec=None,
886                              attach_timeout_ms=None):
887    """Start discovery with the specified discovery subsystem
888    Args:
889        name: bdev name prefix; "n" + namespace ID will be appended to create unique names
890        trtype: transport type ("PCIe", "RDMA", "FC", "TCP")
891        traddr: transport address (PCI BDF or IP address)
892        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
893        trsvcid: transport service ID (port number for IP-based addresses)
894        hostnqn: NQN to connect from (optional)
895        wait_for_attach: Wait to complete RPC until all discovered NVM subsystems have attached (optional)
896        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
897        -1 means infinite reconnect retries. 0 means no reconnect retry.
898        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
899        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
900        (optional)
901        reconnect_delay_sec: Time to delay a reconnect retry.
902        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
903        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
904        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
905        (optional)
906        fast_io_fail_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
907        0 means no such timeout.
908        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
909        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. (optional)
910        attach_timeout_ms: Time to wait until the discovery and all discovered NVM subsystems are attached (optional)
911    """
912    params = dict()
913    params['name'] = name
914    params['trtype'] = trtype
915    params['traddr'] = traddr
916    if adrfam is not None:
917        params['adrfam'] = adrfam
918    if trsvcid is not None:
919        params['trsvcid'] = trsvcid
920    if hostnqn is not None:
921        params['hostnqn'] = hostnqn
922    if wait_for_attach is not None:
923        params['wait_for_attach'] = wait_for_attach
924    if ctrlr_loss_timeout_sec is not None:
925        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
926    if reconnect_delay_sec is not None:
927        params['reconnect_delay_sec'] = reconnect_delay_sec
928    if fast_io_fail_timeout_sec is not None:
929        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
930    if attach_timeout_ms is not None:
931        params['attach_timeout_ms'] = attach_timeout_ms
932    return client.call('bdev_nvme_start_discovery', params)
933
934
935def bdev_nvme_stop_discovery(client, name):
936    """Stop a previously started discovery service
937    Args:
938        name: name of discovery service to start
939    """
940    params = dict()
941    params['name'] = name
942    return client.call('bdev_nvme_stop_discovery', params)
943
944
945def bdev_nvme_get_discovery_info(client):
946    """Get information about the automatic discovery
947    """
948    return client.call('bdev_nvme_get_discovery_info')
949
950
951def bdev_nvme_get_io_paths(client, name=None):
952    """Display all or the specified NVMe bdev's active I/O paths
953    Args:
954        name: Name of the NVMe bdev (optional)
955    Returns:
956        List of active I/O paths
957    """
958    params = dict()
959    if name is not None:
960        params['name'] = name
961    return client.call('bdev_nvme_get_io_paths', params)
962
963
964def bdev_nvme_set_preferred_path(client, name, cntlid):
965    """Set the preferred I/O path for an NVMe bdev when in multipath mode
966    Args:
967        name: NVMe bdev name
968        cntlid: NVMe-oF controller ID
969    """
970    params = dict()
971    params['name'] = name
972    params['cntlid'] = cntlid
973    return client.call('bdev_nvme_set_preferred_path', params)
974
975
976def bdev_nvme_set_multipath_policy(client, name, policy, selector=None, rr_min_io=None):
977    """Set multipath policy of the NVMe bdev
978    Args:
979        name: NVMe bdev name
980        policy: Multipath policy (active_passive or active_active)
981        selector: Multipath selector (round_robin, queue_depth)
982        rr_min_io: Number of IO to route to a path before switching to another one (optional)
983    """
984    params = dict()
985    params['name'] = name
986    params['policy'] = policy
987    if selector is not None:
988        params['selector'] = selector
989    if rr_min_io is not None:
990        params['rr_min_io'] = rr_min_io
991    return client.call('bdev_nvme_set_multipath_policy', params)
992
993
994def bdev_nvme_get_path_iostat(client, name):
995    """Get I/O statistics for IO paths of the block device.
996    Args:
997        name: bdev name to query
998    Returns:
999        I/O statistics for IO paths of the requested block device.
1000    """
1001    params = dict()
1002    params['name'] = name
1003    return client.call('bdev_nvme_get_path_iostat', params)
1004
1005
1006def bdev_nvme_cuse_register(client, name):
1007    """Register CUSE devices on NVMe controller.
1008    Args:
1009        name: Name of the operating NVMe controller
1010    """
1011    params = dict()
1012    params['name'] = name
1013    return client.call('bdev_nvme_cuse_register', params)
1014
1015
1016def bdev_nvme_cuse_unregister(client, name):
1017    """Unregister CUSE devices on NVMe controller.
1018    Args:
1019        name: Name of the operating NVMe controller
1020    """
1021    params = dict()
1022    params['name'] = name
1023    return client.call('bdev_nvme_cuse_unregister', params)
1024
1025
1026def bdev_nvme_set_keys(client, name, dhchap_key=None, dhchap_ctrlr_key=None):
1027    """Set DH-HMAC-CHAP keys and force (re)authentication on all connected qpairs.
1028    Args:
1029        name: name of the NVMe controller
1030        dhchap_key: DH-HMAC-CHAP key name
1031        dhchap_ctrlr_key: DH-HMAC-CHAP controller key name
1032    """
1033    params = {'name': name}
1034    if dhchap_key is not None:
1035        params['dhchap_key'] = dhchap_key
1036    if dhchap_ctrlr_key is not None:
1037        params['dhchap_ctrlr_key'] = dhchap_ctrlr_key
1038    return client.call('bdev_nvme_set_keys', params)
1039
1040
1041def bdev_zone_block_create(client, name, base_bdev, zone_capacity, optimal_open_zones):
1042    """Creates a virtual zone device on top of existing non-zoned bdev.
1043    Args:
1044        name: Zone device name
1045        base_bdev: Base Nvme bdev name
1046        zone_capacity: Surfaced zone capacity in blocks
1047        optimal_open_zones: Number of zones required to reach optimal write speed (optional, default: 1)
1048    Returns:
1049        Name of created block device.
1050    """
1051    params = dict()
1052    params['name'] = name
1053    params['base_bdev'] = base_bdev
1054    params['zone_capacity'] = zone_capacity
1055    params['optimal_open_zones'] = optimal_open_zones
1056    return client.call('bdev_zone_block_create', params)
1057
1058
1059def bdev_zone_block_delete(client, name):
1060    """Remove block zone bdev from the system.
1061    Args:
1062        name: name of block zone bdev to delete
1063    """
1064    params = dict()
1065    params['name'] = name
1066    return client.call('bdev_zone_block_delete', params)
1067
1068
1069def bdev_rbd_register_cluster(client, name=None, user_id=None, config_param=None, config_file=None, key_file=None, core_mask=None):
1070    """Create a Rados Cluster object of the Ceph RBD backend.
1071    Args:
1072        name: name of Rados Cluster
1073        user_id: Ceph user name (optional)
1074        config_param: map of config keys to values (optional)
1075        config_file: file path of Ceph configuration file (optional)
1076        key_file: file path of Ceph key file (optional)
1077        core_mask: core mask for librbd IO context threads (optional)
1078    Returns:
1079        Name of registered Rados Cluster object.
1080    """
1081    params = dict()
1082    if name is not None:
1083        params['name'] = name
1084    if user_id is not None:
1085        params['user_id'] = user_id
1086    if config_param is not None:
1087        params['config_param'] = config_param
1088    if config_file is not None:
1089        params['config_file'] = config_file
1090    if key_file is not None:
1091        params['key_file'] = key_file
1092    if core_mask is not None:
1093        params['core_mask'] = core_mask
1094    return client.call('bdev_rbd_register_cluster', params)
1095
1096
1097def bdev_rbd_unregister_cluster(client, name):
1098    """Remove Rados cluster object from the system.
1099    Args:
1100        name: name of Rados cluster object to unregister
1101    """
1102    params = dict()
1103    params['name'] = name
1104    return client.call('bdev_rbd_unregister_cluster', params)
1105
1106
1107def bdev_rbd_get_clusters_info(client, name=None):
1108    """Get the cluster(s) info
1109    Args:
1110        name: name of Rados cluster object to query (optional; if omitted, query all clusters)
1111    Returns:
1112        List of registered Rados cluster information objects.
1113    """
1114    params = dict()
1115    if name is not None:
1116        params['name'] = name
1117    return client.call('bdev_rbd_get_clusters_info', params)
1118
1119
1120def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user_id=None, config=None, cluster_name=None, uuid=None):
1121    """Create a Ceph RBD block device.
1122    Args:
1123        pool_name: Ceph RBD pool name
1124        rbd_name: Ceph RBD image name
1125        block_size: block size of RBD volume
1126        name: name of block device (optional)
1127        user_id: Ceph user name (optional)
1128        config: map of config keys to values (optional)
1129        cluster_name: Name to identify Rados cluster (optional)
1130        uuid: UUID of block device (optional)
1131    Returns:
1132        Name of created block device.
1133    """
1134    params = dict()
1135    params['pool_name'] = pool_name
1136    params['rbd_name'] = rbd_name
1137    params['block_size'] = block_size
1138    if name is not None:
1139        params['name'] = name
1140    if user_id is not None:
1141        params['user_id'] = user_id
1142    if config is not None:
1143        params['config'] = config
1144    if cluster_name is not None:
1145        params['cluster_name'] = cluster_name
1146    else:
1147        print("WARNING:bdev_rbd_create should be used with specifying -c to have a cluster name after bdev_rbd_register_cluster.")
1148    if uuid is not None:
1149        params['uuid'] = uuid
1150    return client.call('bdev_rbd_create', params)
1151
1152
1153def bdev_rbd_delete(client, name):
1154    """Remove rbd bdev from the system.
1155    Args:
1156        name: name of rbd bdev to delete
1157    """
1158    params = dict()
1159    params['name'] = name
1160    return client.call('bdev_rbd_delete', params)
1161
1162
1163def bdev_rbd_resize(client, name, new_size):
1164    """Resize rbd bdev in the system.
1165    Args:
1166        name: name of rbd bdev to resize
1167        new_size: new bdev size of resize operation. The unit is MiB
1168    """
1169    params = dict()
1170    params['name'] = name
1171    params['new_size'] = new_size
1172    return client.call('bdev_rbd_resize', params)
1173
1174
1175def bdev_error_create(client, base_name, uuid=None):
1176    """Construct an error injection block device.
1177    Args:
1178        base_name: base bdev name
1179        uuid: UUID for this bdev (optional)
1180    """
1181    params = dict()
1182    params['base_name'] = base_name
1183    if uuid is not None:
1184        params['uuid'] = uuid
1185    return client.call('bdev_error_create', params)
1186
1187
1188def bdev_delay_create(client, base_bdev_name, name, avg_read_latency, p99_read_latency, avg_write_latency, p99_write_latency, uuid=None):
1189    """Construct a delay block device.
1190    Args:
1191        base_bdev_name: name of the existing bdev
1192        name: name of block device
1193        avg_read_latency: complete 99% of read ops with this delay
1194        p99_read_latency: complete 1% of read ops with this delay
1195        avg_write_latency: complete 99% of write ops with this delay
1196        p99_write_latency: complete 1% of write ops with this delay
1197        uuid: UUID of block device (optional)
1198    Returns:
1199        Name of created block device.
1200    """
1201    params = dict()
1202    params['base_bdev_name'] = base_bdev_name
1203    params['name'] = name
1204    params['avg_read_latency'] = avg_read_latency
1205    params['p99_read_latency'] = p99_read_latency
1206    params['avg_write_latency'] = avg_write_latency
1207    params['p99_write_latency'] = p99_write_latency
1208    if uuid is not None:
1209        params['uuid'] = uuid
1210    return client.call('bdev_delay_create', params)
1211
1212
1213def bdev_delay_delete(client, name):
1214    """Remove delay bdev from the system.
1215    Args:
1216        name: name of delay bdev to delete
1217    """
1218    params = dict()
1219    params['name'] = name
1220    return client.call('bdev_delay_delete', params)
1221
1222
1223def bdev_delay_update_latency(client, delay_bdev_name, latency_type, latency_us):
1224    """Update the latency value for a delay block device
1225    Args:
1226        delay_bdev_name: name of the delay bdev
1227        latency_type: 'one of: avg_read, avg_write, p99_read, p99_write. No other values accepted.'
1228        latency_us: 'new latency value.'
1229    Returns:
1230        True if successful, or a specific error otherwise.
1231    """
1232    params = dict()
1233    params['delay_bdev_name'] = delay_bdev_name
1234    params['latency_type'] = latency_type
1235    params['latency_us'] = latency_us
1236    return client.call('bdev_delay_update_latency', params)
1237
1238
1239def bdev_error_delete(client, name):
1240    """Remove error bdev from the system.
1241    Args:
1242        bdev_name: name of error bdev to delete
1243    """
1244    params = dict()
1245    params['name'] = name
1246    return client.call('bdev_error_delete', params)
1247
1248
1249def bdev_iscsi_set_options(client, timeout_sec=None):
1250    """Set options for the bdev iscsi.
1251    Args:
1252        timeout_sec: Timeout for command, in seconds, if 0, don't track timeout
1253    """
1254    params = dict()
1255    if timeout_sec is not None:
1256        params['timeout_sec'] = timeout_sec
1257    return client.call('bdev_iscsi_set_options', params)
1258
1259
1260def bdev_iscsi_create(client, name, url, initiator_iqn):
1261    """Construct an iSCSI block device.
1262    Args:
1263        name: name of block device
1264        url: iSCSI URL
1265        initiator_iqn: IQN name to be used by initiator
1266    Returns:
1267        Name of created block device.
1268    """
1269    params = dict()
1270    params['name'] = name
1271    params['url'] = url
1272    params['initiator_iqn'] = initiator_iqn
1273    return client.call('bdev_iscsi_create', params)
1274
1275
1276def bdev_iscsi_delete(client, name):
1277    """Remove iSCSI bdev from the system.
1278    Args:
1279        bdev_name: name of iSCSI bdev to delete
1280    """
1281    params = dict()
1282    params['name'] = name
1283    return client.call('bdev_iscsi_delete', params)
1284
1285
1286def bdev_passthru_create(client, base_bdev_name, name, uuid=None):
1287    """Construct a pass-through block device.
1288    Args:
1289        base_bdev_name: name of the existing bdev
1290        name: name of block device
1291        uuid: UUID of block device (optional)
1292    Returns:
1293        Name of created block device.
1294    """
1295    params = dict()
1296    params['base_bdev_name'] = base_bdev_name
1297    params['name'] = name
1298    if uuid is not None:
1299        params['uuid'] = uuid
1300    return client.call('bdev_passthru_create', params)
1301
1302
1303def bdev_passthru_delete(client, name):
1304    """Remove pass through bdev from the system.
1305    Args:
1306        name: name of pass through bdev to delete
1307    """
1308    params = dict()
1309    params['name'] = name
1310    return client.call('bdev_passthru_delete', params)
1311
1312
1313def bdev_opal_create(client, nvme_ctrlr_name, nsid, locking_range_id, range_start, range_length, password):
1314    """Create opal virtual block devices from a base nvme bdev.
1315    Args:
1316        nvme_ctrlr_name: name of the nvme ctrlr
1317        nsid: namespace ID of nvme ctrlr
1318        locking_range_id: locking range ID corresponding to this virtual bdev
1319        range_start: start address of this locking range
1320        range_length: length of this locking range
1321        password: admin password of base nvme bdev
1322    Returns:
1323        Name of the new created block devices.
1324    """
1325    params = dict()
1326    params['nvme_ctrlr_name'] = nvme_ctrlr_name
1327    params['nsid'] = nsid
1328    params['locking_range_id'] = locking_range_id
1329    params['range_start'] = range_start
1330    params['range_length'] = range_length
1331    params['password'] = password
1332    return client.call('bdev_opal_create', params)
1333
1334
1335def bdev_opal_get_info(client, bdev_name, password):
1336    """Get opal locking range info.
1337    Args:
1338        bdev_name: name of opal vbdev to get info
1339        password: admin password
1340    Returns:
1341        Locking range info.
1342    """
1343    params = dict()
1344    params['bdev_name'] = bdev_name
1345    params['password'] = password
1346    return client.call('bdev_opal_get_info', params)
1347
1348
1349def bdev_opal_delete(client, bdev_name, password):
1350    """Delete opal virtual bdev from the system.
1351    Args:
1352        bdev_name: name of opal vbdev to delete
1353        password: admin password of base nvme bdev
1354    """
1355    params = dict()
1356    params['bdev_name'] = bdev_name
1357    params['password'] = password
1358    return client.call('bdev_opal_delete', params)
1359
1360
1361def bdev_opal_new_user(client, bdev_name, admin_password, user_id, user_password):
1362    """Add a user to opal bdev who can set lock state for this bdev.
1363    Args:
1364        bdev_name: name of opal vbdev
1365        admin_password: admin password
1366        user_id: ID of the user who will be added to this opal bdev
1367        user_password: password set for this user
1368    """
1369    params = dict()
1370    params['bdev_name'] = bdev_name
1371    params['admin_password'] = admin_password
1372    params['user_id'] = user_id
1373    params['user_password'] = user_password
1374    return client.call('bdev_opal_new_user', params)
1375
1376
1377def bdev_opal_set_lock_state(client, bdev_name, user_id, password, lock_state):
1378    """set lock state for an opal bdev.
1379    Args:
1380        bdev_name: name of opal vbdev
1381        user_id: ID of the user who will set lock state
1382        password: password of the user
1383        lock_state: lock state to set
1384    """
1385    params = dict()
1386    params['bdev_name'] = bdev_name
1387    params['user_id'] = user_id
1388    params['password'] = password
1389    params['lock_state'] = lock_state
1390    return client.call('bdev_opal_set_lock_state', params)
1391
1392
1393def bdev_split_create(client, base_bdev, split_count, split_size_mb=None):
1394    """Create split block devices from a base bdev.
1395    Args:
1396        base_bdev: name of bdev to split
1397        split_count: number of split bdevs to create
1398        split_size_mb: size of each split volume in MiB (optional)
1399    Returns:
1400        List of created block devices.
1401    """
1402    params = dict()
1403    params['base_bdev'] = base_bdev
1404    params['split_count'] = split_count
1405    if split_size_mb is not None:
1406        params['split_size_mb'] = split_size_mb
1407    return client.call('bdev_split_create', params)
1408
1409
1410def bdev_split_delete(client, base_bdev):
1411    """Delete split block devices.
1412    Args:
1413        base_bdev: name of previously split bdev
1414    """
1415    params = dict()
1416    params['base_bdev'] = base_bdev
1417    return client.call('bdev_split_delete', params)
1418
1419
1420def bdev_ftl_create(client, name, base_bdev, cache, **kwargs):
1421    """Construct FTL bdev
1422    Args:
1423        name: name of the bdev
1424        base_bdev: name of the base bdev
1425        cache: name of the cache device
1426        kwargs: optional parameters
1427    """
1428    params = dict()
1429    params['name'] = name
1430    params['base_bdev'] = base_bdev
1431    params['cache'] = cache
1432    for key, value in kwargs.items():
1433        if value is not None:
1434            params[key] = value
1435    return client.call('bdev_ftl_create', params)
1436
1437
1438def bdev_ftl_load(client, name, base_bdev, cache, **kwargs):
1439    """Load FTL bdev
1440    Args:
1441        name: name of the bdev
1442        base_bdev: name of the base bdev
1443        cache: Name of the cache device
1444        kwargs: optional parameters
1445    """
1446    params = dict()
1447    params['name'] = name
1448    params['base_bdev'] = base_bdev
1449    params['cache'] = cache
1450    for key, value in kwargs.items():
1451        if value is not None:
1452            params[key] = value
1453    return client.call('bdev_ftl_load', params)
1454
1455
1456def bdev_ftl_unload(client, name, fast_shutdown=None):
1457    """Unload FTL bdev
1458    Args:
1459        name: name of the bdev
1460        fast_shutdown: When set FTL will minimize persisted data during deletion and rely on shared memory during next load
1461    """
1462    params = dict()
1463    params['name'] = name
1464    if fast_shutdown is not None:
1465        params['fast_shutdown'] = fast_shutdown
1466    return client.call('bdev_ftl_unload', params)
1467
1468
1469def bdev_ftl_delete(client, name, fast_shutdown=None):
1470    """Delete FTL bdev
1471    Args:
1472        name: name of the bdev
1473        fast_shutdown: When set FTL will minimize persisted data during deletion and rely on shared memory during next load
1474    """
1475    params = dict()
1476    params['name'] = name
1477    if fast_shutdown is not None:
1478        params['fast_shutdown'] = fast_shutdown
1479    return client.call('bdev_ftl_delete', params)
1480
1481
1482def bdev_ftl_unmap(client, name, lba, num_blocks):
1483    """FTL unmap
1484    Args:
1485        name: name of the bdev
1486        lba: starting lba to be unmapped
1487        num_blocks: number of blocks to unmap
1488    """
1489    params = dict()
1490    params['name'] = name
1491    params['lba'] = lba
1492    params['num_blocks'] = num_blocks
1493    return client.call('bdev_ftl_unmap', params)
1494
1495
1496def bdev_ftl_get_stats(client, name):
1497    """get FTL stats
1498    Args:
1499        name: name of the bdev
1500    """
1501    params = dict()
1502    params['name'] = name
1503    return client.call('bdev_ftl_get_stats', params)
1504
1505
1506def bdev_ftl_get_properties(client, name):
1507    """Get FTL properties
1508    Args:
1509        name: name of the bdev
1510    """
1511    params = dict()
1512    params['name'] = name
1513    return client.call('bdev_ftl_get_properties', params)
1514
1515
1516def bdev_ftl_set_property(client, name, ftl_property, value):
1517    """Set FTL property
1518    Args:
1519        name: name of the bdev
1520        ftl_property: name of the property to be set
1521        value: The new value of the updated property
1522    """
1523    params = dict()
1524    params['name'] = name
1525    params['ftl_property'] = ftl_property
1526    params['value'] = value
1527    return client.call('bdev_ftl_set_property', params)
1528
1529
1530def bdev_get_bdevs(client, name=None, timeout=None):
1531    """Get information about block devices.
1532    Args:
1533        name: bdev name to query (optional; if omitted, query all bdevs)
1534        timeout: time in ms to wait for the bdev with specified name to appear
1535    Returns:
1536        List of bdev information objects.
1537    """
1538    params = dict()
1539    if name is not None:
1540        params['name'] = name
1541    if timeout is not None:
1542        params['timeout'] = timeout
1543    return client.call('bdev_get_bdevs', params)
1544
1545
1546def bdev_get_iostat(client, name=None, per_channel=None, reset_mode=None):
1547    """Get I/O statistics for block devices.
1548    Args:
1549        name: bdev name to query (optional; if omitted, query all bdevs)
1550        per_channel: display per channel IO stats for specified bdev
1551        reset_mode: mode to reset stats after getting: all, maxmin, none (optional: if omitted, no reset will happen)
1552    Returns:
1553        I/O statistics for the requested block devices.
1554    """
1555    params = dict()
1556    if name is not None:
1557        params['name'] = name
1558    if per_channel is not None:
1559        params['per_channel'] = per_channel
1560    if reset_mode is not None:
1561        params['reset_mode'] = reset_mode
1562    return client.call('bdev_get_iostat', params)
1563
1564
1565def bdev_reset_iostat(client, name=None, mode=None):
1566    """Reset I/O statistics for block devices.
1567    Args:
1568        name: bdev name to reset (optional; if omitted, reset all bdevs)
1569        mode: mode to reset: all, maxmin (optional: if omitted, reset all fields)
1570    """
1571    params = dict()
1572    if name is not None:
1573        params['name'] = name
1574    if mode is not None:
1575        params['mode'] = mode
1576    return client.call('bdev_reset_iostat', params)
1577
1578
1579def bdev_enable_histogram(client, name, enable, opc):
1580    """Control whether histogram is enabled for specified bdev.
1581    Args:
1582        name: name of bdev
1583        enable: Enable or disable histogram on specified device
1584        opc: name of io_type (optional)
1585    """
1586    params = dict()
1587    params['name'] = name
1588    params['enable'] = enable
1589    if opc:
1590        params['opc'] = opc
1591    return client.call('bdev_enable_histogram', params)
1592
1593
1594def bdev_get_histogram(client, name):
1595    """Get histogram for specified bdev.
1596    Args:
1597        name: name of bdev
1598    """
1599    params = dict()
1600    params['name'] = name
1601    return client.call('bdev_get_histogram', params)
1602
1603
1604def bdev_error_inject_error(client, name, io_type, error_type, num=None,
1605                            queue_depth=None, corrupt_offset=None, corrupt_value=None):
1606    """Inject an error via an error bdev.
1607    Args:
1608        name: name of error bdev
1609        io_type: one of "clear", "read", "write", "unmap", "flush", or "all"
1610        error_type: one of "failure", "pending", "corrupt_data" or "nomem"
1611        num: number of commands to fail
1612        queue_depth: the queue depth at which to trigger the error
1613        corrupt_offset: offset in bytes to xor with corrupt_value
1614        corrupt_value: value for xor (1-255, 0 is invalid)
1615    """
1616    params = dict()
1617    params['name'] = name
1618    params['io_type'] = io_type
1619    params['error_type'] = error_type
1620    if num is not None:
1621        params['num'] = num
1622    if queue_depth is not None:
1623        params['queue_depth'] = queue_depth
1624    if corrupt_offset is not None:
1625        params['corrupt_offset'] = corrupt_offset
1626    if corrupt_value is not None:
1627        params['corrupt_value'] = corrupt_value
1628    return client.call('bdev_error_inject_error', params)
1629
1630
1631def bdev_set_qd_sampling_period(client, name, period):
1632    """Enable queue depth tracking on a specified bdev.
1633    Args:
1634        name: name of a bdev on which to track queue depth.
1635        period: period (in microseconds) at which to update the queue depth reading. If set to 0, polling will be disabled.
1636    """
1637    params = dict()
1638    params['name'] = name
1639    params['period'] = period
1640    return client.call('bdev_set_qd_sampling_period', params)
1641
1642
1643def bdev_set_qos_limit(
1644        client,
1645        name,
1646        rw_ios_per_sec=None,
1647        rw_mbytes_per_sec=None,
1648        r_mbytes_per_sec=None,
1649        w_mbytes_per_sec=None):
1650    """Set QoS rate limit on a block device.
1651    Args:
1652        name: name of block device
1653        rw_ios_per_sec: R/W IOs per second limit (>=1000, example: 20000). 0 means unlimited.
1654        rw_mbytes_per_sec: R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.
1655        r_mbytes_per_sec: Read megabytes per second limit (>=10, example: 100). 0 means unlimited.
1656        w_mbytes_per_sec: Write megabytes per second limit (>=10, example: 100). 0 means unlimited.
1657    """
1658    params = dict()
1659    params['name'] = name
1660    if rw_ios_per_sec is not None:
1661        params['rw_ios_per_sec'] = rw_ios_per_sec
1662    if rw_mbytes_per_sec is not None:
1663        params['rw_mbytes_per_sec'] = rw_mbytes_per_sec
1664    if r_mbytes_per_sec is not None:
1665        params['r_mbytes_per_sec'] = r_mbytes_per_sec
1666    if w_mbytes_per_sec is not None:
1667        params['w_mbytes_per_sec'] = w_mbytes_per_sec
1668    return client.call('bdev_set_qos_limit', params)
1669
1670
1671def bdev_nvme_apply_firmware(client, bdev_name, filename):
1672    """Download and commit firmware to NVMe device.
1673    Args:
1674        bdev_name: name of NVMe block device
1675        filename: filename of the firmware to download
1676    """
1677    params = dict()
1678    params['bdev_name'] = bdev_name
1679    params['filename'] = filename
1680    return client.call('bdev_nvme_apply_firmware', params)
1681
1682
1683def bdev_nvme_get_transport_statistics(client):
1684    """Get bdev_nvme poll group transport statistics"""
1685    return client.call('bdev_nvme_get_transport_statistics')
1686
1687
1688def bdev_nvme_get_controller_health_info(client, name):
1689    """Display health log of the required NVMe bdev controller.
1690    Args:
1691        name: name of the required NVMe bdev controller
1692    Returns:
1693        Health log for the requested NVMe bdev controller.
1694    """
1695    params = dict()
1696    params['name'] = name
1697    return client.call('bdev_nvme_get_controller_health_info', params)
1698
1699
1700def bdev_daos_create(client, num_blocks, block_size, pool, cont, name, oclass=None, uuid=None):
1701    """Construct DAOS block device.
1702    Args:
1703        num_blocks: size of block device in blocks
1704        block_size: block size of device; must be a power of 2 and at least 512
1705        pool: UUID of DAOS pool
1706        cont: UUID of DAOS container
1707        name: name of block device (also the name of the backend file on DAOS DFS)
1708        oclass: DAOS object class (optional)
1709        uuid: UUID of block device (optional)
1710    Returns:
1711        Name of created block device.
1712    """
1713    params = dict()
1714    params['num_blocks'] = num_blocks
1715    params['block_size'] = block_size
1716    params['pool'] = pool
1717    params['cont'] = cont
1718    params['name'] = name
1719    if oclass is not None:
1720        params['oclass'] = oclass
1721    if uuid is not None:
1722        params['uuid'] = uuid
1723    return client.call('bdev_daos_create', params)
1724
1725
1726def bdev_daos_delete(client, name):
1727    """Delete DAOS block device.
1728    Args:
1729        bdev_name: name of DAOS bdev to delete
1730    """
1731    params = dict()
1732    params['name'] = name
1733    return client.call('bdev_daos_delete', params)
1734
1735
1736def bdev_daos_resize(client, name, new_size):
1737    """Resize DAOS bdev in the system.
1738    Args:
1739        name: name of DAOS bdev to resize
1740        new_size: new bdev size of resize operation. The unit is MiB
1741    """
1742    params = dict()
1743    params['name'] = name
1744    params['new_size'] = new_size
1745    return client.call('bdev_daos_resize', params)
1746
1747
1748def bdev_nvme_start_mdns_discovery(client, name, svcname, hostnqn=None):
1749    """Start discovery with mDNS
1750    Args:
1751        name: bdev name prefix; "n" + unique seqno + namespace ID will be appended to create unique names
1752        svcname: service to discover ("_nvme-disc._tcp")
1753        hostnqn: NQN to connect from (optional)
1754    """
1755    params = dict()
1756    params['name'] = name
1757    params['svcname'] = svcname
1758    if hostnqn is not None:
1759        params['hostnqn'] = hostnqn
1760    return client.call('bdev_nvme_start_mdns_discovery', params)
1761
1762
1763def bdev_nvme_stop_mdns_discovery(client, name):
1764    """Stop a previously started mdns discovery service
1765    Args:
1766        name: name of the discovery service to stop
1767    """
1768    params = dict()
1769    params['name'] = name
1770    return client.call('bdev_nvme_stop_mdns_discovery', params)
1771
1772
1773def bdev_nvme_get_mdns_discovery_info(client):
1774    """Get information about the automatic mdns discovery
1775    """
1776    return client.call('bdev_nvme_get_mdns_discovery_info')
1777