2018-05-21 20:28:21 +00:00
|
|
|
def construct_malloc_bdev(client, num_blocks, block_size, name=None, uuid=None):
|
|
|
|
"""Construct a malloc block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
num_blocks: size of block device in blocks
|
|
|
|
block_size: block size of device; must be a power of 2 and at least 512
|
|
|
|
name: name of block device (optional)
|
|
|
|
uuid: UUID of block device (optional)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
|
|
|
params = {'num_blocks': num_blocks, 'block_size': block_size}
|
|
|
|
if name:
|
|
|
|
params['name'] = name
|
|
|
|
if uuid:
|
|
|
|
params['uuid'] = uuid
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_malloc_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_null_bdev(client, num_blocks, block_size, name, uuid=None):
|
|
|
|
"""Construct a null block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
num_blocks: size of block device in blocks
|
|
|
|
block_size: block size of device; must be a power of 2 and at least 512
|
|
|
|
name: name of block device
|
|
|
|
uuid: UUID of block device (optional)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
|
|
|
params = {'name': name, 'num_blocks': num_blocks,
|
|
|
|
'block_size': block_size}
|
|
|
|
if uuid:
|
|
|
|
params['uuid'] = uuid
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_null_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_aio_bdev(client, filename, name, block_size=None):
|
|
|
|
"""Construct a Linux AIO block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
filename: path to device or file (ex: /dev/sda)
|
|
|
|
name: name of block device
|
|
|
|
block_size: block size of device (optional; autodetected if omitted)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
|
|
|
params = {'name': name,
|
|
|
|
'filename': filename}
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
if block_size:
|
|
|
|
params['block_size'] = block_size
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_aio_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_nvme_bdev(client, name, trtype, traddr, adrfam=None, trsvcid=None, subnqn=None):
|
|
|
|
"""Construct NVMe namespace block devices.
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
Args:
|
|
|
|
name: bdev name prefix; "n" + namespace ID will be appended to create unique names
|
|
|
|
trtype: transport type ("PCIe", "RDMA")
|
|
|
|
traddr: transport address (PCI BDF or IP address)
|
|
|
|
adrfam: address family ("IPv4", "IPv6", "IB", or "FC") (optional for PCIe)
|
|
|
|
trsvcid: transport service ID (port number for IP-based addresses; optional for PCIe)
|
|
|
|
subnqn: subsystem NQN to connect to (optional)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
|
|
|
params = {'name': name,
|
|
|
|
'trtype': trtype,
|
|
|
|
'traddr': traddr}
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
if adrfam:
|
|
|
|
params['adrfam'] = adrfam
|
|
|
|
|
|
|
|
if trsvcid:
|
|
|
|
params['trsvcid'] = trsvcid
|
|
|
|
|
|
|
|
if subnqn:
|
|
|
|
params['subnqn'] = subnqn
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_nvme_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_rbd_bdev(client, pool_name, rbd_name, block_size, name=None):
|
|
|
|
"""Construct a Ceph RBD block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
pool_name: Ceph RBD pool name
|
|
|
|
rbd_name: Ceph RBD image name
|
|
|
|
block_size: block size of RBD volume
|
|
|
|
name: name of block device (optional)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
2017-06-06 21:22:03 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'pool_name': pool_name,
|
|
|
|
'rbd_name': rbd_name,
|
|
|
|
'block_size': block_size,
|
2017-06-06 21:22:03 +00:00
|
|
|
}
|
2018-02-23 19:05:47 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
if name:
|
|
|
|
params['name'] = name
|
2018-02-23 19:05:47 +00:00
|
|
|
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_rbd_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_error_bdev(client, base_name):
|
|
|
|
"""Construct an error injection block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
base_name: base bdev name
|
|
|
|
"""
|
|
|
|
params = {'base_name': base_name}
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_error_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_pmem_bdev(client, pmem_file, name):
|
|
|
|
"""Construct a libpmemblk block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
pmem_file: path to pmemblk pool file
|
|
|
|
name: name of block device
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
2017-06-06 21:22:03 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'pmem_file': pmem_file,
|
|
|
|
'name': name
|
2017-06-06 21:22:03 +00:00
|
|
|
}
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('construct_pmem_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_passthru_bdev(client, base_bdev_name, passthru_bdev_name):
|
|
|
|
"""Construct a pass-through block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
base_bdev_name: name of the existing bdev
|
|
|
|
passthru_bdev_name: name of block device
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
2018-04-08 01:53:31 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'base_bdev_name': base_bdev_name,
|
|
|
|
'passthru_bdev_name': passthru_bdev_name,
|
2018-04-08 01:53:31 +00:00
|
|
|
}
|
|
|
|
return client.call('construct_passthru_bdev', params)
|
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def construct_split_vbdev(client, base_bdev, split_count, split_size_mb=None):
|
|
|
|
"""Construct split block devices from a base bdev.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
base_bdev: name of bdev to split
|
|
|
|
split_count: number of split bdevs to create
|
|
|
|
split_size_mb: size of each split volume in MiB (optional)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of created block devices.
|
|
|
|
"""
|
2018-03-16 18:27:57 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'base_bdev': base_bdev,
|
|
|
|
'split_count': split_count,
|
2018-03-16 18:27:57 +00:00
|
|
|
}
|
2018-05-25 13:31:23 +00:00
|
|
|
if split_size_mb:
|
2018-05-21 20:28:21 +00:00
|
|
|
params['split_size_mb'] = split_size_mb
|
2018-03-16 18:27:57 +00:00
|
|
|
|
|
|
|
return client.call('construct_split_vbdev', params)
|
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def destruct_split_vbdev(client, base_bdev):
|
|
|
|
"""Destroy split block devices.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
base_bdev: name of previously split bdev
|
|
|
|
"""
|
2018-03-16 18:27:57 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'base_bdev': base_bdev,
|
2018-03-16 18:27:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return client.call('destruct_split_vbdev', params)
|
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def get_bdevs(client, name=None):
|
|
|
|
"""Get information about block devices.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: bdev name to query (optional; if omitted, query all bdevs)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of bdev information objects.
|
|
|
|
"""
|
2017-06-06 21:22:03 +00:00
|
|
|
params = {}
|
2018-05-21 20:28:21 +00:00
|
|
|
if name:
|
|
|
|
params['name'] = name
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('get_bdevs', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def get_bdevs_config(client, name=None):
|
|
|
|
"""Get configuration for block devices.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: bdev name to query (optional; if omitted, query all bdevs)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
List of RPC methods to reproduce the current bdev configuration.
|
|
|
|
"""
|
2018-02-22 12:48:13 +00:00
|
|
|
params = {}
|
2018-05-21 20:28:21 +00:00
|
|
|
if name:
|
|
|
|
params['name'] = name
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('get_bdevs_config', params)
|
2018-02-22 12:48:13 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def get_bdevs_iostat(client, name=None):
|
|
|
|
"""Get I/O statistics for block devices.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: bdev name to query (optional; if omitted, query all bdevs)
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
I/O statistics for the requested block devices.
|
|
|
|
"""
|
2017-12-28 09:03:17 +00:00
|
|
|
params = {}
|
2018-05-21 20:28:21 +00:00
|
|
|
if name:
|
|
|
|
params['name'] = name
|
2017-12-28 09:03:17 +00:00
|
|
|
return client.call('get_bdevs_iostat', params)
|
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def delete_bdev(client, bdev_name):
|
|
|
|
"""Remove a bdev from the system.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
bdev_name: name of bdev to delete
|
|
|
|
"""
|
|
|
|
params = {'name': bdev_name}
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('delete_bdev', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def bdev_inject_error(client, name, io_type, error_type, num=1):
|
|
|
|
"""Inject an error via an error bdev.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: name of error bdev
|
|
|
|
io_type: one of "clear", "read", "write", "unmap", "flush", or "all"
|
|
|
|
error_type: one of "failure" or "pending"
|
|
|
|
num: number of commands to fail
|
|
|
|
"""
|
2017-06-06 21:22:03 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'name': name,
|
|
|
|
'io_type': io_type,
|
|
|
|
'error_type': error_type,
|
|
|
|
'num': num,
|
2017-06-06 21:22:03 +00:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('bdev_inject_error', params)
|
2017-06-06 21:22:03 +00:00
|
|
|
|
2018-02-14 21:34:55 +00:00
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def set_bdev_qos_limit_iops(client, name, ios_per_sec):
|
|
|
|
"""Set QoS IOPS limit on a block device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
name: name of block device
|
|
|
|
ios_per_sec: IOs per second limit (>=10000, example: 20000). 0 means unlimited.
|
|
|
|
"""
|
2017-12-29 08:02:08 +00:00
|
|
|
params = {}
|
2018-05-21 20:28:21 +00:00
|
|
|
params['name'] = name
|
|
|
|
params['ios_per_sec'] = ios_per_sec
|
2017-12-29 08:02:08 +00:00
|
|
|
return client.call('set_bdev_qos_limit_iops', params)
|
|
|
|
|
|
|
|
|
2018-05-21 20:28:21 +00:00
|
|
|
def apply_firmware(client, bdev_name, filename):
|
|
|
|
"""Download and commit firmware to NVMe device.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
bdev_name: name of NVMe block device
|
|
|
|
filename: filename of the firmware to download
|
|
|
|
"""
|
2017-06-06 21:22:03 +00:00
|
|
|
params = {
|
2018-05-21 20:28:21 +00:00
|
|
|
'filename': filename,
|
|
|
|
'bdev_name': bdev_name,
|
2017-06-06 21:22:03 +00:00
|
|
|
}
|
2018-03-27 21:31:52 +00:00
|
|
|
return client.call('apply_nvme_firmware', params)
|