diff --git a/src/disk_tool/disk_tool.h b/src/disk_tool/disk_tool.h index 7dc854e0..9bdb8ffc 100644 --- a/src/disk_tool/disk_tool.h +++ b/src/disk_tool/disk_tool.h @@ -121,6 +121,7 @@ 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 prepare(std::vector devices); std::vector collect_devices(const std::vector & devices); json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector sizes); @@ -135,6 +136,7 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output); uint64_t sscanf_json(const char *fmt, const json11::Json & str); void fromhexstr(const std::string & from, int bytes, uint8_t *to); int disable_cache(std::string dev); +uint64_t get_device_size(const std::string & dev, bool should_exist = false); std::string get_parent_device(std::string dev); int shell_exec(const std::vector & cmd, const std::string & in, std::string *out, std::string *err); int write_zero(int fd, uint64_t offset, uint64_t size); diff --git a/src/disk_tool/disk_tool_prepare.cpp b/src/disk_tool/disk_tool_prepare.cpp index 8c9958a2..d6bbf108 100644 --- a/src/disk_tool/disk_tool_prepare.cpp +++ b/src/disk_tool/disk_tool_prepare.cpp @@ -54,23 +54,8 @@ int disk_tool_t::prepare_one(std::map options, int is_ } if (i == 0 && is_hdd == -1) is_hdd = trim(read_file("/sys/block/"+parent_dev+"/queue/rotational")) == "1"; - std::string out; - if (shell_exec({ "wipefs", dev }, "", &out, NULL) != 0 || out != "") - { - fprintf(stderr, "%s contains data, not creating OSD without --force. wipefs shows:\n%s", dev.c_str(), out.c_str()); + if (check_existing_partition(dev) != 0) return 1; - } - json11::Json sb = read_osd_superblock(dev, false); - if (!sb.is_null()) - { - fprintf(stderr, "%s already contains Vitastor OSD superblock, not creating OSD without --force\n", dev.c_str()); - return 1; - } - if (fix_partition_type(dev) != 0) - { - fprintf(stderr, "%s has incorrect type and we failed to change it to Vitastor type\n", dev.c_str()); - return 1; - } } } for (auto dev: std::vector{"data", "meta", "journal"}) @@ -222,6 +207,28 @@ int disk_tool_t::prepare_one(std::map options, int is_ return 0; } +int disk_tool_t::check_existing_partition(const std::string & dev) +{ + std::string out; + if (shell_exec({ "wipefs", dev }, "", &out, NULL) != 0 || out != "") + { + fprintf(stderr, "%s contains data, not creating OSD without --force. wipefs shows:\n%s", dev.c_str(), out.c_str()); + return 1; + } + json11::Json sb = read_osd_superblock(dev, false); + if (!sb.is_null()) + { + fprintf(stderr, "%s already contains Vitastor OSD superblock, not creating OSD without --force\n", dev.c_str()); + return 1; + } + if (fix_partition_type(dev) != 0) + { + fprintf(stderr, "%s has incorrect type and we failed to change it to Vitastor type\n", dev.c_str()); + return 1; + } + return 0; +} + std::vector disk_tool_t::collect_devices(const std::vector & devices) { std::vector devinfo; @@ -233,33 +240,16 @@ std::vector disk_tool_t::collect_devices(const std::vector< fprintf(stderr, "%s does not start with /dev/, ignoring\n", dev.c_str()); continue; } - struct stat dev_st, sys_st; - if (stat(dev.c_str(), &dev_st) < 0) + struct stat sys_st; + uint64_t dev_size = get_device_size(dev, false); + if (dev_size == UINT64_MAX) { - if (errno == ENOENT) - { - fprintf(stderr, "%s does not exist, skipping\n", dev.c_str()); - continue; - } - fprintf(stderr, "Error checking %s: %s\n", dev.c_str(), strerror(errno)); return {}; } - uint64_t dev_size = dev_st.st_size; - if (S_ISBLK(dev_st.st_mode)) + else if (!dev_size) { - int fd = open(dev.c_str(), O_DIRECT|O_RDWR); - if (fd < 0) - { - fprintf(stderr, "Failed to open %s: %s\n", dev.c_str(), strerror(errno)); - return {}; - } - if (ioctl(fd, BLKGETSIZE64, &dev_size) < 0) - { - fprintf(stderr, "Failed to get %s size: %s\n", dev.c_str(), strerror(errno)); - close(fd); - return {}; - } - close(fd); + fprintf(stderr, "%s does not exist, skipping\n", dev.c_str()); + continue; } if (stat(("/sys/block/"+dev.substr(5)).c_str(), &sys_st) < 0) { diff --git a/src/disk_tool/disk_tool_utils.cpp b/src/disk_tool/disk_tool_utils.cpp index 906b4196..0ce30a82 100644 --- a/src/disk_tool/disk_tool_utils.cpp +++ b/src/disk_tool/disk_tool_utils.cpp @@ -117,6 +117,38 @@ int disable_cache(std::string dev) return 0; } +uint64_t get_device_size(const std::string & dev, bool should_exist) +{ + struct stat dev_st; + if (stat(dev.c_str(), &dev_st) < 0) + { + if (errno == ENOENT && !should_exist) + { + return 0; + } + fprintf(stderr, "Error checking %s: %s\n", dev.c_str(), strerror(errno)); + return UINT64_MAX; + } + uint64_t dev_size = dev_st.st_size; + if (S_ISBLK(dev_st.st_mode)) + { + int fd = open(dev.c_str(), O_DIRECT|O_RDWR); + if (fd < 0) + { + fprintf(stderr, "Failed to open %s: %s\n", dev.c_str(), strerror(errno)); + return UINT64_MAX; + } + if (ioctl(fd, BLKGETSIZE64, &dev_size) < 0) + { + fprintf(stderr, "Failed to get %s size: %s\n", dev.c_str(), strerror(errno)); + close(fd); + return UINT64_MAX; + } + close(fd); + } + return dev_size; +} + std::string get_parent_device(std::string dev) { if (dev.substr(0, 5) != "/dev/") @@ -125,16 +157,26 @@ std::string get_parent_device(std::string dev) return ""; } dev = dev.substr(5); + // check if it's a partition - partitions aren't present in /sys/block/ + struct stat st; + auto chk = "/sys/block/"+dev; + if (stat(chk.c_str(), &st) == 0) + { + // present in /sys/block/ - not a partition + return dev; + } + else if (errno != ENOENT) + { + fprintf(stderr, "Failed to stat %s: %s\n", chk.c_str(), strerror(errno)); + return ""; + } int i = dev.size(); while (i > 0 && isdigit(dev[i-1])) i--; - if (i >= 1 && dev[i-1] == '-') // dm-0, dm-1 - return dev; - else if (i >= 2 && dev[i-1] == 'p' && isdigit(dev[i-2])) // nvme0n1p1 + if (i >= 2 && dev[i-1] == 'p' && isdigit(dev[i-2])) // nvme0n1p1 i--; // Check that such block device exists - struct stat st; - auto chk = "/sys/block/"+dev.substr(0, i); + chk = "/sys/block/"+dev.substr(0, i); if (stat(chk.c_str(), &st) < 0) { if (errno != ENOENT)