]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw_admin: add --remove-bad flag to bucket check
authorYehuda Sadeh <yehuda@redhat.com>
Wed, 22 Apr 2015 23:04:35 +0000 (16:04 -0700)
committerLoic Dachary <ldachary@redhat.com>
Tue, 28 Jul 2015 15:54:42 +0000 (17:54 +0200)
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 <yehuda@redhat.com>
(cherry picked from commit 06d67d9139a95b704b80de527381fd1bbf7981ce)

src/rgw/rgw_admin.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index a7a00390c02bfe2caecbd7ba33bd468a5126e4eb..832417a0f07a1617393fc8923ea451e851683522 100644 (file)
@@ -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<string, bool> 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);
     }
index 38718b44bb5fbeb45875fae741f294ed4a53dd2c..0584bcf24396694dca60701acdad32a25ab2c531 100644 (file)
@@ -2966,7 +2966,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;
@@ -3016,19 +3016,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<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;
 }
index b1cfac87deceb52ab89ada967299e4a88de3dc18..51b6a728ff9db0d0779662bdbfa6ec56b949d463 100644 (file)
@@ -2031,7 +2031,7 @@ public:
                          map<RGWObjCategory, RGWStorageStats> *calculated_stats);
   int bucket_rebuild_index(rgw_bucket& bucket);
   int remove_objs_from_index(rgw_bucket& bucket, list<rgw_obj_key>& 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);