From c0d5e83fb8f5b8f8a8908054b1639f95afb79e93 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Thu, 18 Aug 2022 02:05:16 +0300 Subject: [PATCH] Run partprobe when partitions do not appear --- src/disk_tool.cpp | 2 +- src/disk_tool_prepare.cpp | 45 ++++++++++++++++++++++++++++++++++----- src/disk_tool_upgrade.cpp | 2 +- src/disk_tool_utils.cpp | 4 ++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/disk_tool.cpp b/src/disk_tool.cpp index 9efede1e..ba9e678f 100644 --- a/src/disk_tool.cpp +++ b/src/disk_tool.cpp @@ -18,7 +18,7 @@ static const char *help_text = " In the second form, you omit and pass --data_device, --journal_device\n" " and/or --meta_device which must be already existing partitions. In this case\n" " a single OSD is created.\n" - " Requires `vitastor-cli`, `blkid` and `sfdisk` utilities.\n" + " Requires `vitastor-cli`, `blkid`, `sfdisk` and `partprobe` (from parted) utilities.\n" " OPTIONS may include:\n" " --hybrid\n" " Prepare hybrid (HDD+SSD) OSDs using provided devices. SSDs will be used for\n" diff --git a/src/disk_tool_prepare.cpp b/src/disk_tool_prepare.cpp index ee888770..69ed22fe 100644 --- a/src/disk_tool_prepare.cpp +++ b/src/disk_tool_prepare.cpp @@ -44,7 +44,7 @@ int disk_tool_t::prepare_one(std::map options, int is_ if (i == 0 && is_hdd == -1) is_hdd = read_file("/sys/block/"+parent_dev+"/queue/rotational") == "1"; std::string out; - if (shell_exec({ "/sbin/blkid", "-D", "-p", dev }, "", &out, NULL) == 0) + if (shell_exec({ "blkid", "-D", "-p", dev }, "", &out, NULL) == 0) { fprintf(stderr, "%s contains data, not creating OSD without --force. blkid -D -p says:\n%s", dev.c_str(), out.c_str()); return 1; @@ -202,7 +202,7 @@ std::vector disk_tool_t::collect_devices(const std::vector< { // No partition table std::string out; - int r = shell_exec({ "/sbin/blkid", "-p", dev }, "", &out, NULL); + int r = shell_exec({ "blkid", "-p", dev }, "", &out, NULL); if (r == 0) { fprintf(stderr, "%s contains data, skipping:\n %s\n", dev.c_str(), str_replace(trim(out), "\n", "\n ").c_str()); @@ -255,7 +255,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec { script += "+ "+size+" "+std::string(VITASTOR_PART_TYPE)+"\n"; } - if (shell_exec({ "/sbin/sfdisk", "--force", devinfo.path }, script, NULL, NULL) != 0) + if (shell_exec({ "sfdisk", "--force", devinfo.path }, script, NULL, NULL) != 0) { fprintf(stderr, "Failed to add %lu partition(s) with sfdisk\n", sizes.size()); return {}; @@ -275,13 +275,48 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec fprintf(stderr, "Failed to add %lu partition(s) with sfdisk: new partitions not found in table\n", sizes.size()); return {}; } + // Check if new nodes exist and run partprobe if not + // FIXME: We could use parted instead of sfdisk because partprobe is already a part of parted + int iter = 0, r; + while (true) + { + for (const auto & part: new_parts) + { + struct stat st; + if (stat(part["node"].string_value().c_str(), &st) < 0) + { + if (errno == ENOENT) + { + iter++; + // Run partprobe + if (iter > 1 || (r = shell_exec({ "partprobe", devinfo.path }, "", NULL, NULL)) != 0) + { + fprintf( + stderr, iter == 1 && r == 255 + ? "partprobe utility is required to reread partition table while disk %s is in use\n" + : "partprobe failed to re-read partition table while disk %s is in use\n", + devinfo.path.c_str() + ); + return {}; + } + break; + } + else + { + fprintf(stderr, "Failed to lstat %s: %s\n", part["node"].string_value().c_str(), strerror(errno)); + return {}; + } + } + } + break; + } // Wait until device symlinks in /dev/disk/by-partuuid/ appear bool exists = false; - int iter = 0; + iter = 0; while (!exists && iter < 300) // max 30 sec { exists = true; - for (const auto & part: newpt["partitions"].array_items()) + for (const auto & part: new_parts) { std::string link_path = "/dev/disk/by-partuuid/"+strtolower(part["uuid"].string_value()); struct stat st; diff --git a/src/disk_tool_upgrade.cpp b/src/disk_tool_upgrade.cpp index cad2d4ab..00fc2e9b 100644 --- a/src/disk_tool_upgrade.cpp +++ b/src/disk_tool_upgrade.cpp @@ -71,7 +71,7 @@ static int fix_partition_type(std::string dev_by_uuid) } script += "\n"; } - return shell_exec({ "/sbin/sfdisk", "--no-reread", "--force", "/dev/"+parent_dev }, script, NULL, NULL); + return shell_exec({ "sfdisk", "--no-reread", "--force", "/dev/"+parent_dev }, script, NULL, NULL); } int disk_tool_t::upgrade_simple_unit(std::string unit) diff --git a/src/disk_tool_utils.cpp b/src/disk_tool_utils.cpp index 9750a544..9eef0088 100644 --- a/src/disk_tool_utils.cpp +++ b/src/disk_tool_utils.cpp @@ -206,10 +206,10 @@ int write_zero(int fd, uint64_t offset, uint64_t size) json11::Json read_parttable(std::string dev) { std::string part_dump; - int r = shell_exec({ "/sbin/sfdisk", "--dump", dev, "--json" }, "", &part_dump, NULL); + int r = shell_exec({ "sfdisk", "--dump", dev, "--json" }, "", &part_dump, NULL); if (r == 255) { - fprintf(stderr, "Error running /sbin/sfdisk --dump %s --json\n", dev.c_str()); + fprintf(stderr, "Error running sfdisk --dump %s --json\n", dev.c_str()); return json11::Json(false); } // Decode partition table