From 06d67d9139a95b704b80de527381fd1bbf7981ce Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 22 Apr 2015 16:04:35 -0700 Subject: [PATCH] rgw_admin: add --remove-bad flag to bucket check Add this flag so that the bad object will be removed (should be called only after user has verified that objects content is correct). Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_admin.cc | 20 ++++++++++++++------ src/rgw/rgw_rados.cc | 30 +++++++++++++++++++++--------- src/rgw/rgw_rados.h | 2 +- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 63971d8f708fa..b6fdd1ccca627 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -908,7 +908,7 @@ int check_min_obj_stripe_size(RGWRados *store, RGWBucketInfo& bucket_info, rgw_o } -int check_obj_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_obj_key& key, bool fix, Formatter *f) { +int check_obj_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_obj_key& key, bool fix, bool remove_bad, Formatter *f) { f->open_object_section("object"); f->open_object_section("key"); f->dump_string("name", key.name); @@ -936,8 +936,8 @@ int check_obj_locator_underscore(RGWBucketInfo& bucket_info, rgw_obj& obj, rgw_o string status = (needs_fixing ? "needs_fixing" : "ok"); - if (needs_fixing && fix) { - ret = store->fix_head_obj_locator(obj.bucket, key); + if ((needs_fixing || remove_bad) && fix) { + ret = store->fix_head_obj_locator(obj.bucket, needs_fixing, remove_bad, key); if (ret < 0) { cerr << "ERROR: fix_head_object_locator() returned ret=" << ret << std::endl; goto done; @@ -953,8 +953,13 @@ done: return 0; } -int do_check_object_locator(const string& bucket_name, bool fix, Formatter *f) +int do_check_object_locator(const string& bucket_name, bool fix, bool remove_bad, Formatter *f) { + if (remove_bad && !fix) { + cerr << "ERROR: can't have remove_bad specified without fix" << std::endl; + return -EINVAL; + } + RGWBucketInfo bucket_info; rgw_bucket bucket; string bucket_id; @@ -1005,7 +1010,7 @@ int do_check_object_locator(const string& bucket_name, bool fix, Formatter *f) rgw_obj obj(bucket, key); if (key.name[0] == '_') { - ret = check_obj_locator_underscore(bucket_info, obj, key, fix, f); + ret = check_obj_locator_underscore(bucket_info, obj, key, fix, remove_bad, f); /* ignore return code, move to the next one */ } } @@ -1056,6 +1061,7 @@ int main(int argc, char **argv) int yes_i_really_mean_it = false; int delete_child_objects = false; int fix = false; + int remove_bad = false; int check_head_obj_locator = false; int max_buckets = -1; map categories; @@ -1241,6 +1247,8 @@ int main(int argc, char **argv) // do nothing } else if (ceph_argparse_binary_flag(args, i, &fix, NULL, "--fix", (char*)NULL)) { // do nothing + } else if (ceph_argparse_binary_flag(args, i, &remove_bad, NULL, "--remove-bad", (char*)NULL)) { + // do nothing } else if (ceph_argparse_binary_flag(args, i, &check_head_obj_locator, NULL, "--check-head-obj-locator", (char*)NULL)) { // do nothing } else if (ceph_argparse_binary_flag(args, i, &check_objects, NULL, "--check-objects", (char*)NULL)) { @@ -2468,7 +2476,7 @@ next: cerr << "ERROR: need to specify bucket name" << std::endl; return EINVAL; } - do_check_object_locator(bucket_name, fix, formatter); + do_check_object_locator(bucket_name, fix, remove_bad, formatter); } else { RGWBucketAdminOp::check_index(store, bucket_op, f); } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index e09cb18693143..8ef9c7e7908b8 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2971,7 +2971,7 @@ int RGWRados::get_obj_ref(const rgw_obj& obj, rgw_rados_ref *ref, rgw_bucket *bu * fixes an issue where head objects were supposed to have a locator created, but ended * up without one */ -int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, rgw_obj_key& key) +int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remove_bad, rgw_obj_key& key) { string oid; string locator; @@ -3021,19 +3021,31 @@ int RGWRados::fix_head_obj_locator(rgw_bucket& bucket, rgw_obj_key& key) return -EIO; } - librados::ObjectWriteOperation wop; + if (copy_obj) { + librados::ObjectWriteOperation wop; - wop.mtime(&mtime); + wop.mtime(&mtime); - map::iterator iter; - for (iter = attrs.begin(); iter != attrs.end(); ++iter) { - wop.setxattr(iter->first.c_str(), iter->second); + map::iterator iter; + for (iter = attrs.begin(); iter != attrs.end(); ++iter) { + wop.setxattr(iter->first.c_str(), iter->second); + } + + wop.write(0, data); + + ioctx.locator_set_key(locator); + ioctx.operate(oid, &wop); } - wop.write(0, data); + if (remove_bad) { + ioctx.locator_set_key(string()); - ioctx.locator_set_key(locator); - ioctx.operate(oid, &wop); + ret = ioctx.remove(oid); + if (ret < 0) { + lderr(cct) << "ERROR: failed to remove original bad object" << dendl; + return ret; + } + } return 0; } diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 240ff80db9b08..a8d42dd182671 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2027,7 +2027,7 @@ public: map *calculated_stats); int bucket_rebuild_index(rgw_bucket& bucket); int remove_objs_from_index(rgw_bucket& bucket, list& oid_list); - int fix_head_obj_locator(rgw_bucket& bucket, rgw_obj_key& key); + int fix_head_obj_locator(rgw_bucket& bucket, bool copy_obj, bool remove_bad, rgw_obj_key& key); int cls_user_get_header(const string& user_id, cls_user_header *header); int cls_user_get_header_async(const string& user_id, RGWGetUserHeader_CB *ctx); -- 2.39.5