]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs-journal-tool: check fsid when import purge queue
authorGu Zhongyan <guzhongyan@360.cn>
Mon, 21 May 2018 07:00:38 +0000 (15:00 +0800)
committerNathan Cutler <ncutler@suse.com>
Tue, 11 Sep 2018 15:46:15 +0000 (17:46 +0200)
import purge queue will triger file delete in cluster.
we occasionally imported a purge queue from one production
cluster to a test cluster and found the the fs in test cluster
was damaged because some objects are really delted as its inode
recorded in purge queue.

add fsid when exporting purge queue, check if the fsid matched when
importing purge queue. This could make cephfs-journal-tool safer to
handle purge queue issues.

Signed-off-by: Gu Zhongyan <guzhongyan@360.cn>
Signed-off-by: yupeng chen chenyupeng-it@360.cn
(cherry picked from commit e0eef2aab10747de0efc128133c567204b4d0322)

src/tools/cephfs/Dumper.cc
src/tools/cephfs/Dumper.h
src/tools/cephfs/JournalTool.cc
src/tools/cephfs/JournalTool.h

index b7e2b8ba88bc9b533f67f7f334e0ac302260bba4..8141754b99305c86fc8c45fe60522f1d278e948d 100644 (file)
@@ -25,6 +25,7 @@
 #include "mds/LogEvent.h"
 #include "mds/JournalPointer.h"
 #include "osdc/Journaler.h"
+#include "mon/MonClient.h"
 
 #include "Dumper.h"
 
@@ -100,15 +101,19 @@ int Dumper::dump(const char *dump_file)
   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    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,
+           fsid_str,
            4);
     r = safe_write(fd, buf, sizeof(buf));
     if (r) {
@@ -179,7 +184,7 @@ int Dumper::dump(const char *dump_file)
   }
 }
 
-int Dumper::undump(const char *dump_file)
+int Dumper::undump(const char *dump_file, bool force)
 {
   cout << "undump " << dump_file << std::endl;
   
@@ -210,6 +215,33 @@ int Dumper::undump(const char *dump_file)
   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 (strstr(buf, "trimmed_pos")) {
     sscanf(strstr(buf, "trimmed_pos"), "trimmed_pos %llu", &trimmed_pos);
   } else {
index f95a06290dbe8284ff05dc312e53b74faaa29318..96fca3be2bc776a188d60eb4cece90460b2ba1d4 100644 (file)
@@ -39,7 +39,7 @@ public:
   int init(mds_role_t role_);
   int recover_journal(Journaler *journaler);
   int dump(const char *dumpfile);
-  int undump(const char *dumpfile);
+  int undump(const char *dumpfile, bool force);
 };
 
 #endif /* JOURNAL_DUMPER_H_ */
index 1ec083056a9e9b295bc167814026c81124454a00..a66cc2d70ba565f31b8853f2eb3898cfe466b597 100644 (file)
@@ -45,7 +45,7 @@ void JournalTool::usage()
     << "  cephfs-journal-tool [options] journal <command>\n"
     << "    <command>:\n"
     << "      inspect\n"
-    << "      import <path>\n"
+    << "      import <path> [--force]\n"
     << "      export <path>\n"
     << "      reset [--force]\n"
     << "  cephfs-journal-tool [options] header <get|set <field> <value>\n"
@@ -180,9 +180,18 @@ int JournalTool::main_journal(std::vector<const char*> &argv)
   if (command == "inspect") {
     return journal_inspect();
   } else if (command == "export" || command == "import") {
+    bool force = false;
     if (argv.size() >= 2) {
       std::string const path = argv[1];
-      return journal_export(path, command == "import");
+      if (argv.size() == 3) {
+        if (std::string(argv[2]) == "--force") {
+          force = true;
+        } else {
+          std::cerr << "Unknown argument " << argv[1] << std::endl;
+          return -EINVAL;
+        }
+      }
+      return journal_export(path, command == "import", force);
     } else {
       derr << "Missing path" << dendl;
       return -EINVAL;
@@ -537,7 +546,7 @@ int JournalTool::journal_inspect()
  * back to manually listing RADOS objects and extracting them, which
  * they can do with the ``rados`` CLI.
  */
-int JournalTool::journal_export(std::string const &path, bool import)
+int JournalTool::journal_export(std::string const &path, bool import, bool force)
 {
   int r = 0;
   JournalScanner js(input, rank);
@@ -569,7 +578,7 @@ int JournalTool::journal_export(std::string const &path, bool import)
       return r;
     }
     if (import) {
-      r = dumper.undump(path.c_str());
+      r = dumper.undump(path.c_str(), force);
     } else {
       r = dumper.dump(path.c_str());
     }
index d3944144ddcf4693a98982655c0b009ee1998f7d..2edeb6a76535c4e2f755634cda38aa6e26b8ee93 100644 (file)
@@ -48,7 +48,7 @@ class JournalTool : public MDSUtility
 
     // Journal operations
     int journal_inspect();
-    int journal_export(std::string const &path, bool import);
+    int journal_export(std::string const &path, bool import, bool force);
     int journal_reset(bool hard);
 
     // Header operations