]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools: chunk reads in Dumper 5120/head
authorJohn Spray <john.spray@redhat.com>
Wed, 3 Jun 2015 09:04:26 +0000 (10:04 +0100)
committerAbhishek Lekshmanan <abhishek.lekshmanan@ril.com>
Wed, 1 Jul 2015 17:28:40 +0000 (22:58 +0530)
Previously tried to read entire journal
into memory in one go, which was problematic
for large journals.

Fixes: #11746
Signed-off-by: John Spray <john.spray@redhat.com>
(cherry picked from commit e3ddcb894ad09326698999d42de0ce3feb69f28e)

src/tools/cephfs/Dumper.cc

index 2075c7c2b3161674b1ddb0162e318a8c680f1918..060366106559057c587c55f1c65ee8e45b9ad231 100644 (file)
@@ -83,19 +83,9 @@ int Dumper::dump(const char *dump_file)
   uint64_t end = journaler.get_write_pos();
   uint64_t len = end-start;
 
-  cout << "journal is " << start << "~" << len << std::endl;
-
   Filer filer(objecter, &finisher);
-  bufferlist bl;
-
-  C_SaferCond cond;
-  lock.Lock();
-  filer.read(ino, &journaler.get_layout(), CEPH_NOSNAP,
-             start, len, &bl, 0, &cond);
-  lock.Unlock();
-  r = cond.wait();
 
-  cout << "read " << bl.length() << " bytes at offset " << start << std::endl;
+  cout << "journal is " << start << "~" << len << std::endl;
 
   int fd = ::open(dump_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
   if (fd >= 0) {
@@ -105,7 +95,7 @@ int Dumper::dump(const char *dump_file)
     sprintf(buf, "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",
            rank, 
            (unsigned long long)start, (unsigned long long)start,
-           (unsigned long long)bl.length(), (unsigned long long)bl.length(),
+           (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,
@@ -125,11 +115,39 @@ int Dumper::dump(const char *dump_file)
       ::close(fd);
       return r;
     }
-    r = bl.write_fd(fd);
-    if (r) {
-      derr << "Error " << r << " (" << cpp_strerror(r) << ") writing journal file" << dendl;
-      ::close(fd);
-      return r;
+
+
+    // Read and write 32MB chunks.  Slower than it could be because we're not
+    // streaming, but that's okay because this is just a debug/disaster tool.
+    const uint32_t chunk_size = 32 * 1024 * 1024;
+
+    for (uint64_t pos = start; pos < start + len; pos += chunk_size) {
+      bufferlist bl;
+      dout(10) << "Reading at pos=0x" << std::hex << pos << std::dec << dendl;
+
+      const uint32_t read_size = MIN(chunk_size, end - pos);
+
+      C_SaferCond cond;
+      lock.Lock();
+      filer.read(ino, &journaler.get_layout(), CEPH_NOSNAP,
+                 pos, read_size, &bl, 0, &cond);
+      lock.Unlock();
+      r = cond.wait();
+      if (r < 0) {
+        derr << "Error " << r << " (" << cpp_strerror(r) << ") reading "
+                "journal at offset 0x" << std::hex << pos << std::dec << dendl;
+        ::close(fd);
+        return r;
+      }
+      dout(10) << "Got 0x" << std::hex << bl.length() << std::dec
+               << " bytes" << dendl;
+
+      r = bl.write_fd(fd);
+      if (r) {
+        derr << "Error " << r << " (" << cpp_strerror(r) << ") writing journal file" << dendl;
+        ::close(fd);
+        return r;
+      }
     }
 
     r = ::close(fd);
@@ -139,7 +157,7 @@ int Dumper::dump(const char *dump_file)
       return r;
     }
 
-    cout << "wrote " << bl.length() << " bytes at offset " << start << " to " << dump_file << "\n"
+    cout << "wrote " << len << " bytes at offset " << start << " to " << dump_file << "\n"
         << "NOTE: this is a _sparse_ file; you can\n"
         << "\t$ tar cSzf " << dump_file << ".tgz " << dump_file << "\n"
         << "      to efficiently compress it while preserving sparseness." << std::endl;