#include "mds/LogEvent.h"
#include "mds/JournalPointer.h"
#include "osdc/Journaler.h"
+#include "mon/MonClient.h"
#include "Dumper.h"
int fd = ::open(dump_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (fd >= 0) {
// include an informative header
+ uuid_d fsid = monc->get_fsid();
+ char fsid_str[40];
+ fsid.print(fsid_str);
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,
+ fsid_str,
4);
r = safe_write(fd, buf, sizeof(buf));
if (r) {
}
}
-int Dumper::undump(const char *dump_file)
+int Dumper::undump(const char *dump_file, bool force)
{
cout << "undump " << dump_file << std::endl;
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;
}
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 (!force) {
+ // need to check if fsid match onlien cluster fsid
+ if (strstr(buf, "fsid")) {
+ uuid_d fsid;
+ char fsid_str[40];
+ sscanf(strstr(buf, "fsid"), "fsid %s", fsid_str);
+ r = fsid.parse(fsid_str);
+ if (!r) {
+ derr << "Invalid fsid" << dendl;
+ ::close(fd);
+ return -EINVAL;
+ }
+
+ if (fsid != monc->get_fsid()) {
+ derr << "Imported journal fsid does not match online cluster fsid" << dendl;
+ derr << "Use --force to skip fsid check" << dendl;
+ ::close(fd);
+ return -EINVAL;
+ }
+ } else {
+ derr << "Invalid header, no fsid embeded" << dendl;
+ ::close(fd);
+ return -EINVAL;
+ }
+ }
+
+ 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) {
" 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;
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;