From: Zhang Shaowen Date: Thu, 16 Nov 2017 09:36:31 +0000 (+0800) Subject: rgw: add admin rest api for bucket sync. X-Git-Tag: v15.1.0~1490^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=44982c8582fb1b718b9ccc9e19fff1d496dd33cb;p=ceph.git rgw: add admin rest api for bucket sync. Signed-off-by: Zhang Shaowen --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 908de6af4ff7..9daf73a2d765 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -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) { diff --git a/src/rgw/rgw_bucket.cc b/src/rgw/rgw_bucket.cc index 549b75b1a3a3..f97275399a7e 100644 --- a/src/rgw/rgw_bucket.cc +++ b/src/rgw/rgw_bucket.cc @@ -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; diff --git a/src/rgw/rgw_bucket.h b/src/rgw/rgw_bucket.h index 7b675386a47e..34f1f0b92d43 100644 --- a/src/rgw/rgw_bucket.h +++ b/src/rgw/rgw_bucket.h @@ -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); }; diff --git a/src/rgw/rgw_rest_bucket.cc b/src/rgw/rgw_rest_bucket.cc index 295820db6002..f5526a71f044 100644 --- a/src/rgw/rgw_rest_bucket.cc +++ b/src/rgw/rgw_rest_bucket.cc @@ -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() {