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