}
-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);
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;
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;
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 */
}
}
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<string, bool> categories;
// 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)) {
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);
}
* 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;
return -EIO;
}
- librados::ObjectWriteOperation wop;
+ if (copy_obj) {
+ librados::ObjectWriteOperation wop;
- wop.mtime(&mtime);
+ wop.mtime(&mtime);
- map<string, bufferlist>::iterator iter;
- for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
- wop.setxattr(iter->first.c_str(), iter->second);
+ map<string, bufferlist>::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;
}