Commit 2a1b861b authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Jim Harris
Browse files

raid: allow re-adding base bdev when in CONFIGURING state



When a base bdev is removed from a raid bdev in CONFIGURING state, make
it possible to add it back.

Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Change-Id: Iaced5234c62015b4a7115f246fd387b556d81146
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22497


Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 8aa7730c
Loading
Loading
Loading
Loading
+23 −15
Original line number Diff line number Diff line
@@ -3236,12 +3236,28 @@ raid_bdev_add_base_bdev(struct raid_bdev *raid_bdev, const char *name,
		return -EPERM;
	}

	if (raid_bdev->state == RAID_BDEV_STATE_CONFIGURING) {
		struct spdk_bdev *bdev = spdk_bdev_get_by_name(name);

		if (bdev != NULL) {
			RAID_FOR_EACH_BASE_BDEV(raid_bdev, iter) {
				if (iter->name == NULL &&
				    spdk_uuid_compare(&bdev->uuid, &iter->uuid) == 0) {
					base_info = iter;
					break;
				}
			}
		}
	}

	if (base_info == NULL || raid_bdev->state == RAID_BDEV_STATE_ONLINE) {
		RAID_FOR_EACH_BASE_BDEV(raid_bdev, iter) {
		if (iter->name == NULL) {
			if (iter->name == NULL && spdk_uuid_is_null(&iter->uuid)) {
				base_info = iter;
				break;
			}
		}
	}

	if (base_info == NULL) {
		SPDK_ERRLOG("no empty slot found in raid bdev '%s' for new base bdev '%s'\n",
@@ -3256,15 +3272,6 @@ raid_bdev_add_base_bdev(struct raid_bdev *raid_bdev, const char *name,
		assert(base_info->desc == NULL);
	}

	if (!spdk_uuid_is_null(&base_info->uuid)) {
		char uuid_str[SPDK_UUID_STRING_LEN];

		spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &base_info->uuid);
		SPDK_ERRLOG("Slot %u on raid bdev '%s' already assigned to bdev with uuid %s\n",
			    raid_bdev_base_bdev_slot(base_info), raid_bdev->bdev.name, uuid_str);
		return -EBUSY;
	}

	base_info->name = strdup(name);
	if (base_info->name == NULL) {
		return -ENOMEM;
@@ -3334,8 +3341,9 @@ raid_bdev_examine_no_sb(struct spdk_bdev *bdev)
			continue;
		}
		RAID_FOR_EACH_BASE_BDEV(raid_bdev, base_info) {
			if (base_info->desc == NULL && base_info->name != NULL &&
			    strcmp(bdev->name, base_info->name) == 0) {
			if (base_info->desc == NULL &&
			    ((base_info->name != NULL && strcmp(bdev->name, base_info->name) == 0) ||
			     spdk_uuid_compare(&base_info->uuid, &bdev->uuid) == 0)) {
				raid_bdev_configure_base_bdev(base_info, true, NULL, NULL);
				break;
			}
+42 −0
Original line number Diff line number Diff line
@@ -304,6 +304,48 @@ function raid_state_function_test() {
		return 1
	fi

	if [ $num_base_bdevs -gt 2 ]; then
		# Test removing and re-adding base bdevs when in CONFIGURING state
		for ((i = 1; i < num_base_bdevs; i++)); do
			$rpc_py bdev_malloc_create 32 $base_blocklen $base_malloc_params -b ${base_bdevs[$i]}
			waitforbdev ${base_bdevs[$i]}
		done
		$rpc_py bdev_raid_create $strip_size_create_arg $superblock_create_arg -r $raid_level -b "${base_bdevs[*]}" -n $raid_bdev_name
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs

		$rpc_py bdev_raid_remove_base_bdev ${base_bdevs[1]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[1].is_configured') == "false" ]]

		$rpc_py bdev_malloc_create 32 $base_blocklen $base_malloc_params -b ${base_bdevs[0]}
		waitforbdev ${base_bdevs[0]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[0].is_configured') == "true" ]]

		$rpc_py bdev_raid_remove_base_bdev ${base_bdevs[2]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[2].is_configured') == "false" ]]

		$rpc_py bdev_raid_add_base_bdev $raid_bdev_name ${base_bdevs[2]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[2].is_configured') == "true" ]]

		$rpc_py bdev_malloc_delete ${base_bdevs[0]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[0].is_configured') == "false" ]]

		$rpc_py bdev_raid_add_base_bdev $raid_bdev_name ${base_bdevs[1]}
		verify_raid_bdev_state $raid_bdev_name "configuring" $raid_level $strip_size $num_base_bdevs
		[[ $($rpc_py bdev_raid_get_bdevs all | jq '.[0].base_bdevs_list[1].is_configured') == "true" ]]

		$rpc_py bdev_malloc_create 32 $base_blocklen $base_malloc_params -b NewBaseBdev -u "$($rpc_py bdev_raid_get_bdevs all | jq -r '.[0].base_bdevs_list[0].uuid')"
		waitforbdev NewBaseBdev
		verify_raid_bdev_state $raid_bdev_name "online" $raid_level $strip_size $num_base_bdevs
		verify_raid_bdev_properties $raid_bdev_name

		$rpc_py bdev_raid_delete $raid_bdev_name
	fi

	killprocess $raid_pid

	return 0