OPT_GC_LIST,
OPT_GC_PROCESS,
OPT_ORPHANS_FIND,
+ OPT_ORPHANS_FINISH,
OPT_REGION_GET,
OPT_REGION_LIST,
OPT_REGION_SET,
} else if (strcmp(prev_cmd, "orphans") == 0) {
if (strcmp(cmd, "find") == 0)
return OPT_ORPHANS_FIND;
+ if (strcmp(cmd, "finish") == 0)
+ return OPT_ORPHANS_FINISH;
} else if (strcmp(prev_cmd, "metadata") == 0) {
if (strcmp(cmd, "get") == 0)
return OPT_METADATA_GET;
RGWOrphanSearchInfo info, *pinfo = NULL;
if (init_search) {
if (pool_name.empty()) {
- cerr << "ERROR: --pool-name not specified" << std::endl;
+ cerr << "ERROR: --pool not specified" << std::endl;
return EINVAL;
}
info.pool = pool_name;
}
}
+ if (opt_cmd == OPT_ORPHANS_FINISH) {
+ RGWOrphanSearch search(store, max_concurrent_ios);
+
+ if (job_id.empty()) {
+ cerr << "ERROR: --job-id not specified" << std::endl;
+ return EINVAL;
+ }
+ int ret = search.init(job_id, NULL);
+ if (ret < 0) {
+ if (ret == -ENOENT) {
+ cerr << "job not found" << std::endl;
+ }
+ return -ret;
+ }
+ ret = search.finish();
+ if (ret < 0) {
+ return -ret;
+ }
+ }
+
if (opt_cmd == OPT_USER_CHECK) {
check_bad_user_bucket_mapping(store, user_id, fix);
}
return 0;
}
+int RGWOrphanStore::remove_job(const string& job_name)
+{
+ set<string> keys;
+ keys.insert(job_name);
+
+ int r = ioctx.omap_rm_keys(oid, keys);
+ if (r < 0) {
+ return r;
+ }
+
+ return 0;
+}
+
int RGWOrphanStore::init()
{
const char *log_pool = store->get_zone_params().log_pool.name.c_str();
}
+int RGWOrphanSearch::remove_index(map<int, string>& index)
+{
+ librados::IoCtx& ioctx = orphan_store.get_ioctx();
+
+ for (map<int, string>::iterator iter = index.begin(); iter != index.end(); ++iter) {
+ int r = ioctx.remove(iter->second);
+ if (r < 0) {
+ if (r != -ENOENT) {
+ ldout(store->ctx(), 0) << "ERROR: couldn't remove " << iter->second << ": ret=" << r << dendl;
+ }
+ }
+ }
+ return 0;
+}
+
+int RGWOrphanSearch::finish()
+{
+ int r = remove_index(all_objs_index);
+ if (r < 0) {
+ ldout(store->ctx(), 0) << "ERROR: remove_index(" << all_objs_index << ") returned ret=" << r << dendl;
+ }
+ r = remove_index(buckets_instance_index);
+ if (r < 0) {
+ ldout(store->ctx(), 0) << "ERROR: remove_index(" << buckets_instance_index << ") returned ret=" << r << dendl;
+ }
+ r = remove_index(linked_objs_index);
+ if (r < 0) {
+ ldout(store->ctx(), 0) << "ERROR: remove_index(" << linked_objs_index << ") returned ret=" << r << dendl;
+ }
+
+ r = orphan_store.remove_job(search_info.job_name);
+ if (r < 0) {
+ ldout(store->ctx(), 0) << "ERROR: could not remove job name (" << search_info.job_name << ") ret=" << r << dendl;
+ }
+
+ return r;
+}
int read_job(const string& job_name, RGWOrphanSearchState& state);
int write_job(const string& job_name, const RGWOrphanSearchState& state);
+ int remove_job(const string& job_name);
int store_entries(const string& oid, const map<string, bufferlist>& entries);
class RGWOrphanSearch {
RGWRados *store;
- librados::IoCtx log_ioctx;
RGWOrphanStore orphan_store;
int handle_stat_result(map<int, list<string> >& oids, RGWRados::Object::Stat::Result& result);
int pop_and_handle_stat_op(map<int, list<string> >& oids, std::deque<RGWRados::Object::Stat>& ops);
+
+ int remove_index(map<int, string>& index);
public:
RGWOrphanSearch(RGWRados *_store, int _max_ios) : store(_store), orphan_store(store), max_concurrent_ios(_max_ios) {}
int compare_oid_indexes();
int run();
+ int finish();
};