bdev/rbd: add ceph rbd resize function

This is to backport below change to SPDK v20.01.2 LTS release.
6a29c6a906

Change-Id: I9b7ed97f2a376af71578ccb5556231832863b255
Signed-off-by: Liang Yan <liang.z.yan@intel.com>
Signed-off-by: GangCao <gang.cao@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/2262
Tested-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
GangCao 2020-05-07 14:25:21 -04:00 committed by Tomasz Zawadzki
parent d4d3e76aed
commit a7f7b1955e
9 changed files with 187 additions and 0 deletions

View File

@ -153,6 +153,8 @@ A new RPC, `framework_get_reactors`, has been added to retrieve a list of all re
`nvmf_set_config` now takes an argument to enable passthru of identify commands to base NVMe devices.
Please see the nvmf section above for more details.
A new RPC, `bdev_rbd_resize` has been added to resize the Ceph RBD bdev.
### scsi
`spdk_scsi_lun_get_dif_ctx` now takes an additional argument of type `spdk_scsi_task`.

View File

@ -119,6 +119,12 @@ To remove a block device representation use the bdev_rbd_delete command.
`rpc.py bdev_rbd_delete Rbd0`
To resize a bdev use the bdev_rbd_resize command.
`rpc.py bdev_rbd_resize Rbd0 4096`
This command will resize the Rbd0 bdev to 4096 MiB.
# Compression Virtual Bdev Module {#bdev_config_compress}
The compression bdev module can be configured to provide compression/decompression

View File

@ -1853,6 +1853,49 @@ Example response:
}
~~~
## bdev_rbd_resize {#rpc_bdev_rbd_resize}
Resize @ref bdev_config_rbd bdev
This method is available only if SPDK was build with Ceph RBD support.
### Result
`true` if bdev with provided name was resized or `false` otherwise.
### Parameters
Name | Optional | Type | Description
----------------------- | -------- | ----------- | -----------
name | Required | string | Bdev name
new_size | Required | int | New bdev size for resize operation in MiB
### Example
Example request:
~~~
{
"params": {
"name": "Rbd0"
"new_size": "4096"
},
"jsonrpc": "2.0",
"method": "bdev_rbd_resize",
"id": 1
}
~~~
Example response:
~~~
{
"jsonrpc": "2.0",
"id": 1,
"result": true
}
~~~
## bdev_delay_create {#rpc_bdev_delay_create}
Create delay bdev. This bdev type redirects all IO to it's base bdev and inserts a delay on the completion

View File

