Skip to content

Commit

Permalink
tools: Add clear-data-digest command to objectstore tool.
Browse files Browse the repository at this point in the history
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 da5832b)
  • Loading branch information
liyichao authored and smithfarm committed Jul 23, 2019
1 parent c1cd465 commit 3cf8dc8
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
21 changes: 21 additions & 0 deletions qa/standalone/special/ceph_objectstore_tool.py
Expand Up @@ -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:
Expand Down
40 changes: 40 additions & 0 deletions src/tools/ceph_objectstore_tool.cc
Expand Up @@ -2658,6 +2658,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)
{
Expand Down Expand Up @@ -2987,6 +3023,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;
Expand Down Expand Up @@ -4076,6 +4113,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
Expand Down

0 comments on commit 3cf8dc8

Please sign in to comment.