diff options
author | Sage Weil <sage@newdream.net> | 2020-05-21 19:09:15 +0200 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2020-05-27 17:44:31 +0200 |
commit | 07f4e396955630f9e9350bbcc247e9f2fa73dccc (patch) | |
tree | fac1d8190c237f9378b2790c553000dfea854766 /src/tools | |
parent | cls_cas: 0 on dup get of same ref (diff) | |
download | ceph-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.cc | 84 |
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(); |