]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add a fix_lc_shards AdminOp that can fix lc shards for all the buckets
authorAbhishek Lekshmanan <abhishek@suse.com>
Thu, 7 Mar 2019 13:12:49 +0000 (14:12 +0100)
committerAbhishek Lekshmanan <abhishek@suse.com>
Fri, 12 Apr 2019 16:08:27 +0000 (18:08 +0200)
The output would be a list of bucket names and their fix status, currently
buckets which do not need a fix will also be logged with a status of 0.

Signed-off-by: Abhishek Lekshmanan <abhishek@suse.com>
(cherry picked from commit 767a16815b85e351eafb17fa369f580761e2f22a)

src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h

index b66f4dc72eed2f8c2f9b15fe1b801f60a7227d38..04db4455cb3571b27d6c32494a2773f931e150b8 100644 (file)
@@ -31,6 +31,7 @@
 // until everything is moved from rgw_common
 #include "rgw_common.h"
 #include "rgw_reshard.h"
+#include "rgw_lc.h"
 #include "cls/user/cls_user_types.h"
 
 #define dout_context g_ceph_context
@@ -1877,6 +1878,87 @@ int RGWBucketAdminOp::clear_stale_instances(RGWRados *store,
   return process_stale_instances(store, op_state, flusher, process_f);
 }
 
+static int fix_single_bucket_lc(RGWRados *store,
+                                const std::string& tenant_name,
+                                const std::string& bucket_name)
+{
+  auto obj_ctx = store->svc.sysobj->init_obj_ctx();
+  RGWBucketInfo bucket_info;
+  map <std::string, bufferlist> bucket_attrs;
+  int ret = store->get_bucket_info(obj_ctx, tenant_name, bucket_name,
+                                   bucket_info, nullptr, &bucket_attrs);
+  if (ret < 0) {
+    // TODO: Should we handle the case where the bucket could've been removed between
+    // listing and fetching?
+    return ret;
+  }
+
+  return rgw::lc::fix_lc_shard_entry(store, bucket_info, bucket_attrs);
+}
+
+static void format_lc_status(Formatter* formatter,
+                             const std::string& tenant_name,
+                             const std::string& bucket_name,
+                             int status)
+{
+  formatter->open_object_section("bucket_entry");
+  std::string entry = tenant_name.empty() ? bucket_name : tenant_name + "/" + bucket_name;
+  formatter->dump_string("bucket", entry);
+  formatter->dump_int("status", status);
+  formatter->close_section(); // bucket_entry
+}
+
+static void process_single_lc_entry(RGWRados *store, Formatter *formatter,
+                                    const std::string& tenant_name,
+                                    const std::string& bucket_name)
+{
+  int ret = fix_single_bucket_lc(store, tenant_name, bucket_name);
+  format_lc_status(formatter, tenant_name, bucket_name, -ret);
+}
+
+int RGWBucketAdminOp::fix_lc_shards(RGWRados *store,
+                                    RGWBucketAdminOpState& op_state,
+                                    RGWFormatterFlusher& flusher)
+{
+  std::string marker;
+  void *handle;
+  Formatter *formatter = flusher.get_formatter();
+  static constexpr auto default_max_keys = 1000;
+
+  int ret = store->meta_mgr->list_keys_init("bucket", marker, &handle);
+  if (ret < 0) {
+    std::cerr << "ERROR: can't get key: " << cpp_strerror(-ret) << std::endl;
+    return ret;
+  }
+
+  bool truncated;
+  if (const std::string& bucket_name = op_state.get_bucket_name();
+      ! bucket_name.empty()) {
+    const rgw_user user_id = op_state.get_user_id();
+    process_single_lc_entry(store, formatter, user_id.tenant, bucket_name);
+  } else {
+    formatter->open_array_section("lc_fix_status");
+    do {
+      list<std::string> keys;
+      ret = store->meta_mgr->list_keys_next(handle, default_max_keys, keys, &truncated);
+      if (ret < 0 && ret != -ENOENT) {
+        std::cerr << "ERROR: lists_keys_next(): " << cpp_strerror(-ret) << std::endl;
+        return ret;
+      } if (ret != -ENOENT) {
+        for (const auto &key:keys) {
+          auto [tenant_name, bucket_name] = split_tenant(key);
+          process_single_lc_entry(store, formatter, tenant_name, bucket_name);
+        }
+      }
+      formatter->flush(cout); // regularly flush every 1k entries
+    } while (truncated);
+    formatter->close_section(); // lc_fix_status
+  }
+  formatter->flush(cout);
+  return 0;
+
+}
+
 void rgw_data_change::dump(Formatter *f) const
 {
   string type;
index 2834fbf78d7870d1f0e950f3cee89442478c67e2..c0a94230b1ae3559331e82455846ed22fcf3a101 100644 (file)
@@ -365,6 +365,8 @@ public:
 
   static int clear_stale_instances(RGWRados *store, RGWBucketAdminOpState& op_state,
                                   RGWFormatterFlusher& flusher);
+  static int fix_lc_shards(RGWRados *store, RGWBucketAdminOpState& op_state,
+                           RGWFormatterFlusher& flusher);
 };