xref: /spdk/python/spdk/rpc/bdev.py (revision f6866117acb32c78d5ea7bd76ba330284655af35)
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):
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
400    Returns:
401        None
402    """
403    params = {'name': name, 'raid_level': raid_level, 'base_bdevs': base_bdevs}
404
405    if strip_size:
406        params['strip_size'] = strip_size
407
408    if strip_size_kb:
409        params['strip_size_kb'] = strip_size_kb
410
411    return client.call('bdev_raid_create', params)
412
413
414def bdev_raid_delete(client, name):
415    """Delete raid bdev
416
417    Args:
418        name: raid bdev name
419
420    Returns:
421        None
422    """
423    params = {'name': name}
424    return client.call('bdev_raid_delete', params)
425
426
427def bdev_aio_create(client, filename, name, block_size=None, readonly=False):
428    """Construct a Linux AIO block device.
429
430    Args:
431        filename: path to device or file (ex: /dev/sda)
432        name: name of block device
433        block_size: block size of device (optional; autodetected if omitted)
434        readonly: set aio bdev as read-only
435
436    Returns:
437        Name of created block device.
438    """
439    params = {'name': name,
440              'filename': filename}
441
442    if block_size:
443        params['block_size'] = block_size
444
445    if readonly:
446        params['readonly'] = readonly
447
448    return client.call('bdev_aio_create', params)
449
450
451def bdev_aio_rescan(client, name):
452    """Rescan a Linux AIO block device.
453
454    Args:
455        bdev_name: name of aio bdev to delete
456    """
457    params = {'name': name}
458    return client.call('bdev_aio_rescan', params)
459
460
461def bdev_aio_delete(client, name):
462    """Remove aio bdev from the system.
463
464    Args:
465        bdev_name: name of aio bdev to delete
466    """
467    params = {'name': name}
468    return client.call('bdev_aio_delete', params)
469
470
471def bdev_uring_create(client, filename, name, block_size=None):
472    """Create a bdev with Linux io_uring backend.
473
474    Args:
475        filename: path to device or file (ex: /dev/nvme0n1)
476        name: name of bdev
477        block_size: block size of device (optional; autodetected if omitted)
478
479    Returns:
480        Name of created bdev.
481    """
482    params = {'name': name,
483              'filename': filename}
484
485    if block_size:
486        params['block_size'] = block_size
487
488    return client.call('bdev_uring_create', params)
489
490
491def bdev_uring_delete(client, name):
492    """Delete a uring bdev.
493
494    Args:
495        name: name of uring bdev to delete
496    """
497    params = {'name': name}
498    return client.call('bdev_uring_delete', params)
499
500
501def bdev_xnvme_create(client, filename, name, io_mechanism, conserve_cpu=None):
502    """Create a bdev with xNVMe backend.
503
504    Args:
505        filename: path to device or file (ex: /dev/nvme0n1)
506        name: name of xNVMe bdev to create
507        io_mechanism: I/O mechanism to use (ex: io_uring, io_uring_cmd, etc.)
508        conserve_cpu: Whether or not to conserve CPU when polling (default: False)
509
510    Returns:
511        Name of created bdev.
512    """
513    params = {
514        'name': name,
515        'filename': filename,
516        'io_mechanism': io_mechanism,
517    }
518    if conserve_cpu:
519        params['conserve_cpu'] = conserve_cpu
520
521    return client.call('bdev_xnvme_create', params)
522
523
524def bdev_xnvme_delete(client, name):
525    """Delete a xNVMe bdev.
526
527    Args:
528        name: name of xNVMe bdev to delete
529    """
530    params = {'name': name}
531    return client.call('bdev_xnvme_delete', params)
532
533
534def bdev_nvme_set_options(client, action_on_timeout=None, timeout_us=None, timeout_admin_us=None,
535                          keep_alive_timeout_ms=None, retry_count=None, arbitration_burst=None,
536                          low_priority_weight=None, medium_priority_weight=None, high_priority_weight=None,
537                          nvme_adminq_poll_period_us=None, nvme_ioq_poll_period_us=None, io_queue_requests=None,
538                          delay_cmd_submit=None, transport_retry_count=None, bdev_retry_count=None,
539                          transport_ack_timeout=None, ctrlr_loss_timeout_sec=None, reconnect_delay_sec=None,
540                          fast_io_fail_timeout_sec=None, disable_auto_failback=None, generate_uuids=None,
541                          transport_tos=None, nvme_error_stat=None, rdma_srq_size=None, io_path_stat=None):
542    """Set options for the bdev nvme. This is startup command.
543
544    Args:
545        action_on_timeout:  action to take on command time out. Valid values are: none, reset, abort (optional)
546        timeout_us: Timeout for each command, in microseconds. If 0, don't track timeouts (optional)
547        timeout_admin_us: Timeout for each admin command, in microseconds. If 0, treat same as io timeouts (optional)
548        keep_alive_timeout_ms: Keep alive timeout period in millisecond, default is 10s (optional)
549        retry_count: The number of attempts per I/O when an I/O fails (deprecated) (optional)
550        arbitration_burst: The value is expressed as a power of two (optional)
551        low_priority_weight: The number of commands that may be executed from the low priority queue at one time (optional)
552        medium_priority_weight: The number of commands that may be executed from the medium priority queue at one time (optional)
553        high_priority_weight: The number of commands that may be executed from the high priority queue at one time (optional)
554        nvme_adminq_poll_period_us: How often the admin queue is polled for asynchronous events in microseconds (optional)
555        nvme_ioq_poll_period_us: How often to poll I/O queues for completions in microseconds (optional)
556        io_queue_requests: The number of requests allocated for each NVMe I/O queue. Default: 512 (optional)
557        delay_cmd_submit: Enable delayed NVMe command submission to allow batching of multiple commands (optional)
558        transport_retry_count: The number of attempts per I/O in the transport layer when an I/O fails (optional)
559        bdev_retry_count: The number of attempts per I/O in the bdev layer when an I/O fails. -1 means infinite retries. (optional)
560        transport_ack_timeout: Time to wait ack until packet retransmission for RDMA or until closes connection for TCP.
561        Range 0-31 where 0 is driver-specific default value (optional)
562        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
563        -1 means infinite reconnect retries. 0 means no reconnect retry.
564        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
565        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
566        This can be overridden by bdev_nvme_attach_controller. (optional)
567        reconnect_delay_sec: Time to delay a reconnect retry.
568        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
569        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
570        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
571        This can be overridden by bdev_nvme_attach_controller. (optional)
572        fail_io_fast_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
573        0 means no such timeout.
574        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
575        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1.
576        This can be overridden by bdev_nvme_attach_controller. (optional)
577        disable_auto_failback: Disable automatic failback. bdev_nvme_set_preferred_path can be used to do manual failback.
578        By default, immediately failback to the preferred I/O path if it is restored. (optional)
579        generate_uuids: Enable generation of unique identifiers for NVMe bdevs only if they do not provide UUID themselves.
580        These strings are based on device serial number and namespace ID and will always be the same for that device.
581        transport_tos: IPv4 Type of Service value. Only applicable for RDMA transports.
582        The default is 0 which means no TOS is applied. (optional)
583        nvme_error_stat: Enable collecting NVMe error counts. (optional)
584        rdma_srq_size: Set the size of a shared rdma receive queue. Default: 0 (disabled) (optional)
585        io_path_stat: Enable collection I/O path stat of each io path. (optional)
586
587    """
588    params = {}
589
590    if action_on_timeout:
591        params['action_on_timeout'] = action_on_timeout
592
593    if timeout_us is not None:
594        params['timeout_us'] = timeout_us
595
596    if timeout_admin_us is not None:
597        params['timeout_admin_us'] = timeout_admin_us
598
599    if keep_alive_timeout_ms is not None:
600        params['keep_alive_timeout_ms'] = keep_alive_timeout_ms
601
602    if retry_count is not None:
603        print("WARNING: retry_count is deprecated, please use transport_retry_count.")
604        params['retry_count'] = retry_count
605
606    if arbitration_burst is not None:
607        params['arbitration_burst'] = arbitration_burst
608
609    if low_priority_weight is not None:
610        params['low_priority_weight'] = low_priority_weight
611
612    if medium_priority_weight is not None:
613        params['medium_priority_weight'] = medium_priority_weight
614
615    if high_priority_weight is not None:
616        params['high_priority_weight'] = high_priority_weight
617
618    if nvme_adminq_poll_period_us:
619        params['nvme_adminq_poll_period_us'] = nvme_adminq_poll_period_us
620
621    if nvme_ioq_poll_period_us is not None:
622        params['nvme_ioq_poll_period_us'] = nvme_ioq_poll_period_us
623
624    if io_queue_requests is not None:
625        params['io_queue_requests'] = io_queue_requests
626
627    if delay_cmd_submit is not None:
628        params['delay_cmd_submit'] = delay_cmd_submit
629
630    if transport_retry_count is not None:
631        params['transport_retry_count'] = transport_retry_count
632
633    if bdev_retry_count is not None:
634        params['bdev_retry_count'] = bdev_retry_count
635
636    if transport_ack_timeout is not None:
637        params['transport_ack_timeout'] = transport_ack_timeout
638
639    if ctrlr_loss_timeout_sec is not None:
640        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
641
642    if reconnect_delay_sec is not None:
643        params['reconnect_delay_sec'] = reconnect_delay_sec
644
645    if fast_io_fail_timeout_sec is not None:
646        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
647
648    if disable_auto_failback is not None:
649        params['disable_auto_failback'] = disable_auto_failback
650
651    if generate_uuids is not None:
652        params['generate_uuids'] = generate_uuids
653
654    if transport_tos is not None:
655        params['transport_tos'] = transport_tos
656
657    if nvme_error_stat is not None:
658        params['nvme_error_stat'] = nvme_error_stat
659
660    if rdma_srq_size is not None:
661        params['rdma_srq_size'] = rdma_srq_size
662
663    if io_path_stat is not None:
664        params['io_path_stat'] = io_path_stat
665
666    return client.call('bdev_nvme_set_options', params)
667
668
669def bdev_nvme_set_hotplug(client, enable, period_us=None):
670    """Set options for the bdev nvme. This is startup command.
671
672    Args:
673       enable: True to enable hotplug, False to disable.
674       period_us: how often the hotplug is processed for insert and remove events. Set 0 to reset to default. (optional)
675    """
676    params = {'enable': enable}
677
678    if period_us:
679        params['period_us'] = period_us
680
681    return client.call('bdev_nvme_set_hotplug', params)
682
683
684def bdev_nvme_attach_controller(client, name, trtype, traddr, adrfam=None, trsvcid=None,
685                                priority=None, subnqn=None, hostnqn=None, hostaddr=None,
686                                hostsvcid=None, prchk_reftag=None, prchk_guard=None,
687                                hdgst=None, ddgst=None, fabrics_timeout=None, multipath=None, num_io_queues=None,
688                                ctrlr_loss_timeout_sec=None, reconnect_delay_sec=None,
689                                fast_io_fail_timeout_sec=None, psk=None):
690    """Construct block device for each NVMe namespace in the attached controller.
691
692    Args:
693        name: bdev name prefix; "n" + namespace ID will be appended to create unique names
694        trtype: transport type ("PCIe", "RDMA", "FC", "TCP")
695        traddr: transport address (PCI BDF or IP address)
696        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
697        trsvcid: transport service ID (port number for IP-based addresses)
698        priority: transport connection priority (Sock priority for TCP-based transports; optional)
699        subnqn: subsystem NQN to connect to (optional)
700        hostnqn: NQN to connect from (optional)
701        hostaddr: host transport address (IP address for IP-based transports, NULL for PCIe or FC; optional)
702        hostsvcid: host transport service ID (port number for IP-based transports, NULL for PCIe or FC; optional)
703        prchk_reftag: Enable checking of PI reference tag for I/O processing (optional)
704        prchk_guard: Enable checking of PI guard for I/O processing (optional)
705        hdgst: Enable TCP header digest (optional)
706        ddgst: Enable TCP data digest (optional)
707        fabrics_timeout: Fabrics connect timeout in us (optional)
708        multipath: The behavior when multiple paths are created ("disable", "failover", or "multipath"; failover if not specified)
709        num_io_queues: The number of IO queues to request during initialization. (optional)
710        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
711        -1 means infinite reconnect retries. 0 means no reconnect retry.
712        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
713        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
714        (optional)
715        reconnect_delay_sec: Time to delay a reconnect retry.
716        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
717        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
718        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
719        (optional)
720        fail_io_fast_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
721        0 means no such timeout.
722        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
723        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. (optional)
724        psk: Set PSK and enable TCP SSL socket implementation (optional)
725
726    Returns:
727        Names of created block devices.
728    """
729    params = {'name': name,
730              'trtype': trtype,
731              'traddr': traddr}
732
733    if hostnqn:
734        params['hostnqn'] = hostnqn
735
736    if hostaddr:
737        params['hostaddr'] = hostaddr
738
739    if hostsvcid:
740        params['hostsvcid'] = hostsvcid
741
742    if adrfam:
743        params['adrfam'] = adrfam
744
745    if trsvcid:
746        params['trsvcid'] = trsvcid
747
748    if priority:
749        params['priority'] = priority
750
751    if subnqn:
752        params['subnqn'] = subnqn
753
754    if prchk_reftag:
755        params['prchk_reftag'] = prchk_reftag
756
757    if prchk_guard:
758        params['prchk_guard'] = prchk_guard
759
760    if hdgst:
761        params['hdgst'] = hdgst
762
763    if ddgst:
764        params['ddgst'] = ddgst
765
766    if fabrics_timeout:
767        params['fabrics_connect_timeout_us'] = fabrics_timeout
768
769    if multipath:
770        params['multipath'] = multipath
771
772    if num_io_queues:
773        params['num_io_queues'] = num_io_queues
774
775    if ctrlr_loss_timeout_sec is not None:
776        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
777
778    if reconnect_delay_sec is not None:
779        params['reconnect_delay_sec'] = reconnect_delay_sec
780
781    if fast_io_fail_timeout_sec is not None:
782        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
783
784    if psk:
785        params['psk'] = psk
786
787    return client.call('bdev_nvme_attach_controller', params)
788
789
790def bdev_nvme_detach_controller(client, name, trtype=None, traddr=None,
791                                adrfam=None, trsvcid=None, subnqn=None,
792                                hostaddr=None, hostsvcid=None):
793    """Detach NVMe controller and delete any associated bdevs. Optionally,
794       If all of the transport ID options are specified, only remove that
795       transport path from the specified controller. If that is the only
796       available path for the controller, this will also result in the
797       controller being detached and the associated bdevs being deleted.
798
799    Args:
800        name: controller name
801        trtype: transport type ("PCIe", "RDMA")
802        traddr: transport address (PCI BDF or IP address)
803        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
804        trsvcid: transport service ID (port number for IP-based addresses)
805        subnqn: subsystem NQN to connect to (optional)
806        hostaddr: Host address (IP address)
807        hostsvcid: transport service ID on host side (port number)
808    """
809
810    params = {'name': name}
811
812    if trtype:
813        params['trtype'] = trtype
814
815    if traddr:
816        params['traddr'] = traddr
817
818    if adrfam:
819        params['adrfam'] = adrfam
820
821    if trsvcid:
822        params['trsvcid'] = trsvcid
823
824    if subnqn:
825        params['subnqn'] = subnqn
826
827    if hostaddr:
828        params['hostaddr'] = hostaddr
829
830    if hostsvcid:
831        params['hostsvcid'] = hostsvcid
832
833    return client.call('bdev_nvme_detach_controller', params)
834
835
836def bdev_nvme_reset_controller(client, name):
837    """Reset NVMe controller.
838
839    Args:
840        name: controller name
841    """
842
843    params = {'name': name}
844
845    return client.call('bdev_nvme_reset_controller', params)
846
847
848def bdev_nvme_start_discovery(client, name, trtype, traddr, adrfam=None, trsvcid=None,
849                              hostnqn=None, wait_for_attach=None, ctrlr_loss_timeout_sec=None,
850                              reconnect_delay_sec=None, fast_io_fail_timeout_sec=None,
851                              attach_timeout_ms=None):
852    """Start discovery with the specified discovery subsystem
853
854    Args:
855        name: bdev name prefix; "n" + namespace ID will be appended to create unique names
856        trtype: transport type ("PCIe", "RDMA", "FC", "TCP")
857        traddr: transport address (PCI BDF or IP address)
858        adrfam: address family ("IPv4", "IPv6", "IB", or "FC")
859        trsvcid: transport service ID (port number for IP-based addresses)
860        hostnqn: NQN to connect from (optional)
861        wait_for_attach: Wait to complete RPC until all discovered NVM subsystems have attached (optional)
862        ctrlr_loss_timeout_sec: Time to wait until ctrlr is reconnected before deleting ctrlr.
863        -1 means infinite reconnect retries. 0 means no reconnect retry.
864        If reconnect_delay_sec is zero, ctrlr_loss_timeout_sec has to be zero.
865        If reconnect_delay_sec is non-zero, ctrlr_loss_timeout_sec has to be -1 or not less than reconnect_delay_sec.
866        (optional)
867        reconnect_delay_sec: Time to delay a reconnect retry.
868        If ctrlr_loss_timeout_sec is zero, reconnect_delay_sec has to be zero.
869        If ctrlr_loss_timeout_sec is -1, reconnect_delay_sec has to be non-zero.
870        If ctrlr_loss_timeout_sec is not -1 or zero, reconnect_sec has to be non-zero and less than ctrlr_loss_timeout_sec.
871        (optional)
872        fail_io_fast_timeout_sec: Time to wait until ctrlr is reconnected before failing I/O to ctrlr.
873        0 means no such timeout.
874        If fast_io_fail_timeout_sec is not zero, it has to be not less than reconnect_delay_sec and less than
875        ctrlr_loss_timeout_sec if ctrlr_loss_timeout_sec is not -1. (optional)
876        attach_timeout_ms: Time to wait until the discovery and all discovered NVM subsystems are attached (optional)
877    """
878    params = {'name': name,
879              'trtype': trtype,
880              'traddr': traddr}
881
882    if hostnqn:
883        params['hostnqn'] = hostnqn
884
885    if adrfam:
886        params['adrfam'] = adrfam
887
888    if trsvcid:
889        params['trsvcid'] = trsvcid
890
891    if wait_for_attach:
892        params['wait_for_attach'] = True
893
894    if attach_timeout_ms is not None:
895        params['attach_timeout_ms'] = attach_timeout_ms
896
897    if ctrlr_loss_timeout_sec is not None:
898        params['ctrlr_loss_timeout_sec'] = ctrlr_loss_timeout_sec
899
900    if reconnect_delay_sec is not None:
901        params['reconnect_delay_sec'] = reconnect_delay_sec
902
903    if fast_io_fail_timeout_sec is not None:
904        params['fast_io_fail_timeout_sec'] = fast_io_fail_timeout_sec
905
906    return client.call('bdev_nvme_start_discovery', params)
907
908
909def bdev_nvme_stop_discovery(client, name):
910    """Stop a previously started discovery service
911
912    Args:
913        name: name of discovery service to start
914    """
915    params = {'name': name}
916
917    return client.call('bdev_nvme_stop_discovery', params)
918
919
920def bdev_nvme_get_discovery_info(client):
921    """Get information about the automatic discovery
922    """
923    return client.call('bdev_nvme_get_discovery_info')
924
925
926def bdev_nvme_get_io_paths(client, name):
927    """Display all or the specified NVMe bdev's active I/O paths
928
929    Args:
930        name: Name of the NVMe bdev (optional)
931
932    Returns:
933        List of active I/O paths
934    """
935    params = {}
936    if name:
937        params['name'] = name
938    return client.call('bdev_nvme_get_io_paths', params)
939
940
941def bdev_nvme_set_preferred_path(client, name, cntlid):
942    """Set the preferred I/O path for an NVMe bdev when in multipath mode
943
944    Args:
945        name: NVMe bdev name
946        cntlid: NVMe-oF controller ID
947    """
948
949    params = {'name': name,
950              'cntlid': cntlid}
951
952    return client.call('bdev_nvme_set_preferred_path', params)
953
954
955def bdev_nvme_set_multipath_policy(client, name, policy, selector, rr_min_io):
956    """Set multipath policy of the NVMe bdev
957
958    Args:
959        name: NVMe bdev name
960        policy: Multipath policy (active_passive or active_active)
961        selector: Multipath selector (round_robin, queue_depth)
962        rr_min_io: Number of IO to route to a path before switching to another one (optional)
963    """
964
965    params = {'name': name,
966              'policy': policy}
967    if selector:
968        params['selector'] = selector
969    if rr_min_io:
970        params['rr_min_io'] = rr_min_io
971
972    return client.call('bdev_nvme_set_multipath_policy', params)
973
974
975def bdev_nvme_get_path_iostat(client, name):
976    """Get I/O statistics for IO paths of the block device.
977
978    Args:
979        name: bdev name to query
980
981    Returns:
982        I/O statistics for IO paths of the requested block device.
983    """
984    params = {'name': name}
985
986    return client.call('bdev_nvme_get_path_iostat', params)
987
988
989def bdev_nvme_cuse_register(client, name):
990    """Register CUSE devices on NVMe controller.
991
992    Args:
993        name: Name of the operating NVMe controller
994    """
995    params = {'name': name}
996
997    return client.call('bdev_nvme_cuse_register', params)
998
999
1000def bdev_nvme_cuse_unregister(client, name):
1001    """Unregister CUSE devices on NVMe controller.
1002
1003    Args:
1004        name: Name of the operating NVMe controller
1005    """
1006    params = {'name': name}
1007
1008    return client.call('bdev_nvme_cuse_unregister', params)
1009
1010
1011def bdev_zone_block_create(client, name, base_bdev, zone_capacity, optimal_open_zones):
1012    """Creates a virtual zone device on top of existing non-zoned bdev.
1013
1014    Args:
1015        name: Zone device name
1016        base_bdev: Base Nvme bdev name
1017        zone_capacity: Surfaced zone capacity in blocks
1018        optimal_open_zones: Number of zones required to reach optimal write speed (optional, default: 1)
1019
1020    Returns:
1021        Name of created block device.
1022    """
1023    params = {'name': name,
1024              'base_bdev': base_bdev,
1025              'zone_capacity': zone_capacity,
1026              'optimal_open_zones': optimal_open_zones}
1027
1028    return client.call('bdev_zone_block_create', params)
1029
1030
1031def bdev_zone_block_delete(client, name):
1032    """Remove block zone bdev from the system.
1033
1034    Args:
1035        name: name of block zone bdev to delete
1036    """
1037    params = {'name': name}
1038    return client.call('bdev_zone_block_delete', params)
1039
1040
1041def bdev_rbd_register_cluster(client, name, user=None, config_param=None, config_file=None, key_file=None):
1042    """Create a Rados Cluster object of the Ceph RBD backend.
1043
1044    Args:
1045        name: name of Rados Cluster
1046        user: Ceph user name (optional)
1047        config_param: map of config keys to values (optional)
1048        config_file: file path of Ceph configuration file (optional)
1049        key_file: file path of Ceph key file (optional)
1050
1051    Returns:
1052        Name of registered Rados Cluster object.
1053    """
1054    params = {'name': name}
1055
1056    if user is not None:
1057        params['user_id'] = user
1058    if config_param is not None:
1059        params['config_param'] = config_param
1060    if config_file is not None:
1061        params['config_file'] = config_file
1062    if key_file is not None:
1063        params['key_file'] = key_file
1064
1065    return client.call('bdev_rbd_register_cluster', params)
1066
1067
1068def bdev_rbd_unregister_cluster(client, name):
1069    """Remove Rados cluster object from the system.
1070
1071    Args:
1072        name: name of Rados cluster object to unregister
1073    """
1074    params = {'name': name}
1075    return client.call('bdev_rbd_unregister_cluster', params)
1076
1077
1078def bdev_rbd_get_clusters_info(client, name):
1079    """Get the cluster(s) info
1080
1081    Args:
1082        name: name of Rados cluster object to query (optional; if omitted, query all clusters)
1083
1084    Returns:
1085        List of registered Rados cluster information objects.
1086    """
1087    params = {}
1088    if name:
1089        params['name'] = name
1090    return client.call('bdev_rbd_get_clusters_info', params)
1091
1092
1093def bdev_rbd_create(client, pool_name, rbd_name, block_size, name=None, user=None, config=None, cluster_name=None, uuid=None):
1094    """Create a Ceph RBD block device.
1095
1096    Args:
1097        pool_name: Ceph RBD pool name
1098        rbd_name: Ceph RBD image name
1099        block_size: block size of RBD volume
1100        name: name of block device (optional)
1101        user: Ceph user name (optional)
1102        config: map of config keys to values (optional)
1103        cluster_name: Name to identify Rados cluster (optional)
1104        uuid: UUID of block device (optional)
1105
1106    Returns:
1107        Name of created block device.
1108    """
1109    params = {
1110        'pool_name': pool_name,
1111        'rbd_name': rbd_name,
1112        'block_size': block_size,
1113    }
1114
1115    if name:
1116        params['name'] = name
1117    if user is not None:
1118        params['user_id'] = user
1119    if config is not None:
1120        params['config'] = config
1121    if cluster_name is not None:
1122        params['cluster_name'] = cluster_name
1123    else:
1124        print("WARNING:bdev_rbd_create should be used with specifying -c to have a cluster name after bdev_rbd_register_cluster.")
1125    if uuid is not None:
1126        params['uuid'] = uuid
1127
1128    return client.call('bdev_rbd_create', params)
1129
1130
1131def bdev_rbd_delete(client, name):
1132    """Remove rbd bdev from the system.
1133
1134    Args:
1135        name: name of rbd bdev to delete
1136    """
1137    params = {'name': name}
1138    return client.call('bdev_rbd_delete', params)
1139
1140
1141def bdev_rbd_resize(client, name, new_size):
1142    """Resize rbd bdev in the system.
1143
1144    Args:
1145        name: name of rbd bdev to resize
1146        new_size: new bdev size of resize operation. The unit is MiB
1147    """
1148    params = {
1149            'name': name,
1150            'new_size': new_size,
1151            }
1152    return client.call('bdev_rbd_resize', params)
1153
1154
1155def bdev_error_create(client, base_name):
1156    """Construct an error injection block device.
1157
1158    Args:
1159        base_name: base bdev name
1160    """
1161    params = {'base_name': base_name}
1162    return client.call('bdev_error_create', params)
1163
1164
1165def bdev_delay_create(client, base_bdev_name, name, avg_read_latency, p99_read_latency, avg_write_latency, p99_write_latency, uuid=None):
1166    """Construct a delay block device.
1167
1168    Args:
1169        base_bdev_name: name of the existing bdev
1170        name: name of block device
1171        avg_read_latency: complete 99% of read ops with this delay
1172        p99_read_latency: complete 1% of read ops with this delay
1173        avg_write_latency: complete 99% of write ops with this delay
1174        p99_write_latency: complete 1% of write ops with this delay
1175        uuid: UUID of block device (optional)
1176
1177    Returns:
1178        Name of created block device.
1179    """
1180    params = {
1181        'base_bdev_name': base_bdev_name,
1182        'name': name,
1183        'avg_read_latency': avg_read_latency,
1184        'p99_read_latency': p99_read_latency,
1185        'avg_write_latency': avg_write_latency,
1186        'p99_write_latency': p99_write_latency,
1187    }
1188    if uuid:
1189        params['uuid'] = uuid
1190    return client.call('bdev_delay_create', params)
1191
1192
1193def bdev_delay_delete(client, name):
1194    """Remove delay bdev from the system.
1195
1196    Args:
1197        name: name of delay bdev to delete
1198    """
1199    params = {'name': name}
1200    return client.call('bdev_delay_delete', params)
1201
1202
1203def bdev_delay_update_latency(client, delay_bdev_name, latency_type, latency_us):
1204    """Update the latency value for a delay block device
1205
1206    Args:
1207        delay_bdev_name: name of the delay bdev
1208        latency_type: 'one of: avg_read, avg_write, p99_read, p99_write. No other values accepted.'
1209        latency_us: 'new latency value.'
1210
1211    Returns:
1212        True if successful, or a specific error otherwise.
1213    """
1214    params = {
1215        'delay_bdev_name': delay_bdev_name,
1216        'latency_type': latency_type,
1217        'latency_us': latency_us,
1218    }
1219    return client.call('bdev_delay_update_latency', params)
1220
1221
1222def bdev_error_delete(client, name):
1223    """Remove error bdev from the system.
1224
1225    Args:
1226        bdev_name: name of error bdev to delete
1227    """
1228    params = {'name': name}
1229    return client.call('bdev_error_delete', params)
1230
1231
1232def bdev_iscsi_set_options(client, timeout_sec):
1233    """Set options for the bdev iscsi.
1234
1235    Args:
1236        timeout_sec: Timeout for command, in seconds, if 0, don't track timeout
1237    """
1238    params = {}
1239
1240    if timeout_sec is not None:
1241        params['timeout_sec'] = timeout_sec
1242
1243    return client.call('bdev_iscsi_set_options', params)
1244
1245
1246def bdev_iscsi_create(client, name, url, initiator_iqn):
1247    """Construct an iSCSI block device.
1248
1249    Args:
1250        name: name of block device
1251        url: iSCSI URL
1252        initiator_iqn: IQN name to be used by initiator
1253
1254    Returns:
1255        Name of created block device.
1256    """
1257    params = {
1258        'name': name,
1259        'url': url,
1260        'initiator_iqn': initiator_iqn,
1261    }
1262    return client.call('bdev_iscsi_create', params)
1263
1264
1265def bdev_iscsi_delete(client, name):
1266    """Remove iSCSI bdev from the system.
1267
1268    Args:
1269        bdev_name: name of iSCSI bdev to delete
1270    """
1271    params = {'name': name}
1272    return client.call('bdev_iscsi_delete', params)
1273
1274
1275def bdev_passthru_create(client, base_bdev_name, name):
1276    """Construct a pass-through block device.
1277
1278    Args:
1279        base_bdev_name: name of the existing bdev
1280        name: name of block device
1281
1282    Returns:
1283        Name of created block device.
1284    """
1285    params = {
1286        'base_bdev_name': base_bdev_name,
1287        'name': name,
1288    }
1289    return client.call('bdev_passthru_create', params)
1290
1291
1292def bdev_passthru_delete(client, name):
1293    """Remove pass through bdev from the system.
1294
1295    Args:
1296        name: name of pass through bdev to delete
1297    """
1298    params = {'name': name}
1299    return client.call('bdev_passthru_delete', params)
1300
1301
1302def bdev_opal_create(client, nvme_ctrlr_name, nsid, locking_range_id, range_start, range_length, password):
1303    """Create opal virtual block devices from a base nvme bdev.
1304
1305    Args:
1306        nvme_ctrlr_name: name of the nvme ctrlr
1307        nsid: namespace ID of nvme ctrlr
1308        locking_range_id: locking range ID corresponding to this virtual bdev
1309        range_start: start address of this locking range
1310        range_length: length of this locking range
1311        password: admin password of base nvme bdev
1312
1313    Returns:
1314        Name of the new created block devices.
1315    """
1316    params = {
1317        'nvme_ctrlr_name': nvme_ctrlr_name,
1318        'nsid': nsid,
1319        'locking_range_id': locking_range_id,
1320        'range_start': range_start,
1321        'range_length': range_length,
1322        'password': password,
1323    }
1324
1325    return client.call('bdev_opal_create', params)
1326
1327
1328def bdev_opal_get_info(client, bdev_name, password):
1329    """Get opal locking range info.
1330
1331    Args:
1332        bdev_name: name of opal vbdev to get info
1333        password: admin password
1334
1335    Returns:
1336        Locking range info.
1337    """
1338    params = {
1339        'bdev_name': bdev_name,
1340        'password': password,
1341    }
1342
1343    return client.call('bdev_opal_get_info', params)
1344
1345
1346def bdev_opal_delete(client, bdev_name, password):
1347    """Delete opal virtual bdev from the system.
1348
1349    Args:
1350        bdev_name: name of opal vbdev to delete
1351        password: admin password of base nvme bdev
1352    """
1353    params = {
1354        'bdev_name': bdev_name,
1355        'password': password,
1356    }
1357
1358    return client.call('bdev_opal_delete', params)
1359
1360
1361def bdev_opal_new_user(client, bdev_name, admin_password, user_id, user_password):
1362    """Add a user to opal bdev who can set lock state for this bdev.
1363
1364    Args:
1365        bdev_name: name of opal vbdev
1366        admin_password: admin password
1367        user_id: ID of the user who will be added to this opal bdev
1368        user_password: password set for this user
1369    """
1370    params = {
1371        'bdev_name': bdev_name,
1372        'admin_password': admin_password,
1373        'user_id': user_id,
1374        'user_password': user_password,
1375    }
1376
1377    return client.call('bdev_opal_new_user', params)
1378
1379
1380def bdev_opal_set_lock_state(client, bdev_name, user_id, password, lock_state):
1381    """set lock state for an opal bdev.
1382
1383    Args:
1384        bdev_name: name of opal vbdev
1385        user_id: ID of the user who will set lock state
1386        password: password of the user
1387        lock_state: lock state to set
1388    """
1389    params = {
1390        'bdev_name': bdev_name,
1391        'user_id': user_id,
1392        'password': password,
1393        'lock_state': lock_state,
1394    }
1395
1396    return client.call('bdev_opal_set_lock_state', params)
1397
1398
1399def bdev_split_create(client, base_bdev, split_count, split_size_mb=None):
1400    """Create split block devices from a base bdev.
1401
1402    Args:
1403        base_bdev: name of bdev to split
1404        split_count: number of split bdevs to create
1405        split_size_mb: size of each split volume in MiB (optional)
1406
1407    Returns:
1408        List of created block devices.
1409    """
1410    params = {
1411        'base_bdev': base_bdev,
1412        'split_count': split_count,
1413    }
1414    if split_size_mb:
1415        params['split_size_mb'] = split_size_mb
1416
1417    return client.call('bdev_split_create', params)
1418
1419
1420def bdev_split_delete(client, base_bdev):
1421    """Delete split block devices.
1422
1423    Args:
1424        base_bdev: name of previously split bdev
1425    """
1426    params = {
1427        'base_bdev': base_bdev,
1428    }
1429
1430    return client.call('bdev_split_delete', params)
1431
1432
1433def bdev_ftl_create(client, name, base_bdev, **kwargs):
1434    """Construct FTL bdev
1435
1436    Args:
1437        name: name of the bdev
1438        base_bdev: name of the base bdev
1439        kwargs: optional parameters
1440    """
1441    params = {'name': name,
1442              'base_bdev': base_bdev}
1443    for key, value in kwargs.items():
1444        if value is not None:
1445            params[key] = value
1446
1447    return client.call('bdev_ftl_create', params)
1448
1449
1450def bdev_ftl_load(client, name, base_bdev, **kwargs):
1451    """Load FTL bdev
1452
1453    Args:
1454        name: name of the bdev
1455        base_bdev: name of the base bdev
1456        kwargs: optional parameters
1457    """
1458    params = {'name': name,
1459              'base_bdev': base_bdev}
1460    for key, value in kwargs.items():
1461        if value is not None:
1462            params[key] = value
1463
1464    return client.call('bdev_ftl_load', params)
1465
1466
1467def bdev_ftl_unload(client, name, fast_shutdown):
1468    """Unload FTL bdev
1469
1470    Args:
1471        name: name of the bdev
1472    """
1473    params = {'name': name,
1474              'fast_shutdown': fast_shutdown}
1475
1476    return client.call('bdev_ftl_unload', params)
1477
1478
1479def bdev_ftl_delete(client, name, fast_shutdown):
1480    """Delete FTL bdev
1481
1482    Args:
1483        name: name of the bdev
1484    """
1485    params = {'name': name,
1486              'fast_shutdown': fast_shutdown}
1487
1488    return client.call('bdev_ftl_delete', params)
1489
1490
1491def bdev_ftl_unmap(client, name, lba, num_blocks):
1492    """FTL unmap
1493
1494    Args:
1495        name: name of the bdev
1496        lba: starting lba to be unmapped
1497        num_blocks: number of blocks to unmap
1498    """
1499    params = {'name': name,
1500              'lba': lba,
1501              'num_blocks': num_blocks}
1502
1503    return client.call('bdev_ftl_unmap', params)
1504
1505
1506def bdev_ftl_get_stats(client, name):
1507    """get FTL stats
1508
1509    Args:
1510        name: name of the bdev
1511    """
1512    params = {'name': name}
1513
1514    return client.call('bdev_ftl_get_stats', params)
1515
1516
1517def bdev_get_bdevs(client, name=None, timeout=None):
1518    """Get information about block devices.
1519
1520    Args:
1521        name: bdev name to query (optional; if omitted, query all bdevs)
1522        timeout: time in ms to wait for the bdev with specified name to appear
1523
1524    Returns:
1525        List of bdev information objects.
1526    """
1527    params = {}
1528    if name:
1529        params['name'] = name
1530    if timeout:
1531        params['timeout'] = timeout
1532    return client.call('bdev_get_bdevs', params)
1533
1534
1535def bdev_get_iostat(client, name=None, per_channel=None):
1536    """Get I/O statistics for block devices.
1537
1538    Args:
1539        name: bdev name to query (optional; if omitted, query all bdevs)
1540        per_channel: display per channel IO stats for specified bdev
1541
1542    Returns:
1543        I/O statistics for the requested block devices.
1544    """
1545    params = {}
1546    if name:
1547        params['name'] = name
1548    if per_channel:
1549        params['per_channel'] = per_channel
1550    return client.call('bdev_get_iostat', params)
1551
1552
1553def bdev_reset_iostat(client, name=None, mode=None):
1554    """Reset I/O statistics for block devices.
1555
1556    Args:
1557        name: bdev name to reset (optional; if omitted, reset all bdevs)
1558        mode: mode to reset: all, maxmin (optional: if omitted, reset all fields)
1559    """
1560    params = {}
1561    if name:
1562        params['name'] = name
1563    if mode:
1564        params['mode'] = mode
1565
1566    return client.call('bdev_reset_iostat', params)
1567
1568
1569def bdev_enable_histogram(client, name, enable):
1570    """Control whether histogram is enabled for specified bdev.
1571
1572    Args:
1573        bdev_name: name of bdev
1574    """
1575    params = {'name': name, "enable": enable}
1576    return client.call('bdev_enable_histogram', params)
1577
1578
1579def bdev_get_histogram(client, name):
1580    """Get histogram for specified bdev.
1581
1582    Args:
1583        bdev_name: name of bdev
1584    """
1585    params = {'name': name}
1586    return client.call('bdev_get_histogram', params)
1587
1588
1589def bdev_error_inject_error(client, name, io_type, error_type, num,
1590                            corrupt_offset, corrupt_value):
1591    """Inject an error via an error bdev.
1592
1593    Args:
1594        name: name of error bdev
1595        io_type: one of "clear", "read", "write", "unmap", "flush", or "all"
1596        error_type: one of "failure", "pending", or "corrupt_data"
1597        num: number of commands to fail
1598        corrupt_offset: offset in bytes to xor with corrupt_value
1599        corrupt_value: value for xor (1-255, 0 is invalid)
1600    """
1601    params = {
1602        'name': name,
1603        'io_type': io_type,
1604        'error_type': error_type,
1605    }
1606
1607    if num:
1608        params['num'] = num
1609    if corrupt_offset:
1610        params['corrupt_offset'] = corrupt_offset
1611    if corrupt_value:
1612        params['corrupt_value'] = corrupt_value
1613
1614    return client.call('bdev_error_inject_error', params)
1615
1616
1617def bdev_set_qd_sampling_period(client, name, period):
1618    """Enable queue depth tracking on a specified bdev.
1619
1620    Args:
1621        name: name of a bdev on which to track queue depth.
1622        period: period (in microseconds) at which to update the queue depth reading. If set to 0, polling will be disabled.
1623    """
1624
1625    params = {}
1626    params['name'] = name
1627    params['period'] = period
1628    return client.call('bdev_set_qd_sampling_period', params)
1629
1630
1631def bdev_set_qos_limit(
1632        client,
1633        name,
1634        rw_ios_per_sec=None,
1635        rw_mbytes_per_sec=None,
1636        r_mbytes_per_sec=None,
1637        w_mbytes_per_sec=None):
1638    """Set QoS rate limit on a block device.
1639
1640    Args:
1641        name: name of block device
1642        rw_ios_per_sec: R/W IOs per second limit (>=1000, example: 20000). 0 means unlimited.
1643        rw_mbytes_per_sec: R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.
1644        r_mbytes_per_sec: Read megabytes per second limit (>=10, example: 100). 0 means unlimited.
1645        w_mbytes_per_sec: Write megabytes per second limit (>=10, example: 100). 0 means unlimited.
1646    """
1647    params = {}
1648    params['name'] = name
1649    if rw_ios_per_sec is not None:
1650        params['rw_ios_per_sec'] = rw_ios_per_sec
1651    if rw_mbytes_per_sec is not None:
1652        params['rw_mbytes_per_sec'] = rw_mbytes_per_sec
1653    if r_mbytes_per_sec is not None:
1654        params['r_mbytes_per_sec'] = r_mbytes_per_sec
1655    if w_mbytes_per_sec is not None:
1656        params['w_mbytes_per_sec'] = w_mbytes_per_sec
1657    return client.call('bdev_set_qos_limit', params)
1658
1659
1660def bdev_nvme_apply_firmware(client, bdev_name, filename):
1661    """Download and commit firmware to NVMe device.
1662
1663    Args:
1664        bdev_name: name of NVMe block device
1665        filename: filename of the firmware to download
1666    """
1667    params = {
1668        'filename': filename,
1669        'bdev_name': bdev_name,
1670    }
1671    return client.call('bdev_nvme_apply_firmware', params)
1672
1673
1674def bdev_nvme_get_transport_statistics(client):
1675    """Get bdev_nvme poll group transport statistics"""
1676    return client.call('bdev_nvme_get_transport_statistics')
1677
1678
1679def bdev_nvme_get_controller_health_info(client, name):
1680    """Display health log of the required NVMe bdev controller.
1681
1682    Args:
1683        name: name of the required NVMe bdev controller
1684
1685    Returns:
1686        Health log for the requested NVMe bdev controller.
1687    """
1688    params = {}
1689    params['name'] = name
1690    return client.call('bdev_nvme_get_controller_health_info', params)
1691
1692
1693def bdev_daos_create(client, num_blocks, block_size, pool, cont, name, oclass=None, uuid=None):
1694    """Construct DAOS block device.
1695
1696    Args:
1697        num_blocks: size of block device in blocks
1698        block_size: block size of device; must be a power of 2 and at least 512
1699        name: name of block device (also the name of the backend file on DAOS DFS)
1700        pool: UUID of DAOS pool
1701        cont: UUID of DAOS container
1702        uuid: UUID of block device (optional)
1703        oclass: DAOS object class (optional)
1704
1705    Returns:
1706        Name of created block device.
1707    """
1708    params = {'num_blocks': num_blocks, 'block_size': block_size, 'pool': pool, 'cont': cont, 'name': name}
1709    if uuid:
1710        params['uuid'] = uuid
1711    if oclass:
1712        params['oclass'] = oclass
1713    return client.call('bdev_daos_create', params)
1714
1715
1716def bdev_daos_delete(client, name):
1717    """Delete DAOS block device.
1718
1719    Args:
1720        bdev_name: name of DAOS bdev to delete
1721    """
1722    params = {'name': name}
1723    return client.call('bdev_daos_delete', params)
1724
1725
1726def bdev_daos_resize(client, name, new_size):
1727    """Resize DAOS bdev in the system.
1728    Args:
1729        name: name of DAOS bdev to resize
1730        new_size: new bdev size of resize operation. The unit is MiB
1731    """
1732    params = {
1733            'name': name,
1734            'new_size': new_size,
1735            }
1736    return client.call('bdev_daos_resize', params)
1737
1738
1739def bdev_nvme_start_mdns_discovery(client, name, svcname, hostnqn=None):
1740    """Start discovery with mDNS
1741
1742    Args:
1743        name: bdev name prefix; "n" + unique seqno + namespace ID will be appended to create unique names
1744        svcname: service to discover ("_nvme-disc._tcp")
1745        hostnqn: NQN to connect from (optional)
1746    """
1747    params = {'name': name,
1748              'svcname': svcname}
1749
1750    if hostnqn:
1751        params['hostnqn'] = hostnqn
1752    return client.call('bdev_nvme_start_mdns_discovery', params)
1753
1754
1755def bdev_nvme_stop_mdns_discovery(client, name):
1756    """Stop a previously started mdns discovery service
1757
1758    Args:
1759        name: name of the discovery service to stop
1760    """
1761    params = {'name': name}
1762
1763    return client.call('bdev_nvme_stop_mdns_discovery', params)
1764
1765
1766def bdev_nvme_get_mdns_discovery_info(client):
1767    """Get information about the automatic mdns discovery
1768    """
1769    return client.call('bdev_nvme_get_mdns_discovery_info')
1770