Skip to content

Commit

Permalink
ceph-dedup-tool: fix scrub
Browse files Browse the repository at this point in the history
This is less comprehensive: it only detects errors, and only sometimes,
because the ref representation may not enumerate objects explicitly.

Signed-off-by: Sage Weil <[email protected]>
  • Loading branch information
liewegas committed May 27, 2020
1 parent 73e504d commit 07f4e39
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/cls/cas/cls_cas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ static int references_chunk(cls_method_context_t hctx,
if (ret) {
return 0;
}
return -ENOENT;
return -ENOLINK;
}

CLS_INIT(cas)
Expand Down
84 changes: 43 additions & 41 deletions src/tools/ceph_dedup_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class EstimateDedupRatio : public CrawlerThread
class ChunkScrub: public CrawlerThread
{
IoCtx chunk_io_ctx;
int fixed_objects = 0;
int damaged_objects = 0;

public:
ChunkScrub(IoCtx& io_ctx, int n, int m, ObjectCursor begin, ObjectCursor end,
Expand All @@ -241,7 +241,7 @@ class ChunkScrub: public CrawlerThread
return NULL;
}
void chunk_scrub_common();
int get_fixed_objects() { return fixed_objects; }
int get_damaged_objects() { return damaged_objects; }
void print_status(Formatter *f, ostream &out);
};

Expand Down Expand Up @@ -429,60 +429,60 @@ void ChunkScrub::chunk_scrub_common()
return;
}
auto oid = i.oid;
set<hobject_t> refs;

chunk_obj_refcount real_refs;
cout << oid << std::endl;
chunk_obj_refcount refs;
{
bufferlist t;
ret = chunk_io_ctx.getxattr(oid, CHUNK_REFCOUNT_ATTR, t);
if (ret < 0) {
continue;
}
#warning fixme
//auto p = t.cbegin();
//decode(refs, p);
auto p = t.cbegin();
decode(refs, p);
}

examined_objects++;
if (refs.get_type() != chunk_obj_refcount::TYPE_BY_OBJECT) {
// we can't do anything here
continue;
}

for (auto pp : refs) {
// check all objects
chunk_obj_refcount::refs_by_object *byo =
static_cast<chunk_obj_refcount::refs_by_object*>(refs.r.get());
set<hobject_t> real_refs;

uint64_t pool_missing = 0;
uint64_t object_missing = 0;
uint64_t does_not_ref = 0;
for (auto& pp : byo->by_object) {
IoCtx target_io_ctx;
ret = rados.ioctx_create2(pp.pool, target_io_ctx);
if (ret < 0) {
cerr << "error opening pool "
<< pp.pool << ": "
<< cpp_strerror(ret) << std::endl;
cerr << oid << " ref " << pp
<< ": referencing pool does not exist" << std::endl;
++pool_missing;
continue;
}

ret = cls_cas_references_chunk(target_io_ctx, pp.oid.name, oid);
if (ret != -ENOENT) {
#warning fixme
//real_refs.get(pp);
}
}

/*
if (refs.size() != real_refs.refs.size()) {
cerr << "ref count mismatch on " << oid << std::endl;
#warning fixme
ObjectWriteOperation op;
cls_cas_chunk_set_refs(op, real_refs);
ret = chunk_io_ctx.operate(oid, &op);
if (ret < 0) {
continue;
if (ret == -ENOENT) {
cerr << oid << " ref " << pp
<< ": referencing object missing" << std::endl;
++object_missing;
} else if (ret == -ENOLINK) {
cerr << oid << " ref " << pp
<< ": referencing object does not reference chunk"
<< std::endl;
++does_not_ref;
}
fixed_objects++;
}
*/
examined_objects++;
m_cond.wait_for(l, std::chrono::nanoseconds(COND_WAIT_INTERVAL));
if (cur_time + utime_t(report_period, 0) < ceph_clock_now()) {
Formatter *formatter = Formatter::create("json-pretty");
print_status(formatter, cout);
delete formatter;
cur_time = ceph_clock_now();
if (pool_missing || object_missing || does_not_ref) {
++damaged_objects;
}
}
}
cout << "--done--" << std::endl;
}

void ChunkScrub::print_status(Formatter *f, ostream &out)
Expand All @@ -492,8 +492,8 @@ void ChunkScrub::print_status(Formatter *f, ostream &out)
f->dump_string("PID", stringify(get_pid()));
f->open_object_section("Status");
f->dump_string("Total object", stringify(total_objects));
f->dump_string("Examined objectes", stringify(examined_objects));
f->dump_string("Fixed objectes", stringify(fixed_objects));
f->dump_string("Examined objects", stringify(examined_objects));
f->dump_string("damaged objects", stringify(damaged_objects));
f->close_section();
f->flush(out);
cout << std::endl;
Expand Down Expand Up @@ -681,20 +681,20 @@ static void print_chunk_scrub()
{
uint64_t total_objects = 0;
uint64_t examined_objects = 0;
int fixed_objects = 0;
int damaged_objects = 0;

for (auto &et : estimate_threads) {
if (!total_objects) {
total_objects = et->get_total_objects();
}
examined_objects += et->get_examined_objects();
ChunkScrub *ptr = static_cast<ChunkScrub*>(et.get());
fixed_objects += ptr->get_fixed_objects();
damaged_objects += ptr->get_damaged_objects();
}

cout << " Total object : " << total_objects << std::endl;
cout << " Examined object : " << examined_objects << std::endl;
cout << " Fixed object : " << fixed_objects << std::endl;
cout << " Damaged object : " << damaged_objects << std::endl;
}

int chunk_scrub_common(const std::map < std::string, std::string > &opts,
Expand Down Expand Up @@ -860,7 +860,9 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts,
glock.unlock();

for (auto &p : estimate_threads) {
cout << "join " << std::endl;
p->join();
cout << "joined " << std::endl;
}

print_chunk_scrub();
Expand Down

0 comments on commit 07f4e39

Please sign in to comment.