summaryrefslogtreecommitdiffstats
path: root/src/tools
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2020-05-21 19:09:15 +0200
committerSage Weil <sage@newdream.net>2020-05-27 17:44:31 +0200
commit07f4e396955630f9e9350bbcc247e9f2fa73dccc (patch)
treefac1d8190c237f9378b2790c553000dfea854766 /src/tools
parentcls_cas: 0 on dup get of same ref (diff)
downloadceph-07f4e396955630f9e9350bbcc247e9f2fa73dccc.tar.xz
ceph-07f4e396955630f9e9350bbcc247e9f2fa73dccc.zip
ceph-dedup-tool: fix scrub
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 <sage@newdream.net>
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/ceph_dedup_tool.cc84
1 files changed, 43 insertions, 41 deletions
diff --git a/src/tools/ceph_dedup_tool.cc b/src/tools/ceph_dedup_tool.cc
index 44574b8043f..6129269fa86 100644
--- a/src/tools/ceph_dedup_tool.cc
+++ b/src/tools/ceph_dedup_tool.cc
@@ -229,7 +229,7 @@ public:
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,
@@ -241,7 +241,7 @@ public:
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);
};
@@ -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)
@@ -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;
@@ -681,7 +681,7 @@ 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) {
@@ -689,12 +689,12 @@ static void print_chunk_scrub()
}
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,
@@ -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();