From: Abhishek Lekshmanan Date: Mon, 4 Mar 2019 18:10:45 +0000 (+0100) Subject: rgw admin: implement a lc fix option X-Git-Tag: v14.2.1~29^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9ee376b866cf35915bd315d3926d9ea77934f3d0;p=ceph.git rgw admin: implement a lc fix option An radosgw-admin lc fix --bucket <> option is added which checks if the bucket entry exists in the corresponding lc shard and creates it if not. In case of resharded buckets not running a fixed rgw that writes/compares the marker this would write a new entry with the marker as the old entry would've already been deleted by a LC process. We currently don't cleanup the stale entry as it is assumed this would be picked up by the LC processor already or would be picked up in the next cycle. Signed-off-by: Abhishek Lekshmanan (cherry picked from commit 4528db4b642c37f67b3338ce04979b1ba7772e3e) --- diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 4b457741c313d..0c711c74fe908 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -193,6 +193,7 @@ void usage() cout << " lc list list all bucket lifecycle progress\n"; cout << " lc get get a lifecycle bucket configuration\n"; cout << " lc process manually process lifecycle\n"; + cout << " lc fix fix LC for a resharded bucket\n"; cout << " metadata get get metadata info\n"; cout << " metadata put put metadata info\n"; cout << " metadata rm remove metadata info\n"; @@ -435,6 +436,7 @@ enum { OPT_LC_LIST, OPT_LC_GET, OPT_LC_PROCESS, + OPT_LC_FIX, OPT_ORPHANS_FIND, OPT_ORPHANS_FINISH, OPT_ORPHANS_LIST_JOBS, @@ -888,6 +890,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, const char *prev_prev_ return OPT_LC_GET; if (strcmp(cmd, "process") == 0) return OPT_LC_PROCESS; + if (strcmp(cmd, "fix") == 0) + return OPT_LC_FIX; } else if (strcmp(prev_cmd, "orphans") == 0) { if (strcmp(cmd, "find") == 0) return OPT_ORPHANS_FIND; @@ -6578,6 +6582,23 @@ next: } } + + if (opt_cmd == OPT_LC_FIX) { + rgw_bucket bucket; + RGWBucketInfo bucket_info; + map attrs; + ret = init_bucket(tenant, bucket_name, bucket_id, bucket_info, bucket, &attrs); + if (ret < 0) { + cerr << "ERROR: could not init bucket: " << cpp_strerror(-ret) << std::endl; + return -ret; + } + + ret = rgw::lc::fix_lc_shard_entry(store, bucket_info, attrs); + if (ret < 0) { + cerr << "ERROR: fixing lc shard entry failed with" << cpp_strerror(-ret) << std::endl; + } + } + if (opt_cmd == OPT_ORPHANS_FIND) { if (!yes_i_really_mean_it) { cerr << "accidental removal of active objects can not be reversed; " diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index 2a779be0e4602..a66f2a3f3f0fc 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -16,6 +16,7 @@ #include "rgw_common.h" #include "rgw_bucket.h" #include "rgw_lc.h" +#include "rgw_string.h" #include "services/svc_sys_obj.h" @@ -1290,7 +1291,7 @@ void RGWLifecycleConfiguration::generate_test_instances(list_conf->rgw_lc_max_objs > HASH_PRIME ? HASH_PRIME : cct->_conf->rgw_lc_max_objs); int index = ceph_str_hash_linux(shard_id.c_str(), shard_id.size()) % HASH_PRIME % max_objs; @@ -1301,11 +1302,17 @@ static void get_lc_oid(CephContext *cct, const string& shard_id, string *oid) return; } + + +static std::string get_lc_shard_name(const rgw_bucket& bucket){ + return string_join_reserve(':', bucket.tenant, bucket.name, bucket.marker); +} + template static int guard_lc_modify(RGWRados* store, const rgw_bucket& bucket, const string& cookie, const F& f) { CephContext *cct = store->ctx(); - string shard_id = bucket.tenant + ':' + bucket.name + ':' + bucket.marker; + string shard_id = get_lc_shard_name(bucket); string oid; get_lc_oid(cct, shard_id, &oid); @@ -1391,3 +1398,52 @@ int RGWLC::remove_bucket_config(RGWBucketInfo& bucket_info, return ret; } +namespace rgw::lc { + +int fix_lc_shard_entry(RGWRados* store, const RGWBucketInfo& bucket_info, + const map& battrs) +{ + if (auto aiter = battrs.find(RGW_ATTR_LC); + aiter == battrs.end()) { + return 0; // No entry, nothing to fix + } + + auto shard_name = get_lc_shard_name(bucket_info.bucket); + std::string lc_oid; + get_lc_oid(store->ctx(), shard_name, &lc_oid); + + rgw_lc_entry_t entry; + // There are multiple cases we need to encounter here + // 1. entry exists and is already set to marker, happens in plain buckets & newly resharded buckets + // 2. entry doesn't exist, which usually happens when reshard has happened prior to update and next LC process has already dropped the update + // 3. entry exists matching the current bucket id which was after a reshard (needs to be updated to the marker) + // We are not dropping the old marker here as that would be caught by the next LC process update + auto lc_pool_ctx = store->get_lc_pool_ctx(); + int ret = cls_rgw_lc_get_entry(*lc_pool_ctx, + lc_oid, shard_name, entry); + if (ret == 0) { + ldout(store->ctx(), 5) << "Entry already exists, nothing to do" << dendl; + return ret; // entry is already existing correctly set to marker + } + ldout(store->ctx(), 5) << "cls_rgw_lc_get_entry errored ret code=" << ret << dendl; + if (ret == -ENOENT) { + ldout(store->ctx(), 1) << "No entry for bucket=" << bucket_info.bucket.name + << " creating " << dendl; + // TODO: we have too many ppl making cookies like this! + char cookie_buf[COOKIE_LEN + 1]; + gen_rand_alphanumeric(store->ctx(), cookie_buf, sizeof(cookie_buf) - 1); + std::string cookie = cookie_buf; + + ret = guard_lc_modify(store, bucket_info.bucket, cookie, + [&lc_pool_ctx, &lc_oid](librados::IoCtx *ctx, const string& oid, + const pair& entry) { + return cls_rgw_lc_set_entry(*lc_pool_ctx, + lc_oid, entry); + }); + + } + + return ret; +} + +} diff --git a/src/rgw/rgw_lc.h b/src/rgw/rgw_lc.h index 01fc01c700550..3566f7c1ce968 100644 --- a/src/rgw/rgw_lc.h +++ b/src/rgw/rgw_lc.h @@ -502,6 +502,11 @@ class RGWLC : public DoutPrefixProvider { int handle_multipart_expiration(RGWRados::Bucket *target, const map& prefix_map); }; +namespace rgw::lc { +int fix_lc_shard_entry(RGWRados *store, const RGWBucketInfo& bucket_info, + const map& battrs); + +} // namespace rgw::lc #endif diff --git a/src/test/cli/radosgw-admin/help.t b/src/test/cli/radosgw-admin/help.t index e0079a19cb90b..8fdacf9ebe2d1 100644 --- a/src/test/cli/radosgw-admin/help.t +++ b/src/test/cli/radosgw-admin/help.t @@ -115,6 +115,7 @@ lc list list all bucket lifecycle progress lc get get a lifecycle bucket configuration lc process manually process lifecycle + lc fix fix LC for a resharded bucket metadata get get metadata info metadata put put metadata info metadata rm remove metadata info