]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools: Add clear-data-digest command to objectstore tool. 29366/head
authorliyichao <liyichao.good@gmail.com>
Wed, 5 Dec 2018 04:22:20 +0000 (12:22 +0800)
committerDavid Zafman <dzafman@redhat.com>
Mon, 1 Jul 2019 05:03:07 +0000 (22:03 -0700)
There may be a situation where data digest in object info is
inconsistent with that computed from object data, then deep-scrub
will fail even though all three repicas have the same object data.

Fixes: https://tracker.ceph.com/issues/37935
Signed-off-by: Li Yichao <liyichao.good@gmail.com>
(cherry picked from commit da5832b2b49be4ab23f7ffc5ba1ba630168b886f)

Adjustments for luminous:
Add ObjectStore::Sequencer
Use begin() instead of cbegin()
Eliminate use of open_collection()

qa/standalone/special/ceph_objectstore_tool.py
src/tools/ceph_objectstore_tool.cc

index 961fac69daddc1afeb0d02e10d54ef41282798da..06053b9f741218af97004cd08842dba415f52fd0 100755 (executable)
@@ -1742,6 +1742,27 @@ def main(argv):
 
     ERRORS += EXP_ERRORS
 
+    print("Test clear-data-digest")
+    for nspace in db.keys():
+        for basename in db[nspace].keys():
+          JSON = db[nspace][basename]['json']
+          cmd = (CFSD_PREFIX + "'{json}' clear-data-digest").format(osd='osd0', json=JSON)
+          logging.debug(cmd)
+          ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+          if ret != 0:
+              logging.error("Clearing data digest failed for {json}".format(json=JSON))
+              ERRORS += 1
+              break
+          cmd = (CFSD_PREFIX + "'{json}' dump | grep '\"data_digest\": \"0xff'").format(osd='osd0', json=JSON)
+          logging.debug(cmd)
+          ret = call(cmd, shell=True, stdout=nullfd, stderr=nullfd)
+          if ret != 0:
+              logging.error("Data digest not cleared for {json}".format(json=JSON))
+              ERRORS += 1
+              break
+          break
+        break
+
     print("Test pg removal")
     RM_ERRORS = 0
     for pg in ALLREPPGS + ALLECPGS:
index 261a3517b030ef4c43cac9032132e7f073858735..0d332b880a5c22d305e236136858dadb0db0d533 100644 (file)
@@ -2559,6 +2559,41 @@ int set_size(ObjectStore *store, coll_t coll, ghobject_t &ghobj, uint64_t setsiz
   return 0;
 }
 
+int clear_data_digest(ObjectStore *store, coll_t coll, ghobject_t &ghobj,
+       ObjectStore::Sequencer &osr) {
+  bufferlist attr;
+  int r = store->getattr(coll, ghobj, OI_ATTR, attr);
+  if (r < 0) {
+    cerr << "Error getting attr on : " << make_pair(coll, ghobj) << ", "
+       << cpp_strerror(r) << std::endl;
+    return r;
+  }
+  object_info_t oi;
+  auto bp = attr.begin();
+  try {
+    decode(oi, bp);
+  } catch (...) {
+    r = -EINVAL;
+    cerr << "Error getting attr on : " << make_pair(coll, ghobj) << ", "
+         << cpp_strerror(r) << std::endl;
+    return r;
+  }
+  if (!dry_run) {
+    attr.clear();
+    oi.clear_data_digest();
+    encode(oi, attr, -1); /* fixme: using full features */
+    ObjectStore::Transaction t;
+    t.setattr(coll, ghobj, OI_ATTR, attr);
+    r = store->apply_transaction(&osr, std::move(t));
+    if (r < 0) {
+      cerr << "Error writing object info: " << make_pair(coll, ghobj) << ", "
+         << cpp_strerror(r) << std::endl;
+      return r;
+    }
+  }
+  return 0;
+}
+
 int clear_snapset(ObjectStore *store, coll_t coll, ghobject_t &ghobj,
                   string arg, ObjectStore::Sequencer &osr)
 {
@@ -2893,6 +2928,7 @@ void usage(po::options_description &desc)
     cerr << "ceph-objectstore-tool ... <object> remove|removeall" << std::endl;
     cerr << "ceph-objectstore-tool ... <object> dump" << std::endl;
     cerr << "ceph-objectstore-tool ... <object> set-size" << std::endl;
+    cerr << "ceph-objectstore-tool ... <object> clear-data-digest" << std::endl;
     cerr << "ceph-objectstore-tool ... <object> remove-clone-metadata <cloneid>" << std::endl;
     cerr << std::endl;
     cerr << "<object> can be a JSON object description as displayed" << std::endl;
@@ -3964,6 +4000,9 @@ int main(int argc, char **argv)
        uint64_t size = atoll(arg1.c_str());
        ret = set_size(fs, coll, ghobj, size, formatter, *osr, corrupt);
        goto out;
+      } else if (objcmd == "clear-data-digest") {
+        ret = clear_data_digest(fs, coll, ghobj, *osr);
+        goto out;
       } else if (objcmd == "clear-snapset") {
         // UNDOCUMENTED: For testing zap SnapSet
         // IGNORE extra args since not in usage anyway