]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add admin rest api for bucket sync.
authorZhang Shaowen <zhangshaowen@cmss.chinamobile.com>
Thu, 16 Nov 2017 09:36:31 +0000 (17:36 +0800)
committerzhang Shaowen <zhangshaowen@cmss.chinamobile.com>
Mon, 26 Aug 2019 01:56:57 +0000 (09:56 +0800)
Signed-off-by: Zhang Shaowen <zhangshaowen@cmss.chinamobile.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_bucket.cc
src/rgw/rgw_bucket.h
src/rgw/rgw_rest_bucket.cc

index 908de6af4ff72737d2d286c381e41a3530c140dc..9daf73a2d76505ea121b5bd3bff155551bb0a158 100644 (file)
@@ -7320,29 +7320,19 @@ next:
     if (bucket_name.empty()) {
       cerr << "ERROR: bucket not specified" << std::endl;
       return EINVAL;
+    } 
+    if (opt_cmd == OPT_BUCKET_SYNC_DISABLE) {
+      bucket_op.set_sync_bucket(false);
+    } else {
+      bucket_op.set_sync_bucket(true);
     }
-
-    if (ret < 0) {
-      cerr << "could not init realm " << ": " << cpp_strerror(-ret) << std::endl;
-      return ret;
-    }
-    RGWPeriod period;
-    ret = period.init(g_ceph_context, store->svc()->sysobj, realm_id, realm_name, true);
+    bucket_op.set_tenant(tenant);
+    string err_msg;
+    ret = RGWBucketAdminOp::sync_bucket(store, bucket_op, &err_msg);
     if (ret < 0) {
-      cerr << "failed to init period " << ": " << cpp_strerror(-ret) << std::endl;
-      return ret;
-    }
-
-    if (!store->svc()->zone->is_meta_master()) {
-      cerr << "failed to update bucket sync: only allowed on meta master zone "  << std::endl;
-      cerr << period.get_master_zone() << " | " << period.get_realm() << std::endl;
-      return EINVAL;
-    }
-
-    rgw_obj obj(bucket, object);
-    ret = set_bucket_sync_enabled(store, opt_cmd, tenant, bucket_name);
-    if (ret < 0)
+      cerr << err_msg << std::endl;
       return -ret;
