diff --git a/CHANGELOG.md b/CHANGELOG.md index bb9e045bb..00687802d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ multiple readers. New function `spdk_env_get_main_core` was added. +### gpt + +GPT bdevs now use the GPT Unique Partition ID as the bdev's UUID. + ### lvol New API `spdk_lvol_iter_immediate_clones` was added to iterate the clones of an lvol. diff --git a/module/bdev/gpt/vbdev_gpt.c b/module/bdev/gpt/vbdev_gpt.c index 785efedaa..fa364844e 100644 --- a/module/bdev/gpt/vbdev_gpt.c +++ b/module/bdev/gpt/vbdev_gpt.c @@ -219,6 +219,29 @@ vbdev_gpt_submit_request(struct spdk_io_channel *_ch, struct spdk_bdev_io *bdev_ } } +static void +gpt_guid_to_uuid(const struct spdk_gpt_guid *guid, struct spdk_uuid *uuid) +{ +#pragma pack(push, 1) + struct tmp_uuid { + uint32_t b0; + uint16_t b4; + uint16_t b6; + uint16_t b8; + uint16_t b10; + uint32_t b12; + } *ret = (struct tmp_uuid *)uuid; +#pragma pack(pop) + SPDK_STATIC_ASSERT(sizeof(*ret) == sizeof(*uuid), "wrong size"); + + ret->b0 = from_be32(&guid->raw[0]); + ret->b4 = from_be16(&guid->raw[4]); + ret->b6 = from_be16(&guid->raw[6]); + ret->b8 = from_le16(&guid->raw[8]); + ret->b10 = from_le16(&guid->raw[10]); + ret->b12 = from_le32(&guid->raw[12]); +} + static void write_guid(struct spdk_json_write_ctx *w, const struct spdk_gpt_guid *guid) { @@ -315,6 +338,7 @@ vbdev_gpt_create_bdevs(struct gpt_base *gpt_base) uint64_t lba_start = from_le64(&p->starting_lba); uint64_t lba_end = from_le64(&p->ending_lba); uint64_t partition_size = lba_end - lba_start + 1; + struct spdk_bdev_part_construct_opts opts; if (lba_start == 0) { continue; @@ -353,8 +377,10 @@ vbdev_gpt_create_bdevs(struct gpt_base *gpt_base) return -1; } - rc = spdk_bdev_part_construct(&d->part, gpt_base->part_base, name, - lba_start, partition_size, "GPT Disk"); + spdk_bdev_part_construct_opts_init(&opts, sizeof(opts)); + gpt_guid_to_uuid(&p->unique_partition_guid, &opts.uuid); + rc = spdk_bdev_part_construct_ext(&d->part, gpt_base->part_base, name, lba_start, + partition_size, "GPT Disk", &opts); free(name); if (rc) { SPDK_ERRLOG("could not construct bdev part\n"); diff --git a/test/bdev/blockdev.sh b/test/bdev/blockdev.sh index 25ff4d764..25ac403b5 100755 --- a/test/bdev/blockdev.sh +++ b/test/bdev/blockdev.sh @@ -117,13 +117,20 @@ function setup_gpt_conf() { fi done if [[ -n $gpt_nvme ]]; then + # These Unique Partition GUIDs were randomly generated for testing and are distinct + # from the Partition Type GUIDs (SPDK_GPT_OLD_GUID and SPDK_GPT_GUID) which have + # special meaning to SPDK. See section 5.3.3 of UEFI Spec 2.3 for the distinction + # between Unique Partition GUID and Partition Type GUID. + typeset -g g_unique_partguid=6f89f330-603b-4116-ac73-2ca8eae53030 + typeset -g g_unique_partguid_old=abf1734f-66e5-4c0f-aa29-4021d4d307df + # Create gpt partition table parted -s "$gpt_nvme" mklabel gpt mkpart SPDK_TEST_first '0%' '50%' mkpart SPDK_TEST_second '50%' '100%' # Change the partition type GUIDs to SPDK partition type values SPDK_GPT_OLD_GUID=$(get_spdk_gpt_old) SPDK_GPT_GUID=$(get_spdk_gpt) - sgdisk -t "1:$SPDK_GPT_GUID" "$gpt_nvme" - sgdisk -t "2:$SPDK_GPT_OLD_GUID" "$gpt_nvme" + sgdisk -t "1:$SPDK_GPT_GUID" -u "1:$g_unique_partguid" "$gpt_nvme" + sgdisk -t "2:$SPDK_GPT_OLD_GUID" -u "2:$g_unique_partguid_old" "$gpt_nvme" "$rootdir/scripts/setup.sh" "$rpc_py" bdev_get_bdevs setup_nvme_conf @@ -609,6 +616,27 @@ function stat_test_suite() { trap - SIGINT SIGTERM EXIT } +function bdev_gpt_uuid() { + local bdev + + start_spdk_tgt + + "$rpc_py" load_config -j "$conf_file" + "$rpc_py" bdev_wait_for_examine + + bdev=$("$rpc_py" bdev_get_bdevs -b "$g_unique_partguid") + [[ "$(jq -r 'length' <<< "$bdev")" == "1" ]] + [[ "$(jq -r '.[0].aliases[0]' <<< "$bdev")" == "$g_unique_partguid" ]] + [[ "$(jq -r '.[0].driver_specific.gpt.unique_partition_guid' <<< "$bdev")" == "$g_unique_partguid" ]] + + bdev=$("$rpc_py" bdev_get_bdevs -b "$g_unique_partguid_old") + [[ "$(jq -r 'length' <<< "$bdev")" == "1" ]] + [[ "$(jq -r '.[0].aliases[0]' <<< "$bdev")" == "$g_unique_partguid_old" ]] + [[ "$(jq -r '.[0].driver_specific.gpt.unique_partition_guid' <<< "$bdev")" == "$g_unique_partguid_old" ]] + + killprocess "$spdk_tgt_pid" +} + # Initial bdev creation and configuration #----------------------------------------------------- QOS_DEV_1="Malloc_0" @@ -743,6 +771,10 @@ if [[ $test_type == bdev ]]; then run_test "bdev_stat" stat_test_suite "$env_ctx" fi +if [[ $test_type == gpt ]]; then + run_test "bdev_gpt_uuid" bdev_gpt_uuid +fi + # Temporarily disabled - infinite loop # if [ $RUN_NIGHTLY -eq 1 ]; then # run_test "bdev_reset" $rootdir/build/examples/bdevperf --json "$conf_file" -q 16 -w reset -o 4096 -t 60 "$env_ctx"