Fix vitastor-disk build (with old metadata and journal formats)
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "blockstore.h"
|
||||
#include "ondisk_formats.h"
|
||||
#include "blockstore_disk.h"
|
||||
#include "blockstore_heap.h"
|
||||
#include "str_util.h"
|
||||
#include "allocator.h"
|
||||
|
||||
@@ -208,6 +209,10 @@ void blockstore_disk_t::parse_config(std::map<std::string, std::string> & config
|
||||
{
|
||||
throw std::runtime_error("journal_offset must be a multiple of journal_block_size = "+std::to_string(journal_block_size));
|
||||
}
|
||||
if (!meta_format)
|
||||
{
|
||||
meta_format = BLOCKSTORE_META_FORMAT_HEAP;
|
||||
}
|
||||
if (meta_device == data_device)
|
||||
{
|
||||
disable_meta_fsync = disable_data_fsync;
|
||||
@@ -218,7 +223,7 @@ void blockstore_disk_t::parse_config(std::map<std::string, std::string> & config
|
||||
}
|
||||
}
|
||||
|
||||
void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
||||
void blockstore_disk_t::calc_lengths()
|
||||
{
|
||||
// data
|
||||
data_len = data_device_size - data_offset;
|
||||
@@ -267,16 +272,37 @@ void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
||||
clean_entry_bitmap_size = data_block_size / bitmap_granularity / 8;
|
||||
clean_dyn_size = clean_entry_bitmap_size*2 + (csum_block_size
|
||||
? data_block_size/csum_block_size*(data_csum_type & 0xFF) : 0);
|
||||
uint32_t entries_per_block = ((meta_block_size-meta_block_target_free_space) /
|
||||
(24 /*sizeof(heap_object_t)*/ + 33 /*sizeof(heap_write_t)*/ + clean_dyn_size));
|
||||
min_meta_len = (block_count+entries_per_block-1) / entries_per_block * meta_block_size;
|
||||
meta_format = BLOCKSTORE_META_FORMAT_HEAP;
|
||||
if (!skip_meta_check && meta_area_size < min_meta_len)
|
||||
if (meta_format == BLOCKSTORE_META_FORMAT_HEAP)
|
||||
{
|
||||
uint32_t entries_per_block = ((meta_block_size-meta_block_target_free_space) /
|
||||
(sizeof(heap_object_t) + sizeof(heap_write_t) + clean_dyn_size));
|
||||
min_meta_len = (block_count+entries_per_block-1) / entries_per_block * meta_block_size;
|
||||
}
|
||||
else if (meta_format == BLOCKSTORE_META_FORMAT_V1)
|
||||
{
|
||||
clean_entry_size = 24 /*sizeof(clean_disk_entry)*/ + 2*clean_entry_bitmap_size;
|
||||
min_meta_len = (1 + (block_count - 1 + meta_block_size / clean_entry_size)
|
||||
/ (meta_block_size / clean_entry_size)) * meta_block_size;
|
||||
}
|
||||
else if (meta_format == BLOCKSTORE_META_FORMAT_V2)
|
||||
{
|
||||
clean_entry_size = 24 /*sizeof(clean_disk_entry)*/ + clean_dyn_size + 4 /*entry_csum*/;
|
||||
min_meta_len = (1 + (block_count - 1 + meta_block_size / clean_entry_size) / (meta_block_size / clean_entry_size)) * meta_block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("meta_format = "+std::to_string(meta_format)+" is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
void blockstore_disk_t::check_lengths()
|
||||
{
|
||||
if (meta_area_size < min_meta_len)
|
||||
{
|
||||
throw std::runtime_error("Metadata area is too small, need at least "+std::to_string(min_meta_len)+" bytes, have only "+std::to_string(meta_area_size)+" bytes");
|
||||
}
|
||||
// requested journal size
|
||||
if (!skip_meta_check && cfg_journal_size > journal_len)
|
||||
if (cfg_journal_size > journal_len)
|
||||
{
|
||||
throw std::runtime_error("Requested journal_size is too large");
|
||||
}
|
||||
|
||||
@@ -76,7 +76,8 @@ struct blockstore_disk_t
|
||||
void open_data();
|
||||
void open_meta();
|
||||
void open_journal();
|
||||
void calc_lengths(bool skip_meta_check = false);
|
||||
void calc_lengths();
|
||||
void check_lengths();
|
||||
void close_all();
|
||||
int trim_data(std::function<bool(uint64_t)> is_free);
|
||||
|
||||
|
||||
@@ -147,6 +147,12 @@ resume_1:
|
||||
exit(1);
|
||||
}
|
||||
bs->heap->set_compacted_lsn(hdr->compacted_lsn);
|
||||
if (bs->dsk.meta_format != hdr->version)
|
||||
{
|
||||
bs->dsk.meta_format = hdr->version;
|
||||
bs->dsk.calc_lengths();
|
||||
}
|
||||
bs->dsk.check_lengths();
|
||||
}
|
||||
if (bs->dsk.inmemory_journal)
|
||||
{
|
||||
|
||||
@@ -374,7 +374,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
self.dsk.meta_block_size = strtoul(cmd[2], NULL, 10);
|
||||
self.dsk.meta_offset = strtoull(cmd[3], NULL, 10);
|
||||
self.dsk.meta_len = strtoull(cmd[4], NULL, 10);
|
||||
self.dsk.meta_area_size = strtoull(cmd[4], NULL, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -404,7 +404,7 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
self.new_meta_device = self.dsk.meta_device;
|
||||
self.new_meta_offset = self.dsk.meta_offset;
|
||||
self.new_meta_len = self.dsk.meta_len;
|
||||
self.new_meta_len = self.dsk.meta_area_size;
|
||||
}
|
||||
std::string json_err;
|
||||
json11::Json meta = json11::Json::parse(read_all_fd(0), json_err);
|
||||
|
||||
@@ -83,7 +83,7 @@ int disk_tool_t::trim_data(std::string device)
|
||||
return r;
|
||||
}
|
||||
// Trim
|
||||
r = dsk.trim_data(data_alloc);
|
||||
r = dsk.trim_data([&](uint64_t block_num) { return data_alloc->get(block_num); });
|
||||
dsk.close_all();
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
@@ -32,15 +32,16 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
|
||||
int buf_size = 1024*1024;
|
||||
if (buf_size % dsk.meta_block_size)
|
||||
buf_size = 8*dsk.meta_block_size;
|
||||
if (buf_size > dsk.meta_len)
|
||||
buf_size = dsk.meta_len;
|
||||
void *data = memalign_or_die(MEM_ALIGNMENT, buf_size);
|
||||
lseek64(dsk.meta_fd, dsk.meta_offset, 0);
|
||||
read_blocking(dsk.meta_fd, data, dsk.meta_block_size);
|
||||
// Check superblock
|
||||
blockstore_meta_header_v2_t *hdr = (blockstore_meta_header_v2_t *)data;
|
||||
lseek64(dsk.meta_fd, dsk.meta_offset, 0);
|
||||
read_blocking(dsk.meta_fd, hdr, dsk.meta_block_size);
|
||||
if (hdr->zero == 0 && hdr->magic == BLOCKSTORE_META_MAGIC_V1)
|
||||
{
|
||||
dsk.meta_format = hdr->version;
|
||||
dsk.calc_lengths();
|
||||
dsk.check_lengths();
|
||||
if (hdr->version == BLOCKSTORE_META_FORMAT_V1)
|
||||
{
|
||||
// Vitastor 0.6-0.8 - static array of clean_disk_entry with bitmaps
|
||||
@@ -80,15 +81,6 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
|
||||
{
|
||||
fprintf(stderr, "Using block size of %u bytes based on information from the superblock\n", hdr->meta_block_size);
|
||||
dsk.meta_block_size = hdr->meta_block_size;
|
||||
if (buf_size % dsk.meta_block_size)
|
||||
{
|
||||
buf_size = 8*dsk.meta_block_size;
|
||||
void *new_data = memalign_or_die(MEM_ALIGNMENT, buf_size);
|
||||
memcpy(new_data, data, dsk.meta_block_size);
|
||||
free(data);
|
||||
data = new_data;
|
||||
hdr = (blockstore_meta_header_v2_t *)data;
|
||||
}
|
||||
}
|
||||
dsk.meta_format = hdr->version;
|
||||
dsk.data_block_size = hdr->data_block_size;
|
||||
@@ -102,14 +94,15 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
|
||||
*(hdr->data_csum_type & 0xff))
|
||||
: 0)
|
||||
+ (dsk.meta_format == BLOCKSTORE_META_FORMAT_V2 ? 4 /*entry_csum*/ : 0);
|
||||
// Read
|
||||
uint64_t block_num = 0;
|
||||
hdr_fn(hdr);
|
||||
hdr = NULL;
|
||||
meta_pos = dsk.meta_block_size;
|
||||
lseek64(dsk.meta_fd, dsk.meta_offset+meta_pos, 0);
|
||||
while (meta_pos < dsk.meta_len)
|
||||
while (meta_pos < dsk.meta_area_size)
|
||||
{
|
||||
uint64_t read_len = buf_size < dsk.meta_len-meta_pos ? buf_size : dsk.meta_len-meta_pos;
|
||||
uint64_t read_len = buf_size < dsk.meta_area_size-meta_pos ? buf_size : dsk.meta_area_size-meta_pos;
|
||||
read_blocking(dsk.meta_fd, data, read_len);
|
||||
meta_pos += read_len;
|
||||
for (uint64_t blk = 0; blk < read_len; blk += dsk.meta_block_size)
|
||||
@@ -136,14 +129,15 @@ int disk_tool_t::process_meta(std::function<void(blockstore_meta_header_v2_t *)>
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vitastor 0.4-0.5 - static array of clean_disk_entry
|
||||
// Vitastor 0.4-0.5 - static array of clean_disk_entry without header
|
||||
lseek64(dsk.meta_fd, dsk.meta_offset, 0);
|
||||
dsk.clean_entry_bitmap_size = 0;
|
||||
dsk.clean_entry_size = sizeof(clean_disk_entry);
|
||||
uint64_t block_num = 0;
|
||||
hdr_fn(NULL);
|
||||
while (meta_pos < dsk.meta_len)
|
||||
while (meta_pos < dsk.meta_area_size)
|
||||
{
|
||||
uint64_t read_len = buf_size < dsk.meta_len-meta_pos ? buf_size : dsk.meta_len-meta_pos;
|
||||
uint64_t read_len = buf_size < dsk.meta_area_size-meta_pos ? buf_size : dsk.meta_area_size-meta_pos;
|
||||
read_blocking(dsk.meta_fd, data, read_len);
|
||||
meta_pos += read_len;
|
||||
for (uint64_t blk = 0; blk < read_len; blk += dsk.meta_block_size)
|
||||
@@ -181,7 +175,7 @@ int disk_tool_t::dump_load_check_superblock(const std::string & device)
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
@@ -228,7 +222,7 @@ void disk_tool_t::dump_meta_header(blockstore_meta_header_v2_t *hdr)
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("{\"version\":\"0.5\",\"meta_block_size\":%ju,\"entries\":[\n", dsk.meta_block_size);
|
||||
printf("{\"version\":\"0.5\",\"meta_block_size\":%u,\"entries\":[\n", dsk.meta_block_size);
|
||||
}
|
||||
first_entry = true;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,10 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||
options["disable_"+dev+"_fsync"] = "1";
|
||||
}
|
||||
}
|
||||
if (options["meta_format"] == "")
|
||||
{
|
||||
options["meta_format"] = std::to_string(BLOCKSTORE_META_FORMAT_HEAP);
|
||||
}
|
||||
if (options["meta_device"] == "" || options["meta_device"] == options["data_device"])
|
||||
{
|
||||
options["disable_meta_fsync"] = options["disable_data_fsync"];
|
||||
@@ -108,6 +112,7 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||
if (options.find("autosync_writes") == options.end())
|
||||
options["autosync_writes"] = "512";
|
||||
}
|
||||
uint64_t new_meta_len = parse_size(options["meta_len"]);
|
||||
json11::Json::object sb;
|
||||
blockstore_disk_t dsk;
|
||||
try
|
||||
@@ -121,22 +126,22 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
sb = json11::Json::object {
|
||||
{ "meta_format", options["meta_format"] },
|
||||
{ "data_device", options["data_device"] },
|
||||
{ "meta_device", options["meta_device"] },
|
||||
{ "journal_device", options["journal_device"] },
|
||||
{ "block_size", (uint64_t)dsk.data_block_size },
|
||||
{ "meta_block_size", dsk.meta_block_size },
|
||||
{ "journal_block_size", dsk.journal_block_size },
|
||||
{ "meta_block_size", (uint64_t)dsk.meta_block_size },
|
||||
{ "journal_block_size", (uint64_t)dsk.journal_block_size },
|
||||
{ "data_size", dsk.cfg_data_size },
|
||||
{ "disk_alignment", (uint64_t)dsk.disk_alignment },
|
||||
{ "bitmap_granularity", dsk.bitmap_granularity },
|
||||
{ "bitmap_granularity", (uint64_t)dsk.bitmap_granularity },
|
||||
{ "disable_device_lock", dsk.disable_flock },
|
||||
{ "journal_offset", 4096 },
|
||||
{ "meta_offset", 4096 + (dsk.meta_device == dsk.journal_device ? dsk.journal_len : 0) },
|
||||
{ "data_offset", 4096 + (dsk.data_device == dsk.meta_device ? dsk.meta_len : 0) +
|
||||
(dsk.data_device == dsk.journal_device ? dsk.journal_len : 0) },
|
||||
{ "meta_offset", dsk.meta_offset },
|
||||
{ "data_offset", dsk.data_offset + (new_meta_len ? 0 : (dsk.meta_format == BLOCKSTORE_META_FORMAT_HEAP ? dsk.min_meta_len*2 : dsk.min_meta_len)) },
|
||||
{ "journal_no_same_sector_overwrites", !is_hdd || is_hybrid },
|
||||
{ "journal_sector_buffer_count", 1024 },
|
||||
{ "disable_data_fsync", json_is_true(options["disable_data_fsync"]) },
|
||||
@@ -180,7 +185,7 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
||||
}
|
||||
sb["osd_num"] = osd_num;
|
||||
// Zero out metadata and journal
|
||||
if (write_zero(dsk.meta_fd, sb["meta_offset"].uint64_value(), dsk.meta_len) != 0 ||
|
||||
if (write_zero(dsk.meta_fd, sb["meta_offset"].uint64_value(), dsk.meta_area_size) != 0 ||
|
||||
write_zero(dsk.journal_fd, sb["journal_offset"].uint64_value(), dsk.journal_len) != 0)
|
||||
{
|
||||
fprintf(stderr, "Failed to zero out metadata or journal: %s\n", strerror(errno));
|
||||
@@ -527,9 +532,9 @@ int disk_tool_t::get_meta_partition(std::vector<vitastor_dev_info_t> & ssds, std
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
dsk.close_all();
|
||||
meta_size = dsk.meta_len;
|
||||
meta_size = dsk.min_meta_len;
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
|
||||
@@ -140,7 +140,7 @@ int disk_tool_t::resize_parse_params()
|
||||
new_data_offset == dsk.data_offset &&
|
||||
new_data_len == dsk.data_len &&
|
||||
new_meta_offset == dsk.meta_offset &&
|
||||
(new_meta_len == dsk.meta_len || new_meta_len == 0) &&
|
||||
(new_meta_len == dsk.meta_area_size || new_meta_len == 0) &&
|
||||
new_journal_offset == dsk.journal_offset &&
|
||||
new_journal_len == dsk.journal_len &&
|
||||
options.find("force") == options.end())
|
||||
|
||||
@@ -29,7 +29,7 @@ int disk_tool_t::resize_data(std::string device)
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
}
|
||||
catch (std::exception & e)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ int disk_tool_t::resize_data(std::string device)
|
||||
dsk.journal_fd = old_journal_fd;
|
||||
dsk.meta_fd = old_meta_fd;
|
||||
dsk.data_fd = old_data_fd;
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
dsk.journal_fd = -1;
|
||||
dsk.meta_fd = -1;
|
||||
dsk.data_fd = -1;
|
||||
@@ -83,7 +83,7 @@ int disk_tool_t::resize_data(std::string device)
|
||||
? 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_meta_device == dsk.data_device ? dsk.meta_area_size : 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);
|
||||
@@ -236,7 +236,7 @@ int disk_tool_t::resize_parse_move_meta(std::map<std::string, std::string> & mov
|
||||
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);
|
||||
move_options["new_meta_len"] = std::to_string(dsk.meta_area_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -260,7 +260,7 @@ int disk_tool_t::resize_parse_move_meta(std::map<std::string, std::string> & mov
|
||||
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;
|
||||
new_meta_len = ((dsk.meta_area_size+1024*1024-1)/1024/1024)*1024*1024;
|
||||
if (!dry_run)
|
||||
{
|
||||
auto devinfos = collect_devices({ real_dev });
|
||||
|
||||
@@ -107,7 +107,7 @@ int disk_tool_t::upgrade_simple_unit(std::string unit)
|
||||
dsk.open_data();
|
||||
dsk.open_meta();
|
||||
dsk.open_journal();
|
||||
dsk.calc_lengths(true);
|
||||
dsk.calc_lengths();
|
||||
dsk.close_all();
|
||||
}
|
||||
catch (std::exception & e)
|
||||
@@ -116,9 +116,8 @@ int disk_tool_t::upgrade_simple_unit(std::string unit)
|
||||
fprintf(stderr, "Error: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
options.erase("meta_format");
|
||||
if (m_is_d && m_o < d_o && d_o-m_o < dsk.meta_len)
|
||||
d_o += ((dsk.meta_len - (d_o-m_o) + blk-1) / blk) * blk;
|
||||
if (m_is_d && m_o < d_o && d_o-m_o < dsk.min_meta_len)
|
||||
d_o += ((dsk.min_meta_len - (d_o-m_o) + blk-1) / blk) * blk;
|
||||
}
|
||||
resize["new_data_offset"] = d_o;
|
||||
resize["new_meta_offset"] = m_o;
|
||||
|
||||
Reference in New Issue
Block a user