+    }
   }
 
   if (opt_cmd == OPT_BUCKET_SYNC_STATUS) {
index 549b75b1a3a352877f903b276ed0b49fca4dcd5e..f97275399a7e742e9f9b97130c1796559252c1a4 100644 (file)
@@ -1068,6 +1068,54 @@ int RGWBucket::check_index(RGWBucketAdminOpState& op_state,
   return 0;
 }
 
+int RGWBucket::sync(RGWBucketAdminOpState& op_state, std::string *err_msg)
+{
+  if (!store->getRados()->is_meta_master()) {
+    set_err_msg(err_msg, "ERROR: failed to update bucket sync: only allowed on meta master zone");
+    return EINVAL;
+  }
+  bool sync = op_state.will_sync_bucket();
+  if (sync) {
+    bucket_info.flags &= ~BUCKET_DATASYNC_DISABLED;
+  } else {
+    bucket_info.flags |= BUCKET_DATASYNC_DISABLED;
+  }
+
+  int r = store->getRados()->put_bucket_instance_info(bucket_info, false, real_time(), &attrs);
+  if (r < 0) {
+    set_err_msg(err_msg, "ERROR: failed writing bucket instance info:" + cpp_strerror(-r));
+    return r;
+  }
+
+  int shards_num = bucket_info.num_shards? bucket_info.num_shards : 1;
+  int shard_id = bucket_info.num_shards? 0 : -1;
+
+  if (!sync) {
+    r = store->getRados()->stop_bi_log_entries(bucket_info, -1);
+    if (r < 0) {
+      set_err_msg(err_msg, "ERROR: failed writing stop bilog:" + cpp_strerror(-r));
+      return r;
+    }
+  } else {
+    r = store->getRados()->resync_bi_log_entries(bucket_info, -1);
+    if (r < 0) {
+      set_err_msg(err_msg, "ERROR: failed writing resync bilog:" + cpp_strerror(-r));
+      return r;
+    }
+  }
+
+  for (int i = 0; i < shards_num; ++i, ++shard_id) {
+    r = store->getRados()->data_log->add_entry(bucket_info.bucket, shard_id);
+    if (r < 0) {
+      set_err_msg(err_msg, "ERROR: failed writing data log:" + cpp_strerror(-r));
+      return r;
+    }
+  }
+
+  return 0;
+}
+
+
 int RGWBucket::policy_bl_to_stream(bufferlist& bl, ostream& o)
 {
   RGWAccessControlPolicy_S3 policy(g_ceph_context);
@@ -1292,6 +1340,17 @@ int RGWBucketAdminOp::remove_object(RGWRadosStore *store, RGWBucketAdminOpState&
   return bucket.remove_object(op_state);
 }
 
+int RGWBucketAdminOp::sync_bucket(RGWRadosStore *store, RGWBucketAdminOpState& op_state, string *err_msg)
+{
+  RGWBucket bucket;
+  int ret = bucket.init(store, op_state, null_yield);
+  if (ret < 0)
+  {
+    return ret;
+  }
+  return bucket.sync(op_state, err_msg);
+}
+
 static int bucket_stats(RGWRadosStore *store, const std::string& tenant_name, std::string&  bucket_name, Formatter *formatter)
 {
   RGWBucketInfo bucket_info;
index 7b675386a47e956f7b0958dbe5ad8fb7cee770b4..34f1f0b92d43289c19487ac87ee8c4568a55ef60 100644 (file)
@@ -243,6 +243,7 @@ struct RGWBucketAdminOpState {
   bool fix_index;
   bool delete_child_objects;
   bool bucket_stored;
+  bool sync_bucket;
   int max_aio = 0;
 
   rgw_bucket bucket;
@@ -260,6 +261,9 @@ struct RGWBucketAdminOpState {
     if (!user_id.empty())
       uid = user_id;
   }
+  void set_tenant(const std::string& tenant_str) {
+    uid.tenant = tenant_str;
+  }
   void set_bucket_name(const std::string& bucket_str) {
     bucket_name = bucket_str; 
   }
@@ -274,10 +278,13 @@ struct RGWBucketAdminOpState {
   }
 
 
+  void set_sync_bucket(bool value) { sync_bucket = value; }
+
   rgw_user& get_user_id() { return uid; }
   std::string& get_user_display_name() { return display_name; }
   std::string& get_bucket_name() { return bucket_name; }
   std::string& get_object_name() { return object_name; }
+  std::string& get_tenant() { return uid.tenant; }
 
   rgw_bucket& get_bucket() { return bucket; }
   void set_bucket(rgw_bucket& _bucket) {
@@ -298,10 +305,11 @@ struct RGWBucketAdminOpState {
   bool is_system_op() { return uid.empty(); }
   bool has_bucket_stored() { return bucket_stored; }
   int get_max_aio() { return max_aio; }
+  bool will_sync_bucket() { return sync_bucket; }
 
   RGWBucketAdminOpState() : list_buckets(false), stat_buckets(false), check_objects(false), 
                             fix_index(false), delete_child_objects(false),
-                            bucket_stored(false)  {}
+                            bucket_stored(false), sync_bucket(true)  {}
 };
 
 /*
@@ -351,6 +359,7 @@ public:
   int remove_object(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
   int policy_bl_to_stream(bufferlist& bl, ostream& o);
   int get_policy(RGWBucketAdminOpState& op_state, RGWAccessControlPolicy& policy, optional_yield y);
+  int sync(RGWBucketAdminOpState& op_state, std::string *err_msg = NULL);
 
   void clear_failure() { failure = false; }
 
@@ -392,6 +401,8 @@ public:
                            RGWFormatterFlusher& flusher);
   static int fix_obj_expiry(rgw::sal::RGWRadosStore *store, RGWBucketAdminOpState& op_state,
                            RGWFormatterFlusher& flusher, bool dry_run = false);
+
+  static int sync_bucket(rgw::sal::RGWRadosStore *store, RGWBucketAdminOpState& op_state, string *err_msg = NULL);
 };
 
 
index 295820db600258b7f9e72518bed281d1133c0941..f5526a71f04496fed6434e83773f1d550d0de2e3 100644 (file)
@@ -289,6 +289,38 @@ void RGWOp_Set_Bucket_Quota::execute()
   http_ret = RGWBucketAdminOp::set_quota(store, op_state);
 }
 
+class RGWOp_Sync_Bucket : public RGWRESTOp {
+
+public:
+  RGWOp_Sync_Bucket() {}
+
+  int check_caps(RGWUserCaps& caps) override {
+    return caps.check_cap("buckets", RGW_CAP_WRITE);
+  }
+
+  void execute() override;
+
+  const char* name() const override { return "sync_bucket"; }
+}
+
+void RGWOp_Sync_Bucket::execute()
+{
+  std::string bucket;
+  std::string tenant;
+  bool sync_bucket;
+
+  RGWBucketAdminOpState op_state;
+  RESTArgs::get_string(s, "bucket", bucket, &bucket);
+  RESTArgs::get_string(s, "tenant", tenant, &tenant);
+  RESTArgs::get_bool(s, "sync", true, &sync_bucket);
+
+  op_state.set_bucket_name(bucket);
+  op_state.set_tenant(tenant);
+  op_state.set_sync_bucket(sync_bucket);
+
+  http_ret = RGWBucketAdminOp::sync_bucket(store, op_state);
+}
+
 class RGWOp_Object_Remove: public RGWRESTOp {
 
 public:
@@ -319,6 +351,7 @@ void RGWOp_Object_Remove::execute()
   http_ret = RGWBucketAdminOp::remove_object(store, op_state);
 }
 
+
 RGWOp *RGWHandler_Bucket::op_get()
 {