From b10656ca094717355070fe4cf930162dbf0b796c Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Fri, 1 Jul 2022 11:59:27 +0300 Subject: [PATCH] Parse new disk params in disk_tool resizer --- src/disk_tool.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/src/disk_tool.cpp b/src/disk_tool.cpp index 7eeda471..08d2a084 100644 --- a/src/disk_tool.cpp +++ b/src/disk_tool.cpp @@ -124,6 +124,10 @@ int main(int argc, char *argv[]) cmd.clear(); cmd.push_back((char*)"help"); } + else if (!strcmp(argv[i], "--force")) + { + self.options["force"] = "1"; + } else if (argv[i][0] == '-' && argv[i][1] == '-') { char *key = argv[i]+2; @@ -169,9 +173,31 @@ int main(int argc, char *argv[]) printf( "USAGE:\n" " %s dump-journal [--all] \n" + " Dump journal in human-readable format.\n" + " Without --all, only actual part of the journal is dumped.\n" + " With --all, the whole journal area is scanned for journal entries,\n" + " some of which may be outdated.\n" + "\n" " %s dump-meta \n" + " Dump metadata in JSON format.\n" + "\n" + " %s resize [--iodepth 32]\n" + " Resize data area and/or rewrite/move journal and metadata\n" + " ALL_OSD_PARAMETERS must include all (at least all disk-related)\n" + " parameters from OSD command line (i.e. from systemd unit).\n" + " NEW_PARAMETERS include new disk layout parameters:\n" + " [--new_data_offset ] resize data area so it starts at \n" + " [--new_data_len ] resize data area to bytes\n" + " [--new_meta_device ] use for new metadata\n" + " [--new_meta_offset ] make new metadata area start at \n" + " [--new_meta_len ] make new metadata area bytes long\n" + " [--new_journal_device ] use for new journal\n" + " [--new_journal_offset ] make new journal area start at \n" + " [--new_journal_len ] make new journal area bytes long\n" + " If any of the new layout parameter options are not specified, old values\n" + " will be used.\n" , - argv[0], argv[0] + argv[0], argv[0], argv[0] ); } return 0; @@ -598,6 +624,36 @@ int disk_tool_t::resize_parse_params() iodepth = strtoull(options["iodepth"].c_str(), NULL, 10); if (!iodepth) iodepth = 32; + new_meta_device = options.find("new_meta_device") != options.end() + ? options["new_meta_device"] : dsk.meta_device; + new_journal_device = options.find("new_journal_device") != options.end() + ? options["new_journal_device"] : dsk.journal_device; + new_data_offset = options.find("new_data_offset") != options.end() + ? strtoull(options["new_data_offset"].c_str(), NULL, 10) : dsk.data_offset; + new_data_len = options.find("new_data_len") != options.end() + ? strtoull(options["new_data_len"].c_str(), NULL, 10) : dsk.data_len; + new_meta_offset = options.find("new_meta_offset") != options.end() + ? strtoull(options["new_meta_offset"].c_str(), NULL, 10) : dsk.meta_offset; + new_meta_len = options.find("new_meta_len") != options.end() + ? strtoull(options["new_meta_len"].c_str(), NULL, 10) : 0; // will be calculated in resize_init() + new_journal_offset = options.find("new_journal_offset") != options.end() + ? strtoull(options["new_journal_offset"].c_str(), NULL, 10) : dsk.journal_offset; + new_journal_len = options.find("new_journal_len") != options.end() + ? strtoull(options["new_journal_len"].c_str(), NULL, 10) : dsk.journal_len; + if (new_meta_device == dsk.meta_device && + new_journal_device == dsk.journal_device && + 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_journal_offset == dsk.journal_offset && + new_journal_len == dsk.journal_len && + options.find("force") == options.end()) + { + // No difference + fprintf(stderr, "No difference, specify --force to rewrite journal and meta anyway\n"); + return 1; + } return 0; } @@ -626,11 +682,34 @@ void disk_tool_t::resize_init(blockstore_meta_header_v1_t *hdr) new_clean_entry_size = sizeof(clean_disk_entry) + 2 * new_clean_entry_bitmap_size; new_entries_per_block = dsk.meta_block_size/new_clean_entry_size; uint64_t new_meta_blocks = 1 + (new_data_len/dsk.data_block_size + new_entries_per_block-1) / new_entries_per_block; + if (!new_meta_len) + { + new_meta_len = dsk.meta_block_size*new_meta_blocks; + } if (new_meta_len < dsk.meta_block_size*new_meta_blocks) { fprintf(stderr, "New metadata area size is too small, should be at least %lu bytes\n", dsk.meta_block_size*new_meta_blocks); exit(1); } + // Check that new metadata, journal and data areas don't overlap + if (new_meta_device == dsk.data_device && new_meta_offset < new_data_offset+new_data_len && + new_meta_offset+new_meta_len > new_data_offset) + { + fprintf(stderr, "New metadata area overlaps with data\n"); + exit(1); + } + if (new_journal_device == dsk.data_device && new_journal_offset < new_data_offset+new_data_len && + new_journal_offset+new_journal_len > new_data_offset) + { + fprintf(stderr, "New journal area overlaps with data\n"); + exit(1); + } + if (new_journal_device == dsk.meta_device && new_journal_offset < new_meta_offset+new_meta_len && + new_journal_offset+new_journal_len > new_meta_offset) + { + fprintf(stderr, "New journal area overlaps with metadata\n"); + exit(1); + } } int disk_tool_t::resize_remap_blocks()