Compare commits
No commits in common. "4ab51c6b58c70e54cb5d8d622fcc377672a1deb2" and "a03508320ee57807d84f38e9d162f4a8c0b2dc5e" have entirely different histories.
4ab51c6b58
...
a03508320e
|
@ -5,8 +5,7 @@ project(vitastor)
|
||||||
# vitastor-disk
|
# vitastor-disk
|
||||||
add_executable(vitastor-disk
|
add_executable(vitastor-disk
|
||||||
disk_tool.cpp disk_simple_offsets.cpp
|
disk_tool.cpp disk_simple_offsets.cpp
|
||||||
disk_tool_journal.cpp disk_tool_meta.cpp disk_tool_prepare.cpp disk_tool_resize.cpp
|
disk_tool_journal.cpp disk_tool_meta.cpp disk_tool_prepare.cpp disk_tool_resize.cpp disk_tool_udev.cpp disk_tool_utils.cpp disk_tool_upgrade.cpp
|
||||||
disk_tool_resize_auto.cpp disk_tool_udev.cpp disk_tool_utils.cpp disk_tool_upgrade.cpp
|
|
||||||
../util/crc32c.c ../util/str_util.cpp ../util/json_util.cpp ../../json11/json11.cpp ../util/rw_blocking.cpp ../util/allocator.cpp ../util/ringloop.cpp ../blockstore/blockstore_disk.cpp
|
../util/crc32c.c ../util/str_util.cpp ../util/json_util.cpp ../../json11/json11.cpp ../util/rw_blocking.cpp ../util/allocator.cpp ../util/ringloop.cpp ../blockstore/blockstore_disk.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(vitastor-disk
|
target_link_libraries(vitastor-disk
|
||||||
|
|
|
@ -92,22 +92,8 @@ static const char *help_text =
|
||||||
" \n"
|
" \n"
|
||||||
" Requires the `sfdisk` utility.\n"
|
" Requires the `sfdisk` utility.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"vitastor-disk resize <osd_num>|<osd_device> [OPTIONS]\n"
|
"vitastor-disk resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]\n"
|
||||||
" Resize data area and/or move journal and metadata:\n"
|
" Resize data area and/or rewrite/move journal and metadata\n"
|
||||||
" --move-journal TARGET move journal to TARGET\n"
|
|
||||||
" --move-meta TARGET move metadata to TARGET\n"
|
|
||||||
" --journal-size NEW_SIZE resize journal to NEW_SIZE\n"
|
|
||||||
" --data-size NEW_SIZE resize data device to NEW_SIZE\n"
|
|
||||||
" --dry-run only show new layout, do not apply it\n"
|
|
||||||
" \n"
|
|
||||||
" NEW_SIZE may include k/m/g/t suffixes.\n"
|
|
||||||
" TARGET may be one of:\n"
|
|
||||||
" <partition> move journal/metadata to an existing GPT partition\n"
|
|
||||||
" <raw_device> create a GPT partition on <raw_device> and move journal/metadata to it\n"
|
|
||||||
" \"\" (empty string) move journal/metadata back to the data device\n"
|
|
||||||
"\n"
|
|
||||||
"vitastor-disk raw-resize <ALL_OSD_PARAMETERS> <NEW_LAYOUT> [--iodepth 32]\n"
|
|
||||||
" Resize data area and/or rewrite/move journal and metadata (manual format).\n"
|
|
||||||
" ALL_OSD_PARAMETERS must include all (at least all disk-related)\n"
|
" ALL_OSD_PARAMETERS must include all (at least all disk-related)\n"
|
||||||
" parameters from OSD command line (i.e. from systemd unit or superblock).\n"
|
" parameters from OSD command line (i.e. from systemd unit or superblock).\n"
|
||||||
" NEW_LAYOUT may include new disk layout parameters:\n"
|
" NEW_LAYOUT may include new disk layout parameters:\n"
|
||||||
|
@ -250,10 +236,6 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
self.options["force"] = "1";
|
self.options["force"] = "1";
|
||||||
}
|
}
|
||||||
else if (!strcmp(argv[i], "--dry-run") || !strcmp(argv[i], "--dry_run"))
|
|
||||||
{
|
|
||||||
self.options["dry_run"] = "1";
|
|
||||||
}
|
|
||||||
else if (!strcmp(argv[i], "--allow-data-loss"))
|
else if (!strcmp(argv[i], "--allow-data-loss"))
|
||||||
{
|
{
|
||||||
self.options["allow_data_loss"] = "1";
|
self.options["allow_data_loss"] = "1";
|
||||||
|
@ -261,7 +243,7 @@ int main(int argc, char *argv[])
|
||||||
else if (argv[i][0] == '-' && argv[i][1] == '-' && i < argc-1)
|
else if (argv[i][0] == '-' && argv[i][1] == '-' && i < argc-1)
|
||||||
{
|
{
|
||||||
char *key = argv[i]+2;
|
char *key = argv[i]+2;
|
||||||
self.options[str_replace(key, "-", "_")] = argv[++i];
|
self.options[key] = argv[++i];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -393,16 +375,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd[0], "resize"))
|
else if (!strcmp(cmd[0], "resize"))
|
||||||
{
|
{
|
||||||
if (cmd.size() != 2)
|
return self.resize_data();
|
||||||
{
|
|
||||||
fprintf(stderr, "Exactly 1 OSD number or OSD device path argument is required\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return self.resize_data(cmd[1]);
|
|
||||||
}
|
|
||||||
else if (!strcmp(cmd[0], "raw-resize"))
|
|
||||||
{
|
|
||||||
return self.raw_resize();
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(cmd[0], "simple-offsets"))
|
else if (!strcmp(cmd[0], "simple-offsets"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,11 +98,7 @@ struct disk_tool_t
|
||||||
int write_json_journal(json11::Json entries);
|
int write_json_journal(json11::Json entries);
|
||||||
int write_json_meta(json11::Json meta);
|
int write_json_meta(json11::Json meta);
|
||||||
|
|
||||||
int resize_data(std::string device);
|
int resize_data();
|
||||||
int resize_parse_move_journal(std::map<std::string, std::string> & move_options, bool dry_run);
|
|
||||||
int resize_parse_move_meta(std::map<std::string, std::string> & move_options, bool dry_run);
|
|
||||||
|
|
||||||
int raw_resize();
|
|
||||||
int resize_parse_params();
|
int resize_parse_params();
|
||||||
void resize_init(blockstore_meta_header_v2_t *hdr);
|
void resize_init(blockstore_meta_header_v2_t *hdr);
|
||||||
int resize_remap_blocks();
|
int resize_remap_blocks();
|
||||||
|
@ -120,13 +116,11 @@ struct disk_tool_t
|
||||||
int systemd_start_stop_osds(const std::vector<std::string> & cmd, const std::vector<std::string> & devices);
|
int systemd_start_stop_osds(const std::vector<std::string> & cmd, const std::vector<std::string> & devices);
|
||||||
int pre_exec_osd(std::string device);
|
int pre_exec_osd(std::string device);
|
||||||
int purge_devices(const std::vector<std::string> & devices);
|
int purge_devices(const std::vector<std::string> & devices);
|
||||||
int clear_osd_superblock(const std::string & dev);
|
|
||||||
|
|
||||||
json11::Json read_osd_superblock(std::string device, bool expect_exist = true, bool ignore_nonref = false);
|
json11::Json read_osd_superblock(std::string device, bool expect_exist = true, bool ignore_nonref = false);
|
||||||
uint32_t write_osd_superblock(std::string device, json11::Json params);
|
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 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);
|
int prepare(std::vector<std::string> devices);
|
||||||
std::vector<vitastor_dev_info_t> collect_devices(const 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);
|
json11::Json add_partitions(vitastor_dev_info_t & devinfo, std::vector<std::string> sizes);
|
||||||
|
@ -141,7 +135,6 @@ void disk_tool_simple_offsets(json11::Json cfg, bool json_output);
|
||||||
uint64_t sscanf_json(const char *fmt, const json11::Json & str);
|
uint64_t sscanf_json(const char *fmt, const json11::Json & str);
|
||||||
void fromhexstr(const std::string & from, int bytes, uint8_t *to);
|
void fromhexstr(const std::string & from, int bytes, uint8_t *to);
|
||||||
int disable_cache(std::string dev);
|
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);
|
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 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);
|
int write_zero(int fd, uint64_t offset, uint64_t size);
|
||||||
|
|
|
@ -159,7 +159,7 @@ int disk_tool_t::dump_load_check_superblock(const std::string & device)
|
||||||
{
|
{
|
||||||
auto cfg = json_to_string_map(sb["params"].object_items());
|
auto cfg = json_to_string_map(sb["params"].object_items());
|
||||||
dsk.parse_config(cfg);
|
dsk.parse_config(cfg);
|
||||||
dsk.data_io = dsk.meta_io = dsk.journal_io = "direct";
|
dsk.data_io = dsk.meta_io = dsk.journal_io = "cached";
|
||||||
dsk.open_data();
|
dsk.open_data();
|
||||||
dsk.open_meta();
|
dsk.open_meta();
|
||||||
dsk.open_journal();
|
dsk.open_journal();
|
||||||
|
|
|
@ -53,9 +53,24 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (i == 0 && is_hdd == -1)
|
if (i == 0 && is_hdd == -1)
|
||||||
is_hdd = trim(read_file("/sys/block/"+parent_dev.substr(5)+"/queue/rotational")) == "1";
|
is_hdd = trim(read_file("/sys/block/"+parent_dev+"/queue/rotational")) == "1";
|
||||||
if (check_existing_partition(dev) != 0)
|
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;
|
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"})
|
for (auto dev: std::vector<std::string>{"data", "meta", "journal"})
|
||||||
|
@ -207,28 +222,6 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||||
return 0;
|
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> disk_tool_t::collect_devices(const std::vector<std::string> & devices)
|
||||||
{
|
{
|
||||||
std::vector<vitastor_dev_info_t> devinfo;
|
std::vector<vitastor_dev_info_t> devinfo;
|
||||||
|
@ -240,16 +233,33 @@ 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());
|
fprintf(stderr, "%s does not start with /dev/, ignoring\n", dev.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
struct stat sys_st;
|
struct stat dev_st, sys_st;
|
||||||
uint64_t dev_size = get_device_size(dev, false);
|
if (stat(dev.c_str(), &dev_st) < 0)
|
||||||
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
else if (!dev_size)
|
uint64_t dev_size = dev_st.st_size;
|
||||||
|
if (S_ISBLK(dev_st.st_mode))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s does not exist, skipping\n", dev.c_str());
|
int fd = open(dev.c_str(), O_DIRECT|O_RDWR);
|
||||||
continue;
|
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);
|
||||||
}
|
}
|
||||||
if (stat(("/sys/block/"+dev.substr(5)).c_str(), &sys_st) < 0)
|
if (stat(("/sys/block/"+dev.substr(5)).c_str(), &sys_st) < 0)
|
||||||
{
|
{
|
||||||
|
@ -328,7 +338,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
|
||||||
script += "+ "+size+" "+std::string(VITASTOR_PART_TYPE)+"\n";
|
script += "+ "+size+" "+std::string(VITASTOR_PART_TYPE)+"\n";
|
||||||
}
|
}
|
||||||
std::string out;
|
std::string out;
|
||||||
if (shell_exec({ "sfdisk", "--no-reread", "--no-tell-kernel", "--force", devinfo.path }, script, &out, NULL) != 0)
|
if (shell_exec({ "sfdisk", "--no-reread", "--force", devinfo.path }, script, &out, NULL) != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to add %zu partition(s) with sfdisk\n", sizes.size());
|
fprintf(stderr, "Failed to add %zu partition(s) with sfdisk\n", sizes.size());
|
||||||
return {};
|
return {};
|
||||||
|
@ -355,9 +365,8 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
|
||||||
{
|
{
|
||||||
for (const auto & part: new_parts)
|
for (const auto & part: new_parts)
|
||||||
{
|
{
|
||||||
std::string link_path = "/dev/disk/by-partuuid/"+strtolower(part["uuid"].string_value());
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (lstat(link_path.c_str(), &st) < 0)
|
if (stat(part["node"].string_value().c_str(), &st) < 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
|
@ -378,7 +387,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to lstat %s: %s\n", link_path.c_str(), strerror(errno));
|
fprintf(stderr, "Failed to lstat %s: %s\n", part["node"].string_value().c_str(), strerror(errno));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,9 +396,8 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
|
||||||
}
|
}
|
||||||
// Wait until device symlinks in /dev/disk/by-partuuid/ appear
|
// Wait until device symlinks in /dev/disk/by-partuuid/ appear
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
const int max_iter = 300; // max 30 sec
|
|
||||||
iter = 0;
|
iter = 0;
|
||||||
while (!exists && iter < max_iter)
|
while (!exists && iter < 300) // max 30 sec
|
||||||
{
|
{
|
||||||
exists = true;
|
exists = true;
|
||||||
for (const auto & part: new_parts)
|
for (const auto & part: new_parts)
|
||||||
|
@ -399,13 +407,7 @@ json11::Json disk_tool_t::add_partitions(vitastor_dev_info_t & devinfo, std::vec
|
||||||
if (lstat(link_path.c_str(), &st) < 0)
|
if (lstat(link_path.c_str(), &st) < 0)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
{
|
|
||||||
exists = false;
|
exists = false;
|
||||||
if (iter == 4)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Waiting for %s to appear for up to %d sec...\n", link_path.c_str(), max_iter/10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to lstat %s: %s\n", link_path.c_str(), strerror(errno));
|
fprintf(stderr, "Failed to lstat %s: %s\n", link_path.c_str(), strerror(errno));
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct resizer_data_moving_t
|
||||||
uint64_t old_loc, new_loc;
|
uint64_t old_loc, new_loc;
|
||||||
};
|
};
|
||||||
|
|
||||||
int disk_tool_t::raw_resize()
|
int disk_tool_t::resize_data()
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
// Parse parameters
|
// Parse parameters
|
||||||
|
|
|
@ -1,296 +0,0 @@
|
||||||
// Copyright (c) Vitaliy Filippov, 2019+
|
|
||||||
// License: VNPL-1.1 (see README.md for details)
|
|
||||||
|
|
||||||
#include "disk_tool.h"
|
|
||||||
#include "rw_blocking.h"
|
|
||||||
#include "str_util.h"
|
|
||||||
#include "json_util.h"
|
|
||||||
|
|
||||||
int disk_tool_t::resize_data(std::string device)
|
|
||||||
{
|
|
||||||
if (options.find("move_journal") == options.end() &&
|
|
||||||
options.find("move_data") == options.end() &&
|
|
||||||
options.find("journal_size") == options.end() &&
|
|
||||||
options.find("data_size") == options.end())
|
|
||||||
{
|
|
||||||
fprintf(stderr, "None of --move-journal, --move-data, --journal-size, --data-size options are specified - nothing to do!\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (stoull_full(device))
|
|
||||||
device = "/dev/vitastor/osd"+device+"-data";
|
|
||||||
json11::Json sb = read_osd_superblock(device, true, false);
|
|
||||||
if (sb.is_null())
|
|
||||||
return 1;
|
|
||||||
auto sb_params = json_to_string_map(sb["params"].object_items());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
dsk.parse_config(sb_params);
|
|
||||||
dsk.data_io = dsk.meta_io = dsk.journal_io = "cached";
|
|
||||||
dsk.open_data();
|
|
||||||
dsk.open_meta();
|
|
||||||
dsk.open_journal();
|
|
||||||
dsk.calc_lengths(true);
|
|
||||||
}
|
|
||||||
catch (std::exception & e)
|
|
||||||
{
|
|
||||||
dsk.close_all();
|
|
||||||
fprintf(stderr, "%s\n", e.what());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
dsk.close_all();
|
|
||||||
bool dry_run = options.find("dry_run") != options.end();
|
|
||||||
auto old_journal_device = dsk.journal_device;
|
|
||||||
auto old_meta_device = dsk.meta_device;
|
|
||||||
new_journal_len = dsk.journal_len;
|
|
||||||
if (options.find("journal_size") != options.end())
|
|
||||||
{
|
|
||||||
new_journal_len = parse_size(options["journal_size"]);
|
|
||||||
if (options.find("move_journal") == options.end())
|
|
||||||
options["move_journal"] = dsk.journal_device == dsk.data_device ? "" : dsk.journal_device;
|
|
||||||
}
|
|
||||||
std::map<std::string, std::string> move_options;
|
|
||||||
if (options.find("move_journal") != options.end())
|
|
||||||
{
|
|
||||||
if (resize_parse_move_journal(move_options, dry_run) != 0)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (options.find("move_meta") != options.end())
|
|
||||||
{
|
|
||||||
if (resize_parse_move_meta(move_options, dry_run) != 0)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
auto new_journal_device = move_options.find("new_journal_device") != move_options.end()
|
|
||||||
? move_options["new_journal_device"] : dsk.journal_device;
|
|
||||||
auto new_meta_device = move_options.find("new_meta_device") != move_options.end()
|
|
||||||
? move_options["new_meta_device"] : dsk.meta_device;
|
|
||||||
// Calculate new data & meta offsets
|
|
||||||
new_data_offset = 4096 + (new_journal_device == dsk.data_device ? new_journal_len : 0) +
|
|
||||||
(new_meta_device == dsk.data_device ? dsk.meta_len : 0);
|
|
||||||
new_data_offset += ((dsk.data_offset-new_data_offset) % dsk.data_block_size);
|
|
||||||
if (new_data_offset != dsk.data_offset)
|
|
||||||
move_options["new_data_offset"] = std::to_string(new_data_offset);
|
|
||||||
if (options.find("data_size") != options.end())
|
|
||||||
{
|
|
||||||
auto new_data_dev_size = parse_size(options["data_size"]);
|
|
||||||
new_data_dev_size = options["data_size"] == "max" || new_data_dev_size > dsk.data_device_size
|
|
||||||
? dsk.data_device_size : new_data_dev_size;
|
|
||||||
if (new_data_dev_size-dsk.data_offset != dsk.data_len)
|
|
||||||
move_options["new_data_len"] = std::to_string(new_data_dev_size-new_data_offset);
|
|
||||||
}
|
|
||||||
new_meta_offset = 4096 + (new_meta_device == new_journal_device ? new_journal_len : 0);
|
|
||||||
if (new_meta_offset != dsk.meta_offset)
|
|
||||||
move_options["new_meta_offset"] = std::to_string(new_meta_offset);
|
|
||||||
// Run resize
|
|
||||||
auto orig_options = std::move(options);
|
|
||||||
options = sb_params;
|
|
||||||
for (auto & kv: move_options)
|
|
||||||
options[kv.first] = kv.second;
|
|
||||||
if (!json)
|
|
||||||
{
|
|
||||||
std::string cmd;
|
|
||||||
for (auto & kv: move_options)
|
|
||||||
cmd += " "+kv.first+" = "+kv.second+"\n";
|
|
||||||
fprintf(stderr, "Running resize:\n%s", cmd.c_str());
|
|
||||||
}
|
|
||||||
if (!dry_run && raw_resize() != 0)
|
|
||||||
return 1;
|
|
||||||
// Write new superblocks
|
|
||||||
json11::Json::object new_sb_params = sb["params"].object_items();
|
|
||||||
if (move_options.find("new_journal_device") != move_options.end())
|
|
||||||
new_sb_params["journal_device"] = move_options["new_journal_device"];
|
|
||||||
if (move_options.find("new_meta_device") != move_options.end())
|
|
||||||
new_sb_params["meta_device"] = move_options["new_meta_device"];
|
|
||||||
new_sb_params["data_offset"] = new_data_offset;
|
|
||||||
new_sb_params["meta_offset"] = new_meta_offset;
|
|
||||||
if (move_options.find("new_data_len") != move_options.end())
|
|
||||||
new_sb_params["data_size"] = stoull_full(move_options["new_data_len"]);
|
|
||||||
std::set<std::string> clear_superblocks, write_superblocks;
|
|
||||||
write_superblocks.insert(dsk.data_device);
|
|
||||||
write_superblocks.insert(new_journal_device);
|
|
||||||
write_superblocks.insert(new_meta_device);
|
|
||||||
if (write_superblocks.find(old_journal_device) == write_superblocks.end())
|
|
||||||
clear_superblocks.insert(old_journal_device);
|
|
||||||
if (write_superblocks.find(old_meta_device) == write_superblocks.end())
|
|
||||||
clear_superblocks.insert(old_meta_device);
|
|
||||||
for (auto & dev: clear_superblocks)
|
|
||||||
{
|
|
||||||
if (!json)
|
|
||||||
fprintf(stderr, "Clearing OSD superblock on %s\n", dev.c_str());
|
|
||||||
if (!dry_run && clear_osd_superblock(dev) != 0)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
for (auto & dev: write_superblocks)
|
|
||||||
{
|
|
||||||
if (!json)
|
|
||||||
fprintf(stderr, "Writing new OSD superblock to %s\n", dev.c_str());
|
|
||||||
if (!dry_run && !write_osd_superblock(dev, new_sb_params))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (json)
|
|
||||||
{
|
|
||||||
printf("%s\n", json11::Json(json11::Json::object {
|
|
||||||
{ "new_sb_params", new_sb_params },
|
|
||||||
}).dump().c_str());
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int disk_tool_t::resize_parse_move_journal(std::map<std::string, std::string> & move_options, bool dry_run)
|
|
||||||
{
|
|
||||||
if (options["move_journal"] == "")
|
|
||||||
{
|
|
||||||
// move back to the data device
|
|
||||||
// but first check if not already there :)
|
|
||||||
if (dsk.journal_device == dsk.data_device && new_journal_len == dsk.journal_len)
|
|
||||||
{
|
|
||||||
// already there
|
|
||||||
fprintf(stderr, "journal is already on data device and has the same size\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
move_options["new_journal_device"] = dsk.data_device;
|
|
||||||
move_options["new_journal_offset"] = "4096";
|
|
||||||
move_options["new_journal_len"] = std::to_string(new_journal_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string real_dev = realpath_str(options["move_journal"], false);
|
|
||||||
if (real_dev == "")
|
|
||||||
return 1;
|
|
||||||
std::string parent_dev = get_parent_device(real_dev);
|
|
||||||
if (parent_dev == "")
|
|
||||||
return 1;
|
|
||||||
if (parent_dev == real_dev)
|
|
||||||
{
|
|
||||||
// whole disk - create partition
|
|
||||||
std::string old_real_dev = realpath_str(dsk.journal_device);
|
|
||||||
if (old_real_dev == "")
|
|
||||||
return 1;
|
|
||||||
if (options.find("force") == options.end() &&
|
|
||||||
get_parent_device(old_real_dev) == parent_dev)
|
|
||||||
{
|
|
||||||
// already there
|
|
||||||
fprintf(stderr, "journal is already on a partition of %s, add --force to create a new partition\n", options["move_journal"].c_str());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
new_journal_len = ((new_journal_len+1024*1024-1)/1024/1024)*1024*1024;
|
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
auto devinfos = collect_devices({ real_dev });
|
|
||||||
if (devinfos.size() == 0)
|
|
||||||
return 1;
|
|
||||||
std::vector<std::string> sizes;
|
|
||||||
sizes.push_back(std::to_string(new_journal_len/1024/1024)+"MiB");
|
|
||||||
auto new_parts = add_partitions(devinfos[0], sizes);
|
|
||||||
if (!new_parts.array_items().size())
|
|
||||||
return 1;
|
|
||||||
options["move_journal"] = "/dev/disk/by-partuuid/"+strtolower(new_parts[0]["uuid"].string_value());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
options["move_journal"] = "<new journal partition on "+parent_dev+">";
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
new_journal_len = get_device_size(options["move_journal"], true);
|
|
||||||
if (new_journal_len == UINT64_MAX)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
new_journal_len -= 4096;
|
|
||||||
move_options["new_journal_device"] = options["move_journal"];
|
|
||||||
move_options["new_journal_offset"] = "4096";
|
|
||||||
move_options["new_journal_len"] = std::to_string(new_journal_len);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int disk_tool_t::resize_parse_move_meta(std::map<std::string, std::string> & move_options, bool dry_run)
|
|
||||||
{
|
|
||||||
if (options["move_meta"] == "")
|
|
||||||
{
|
|
||||||
// move back to the data device
|
|
||||||
// but first check if not already there :)
|
|
||||||
if (dsk.meta_device == dsk.data_device)
|
|
||||||
{
|
|
||||||
// already there
|
|
||||||
fprintf(stderr, "metadata is already on data device\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
auto new_journal_device = move_options.find("new_journal_device") != move_options.end()
|
|
||||||
? move_options["new_journal_device"] : dsk.journal_device;
|
|
||||||
move_options["new_meta_device"] = dsk.data_device;
|
|
||||||
move_options["new_meta_len"] = std::to_string(dsk.meta_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string real_dev = realpath_str(options["move_meta"], false);
|
|
||||||
if (real_dev == "")
|
|
||||||
return 1;
|
|
||||||
std::string parent_dev = get_parent_device(real_dev);
|
|
||||||
if (parent_dev == "")
|
|
||||||
return 1;
|
|
||||||
uint64_t new_meta_len = 0;
|
|
||||||
if (parent_dev == real_dev)
|
|
||||||
{
|
|
||||||
// whole disk - create partition
|
|
||||||
std::string old_real_dev = realpath_str(dsk.meta_device);
|
|
||||||
if (old_real_dev == "")
|
|
||||||
return 1;
|
|
||||||
if (options.find("force") == options.end() &&
|
|
||||||
get_parent_device(old_real_dev) == parent_dev)
|
|
||||||
{
|
|
||||||
// already there
|
|
||||||
fprintf(stderr, "metadata is already on a partition of %s\n", options["move_meta"].c_str());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
new_meta_len = ((dsk.meta_len+1024*1024-1)/1024/1024)*1024*1024;
|
|
||||||
if (!dry_run)
|
|
||||||
{
|
|
||||||
auto devinfos = collect_devices({ real_dev });
|
|
||||||
if (devinfos.size() == 0)
|
|
||||||
return 1;
|
|
||||||
std::vector<std::string> sizes;
|
|
||||||
sizes.push_back(std::to_string(new_meta_len/1024/1024)+"MiB");
|
|
||||||
auto new_parts = add_partitions(devinfos[0], sizes);
|
|
||||||
if (!new_parts.array_items().size())
|
|
||||||
return 1;
|
|
||||||
options["move_meta"] = "/dev/disk/by-partuuid/"+strtolower(new_parts[0]["uuid"].string_value());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
options["move_meta"] = "<new metadata partition on "+parent_dev+">";
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
new_meta_len = get_device_size(options["move_meta"], true);
|
|
||||||
if (new_meta_len == UINT64_MAX)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
new_meta_len -= 4096;
|
|
||||||
move_options["new_meta_len"] = std::to_string(new_meta_len);
|
|
||||||
move_options["new_meta_device"] = options["move_meta"];
|
|
||||||
move_options["new_meta_offset"] = "4096";
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -382,34 +382,6 @@ int disk_tool_t::pre_exec_osd(std::string device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disk_tool_t::clear_osd_superblock(const std::string & dev)
|
|
||||||
{
|
|
||||||
uint8_t *buf = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 4096);
|
|
||||||
int fd = -1, r = open(dev.c_str(), O_DIRECT|O_RDWR);
|
|
||||||
if (r >= 0)
|
|
||||||
{
|
|
||||||
fd = r;
|
|
||||||
r = read_blocking(fd, buf, 4096);
|
|
||||||
if (r == 4096)
|
|
||||||
{
|
|
||||||
// Clear magic and CRC
|
|
||||||
memset(buf, 0, 12);
|
|
||||||
r = lseek64(fd, 0, 0);
|
|
||||||
if (r == 0)
|
|
||||||
{
|
|
||||||
r = write_blocking(fd, buf, 4096);
|
|
||||||
if (r == 4096)
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fd >= 0)
|
|
||||||
close(fd);
|
|
||||||
free(buf);
|
|
||||||
buf = NULL;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
{
|
{
|
||||||
std::set<uint64_t> osd_numbers;
|
std::set<uint64_t> osd_numbers;
|
||||||
|
@ -468,6 +440,7 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Destroy OSD superblocks
|
// Destroy OSD superblocks
|
||||||
|
uint8_t *buf = (uint8_t*)memalign_or_die(MEM_ALIGNMENT, 4096);
|
||||||
for (auto & sb: superblocks)
|
for (auto & sb: superblocks)
|
||||||
{
|
{
|
||||||
for (auto dev_type: std::vector<std::string>{ "data", "meta", "journal" })
|
for (auto dev_type: std::vector<std::string>{ "data", "meta", "journal" })
|
||||||
|
@ -475,7 +448,26 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
auto dev = sb["real_"+dev_type+"_device"].string_value();
|
auto dev = sb["real_"+dev_type+"_device"].string_value();
|
||||||
if (dev != "")
|
if (dev != "")
|
||||||
{
|
{
|
||||||
int r = clear_osd_superblock(dev);
|
int fd = -1, r = open(dev.c_str(), O_DIRECT|O_RDWR);
|
||||||
|
if (r >= 0)
|
||||||
|
{
|
||||||
|
fd = r;
|
||||||
|
r = read_blocking(fd, buf, 4096);
|
||||||
|
if (r == 4096)
|
||||||
|
{
|
||||||
|
// Clear magic and CRC
|
||||||
|
memset(buf, 0, 12);
|
||||||
|
r = lseek64(fd, 0, 0);
|
||||||
|
if (r == 0)
|
||||||
|
{
|
||||||
|
r = write_blocking(fd, buf, 4096);
|
||||||
|
if (r == 4096)
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Failed to clear OSD %ju %s device %s superblock: %s\n",
|
fprintf(stderr, "Failed to clear OSD %ju %s device %s superblock: %s\n",
|
||||||
|
@ -496,7 +488,7 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
fprintf(stderr, "Failed to delete partition %s: failed to find parent device\n", dev.c_str());
|
fprintf(stderr, "Failed to delete partition %s: failed to find parent device\n", dev.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto pt = read_parttable(parent_dev);
|
auto pt = read_parttable("/dev/"+parent_dev);
|
||||||
if (!pt.is_object())
|
if (!pt.is_object())
|
||||||
continue;
|
continue;
|
||||||
json11::Json::array newpt = pt["partitions"].array_items();
|
json11::Json::array newpt = pt["partitions"].array_items();
|
||||||
|
@ -507,7 +499,7 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
auto old_part = newpt[i];
|
auto old_part = newpt[i];
|
||||||
newpt.erase(newpt.begin()+i, newpt.begin()+i+1);
|
newpt.erase(newpt.begin()+i, newpt.begin()+i+1);
|
||||||
vitastor_dev_info_t devinfo = {
|
vitastor_dev_info_t devinfo = {
|
||||||
.path = parent_dev,
|
.path = "/dev/"+parent_dev,
|
||||||
.pt = json11::Json::object{ { "partitions", newpt } },
|
.pt = json11::Json::object{ { "partitions", newpt } },
|
||||||
};
|
};
|
||||||
add_partitions(devinfo, {});
|
add_partitions(devinfo, {});
|
||||||
|
@ -516,7 +508,7 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
errno != ENOENT)
|
errno != ENOENT)
|
||||||
{
|
{
|
||||||
std::string out;
|
std::string out;
|
||||||
shell_exec({ "partprobe", parent_dev }, "", &out, NULL);
|
shell_exec({ "partprobe", "/dev/"+parent_dev }, "", &out, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -525,5 +517,7 @@ int disk_tool_t::purge_devices(const std::vector<std::string> & devices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(buf);
|
||||||
|
buf = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ int disk_tool_t::upgrade_simple_unit(std::string unit)
|
||||||
resizer.options = options;
|
resizer.options = options;
|
||||||
for (auto & kv: resize)
|
for (auto & kv: resize)
|
||||||
resizer.options[kv.first] = std::to_string(kv.second);
|
resizer.options[kv.first] = std::to_string(kv.second);
|
||||||
if (resizer.raw_resize() != 0)
|
if (resizer.resize_data() != 0)
|
||||||
{
|
{
|
||||||
// FIXME: Resize with backup or journal
|
// FIXME: Resize with backup or journal
|
||||||
fprintf(
|
fprintf(
|
||||||
|
|
|
@ -60,14 +60,14 @@ int disable_cache(std::string dev)
|
||||||
auto parent_dev = get_parent_device(dev);
|
auto parent_dev = get_parent_device(dev);
|
||||||
if (parent_dev == "")
|
if (parent_dev == "")
|
||||||
return 1;
|
return 1;
|
||||||
auto scsi_disk = "/sys/block/"+parent_dev.substr(5)+"/device/scsi_disk";
|
auto scsi_disk = "/sys/block/"+parent_dev+"/device/scsi_disk";
|
||||||
DIR *dir = opendir(scsi_disk.c_str());
|
DIR *dir = opendir(scsi_disk.c_str());
|
||||||
if (!dir)
|
if (!dir)
|
||||||
{
|
{
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
// Not a SCSI/SATA device, just check /sys/block/.../queue/write_cache
|
// Not a SCSI/SATA device, just check /sys/block/.../queue/write_cache
|
||||||
return check_queue_cache(dev.substr(5), parent_dev.substr(5));
|
return check_queue_cache(dev.substr(5), parent_dev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ int disable_cache(std::string dev)
|
||||||
{
|
{
|
||||||
// Not a SCSI/SATA device, just check /sys/block/.../queue/write_cache
|
// Not a SCSI/SATA device, just check /sys/block/.../queue/write_cache
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return check_queue_cache(dev.substr(5), parent_dev.substr(5));
|
return check_queue_cache(dev.substr(5), parent_dev);
|
||||||
}
|
}
|
||||||
scsi_disk += "/";
|
scsi_disk += "/";
|
||||||
scsi_disk += de->d_name;
|
scsi_disk += de->d_name;
|
||||||
|
@ -117,38 +117,6 @@ int disable_cache(std::string dev)
|
||||||
return 0;
|
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)
|
std::string get_parent_device(std::string dev)
|
||||||
{
|
{
|
||||||
if (dev.substr(0, 5) != "/dev/")
|
if (dev.substr(0, 5) != "/dev/")
|
||||||
|
@ -157,26 +125,16 @@ std::string get_parent_device(std::string dev)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
dev = dev.substr(5);
|
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/"+dev;
|
|
||||||
}
|
|
||||||
else if (errno != ENOENT)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to stat %s: %s\n", chk.c_str(), strerror(errno));
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
int i = dev.size();
|
int i = dev.size();
|
||||||
while (i > 0 && isdigit(dev[i-1]))
|
while (i > 0 && isdigit(dev[i-1]))
|
||||||
i--;
|
i--;
|
||||||
if (i >= 2 && dev[i-1] == 'p' && isdigit(dev[i-2])) // nvme0n1p1
|
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
|
||||||
i--;
|
i--;
|
||||||
// Check that such block device exists
|
// Check that such block device exists
|
||||||
chk = "/sys/block/"+dev.substr(0, i);
|
struct stat st;
|
||||||
|
auto chk = "/sys/block/"+dev.substr(0, i);
|
||||||
if (stat(chk.c_str(), &st) < 0)
|
if (stat(chk.c_str(), &st) < 0)
|
||||||
{
|
{
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
|
@ -184,9 +142,9 @@ std::string get_parent_device(std::string dev)
|
||||||
fprintf(stderr, "Failed to stat %s: %s\n", chk.c_str(), strerror(errno));
|
fprintf(stderr, "Failed to stat %s: %s\n", chk.c_str(), strerror(errno));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return "/dev/"+dev;
|
return dev;
|
||||||
}
|
}
|
||||||
return "/dev/"+dev.substr(0, i);
|
return dev.substr(0, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int shell_exec(const std::vector<std::string> & cmd, const std::string & in, std::string *out, std::string *err)
|
int shell_exec(const std::vector<std::string> & cmd, const std::string & in, std::string *out, std::string *err)
|
||||||
|
@ -349,7 +307,7 @@ int fix_partition_type(std::string dev_by_uuid)
|
||||||
std::string parent_dev = get_parent_device(realpath_str(dev_by_uuid, false));
|
std::string parent_dev = get_parent_device(realpath_str(dev_by_uuid, false));
|
||||||
if (parent_dev == "")
|
if (parent_dev == "")
|
||||||
return 1;
|
return 1;
|
||||||
auto pt = read_parttable(parent_dev);
|
auto pt = read_parttable("/dev/"+parent_dev);
|
||||||
if (pt.is_null() || pt.is_bool())
|
if (pt.is_null() || pt.is_bool())
|
||||||
return 1;
|
return 1;
|
||||||
std::string script = "label: gpt\n\n";
|
std::string script = "label: gpt\n\n";
|
||||||
|
@ -377,7 +335,7 @@ int fix_partition_type(std::string dev_by_uuid)
|
||||||
script += "\n";
|
script += "\n";
|
||||||
}
|
}
|
||||||
std::string out;
|
std::string out;
|
||||||
return shell_exec({ "sfdisk", "--no-reread", "--no-tell-kernel", "--force", parent_dev }, script, &out, NULL);
|
return shell_exec({ "sfdisk", "--no-reread", "--force", "/dev/"+parent_dev }, script, &out, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string csum_type_str(uint32_t data_csum_type)
|
std::string csum_type_str(uint32_t data_csum_type)
|
||||||
|
|
Loading…
Reference in New Issue