Fix vitastor-disk build (with old metadata and journal formats)

This commit is contained in:
Vitaliy Filippov
2025-11-23 19:08:24 +03:00
parent 4dfb80e6a1
commit 4581084540
10 changed files with 82 additions and 51 deletions
+33 -7
View File
@@ -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");
}
+2 -1
View File
@@ -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);
+6
View File
@@ -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)
{
+2 -2
View File
@@ -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);
+1 -1
View File
@@ -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;
}
+14 -20
View File
@@ -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;
}
+15 -10
View File
@@ -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)
{
+1 -1
View File
@@ -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())
+5 -5
View File
@@ -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 });
+3 -4
View File
@@ -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;