]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tool/ceph_objectstore_tool: ignore read errors during pg export
authorIgor Fedotov <igor.fedotov@croit.io>
Tue, 12 Dec 2023 16:29:12 +0000 (19:29 +0300)
committerIgor Fedotov <igor.fedotov@croit.io>
Wed, 5 Mar 2025 18:42:14 +0000 (21:42 +0300)
If --force flag has been provided. Which permits majority of data
exporting even when some data corruption takes place.

Signed-off-by: Igor Fedotov <igor.fedotov@croit.io>
(cherry picked from commit da13649b5d6db5ccfa8de227a452c3f27422f770)

src/tools/ceph_objectstore_tool.cc
src/tools/ceph_objectstore_tool.h

index 6876e671266e748670f208ce469d949306249404..b7fe32319d5fcfb38498b5764da3c161c327a030 100644 (file)
@@ -830,7 +830,7 @@ void get_omap_batch(ObjectMap::ObjectMapIterator &iter, map<string, bufferlist>
   }
 }
 
-int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj)
+int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj, bool force)
 {
   struct stat st;
   mysize_t total;
@@ -858,13 +858,19 @@ int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj
     bufferlist bl;
     ret = store->getattr(ch, obj, OI_ATTR, bp);
     if (ret < 0) {
-      cerr << "getattr failure object_info " << ret << std::endl;
-      return ret;
+      cerr << "getattr failure: " << cpp_strerror(ret)
+           << " at obj:" << obj
+           << (force ? " IGNORED" : "")
+           << std::endl;
+      if (!force) {
+        return ret;
+      }
+    } else {
+      bl.push_back(bp);
+      decode(objb.oi, bl);
+      if (debug)
+        cerr << "object_info: " << objb.oi << std::endl;
     }
-    bl.push_back(bp);
-    decode(objb.oi, bl);
-    if (debug)
-      cerr << "object_info: " << objb.oi << std::endl;
   }
 
   // NOTE: we include whiteouts, lost, etc.
@@ -882,10 +888,35 @@ int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj
       len = total;
 
     ret = store->read(ch, obj, offset, len, rawdatabl);
-    if (ret < 0)
-      return ret;
-    if (ret == 0)
-      return -EINVAL;
+
+    ret = ret == 0 ? -EINVAL : ret;
+    if (ret < 0) {
+      if (!force) {
+        cerr << "read failure: " << cpp_strerror(ret)
+             << " at obj:" << obj
+             << std::hex << ", read 0x" << offset << "~" << len << std::dec
+             << std::endl;
+        return ret;
+      }
+      // re-read using minimal disk block to minimize error footprint.
+      auto o = offset;
+      const size_t block_size = 4096;
+      while(o < offset + len) {
+        bufferlist bl;
+        int r = store->read(ch, obj, o, block_size, bl);
+        if (r <= 0) {
+          rawdatabl.append_zero(block_size);
+          cerr << "read failure: " << cpp_strerror(r == 0 ? -EINVAL : r)
+               << " at obj:" << obj << std::hex
+               << ", read 0x" << o << "~" << block_size
+               << std::dec << std::endl;
+        } else {
+          rawdatabl.claim_append(bl);
+        }
+        o += block_size;
+      }
+      ret = len;
+    }
 
     data_section dblock(offset, len, rawdatabl);
     if (debug)
@@ -954,7 +985,7 @@ int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj
   return 0;
 }
 
-int ObjectStoreTool::export_files(ObjectStore *store, coll_t coll)
+int ObjectStoreTool::export_files(ObjectStore *store, coll_t coll, bool force)
 {
   ghobject_t next;
   auto ch = store->open_collection(coll);
@@ -975,7 +1006,7 @@ int ObjectStoreTool::export_files(ObjectStore *store, coll_t coll)
       if (i->is_pgmeta() || i->hobj.is_temp() || !i->is_no_gen()) {
        continue;
       }
-      r = export_file(store, coll, *i);
+      r = export_file(store, coll, *i, force);
       if (r < 0)
         return r;
     }
@@ -1152,9 +1183,9 @@ int ObjectStoreTool::do_export(
   if (ret)
     return ret;
 
-  ret = export_files(fs, coll);
+  ret = export_files(fs, coll, force);
   if (ret) {
-    cerr << "export_files error " << ret << std::endl;
+    cerr << "export_files error: " << cpp_strerror(ret) << std::endl;
     return ret;
   }
 
index 07c5eb38801c8f75a21e1e42b312ead80d138c52..40801d6a984e180e10202870e1c9f7dd3037c910 100644 (file)
@@ -37,8 +37,8 @@ class ObjectStoreTool : public RadosDump
       ObjectStore *store, OSDriver& driver, SnapMapper& mapper, coll_t coll,
       bufferlist &bl, OSDMap &curmap, bool *skipped_objects);
     int export_file(
-        ObjectStore *store, coll_t cid, ghobject_t &obj);
-    int export_files(ObjectStore *store, coll_t coll);
+        ObjectStore *store, coll_t cid, ghobject_t &obj, bool force);
+    int export_files(ObjectStore *store, coll_t coll, bool force);
 };
 
 #endif // CEPH_OBJECSTORE_TOOL_H_