From: Yehuda Sadeh Date: Mon, 4 May 2015 22:24:00 +0000 (-0700) Subject: radosgw-admin: stat orphan objects before reporting leakage X-Git-Tag: v9.0.3~76^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=66b0090023859d97da2bbaca698b6a50c225abd0;p=ceph.git radosgw-admin: stat orphan objects before reporting leakage We don't want to report new objects as leaked, because they might just be written, and waiting to be linked to a new object. The number of seconds prior to the job initialization can be cofigured through --orphan-stale-secs (by default it's 24h). Signed-off-by: Yehuda Sadeh --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 965ee7f44f0f..8a081c6efa04 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -1119,6 +1119,7 @@ int main(int argc, char **argv) int init_search = false; int num_shards = 0; int max_concurrent_ios = 32; + uint64_t orphan_stale_secs = (24 * 3600); std::string val; std::ostringstream errs; @@ -1224,6 +1225,8 @@ int main(int argc, char **argv) num_shards = atoi(val.c_str()); } else if (ceph_argparse_witharg(args, i, &val, "--max-concurrent-ios", (char*)NULL)) { max_concurrent_ios = atoi(val.c_str()); + } else if (ceph_argparse_witharg(args, i, &val, "--orphan-stale-secs", (char*)NULL)) { + orphan_stale_secs = (uint64_t)atoi(val.c_str()); } else if (ceph_argparse_witharg(args, i, &val, "--shard-id", (char*)NULL)) { shard_id = atoi(val.c_str()); specified_shard_id = true; @@ -2554,7 +2557,7 @@ next: } if (opt_cmd == OPT_ORPHANS_FIND) { - RGWOrphanSearch search(store, max_concurrent_ios); + RGWOrphanSearch search(store, max_concurrent_ios, orphan_stale_secs); if (job_id.empty()) { cerr << "ERROR: --job-id not specified" << std::endl; @@ -2589,7 +2592,7 @@ next: } if (opt_cmd == OPT_ORPHANS_FINISH) { - RGWOrphanSearch search(store, max_concurrent_ios); + RGWOrphanSearch search(store, max_concurrent_ios, orphan_stale_secs); if (job_id.empty()) { cerr << "ERROR: --job-id not specified" << std::endl; diff --git a/src/rgw/rgw_orphan.cc b/src/rgw/rgw_orphan.cc index 8600c2e48a32..88adb82b9045 100644 --- a/src/rgw/rgw_orphan.cc +++ b/src/rgw/rgw_orphan.cc @@ -158,6 +158,7 @@ int RGWOrphanSearch::init(const string& job_name, RGWOrphanSearchInfo *info) { search_info = *info; search_info.job_name = job_name; search_info.num_shards = (info->num_shards ? info->num_shards : DEFAULT_NUM_SHARDS); + search_info.start_time = ceph_clock_now(store->ctx()); search_stage = RGWOrphanSearchStage(ORPHAN_SEARCH_STAGE_INIT); RGWOrphanSearchState state; @@ -618,6 +619,18 @@ int RGWOrphanSearch::compare_oid_indexes() librados::IoCtx& ioctx = orphan_store.get_ioctx(); + librados::IoCtx data_ioctx; + + librados::Rados *rados = store->get_rados(); + + int ret = rados->ioctx_create(search_info.pool.c_str(), data_ioctx); + if (ret < 0) { + lderr(store->ctx()) << __func__ << ": ioctx_create() returned ret=" << ret << dendl; + return ret; + } + + uint64_t time_threshold = search_info.start_time.sec() - stale_secs; + map::iterator liter = linked_objs_index.begin(); map::iterator aiter = all_objs_index.begin(); @@ -655,6 +668,18 @@ int RGWOrphanSearch::compare_oid_indexes() continue; } + time_t mtime; + r = data_ioctx.stat(key, NULL, &mtime); + if (r < 0) { + if (r != -ENOENT) { + lderr(store->ctx()) << "ERROR: ioctx.stat(" << key << ") returned ret=" << r << dendl; + } + continue; + } + if (stale_secs && (uint64_t)mtime >= time_threshold) { + ldout(store->ctx(), 20) << "skipping: " << key << " (mtime=" << mtime << " threshold=" << time_threshold << ")" << dendl; + continue; + } ldout(store->ctx(), 20) << "leaked: " << key << dendl; cout << "leaked: " << key << std::endl; } while (!done); diff --git a/src/rgw/rgw_orphan.h b/src/rgw/rgw_orphan.h index 076d07eb589d..ad539b262ffd 100644 --- a/src/rgw/rgw_orphan.h +++ b/src/rgw/rgw_orphan.h @@ -72,11 +72,14 @@ struct RGWOrphanSearchInfo { string job_name; string pool; uint16_t num_shards; + utime_t start_time; + void encode(bufferlist& bl) const { ENCODE_START(1, 1, bl); ::encode(job_name, bl); ::encode(pool, bl); ::encode(num_shards, bl); + ::encode(start_time, bl); ENCODE_FINISH(bl); } @@ -85,6 +88,7 @@ struct RGWOrphanSearchInfo { ::decode(job_name, bl); ::decode(pool, bl); ::decode(num_shards, bl); + ::decode(start_time, bl); DECODE_FINISH(bl); } @@ -156,6 +160,7 @@ class RGWOrphanSearch { string index_objs_prefix; uint16_t max_concurrent_ios; + uint64_t stale_secs; struct log_iter_info { string oid; @@ -176,7 +181,7 @@ class RGWOrphanSearch { int remove_index(map& index); public: - RGWOrphanSearch(RGWRados *_store, int _max_ios) : store(_store), orphan_store(store), max_concurrent_ios(_max_ios) {} + RGWOrphanSearch(RGWRados *_store, int _max_ios, uint64_t _stale_secs) : store(_store), orphan_store(store), max_concurrent_ios(_max_ios), stale_secs(_stale_secs) {} int save_state() { RGWOrphanSearchState state;