From e7038ab99cb84fe6561fcd2c60f0fa43db51e079 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Wed, 6 Nov 2024 01:04:05 +0300 Subject: [PATCH] Auto-change partition paths to /dev/disk/by-partuuid/ --- src/disk_tool/disk_tool.h | 6 ++-- src/disk_tool/disk_tool_prepare.cpp | 16 ++++------- src/disk_tool/disk_tool_resize_auto.cpp | 22 ++++---------- src/disk_tool/disk_tool_utils.cpp | 38 ++++++++++++++++++++----- 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/disk_tool/disk_tool.h b/src/disk_tool/disk_tool.h index 287432f1..1a2e26cc 100644 --- a/src/disk_tool/disk_tool.h +++ b/src/disk_tool/disk_tool.h @@ -128,8 +128,8 @@ struct disk_tool_t uint32_t write_osd_superblock(std::string device, json11::Json params); int prepare_one(std::map options, int is_hdd = -1); - int check_existing_partition(const std::string & dev); - int fix_partition_type(const std::string & dev_by_uuid); + int check_existing_partition(std::string & dev_by_uuid); + int fix_partition_type(std::string & dev_by_uuid); int prepare(std::vector devices); std::vector collect_devices(const std::vector & devices); json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector sizes); @@ -151,6 +151,6 @@ int write_zero(int fd, uint64_t offset, uint64_t size); json11::Json read_parttable(std::string dev); uint64_t dev_size_from_parttable(json11::Json pt); uint64_t free_from_parttable(json11::Json pt); -int fix_partition_type_uuid(std::string dev_by_uuid, const std::string & type_uuid); +int fix_partition_type_uuid(std::string & dev_by_uuid, const std::string & type_uuid); std::string csum_type_str(uint32_t data_csum_type); uint32_t csum_type_from_str(std::string data_csum_type); diff --git a/src/disk_tool/disk_tool_prepare.cpp b/src/disk_tool/disk_tool_prepare.cpp index 1447d822..31bbd9dc 100644 --- a/src/disk_tool/disk_tool_prepare.cpp +++ b/src/disk_tool/disk_tool_prepare.cpp @@ -29,18 +29,12 @@ int disk_tool_t::prepare_one(std::map options, int is_ }; if (options.find("force") == options.end()) { - std::vector all_devs = { options["data_device"], options["meta_device"], options["journal_device"] }; - for (int i = 0; i < all_devs.size(); i++) + std::string* all_devs[] = { &options["data_device"], &options["meta_device"], &options["journal_device"] }; + for (int i = 0; i < 3; i++) { - const auto & dev = all_devs[i]; + auto & dev = *all_devs[i]; if (dev == "") continue; - if (dev.substr(0, 22) != "/dev/disk/by-partuuid/") - { - // Partitions should be identified by GPT partition UUID - fprintf(stderr, "%s does not start with /dev/disk/by-partuuid/. Partitions should be identified by GPT partition UUIDs\n", dev.c_str()); - return 1; - } std::string real_dev = realpath_str(dev, false); if (real_dev == "") return 1; @@ -214,7 +208,7 @@ int disk_tool_t::prepare_one(std::map options, int is_ return 0; } -int disk_tool_t::check_existing_partition(const std::string & dev) +int disk_tool_t::check_existing_partition(std::string & dev) { std::string out; if (shell_exec({ "wipefs", dev }, "", &out, NULL) != 0 || out != "") @@ -236,7 +230,7 @@ int disk_tool_t::check_existing_partition(const std::string & dev) return 0; } -int disk_tool_t::fix_partition_type(const std::string & dev) +int disk_tool_t::fix_partition_type(std::string & dev) { std::string type_uuid = VITASTOR_PART_TYPE; if (test_mode && options.find("part_type_uuid") != options.end()) diff --git a/src/disk_tool/disk_tool_resize_auto.cpp b/src/disk_tool/disk_tool_resize_auto.cpp index 723b56cf..1c9dd56f 100644 --- a/src/disk_tool/disk_tool_resize_auto.cpp +++ b/src/disk_tool/disk_tool_resize_auto.cpp @@ -192,17 +192,12 @@ int disk_tool_t::resize_parse_move_journal(std::map & else options["move_journal"] = ""; } - else if (options["move_journal"].substr(0, 22) != "/dev/disk/by-partuuid/") - { - // Partitions should be identified by GPT partition UUID - fprintf(stderr, "%s does not start with /dev/disk/by-partuuid/. Partitions should be identified by GPT partition UUIDs\n", options["move_journal"].c_str()); - return 1; - } else { // already a partition - check that it's a GPT partition with correct type - if (options.find("force") == options.end() && - check_existing_partition(real_dev) != 0) + if ((options.find("force") == options.end() + ? check_existing_partition(options["move_journal"]) + : fix_partition_type(options["move_journal"])) != 0) { return 1; } @@ -273,17 +268,12 @@ int disk_tool_t::resize_parse_move_meta(std::map & mov else options["move_meta"] = ""; } - else if (options["move_meta"].substr(0, 22) != "/dev/disk/by-partuuid/") - { - // Partitions should be identified by GPT partition UUID - fprintf(stderr, "%s does not start with /dev/disk/by-partuuid/. Partitions should be identified by GPT partition UUIDs\n", options["move_meta"].c_str()); - return 1; - } else { // already a partition - check that it's a GPT partition with correct type - if (options.find("force") == options.end() && - check_existing_partition(real_dev) != 0) + if ((options.find("force") == options.end() + ? check_existing_partition(options["move_meta"]) + : fix_partition_type(options["move_meta"])) != 0) { return 1; } diff --git a/src/disk_tool/disk_tool_utils.cpp b/src/disk_tool/disk_tool_utils.cpp index 28318077..c0f33672 100644 --- a/src/disk_tool/disk_tool_utils.cpp +++ b/src/disk_tool/disk_tool_utils.cpp @@ -343,23 +343,42 @@ uint64_t free_from_parttable(json11::Json pt) return free; } -int fix_partition_type_uuid(std::string dev_by_uuid, const std::string & type_uuid) +int fix_partition_type_uuid(std::string & dev_by_uuid, const std::string & type_uuid) { - auto uuid = strtolower(dev_by_uuid.substr(dev_by_uuid.rfind('/')+1)); - std::string parent_dev = get_parent_device(realpath_str(dev_by_uuid, false)); + bool is_partuuid = dev_by_uuid.substr(0, 22) == "/dev/disk/by-partuuid/"; + auto uuid = is_partuuid ? strtolower(dev_by_uuid.substr(22)) : ""; + auto node = realpath_str(dev_by_uuid, false); + std::string parent_dev = get_parent_device(node); if (parent_dev == "") return 1; auto pt = read_parttable(parent_dev); if (pt.is_null() || pt.is_bool()) return 1; + bool found = false; std::string script = "label: gpt\n\n"; for (const auto & part: pt["partitions"].array_items()) { - bool this_part = (strtolower(part["uuid"].string_value()) == uuid); - if (this_part && strtolower(part["type"].string_value()) == type_uuid) + bool this_part = (part["node"].string_value() == node) && + (!is_partuuid || strtolower(part["uuid"].string_value()) == uuid); + if (this_part) { - // Already correct type - return 0; + found = true; + if (!is_partuuid) + { + if (part["uuid"] == "") + { + fprintf(stderr, "Could not determine partition UUID for %s. Please use GPT partitions\n", dev_by_uuid.c_str()); + return 1; + } + auto new_dev = "/dev/disk/by-partuuid/"+strtolower(part["uuid"].string_value()); + fprintf(stderr, "Using %s instead of %s\n", new_dev.c_str(), dev_by_uuid.c_str()); + dev_by_uuid = new_dev; + } + if (strtolower(part["type"].string_value()) == type_uuid) + { + // Already correct type + return 0; + } } script += part["node"].string_value()+": "; bool first = true; @@ -376,6 +395,11 @@ int fix_partition_type_uuid(std::string dev_by_uuid, const std::string & type_uu } script += "\n"; } + if (!found) + { + fprintf(stderr, "Could not find partition table entry for %s\n", dev_by_uuid.c_str()); + return 1; + } std::string out; return shell_exec({ "sfdisk", "--no-reread", "--no-tell-kernel", "--force", parent_dev }, script, &out, NULL); }