From c2c29293cd121fe16c1f09fa49ef3892633aa4e2 Mon Sep 17 00:00:00 2001 From: myoungwon oh Date: Thu, 27 Jun 2019 22:39:06 +0900 Subject: [PATCH] src/tools: fix chunk_scrub This commit makes chunk_scrub as a chunk_pool-based operation. chunk_scrub procedure: 1. find references in the chunk_pool 2. check whether the reference exists in a base_pool 3. fix references Signed-off-by: Myoungwon Oh --- doc/dev/deduplication.rst | 2 +- qa/workunits/rados/test_dedup_tool.sh | 9 ++-- src/tools/ceph_dedup_tool.cc | 78 ++++++++++++++++----------- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/doc/dev/deduplication.rst b/doc/dev/deduplication.rst index 62b487d3c64..bcb888db3aa 100644 --- a/doc/dev/deduplication.rst +++ b/doc/dev/deduplication.rst @@ -254,5 +254,5 @@ and fixing the reference count. (manifest object (has ref), chunk 1(no ref)). To fix such inconsistency, ceph-dedup-tool supports chunk_scrub. :: - ceph-dedup-tool --op chunk_scrub --pool $POOL --chunk_pool $CHUNK_POOL + ceph-dedup-tool --op chunk_scrub --chunk_pool $CHUNK_POOL diff --git a/qa/workunits/rados/test_dedup_tool.sh b/qa/workunits/rados/test_dedup_tool.sh index 6dc84d2d13b..a6e404ee6af 100755 --- a/qa/workunits/rados/test_dedup_tool.sh +++ b/qa/workunits/rados/test_dedup_tool.sh @@ -133,12 +133,13 @@ function test_dedup_chunk_scrub() rados ls -p $CHUNK_POOL CHUNK_OID=$(echo -n "There hi" | sha1sum) - $DEDUP_TOOL --op add_chunk_ref --pool $POOL --chunk_pool $CHUNK_POOL --object $CHUNK_OID --target_ref bar - RESULT=$($DEDUP_TOOL --op get_chunk_ref --pool $POOL --chunk_pool $CHUNK_POOL --object $CHUNK_OID) + POOL_ID=$(ceph osd pool ls detail | grep $POOL | awk '{print$2}') + $DEDUP_TOOL --op add-chunk-ref --chunk-pool $CHUNK_POOL --object $CHUNK_OID --target-ref bar --target-ref-pool-id $POOL_ID + RESULT=$($DEDUP_TOOL --op get-chunk-ref --chunk-pool $CHUNK_POOL --object $CHUNK_OID) - $DEDUP_TOOL --op chunk_scrub --pool $POOL --chunk_pool $CHUNK_POOL + $DEDUP_TOOL --op chunk-scrub --chunk-pool $CHUNK_POOL - RESULT=$($DEDUP_TOOL --op get_chunk_ref --pool $POOL --chunk_pool $CHUNK_POOL --object $CHUNK_OID | grep bar) + RESULT=$($DEDUP_TOOL --op get-chunk-ref --chunk-pool $CHUNK_POOL --object $CHUNK_OID | grep bar) if [ -n "$RESULT" ] ; then $CEPH_TOOL osd pool delete $POOL $POOL --yes-i-really-really-mean-it $CEPH_TOOL osd pool delete $CHUNK_POOL $CHUNK_POOL --yes-i-really-really-mean-it diff --git a/src/tools/ceph_dedup_tool.cc b/src/tools/ceph_dedup_tool.cc index eab1a5a243d..56ba56ca69b 100644 --- a/src/tools/ceph_dedup_tool.cc +++ b/src/tools/ceph_dedup_tool.cc @@ -458,6 +458,18 @@ void ChunkScrub::chunk_scrub_common() ObjectCursor shard_end; int ret; utime_t cur_time = ceph_clock_now(); + Rados rados; + + ret = rados.init_with_context(g_ceph_context); + if (ret < 0) { + cerr << "couldn't initialize rados: " << cpp_strerror(ret) << std::endl; + return; + } + ret = rados.connect(); + if (ret) { + cerr << "couldn't connect to cluster: " << cpp_strerror(ret) << std::endl; + return; + } chunk_io_ctx.object_list_slice( begin, @@ -494,7 +506,16 @@ void ChunkScrub::chunk_scrub_common() } for (auto pp : refs) { - ret = cls_chunk_has_chunk(io_ctx, pp.oid.name, oid); + 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; + continue; + } + + ret = cls_chunk_has_chunk(target_io_ctx, pp.oid.name, oid); if (ret != -ENOENT) { real_refs.insert(pp); } @@ -753,7 +774,7 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, Rados rados; IoCtx io_ctx, chunk_io_ctx; std::string object_name, target_object_name; - string pool_name, chunk_pool_name, op_name; + string chunk_pool_name, op_name; int ret; unsigned max_thread = default_max_thread; std::map::const_iterator i; @@ -764,12 +785,6 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, list pool_names; map stats; - i = opts.find("pool"); - if (i != opts.end()) { - pool_name = i->second.c_str(); - } else { - usage_exit(); - } i = opts.find("op_name"); if (i != opts.end()) { op_name= i->second.c_str(); @@ -809,17 +824,6 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, ret = -1; goto out; } - if (pool_name.empty()) { - cerr << "--create-pool requested but pool_name was not specified!" << std::endl; - usage_exit(); - } - ret = rados.ioctx_create(pool_name.c_str(), io_ctx); - if (ret < 0) { - cerr << "error opening pool " - << pool_name << ": " - << cpp_strerror(ret) << std::endl; - goto out; - } ret = rados.ioctx_create(chunk_pool_name.c_str(), chunk_io_ctx); if (ret < 0) { cerr << "error opening pool " @@ -828,8 +832,9 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, goto out; } - if (op_name == "add_chunk_ref") { + if (op_name == "add-chunk-ref") { string target_object_name; + uint64_t pool_id; i = opts.find("object"); if (i != opts.end()) { object_name = i->second.c_str(); @@ -842,6 +847,14 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, } else { usage_exit(); } + i = opts.find("target-ref-pool-id"); + if (i != opts.end()) { + if (rados_sistrtoll(i, &pool_id)) { + return -EINVAL; + } + } else { + usage_exit(); + } set refs; ret = cls_chunk_refcount_read(chunk_io_ctx, object_name, &refs); @@ -858,7 +871,7 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, if (ret < 0) { return ret; } - hobject_t oid(sobject_t(target_object_name, CEPH_NOSNAP), "", hash, -1, ""); + hobject_t oid(sobject_t(target_object_name, CEPH_NOSNAP), "", hash, pool_id, ""); refs.insert(oid); ObjectWriteOperation op; @@ -870,7 +883,7 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, return ret; - } else if (op_name == "get_chunk_ref") { + } else if (op_name == "get-chunk-ref") { i = opts.find("object"); if (i != opts.end()) { object_name = i->second.c_str(); @@ -888,22 +901,21 @@ int chunk_scrub_common(const std::map < std::string, std::string > &opts, } glock.Lock(); - begin = io_ctx.object_list_begin(); - end = io_ctx.object_list_end(); - pool_names.push_back(pool_name); + begin = chunk_io_ctx.object_list_begin(); + end = chunk_io_ctx.object_list_end(); + pool_names.push_back(chunk_pool_name); ret = rados.get_pool_stats(pool_names, stats); if (ret < 0) { cerr << "error fetching pool stats: " << cpp_strerror(ret) << std::endl; glock.Unlock(); return ret; } - if (stats.find(pool_name) == stats.end()) { - cerr << "stats can not find pool name: " << pool_name << std::endl; + if (stats.find(chunk_pool_name) == stats.end()) { + cerr << "stats can not find pool name: " << chunk_pool_name << std::endl; glock.Unlock(); return ret; } - //librados::pool_stat_t& s = stats[pool_name]; - s = stats[pool_name]; + s = stats[chunk_pool_name]; for (unsigned i = 0; i < max_thread; i++) { std::unique_ptr ptr (new ChunkScrub(io_ctx, i, max_thread, begin, end, chunk_io_ctx, @@ -968,6 +980,8 @@ int main(int argc, const char **argv) opts["chunk-pool"] = val; } else if (ceph_argparse_witharg(args, i, &val, "--target-ref", (char*)NULL)) { opts["target-ref"] = val; + } else if (ceph_argparse_witharg(args, i, &val, "--target-ref-pool-id", (char*)NULL)) { + opts["target-ref-pool-id"] = val; } else if (ceph_argparse_witharg(args, i, &val, "--max-thread", (char*)NULL)) { opts["max-thread"] = val; } else if (ceph_argparse_witharg(args, i, &val, "--report-period", (char*)NULL)) { @@ -999,11 +1013,11 @@ int main(int argc, const char **argv) if (op_name == "estimate") { return estimate_dedup_ratio(opts, args); - } else if (op_name == "chunk_scrub") { + } else if (op_name == "chunk-scrub") { return chunk_scrub_common(opts, args); - } else if (op_name == "add_chunk_ref") { + } else if (op_name == "add-chunk-ref") { return chunk_scrub_common(opts, args); - } else if (op_name == "get_chunk_ref") { + } else if (op_name == "get-chunk-ref") { return chunk_scrub_common(opts, args); } else { usage(); -- 2.39.5