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