Fix upgrading from pre-0.7.1 systemd units O_o
This commit is contained in:
@@ -172,10 +172,6 @@ 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));
|
throw std::runtime_error("journal_offset must be a multiple of journal_block_size = "+std::to_string(journal_block_size));
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
clean_entry_size = sizeof(clean_disk_entry) + clean_dyn_size + 4 /*entry_csum*/;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
||||||
@@ -224,9 +220,13 @@ void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
|||||||
}
|
}
|
||||||
// required metadata size
|
// required metadata size
|
||||||
block_count = data_len / data_block_size;
|
block_count = data_len / data_block_size;
|
||||||
|
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);
|
||||||
|
clean_entry_size = sizeof(clean_disk_entry) + clean_dyn_size + 4 /*entry_csum*/;
|
||||||
meta_len = (1 + (block_count - 1 + meta_block_size / clean_entry_size) / (meta_block_size / clean_entry_size)) * meta_block_size;
|
meta_len = (1 + (block_count - 1 + meta_block_size / clean_entry_size) / (meta_block_size / clean_entry_size)) * meta_block_size;
|
||||||
if (meta_format == BLOCKSTORE_META_FORMAT_V1 ||
|
bool new_doesnt_fit = (!meta_format && !skip_meta_check && meta_area_size < meta_len && !data_csum_type);
|
||||||
!meta_format && !skip_meta_check && meta_area_size < meta_len && !data_csum_type)
|
if (meta_format == BLOCKSTORE_META_FORMAT_V1 || new_doesnt_fit)
|
||||||
{
|
{
|
||||||
uint64_t clean_entry_v0_size = sizeof(clean_disk_entry) + 2*clean_entry_bitmap_size;
|
uint64_t clean_entry_v0_size = sizeof(clean_disk_entry) + 2*clean_entry_bitmap_size;
|
||||||
uint64_t meta_v0_len = (1 + (block_count - 1 + meta_block_size / clean_entry_v0_size)
|
uint64_t meta_v0_len = (1 + (block_count - 1 + meta_block_size / clean_entry_v0_size)
|
||||||
@@ -234,7 +234,11 @@ void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
|||||||
if (meta_format == BLOCKSTORE_META_FORMAT_V1 || meta_area_size >= meta_v0_len)
|
if (meta_format == BLOCKSTORE_META_FORMAT_V1 || meta_area_size >= meta_v0_len)
|
||||||
{
|
{
|
||||||
// Old metadata fits.
|
// Old metadata fits.
|
||||||
printf("Warning: Using old metadata format without checksums because the new format doesn't fit into provided area\n");
|
if (new_doesnt_fit)
|
||||||
|
{
|
||||||
|
printf("Warning: Using old metadata format without checksums because the new format"
|
||||||
|
" doesn't fit into provided area (%lu bytes required, %lu bytes available)\n", meta_len, meta_area_size);
|
||||||
|
}
|
||||||
clean_entry_size = clean_entry_v0_size;
|
clean_entry_size = clean_entry_v0_size;
|
||||||
meta_len = meta_v0_len;
|
meta_len = meta_v0_len;
|
||||||
meta_format = BLOCKSTORE_META_FORMAT_V1;
|
meta_format = BLOCKSTORE_META_FORMAT_V1;
|
||||||
@@ -246,7 +250,7 @@ void blockstore_disk_t::calc_lengths(bool skip_meta_check)
|
|||||||
meta_format = BLOCKSTORE_META_FORMAT_V2;
|
meta_format = BLOCKSTORE_META_FORMAT_V2;
|
||||||
if (!skip_meta_check && meta_area_size < meta_len)
|
if (!skip_meta_check && meta_area_size < meta_len)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Metadata area is too small, need at least "+std::to_string(meta_len)+" bytes");
|
throw std::runtime_error("Metadata area is too small, need at least "+std::to_string(meta_len)+" bytes, have only "+std::to_string(meta_area_size)+" bytes");
|
||||||
}
|
}
|
||||||
// requested journal size
|
// requested journal size
|
||||||
if (!skip_meta_check && cfg_journal_size > journal_len)
|
if (!skip_meta_check && cfg_journal_size > journal_len)
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ struct blockstore_disk_t
|
|||||||
uint64_t data_offset, data_device_sect, data_device_size, data_len;
|
uint64_t data_offset, data_device_sect, data_device_size, data_len;
|
||||||
uint64_t journal_offset, journal_device_sect, journal_device_size, journal_len;
|
uint64_t journal_offset, journal_device_sect, journal_device_size, journal_len;
|
||||||
|
|
||||||
uint32_t block_order;
|
uint32_t block_order = 0;
|
||||||
uint64_t block_count;
|
uint64_t block_count = 0;
|
||||||
uint32_t clean_entry_bitmap_size = 0, clean_entry_size = 0, clean_dyn_size = 0;
|
uint32_t clean_entry_bitmap_size = 0, clean_entry_size = 0, clean_dyn_size = 0;
|
||||||
|
|
||||||
void parse_config(std::map<std::string, std::string> & config);
|
void parse_config(std::map<std::string, std::string> & config);
|
||||||
|
|||||||
@@ -138,7 +138,11 @@ resume_1:
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
hdr->header_csum = csum;
|
hdr->header_csum = csum;
|
||||||
bs->dsk.meta_format = BLOCKSTORE_META_FORMAT_V2;
|
if (bs->dsk.meta_format != BLOCKSTORE_META_FORMAT_V2)
|
||||||
|
{
|
||||||
|
bs->dsk.meta_format = BLOCKSTORE_META_FORMAT_V2;
|
||||||
|
bs->dsk.calc_lengths();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (hdr->version == BLOCKSTORE_META_FORMAT_V1)
|
else if (hdr->version == BLOCKSTORE_META_FORMAT_V1)
|
||||||
{
|
{
|
||||||
@@ -146,11 +150,15 @@ resume_1:
|
|||||||
hdr->csum_block_size = 0;
|
hdr->csum_block_size = 0;
|
||||||
hdr->header_csum = 0;
|
hdr->header_csum = 0;
|
||||||
// Enable compatibility mode - entries without checksums
|
// Enable compatibility mode - entries without checksums
|
||||||
bs->dsk.clean_entry_size = sizeof(clean_disk_entry) + bs->dsk.clean_entry_bitmap_size*2;
|
if (bs->dsk.meta_format != BLOCKSTORE_META_FORMAT_V1 ||
|
||||||
bs->dsk.meta_len = (1 + (bs->dsk.block_count - 1 + bs->dsk.meta_block_size / bs->dsk.clean_entry_size)
|
bs->dsk.data_csum_type != 0 || bs->dsk.csum_block_size != 0)
|
||||||
/ (bs->dsk.meta_block_size / bs->dsk.clean_entry_size)) * bs->dsk.meta_block_size;
|
{
|
||||||
bs->dsk.meta_format = BLOCKSTORE_META_FORMAT_V1;
|
bs->dsk.data_csum_type = 0;
|
||||||
printf("Warning: Starting with metadata in the old format without checksums, as stored on disk\n");
|
bs->dsk.csum_block_size = 0;
|
||||||
|
bs->dsk.meta_format = BLOCKSTORE_META_FORMAT_V1;
|
||||||
|
bs->dsk.calc_lengths();
|
||||||
|
printf("Warning: Starting with metadata in the old format without checksums, as stored on disk\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (hdr->version > BLOCKSTORE_META_FORMAT_V2)
|
else if (hdr->version > BLOCKSTORE_META_FORMAT_V2)
|
||||||
{
|
{
|
||||||
@@ -338,7 +346,7 @@ bool blockstore_init_meta::handle_meta_block(uint8_t *buf, uint64_t entries_per_
|
|||||||
uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + bs->dsk.clean_entry_size - 4);
|
uint32_t *entry_csum = (uint32_t*)((uint8_t*)entry + bs->dsk.clean_entry_size - 4);
|
||||||
if (*entry_csum != crc32c(0, entry, bs->dsk.clean_entry_size - 4))
|
if (*entry_csum != crc32c(0, entry, bs->dsk.clean_entry_size - 4))
|
||||||
{
|
{
|
||||||
printf("Metadata entry %ju is corrupt (checksum mismatch), skipping\n", done_cnt+i);
|
printf("Metadata entry %ju is corrupt (checksum mismatch: %08x vs %08x), skipping\n", done_cnt+i, *entry_csum, crc32c(0, entry, bs->dsk.clean_entry_size - 4));
|
||||||
// zero out the invalid entry, otherwise we'll hit "tried to overwrite non-zero metadata entry" later
|
// zero out the invalid entry, otherwise we'll hit "tried to overwrite non-zero metadata entry" later
|
||||||
if (bs->inmemory_meta)
|
if (bs->inmemory_meta)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -79,28 +79,59 @@ int disk_tool_t::upgrade_simple_unit(std::string unit)
|
|||||||
{
|
{
|
||||||
// Resize data
|
// Resize data
|
||||||
uint64_t blk = stoull_full(options["block_size"]);
|
uint64_t blk = stoull_full(options["block_size"]);
|
||||||
blk = blk ? blk : 128*1024;
|
blk = blk ? blk : (1 << DEFAULT_DATA_BLOCK_ORDER);
|
||||||
std::map<std::string, uint64_t> resize;
|
std::map<std::string, uint64_t> resize;
|
||||||
if (d_o < 4096 || m_is_d && m_o < 4096 && m_o < d_o || j_is_d && j_o < 4096 && j_o < d_o)
|
if (d_o < 4096 || m_is_d && m_o < 4096 && m_o < d_o || j_is_d && j_o < 4096 && j_o < d_o)
|
||||||
{
|
{
|
||||||
resize["new_data_offset"] = d_o+blk;
|
d_o += blk;
|
||||||
if (m_is_d && m_o < d_o)
|
if (m_is_d && m_o < d_o)
|
||||||
resize["new_meta_offset"] = m_o+blk;
|
m_o += blk;
|
||||||
if (j_is_d && j_o < d_o)
|
if (j_is_d && j_o < d_o)
|
||||||
resize["new_journal_offset"] = j_o+blk;
|
j_o += blk;
|
||||||
}
|
}
|
||||||
if (!m_is_d && m_o < 4096)
|
if (!m_is_d && m_o < 4096)
|
||||||
{
|
{
|
||||||
resize["new_meta_offset"] = m_o+4096;
|
m_o += 4096;
|
||||||
if (j_is_m && m_o < j_o)
|
if (j_is_m && m_o < j_o)
|
||||||
resize["new_journal_offset"] = j_o+4096;
|
j_o += 4096;
|
||||||
}
|
}
|
||||||
if (!j_is_d && !j_is_m && j_o < 4096)
|
if (!j_is_d && !j_is_m && j_o < 4096)
|
||||||
resize["new_journal_offset"] = j_o+4096;
|
j_o += 4096;
|
||||||
|
if (options["meta_format"] == "" || options["meta_format"] == "1")
|
||||||
|
{
|
||||||
|
blockstore_disk_t dsk;
|
||||||
|
options["meta_format"] = std::to_string(BLOCKSTORE_META_FORMAT_V2);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dsk.parse_config(options);
|
||||||
|
dsk.open_data();
|
||||||
|
dsk.open_meta();
|
||||||
|
dsk.open_journal();
|
||||||
|
dsk.calc_lengths(true);
|
||||||
|
dsk.close_all();
|
||||||
|
}
|
||||||
|
catch (std::exception & e)
|
||||||
|
{
|
||||||
|
dsk.close_all();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
resize["new_data_offset"] = d_o;
|
||||||
|
resize["new_meta_offset"] = m_o;
|
||||||
|
resize["new_journal_offset"] = j_o;
|
||||||
disk_tool_t resizer;
|
disk_tool_t resizer;
|
||||||
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);
|
||||||
|
std::string cmd;
|
||||||
|
for (auto & kv: resizer.options)
|
||||||
|
if (kv.second != "")
|
||||||
|
cmd += " "+kv.first+" = "+kv.second+"\n";
|
||||||
|
fprintf(stderr, "Running resize:\n%s", cmd.c_str());
|
||||||
if (resizer.raw_resize() != 0)
|
if (resizer.raw_resize() != 0)
|
||||||
{
|
{
|
||||||
// FIXME: Resize with backup or journal
|
// FIXME: Resize with backup or journal
|
||||||
|
|||||||
Reference in New Issue
Block a user