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