From c731f188362546426bb21ded0558bb013f14c3d6 Mon Sep 17 00:00:00 2001 From: Gu Zhongyan Date: Wed, 23 May 2018 18:41:34 +0800 Subject: [PATCH] cephfs-journal-tool: get and check layout info during dump/undump when cephfs-journal-tool import journal, it uses default layout to get object_size, this is wrong. Because default objetct_size can be changed by Config option change mds_log_segment_size when cluster initialized. The fix is save the layout info to header during journal export, When improt journal, first try to get layout from cluster, if failed, then get layout info from dumped journal file, if still failed, set layout to default. Signed-off-by: Gu Zhongyan Signed-off-by: yupeng chen chenyupeng-it@360.cn --- src/tools/cephfs/Dumper.cc | 53 +++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/src/tools/cephfs/Dumper.cc b/src/tools/cephfs/Dumper.cc index 67252eaa326fb..890756699ab12 100644 --- a/src/tools/cephfs/Dumper.cc +++ b/src/tools/cephfs/Dumper.cc @@ -108,13 +108,19 @@ int Dumper::dump(const char *dump_file) // include an informative header char buf[HEADER_LEN]; memset(buf, 0, sizeof(buf)); - snprintf(buf, HEADER_LEN, "Ceph mds%d journal dump\n start offset %llu (0x%llx)\n length %llu (0x%llx)\n write_pos %llu (0x%llx)\n format %llu\n trimmed_pos %llu (0x%llx)\n%c", + snprintf(buf, HEADER_LEN, "Ceph mds%d journal dump\n start offset %llu (0x%llx)\n\ + length %llu (0x%llx)\n write_pos %llu (0x%llx)\n format %llu\n\ + trimmed_pos %llu (0x%llx)\n stripe_unit %lu (0x%lx)\n stripe_count %lu (0x%lx)\n\ + object_size %lu (0x%lx)\n fsid %s\n%c", role.rank, (unsigned long long)start, (unsigned long long)start, (unsigned long long)len, (unsigned long long)len, (unsigned long long)journaler.last_committed.write_pos, (unsigned long long)journaler.last_committed.write_pos, (unsigned long long)journaler.last_committed.stream_format, (unsigned long long)journaler.last_committed.trimmed_pos, (unsigned long long)journaler.last_committed.trimmed_pos, + (unsigned long)journaler.last_committed.layout.stripe_unit, (unsigned long)journaler.last_committed.layout.stripe_unit, + (unsigned long)journaler.last_committed.layout.stripe_count, (unsigned long)journaler.last_committed.layout.stripe_count, + (unsigned long)journaler.last_committed.layout.object_size, (unsigned long)journaler.last_committed.layout.object_size, 4); r = safe_write(fd, buf, sizeof(buf)); if (r) { @@ -193,6 +199,15 @@ int Dumper::undump(const char *dump_file) assert(fs != nullptr); int r = 0; + // try get layout info from cluster + Journaler journaler("umdumper", ino, fs->mds_map.get_metadata_pool(), + CEPH_FS_ONDISK_MAGIC, objecter, 0, 0, + &finisher); + int recovered = recover_journal(&journaler); + if (recovered != 0) { + derr << "recover_journal failed, try to get header from dump file " << dendl; + } + int fd = ::open(dump_file, O_RDONLY); if (fd < 0) { r = errno; @@ -212,16 +227,41 @@ int Dumper::undump(const char *dump_file) } long long unsigned start, len, write_pos, format, trimmed_pos; + long unsigned stripe_unit, stripe_count, object_size; sscanf(strstr(buf, "start offset"), "start offset %llu", &start); sscanf(strstr(buf, "length"), "length %llu", &len); sscanf(strstr(buf, "write_pos"), "write_pos %llu", &write_pos); sscanf(strstr(buf, "format"), "format %llu", &format); + if (recovered == 0) { + stripe_unit = journaler.last_committed.layout.stripe_unit; + stripe_count = journaler.last_committed.layout.stripe_count; + object_size = journaler.last_committed.layout.object_size; + } else { + // try to get layout from dump file header, if failed set layout to default + if (strstr(buf, "stripe_unit")) { + sscanf(strstr(buf, "stripe_unit"), "stripe_unit %lu", &stripe_unit); + } else { + stripe_unit = file_layout_t::get_default().stripe_unit; + } + if (strstr(buf, "stripe_count")) { + sscanf(strstr(buf, "stripe_count"), "stripe_count %lu", &stripe_count); + } else { + stripe_count = file_layout_t::get_default().stripe_count; + } + if (strstr(buf, "object_size")) { + sscanf(strstr(buf, "object_size"), "object_size %lu", &object_size); + } else { + object_size = file_layout_t::get_default().object_size; + } + } + + if (strstr(buf, "trimmed_pos")) { sscanf(strstr(buf, "trimmed_pos"), "trimmed_pos %llu", &trimmed_pos); } else { // Old format dump, any untrimmed objects before expire_pos will // be discarded as trash. - trimmed_pos = start - (start % file_layout_t::get_default().object_size); + trimmed_pos = start - (start % object_size); } if (trimmed_pos > start) { @@ -242,7 +282,10 @@ int Dumper::undump(const char *dump_file) " len " << len << " write_pos " << write_pos << " format " << format << - " trimmed_pos " << trimmed_pos << std::endl; + " trimmed_pos " << trimmed_pos << + " stripe_unit " << stripe_unit << + " stripe_count " << stripe_count << + " object_size " << object_size << std::endl; Journaler::Header h; h.trimmed_pos = trimmed_pos; @@ -251,7 +294,9 @@ int Dumper::undump(const char *dump_file) h.stream_format = format; h.magic = CEPH_FS_ONDISK_MAGIC; - h.layout = file_layout_t::get_default(); + h.layout.stripe_unit = stripe_unit; + h.layout.stripe_count = stripe_count; + h.layout.object_size = object_size; h.layout.pool_id = fs->mds_map.get_metadata_pool(); bufferlist hbl;