diff --git a/qa/standalone/special/ceph_objectstore_tool.py b/qa/standalone/special/ceph_objectstore_tool.py index a0f2cb46319..8cb36e7c39c 100755 --- a/qa/standalone/special/ceph_objectstore_tool.py +++ b/qa/standalone/special/ceph_objectstore_tool.py @@ -1708,6 +1708,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: diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index 1c947cf9ddb..60f83221fe8 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -2563,6 +2563,42 @@ int set_size( return 0; } +int clear_data_digest(ObjectStore *store, coll_t coll, ghobject_t &ghobj) { + auto ch = store->open_collection(coll); + bufferlist attr; + int r = store->getattr(ch, 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.cbegin(); + 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); + auto ch = store->open_collection(coll); + r = store->queue_transaction(ch, 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) { @@ -2892,6 +2928,7 @@ void usage(po::options_description &desc) cerr << "ceph-objectstore-tool ... remove|removeall" << std::endl; cerr << "ceph-objectstore-tool ... dump" << std::endl; cerr << "ceph-objectstore-tool ... set-size" << std::endl; + cerr << "ceph-objectstore-tool ... clear-data-digest" << std::endl; cerr << "ceph-objectstore-tool ... remove-clone-metadata " << std::endl; cerr << std::endl; cerr << " can be a JSON object description as displayed" << std::endl; @@ -3983,6 +4020,9 @@ int main(int argc, char **argv) uint64_t size = atoll(arg1.c_str()); ret = set_size(fs, coll, ghobj, size, formatter, corrupt); goto out; + } else if (objcmd == "clear-data-digest") { + ret = clear_data_digest(fs, coll, ghobj); + goto out; } else if (objcmd == "clear-snapset") { // UNDOCUMENTED: For testing zap SnapSet // IGNORE extra args since not in usage anyway