]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs-journal-tool: check fsid when import purge queue 22111/head
authorGu Zhongyan <guzhongyan@360.cn>
Mon, 21 May 2018 07:00:38 +0000 (15:00 +0800)
committerGu Zhongyan <guzhongyan@360.cn>
Wed, 23 May 2018 03:50:16 +0000 (11:50 +0800)
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
src/tools/cephfs/Dumper.cc
src/tools/cephfs/Dumper.h
src/tools/cephfs/JournalTool.cc
src/tools/cephfs/JournalTool.h

index 67252eaa326fbee75a9d1273a9e6ff3c8b9fd2fc..9a35eb152bd3da1ef244eb0be0f7fe0d507e8d46 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"
 
@@ -106,15 +107,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) {
@@ -185,7 +190,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;
   
@@ -216,6 +221,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 aad7b3e10a59f1081e79c334bb4b15d5edbea799..758f3cdea0f05dc00ca70abf84e0229f33787fdf 100644 (file)
@@ -39,7 +39,7 @@ public:
   int init(mds_role_t role_, const std::string &type);
   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 3e746de9585900db0499d68e705e181d9aa2c904..30ee369c2a7ab4a98368a936c6051b4013127116 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"
@@ -202,9 +202,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;
@@ -552,7 +561,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, type);
@@ -584,7 +593,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 3d1188222cb7744fb2b8e945b05f91dc890fdcb3..87f37691ae220dc82dfa6a3a46dfad1d9ff1d4d9 100644 (file)
@@ -50,7 +50,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