tools: Add clear-data-digest command to objectstore tool.

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>
This commit is contained in:
liyichao 2018-12-05 12:22:20 +08:00 committed by Li Yichao
parent 948efa96bb
commit da5832b2b4
2 changed files with 61 additions and 0 deletions

View File

@ -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:

View File

@ -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 ... <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;
@ -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