@ -783,6 +783,44 @@ spdk_bdev_rbd_delete(struct spdk_bdev *bdev, spdk_delete_rbd_complete cb_fn, voi
spdk_bdev_unregister(bdev, cb_fn, cb_arg);
}
int
spdk_bdev_rbd_resize(struct spdk_bdev *bdev, const uint64_t new_size_in_mb)
{
struct spdk_io_channel *ch;
struct bdev_rbd_io_channel *rbd_io_ch;
int rc;
uint64_t new_size_in_byte;
uint64_t current_size_in_mb;
if (bdev->module != &rbd_if) {
return -EINVAL;
}
current_size_in_mb = bdev->blocklen * bdev->blockcnt / (1024 * 1024);
if (current_size_in_mb > new_size_in_mb) {
SPDK_ERRLOG("The new bdev size must be lager than current bdev size.\n");
return -EINVAL;
}
ch = bdev_rbd_get_io_channel(bdev);
rbd_io_ch = spdk_io_channel_get_ctx(ch);
new_size_in_byte = new_size_in_mb * 1024 * 1024;
rc = rbd_resize(rbd_io_ch->image, new_size_in_byte);
if (rc != 0) {
SPDK_ERRLOG("failed to resize the ceph bdev.\n");
return rc;
}
rc = spdk_bdev_notify_blockcnt_change(bdev, new_size_in_byte / bdev->blocklen);
if (rc != 0) {
SPDK_ERRLOG("failed to notify block cnt change.\n");
return rc;
}
return rc;
}
static int
bdev_rbd_library_init(void)
{

View File

@ -57,4 +57,12 @@ int spdk_bdev_rbd_create(struct spdk_bdev **bdev, const char *name, const char *
void spdk_bdev_rbd_delete(struct spdk_bdev *bdev, spdk_delete_rbd_complete cb_fn,
void *cb_arg);
/**
* Resize rbd bdev.
*
* \param bdev Pointer to rbd bdev.
* \param new_size_in_mb The new size in MiB for this bdev.
*/
int spdk_bdev_rbd_resize(struct spdk_bdev *bdev, const uint64_t new_size_in_mb);
#endif /* SPDK_BDEV_RBD_H */

View File

@ -197,3 +197,56 @@ cleanup:
}
SPDK_RPC_REGISTER("bdev_rbd_delete", spdk_rpc_bdev_rbd_delete, SPDK_RPC_RUNTIME)
SPDK_RPC_REGISTER_ALIAS_DEPRECATED(bdev_rbd_delete, delete_rbd_bdev)
struct rpc_bdev_rbd_resize {
char *name;
uint64_t new_size;
};
static const struct spdk_json_object_decoder rpc_bdev_rbd_resize_decoders[] = {
{"name", offsetof(struct rpc_bdev_rbd_resize, name), spdk_json_decode_string},
{"new_size", offsetof(struct rpc_bdev_rbd_resize, new_size), spdk_json_decode_uint64}
};
static void
free_rpc_bdev_rbd_resize(struct rpc_bdev_rbd_resize *req)
{
free(req->name);
}
static void
spdk_rpc_bdev_rbd_resize(struct spdk_jsonrpc_request *request,
const struct spdk_json_val *params)
{
struct rpc_bdev_rbd_resize req = {};
struct spdk_bdev *bdev;
struct spdk_json_write_ctx *w;
int rc;
if (spdk_json_decode_object(params, rpc_bdev_rbd_resize_decoders,
SPDK_COUNTOF(rpc_bdev_rbd_resize_decoders),
&req)) {
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
"spdk_json_decode_object failed");
goto cleanup;
}
bdev = spdk_bdev_get_by_name(req.name);
if (bdev == NULL) {
spdk_jsonrpc_send_error_response(request, -ENODEV, spdk_strerror(ENODEV));
goto cleanup;
}
rc = spdk_bdev_rbd_resize(bdev, req.new_size);
if (rc) {
spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc));
goto cleanup;
}
w = spdk_jsonrpc_begin_result(request);
spdk_json_write_bool(w, true);
spdk_jsonrpc_end_result(request, w);
cleanup:
free_rpc_bdev_rbd_resize(&req);
}
SPDK_RPC_REGISTER("bdev_rbd_resize", spdk_rpc_bdev_rbd_resize, SPDK_RPC_RUNTIME)

View File

@ -541,6 +541,20 @@ if __name__ == "__main__":
p.add_argument('name', help='rbd bdev name')
p.set_defaults(func=bdev_rbd_delete)
def bdev_rbd_resize(args):
print_json(rpc.bdev.bdev_rbd_resize(args.client,
name=args.name,
new_size=int(args.new_size)))
rpc.bdev.bdev_rbd_resize(args.client,
name=args.name,
new_size=int(args.new_size))
p = subparsers.add_parser('bdev_rbd_resize',
help='Resize a rbd bdev')
p.add_argument('name', help='rbd bdev name')
p.add_argument('new_size', help='new bdev size for resize operation. The unit is MiB')
p.set_defaults(func=bdev_rbd_resize)
def bdev_delay_create(args):
print_json(rpc.bdev.bdev_delay_create(args.client,
base_bdev_name=args.base_bdev_name,

View File

@ -585,6 +585,20 @@ def bdev_rbd_delete(client, name):
return client.call('bdev_rbd_delete', params)
def bdev_rbd_resize(client, name, new_size):
"""Resize rbd bdev in the system.
Args:
name: name of rbd bdev to resize
new_size: new bdev size of resize operation. The unit is MiB
"""
params = {
'name': name,
'new_size': new_size,
}
return client.call('bdev_rbd_resize', params)
@deprecated_alias('construct_error_bdev')
def bdev_error_create(client, base_name):
"""Construct an error injection block device.

View File

@ -40,6 +40,15 @@ $rpc_py iscsi_create_portal_group $PORTAL_TAG $TARGET_IP:$ISCSI_PORT
$rpc_py iscsi_create_initiator_group $INITIATOR_TAG $INITIATOR_NAME $NETMASK
rbd_bdev="$($rpc_py bdev_rbd_create $RBD_POOL $RBD_NAME 4096)"
$rpc_py bdev_get_bdevs
$rpc_py bdev_rbd_resize $rbd_bdev 2000
num_block=$($rpc_py bdev_get_bdevs|grep num_blocks|sed 's/[^[:digit:]]//g')
# get the bdev size in MiB.
total_size=$(( num_block * 4096/ 1048576 ))
if [ $total_size != 2000 ];then
echo "resize failed."
exit 1
fi
# "Ceph0:0" ==> use Ceph0 blockdev for LUN0
# "1:2" ==> map PortalGroup1 to InitiatorGroup2
# "64" ==> iSCSI queue depth 64