Extract check_existing_partition(), get_device_size()
This commit is contained in:
@@ -121,6 +121,7 @@ struct disk_tool_t
|
||||
uint32_t write_osd_superblock(std::string device, json11::Json params);
|
||||
|
||||
int prepare_one(std::map<std::string, std::string> options, int is_hdd = -1);
|
||||
int check_existing_partition(const std::string & dev);
|
||||
int prepare(std::vector<std::string> devices);
|
||||
std::vector<vitastor_dev_info_t> collect_devices(const std::vector<std::string> & devices);
|
||||
json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector<std::string> 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<std::string> & cmd, const std::string & in, std::string *out, std::string *err);
|
||||
int write_zero(int fd, uint64_t offset, uint64_t size);
|
||||
|
||||
@@ -54,23 +54,8 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> 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<std::string>{"data", "meta", "journal"})
|
||||
@@ -222,6 +207,28 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> 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<vitastor_dev_info_t> disk_tool_t::collect_devices(const std::vector<std::string> & devices)
|
||||
{
|
||||
std::vector<vitastor_dev_info_t> devinfo;
|
||||
@@ -233,33 +240,16 @@ std::vector<vitastor_dev_info_t> 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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user