bdev/raid0: Support resize when increasing the size of base bdevs
Implement the resize function for RAID0. raid0_resize() calculate the new raid_bdev's block count and if it is different from the old block count, call spdk_bdev_notify_blockcnt_change() with the new block count. A raid0 bdev always opens all base bdevs. Hence, if the size of base bdevs are reduced, resize fails now. This limitation will be removed later. Add a simple functional test for this feature. The test is to create a raid0 bdev with two null bdevs, resize one null bdev, check if the raid0 bdev is not resize, resize another null bdev, check if the raid0 bdev is resized. test/iscsi_tgt/resize/resize.sh was used a reference to write the test. Using jq rather than grep&sed is better and hence replace grep&sed by jq of test/iscsi_tgt/resize/resize.sh together in this patch. Signed-off-by: Shuhei Matsumoto <smatsumoto@nvidia.com> Change-Id: I07136648c4189b970843fc6da51ff40355423144 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16261 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com> Reviewed-by: Aleksey Marchuk <alexeymar@nvidia.com> Reviewed-by: Xiaodong Liu <xiaodong.liu@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
c6d73b5aaf
commit
c22b052b60
@ -384,12 +384,36 @@ raid0_start(struct raid_bdev *raid_bdev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
raid0_resize(struct raid_bdev *raid_bdev)
|
||||||
|
{
|
||||||
|
uint64_t blockcnt;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
blockcnt = raid0_calculate_blockcnt(raid_bdev);
|
||||||
|
|
||||||
|
if (blockcnt == raid_bdev->bdev.blockcnt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDK_NOTICELOG("raid0 '%s': min blockcount was changed from %" PRIu64 " to %" PRIu64 "\n",
|
||||||
|
raid_bdev->bdev.name,
|
||||||
|
raid_bdev->bdev.blockcnt,
|
||||||
|
blockcnt);
|
||||||
|
|
||||||
|
rc = spdk_bdev_notify_blockcnt_change(&raid_bdev->bdev, blockcnt);
|
||||||
|
if (rc != 0) {
|
||||||
|
SPDK_ERRLOG("Failed to notify blockcount change\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct raid_bdev_module g_raid0_module = {
|
static struct raid_bdev_module g_raid0_module = {
|
||||||
.level = RAID0,
|
.level = RAID0,
|
||||||
.base_bdevs_min = 1,
|
.base_bdevs_min = 1,
|
||||||
.start = raid0_start,
|
.start = raid0_start,
|
||||||
.submit_rw_request = raid0_submit_rw_request,
|
.submit_rw_request = raid0_submit_rw_request,
|
||||||
.submit_null_payload_request = raid0_submit_null_payload_request,
|
.submit_null_payload_request = raid0_submit_null_payload_request,
|
||||||
|
.resize = raid0_resize,
|
||||||
};
|
};
|
||||||
RAID_MODULE_REGISTER(&g_raid0_module)
|
RAID_MODULE_REGISTER(&g_raid0_module)
|
||||||
|
|
||||||
|
@ -247,11 +247,57 @@ function raid_state_function_test() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function raid0_resize_test() {
|
||||||
|
local blksize=512
|
||||||
|
local bdev_size_mb=32
|
||||||
|
local new_bdev_size_mb=$((bdev_size_mb * 2))
|
||||||
|
local blkcnt
|
||||||
|
local raid_size_mb
|
||||||
|
local new_raid_size_mb
|
||||||
|
|
||||||
|
$rootdir/test/app/bdev_svc/bdev_svc -r $rpc_server -i 0 -L bdev_raid &
|
||||||
|
raid_pid=$!
|
||||||
|
echo "Process raid pid: $raid_pid"
|
||||||
|
waitforlisten $raid_pid $rpc_server
|
||||||
|
|
||||||
|
$rpc_py bdev_null_create Base_1 $bdev_size_mb $blksize
|
||||||
|
$rpc_py bdev_null_create Base_2 $bdev_size_mb $blksize
|
||||||
|
|
||||||
|
$rpc_py bdev_raid_create -z 64 -r 0 -b "Base_1 Base_2" -n Raid
|
||||||
|
|
||||||
|
# Resize Base_1 first.
|
||||||
|
$rpc_py bdev_null_resize Base_1 $new_bdev_size_mb
|
||||||
|
|
||||||
|
# The size of Raid should not be changed.
|
||||||
|
blkcnt=$($rpc_py bdev_get_bdevs -b Raid | jq '.[].num_blocks')
|
||||||
|
raid_size_mb=$((blkcnt * blksize / 1048576))
|
||||||
|
if [ $raid_size_mb != $((bdev_size_mb * 2)) ]; then
|
||||||
|
echo "resize failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resize Base_2 next.
|
||||||
|
$rpc_py bdev_null_resize Base_2 $new_bdev_size_mb
|
||||||
|
|
||||||
|
# The size of Raid should be updated to the expected value.
|
||||||
|
blkcnt=$($rpc_py bdev_get_bdevs -b Raid | jq '.[].num_blocks')
|
||||||
|
raid_size_mb=$((blkcnt * blksize / 1048576))
|
||||||
|
if [ $raid_size_mb != $((new_bdev_size_mb * 2)) ]; then
|
||||||
|
echo "resize failed"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
killprocess $raid_pid
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
trap 'on_error_exit;' ERR
|
trap 'on_error_exit;' ERR
|
||||||
|
|
||||||
raid_function_test raid0
|
raid_function_test raid0
|
||||||
raid_function_test concat
|
raid_function_test concat
|
||||||
raid_state_function_test raid0
|
raid_state_function_test raid0
|
||||||
raid_state_function_test concat
|
raid_state_function_test concat
|
||||||
|
raid0_resize_test
|
||||||
|
|
||||||
rm -f $tmp_file
|
rm -f $tmp_file
|
||||||
|
@ -49,7 +49,7 @@ waitforlisten $bdevperf_pid $RESIZE_SOCK
|
|||||||
# Resize the Bdev from iSCSI target
|
# Resize the Bdev from iSCSI target
|
||||||
$rpc_py bdev_null_resize Null0 $BDEV_NEW_SIZE
|
$rpc_py bdev_null_resize Null0 $BDEV_NEW_SIZE
|
||||||
# Obtain the Bdev from bdevperf with iSCSI initiator
|
# Obtain the Bdev from bdevperf with iSCSI initiator
|
||||||
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | grep num_blocks | sed 's/[^[:digit:]]//g')
|
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | jq '.[].num_blocks')
|
||||||
# Size is not changed as no IO sent yet and resize notification is deferred.
|
# Size is not changed as no IO sent yet and resize notification is deferred.
|
||||||
total_size=$((num_block * BLOCK_SIZE / 1048576))
|
total_size=$((num_block * BLOCK_SIZE / 1048576))
|
||||||
if [ $total_size != $BDEV_SIZE ]; then
|
if [ $total_size != $BDEV_SIZE ]; then
|
||||||
@ -60,7 +60,7 @@ sleep 2
|
|||||||
# Start the bdevperf IO
|
# Start the bdevperf IO
|
||||||
$rootdir/examples/bdev/bdevperf/bdevperf.py -s $RESIZE_SOCK perform_tests
|
$rootdir/examples/bdev/bdevperf/bdevperf.py -s $RESIZE_SOCK perform_tests
|
||||||
# Obtain the Bdev from bdevperf with iSCSI initiator
|
# Obtain the Bdev from bdevperf with iSCSI initiator
|
||||||
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | grep num_blocks | sed 's/[^[:digit:]]//g')
|
num_block=$($rpc_py -s $RESIZE_SOCK bdev_get_bdevs | jq '.[].num_blocks')
|
||||||
# Get the new bdev size in MiB.
|
# Get the new bdev size in MiB.
|
||||||
total_size=$((num_block * BLOCK_SIZE / 1048576))
|
total_size=$((num_block * BLOCK_SIZE / 1048576))
|
||||||
if [ $total_size != $BDEV_NEW_SIZE ]; then
|
if [ $total_size != $BDEV_NEW_SIZE ]; then
|
||||||
|
@ -120,6 +120,7 @@ DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), f
|
|||||||
DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
|
DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev),
|
||||||
SPDK_DIF_DISABLE);
|
SPDK_DIF_DISABLE);
|
||||||
DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
|
DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false);
|
||||||
|
DEFINE_STUB(spdk_bdev_notify_blockcnt_change, int, (struct spdk_bdev *bdev, uint64_t size), 0);
|
||||||
|
|
||||||
struct spdk_io_channel *
|
struct spdk_io_channel *
|
||||||
spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
|
spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)
|
||||||
|
Loading…
Reference in New Issue
Block a user