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