summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@redhat.com>2018-08-17 03:30:44 +0200
committerYehuda Sadeh <yehuda@redhat.com>2018-11-08 18:19:29 +0100
commit7c241f2c1d02c1191cd53022cf41943baae91675 (patch)
treeecfa245d3d32d696fa984f8b154ec118d21962b1 /src
parentrgw: svc: more zone work, add zone_utils, quota services (diff)
downloadceph-7c241f2c1d02c1191cd53022cf41943baae91675.tar.xz
ceph-7c241f2c1d02c1191cd53022cf41943baae91675.zip
rgw: sys_obj service, move zone init to svc_zone
still wip Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/rgw/rgw_period_puller.cc2
-rw-r--r--src/rgw/rgw_rados.cc682
-rw-r--r--src/rgw/rgw_rados.h13
-rw-r--r--src/rgw/rgw_service.cc18
-rw-r--r--src/rgw/rgw_service.h10
-rw-r--r--src/rgw/rgw_zone.cc40
-rw-r--r--src/rgw/rgw_zone.h54
-rw-r--r--src/rgw/services/svc_quota.cc2
-rw-r--r--src/rgw/services/svc_quota.h6
-rw-r--r--src/rgw/services/svc_rados.cc7
-rw-r--r--src/rgw/services/svc_rados.h14
-rw-r--r--src/rgw/services/svc_sys_obj.cc316
-rw-r--r--src/rgw/services/svc_sys_obj.h269
-rw-r--r--src/rgw/services/svc_zone.cc710
-rw-r--r--src/rgw/services/svc_zone.h36
15 files changed, 1430 insertions, 749 deletions
diff --git a/src/rgw/rgw_period_puller.cc b/src/rgw/rgw_period_puller.cc
index 0e3a8f90222..0379739bce1 100644
--- a/src/rgw/rgw_period_puller.cc
+++ b/src/rgw/rgw_period_puller.cc
@@ -61,7 +61,7 @@ int RGWPeriodPuller::pull(const std::string& period_id, RGWPeriod& period)
// try to read the period from rados
period.set_id(period_id);
period.set_epoch(0);
- int r = period.init(store->ctx(), store);
+ int r = period.init(store->ctx(), store->svc.sysobj.get());
if (r < 0) {
if (store->svc.zone->is_meta_master()) {
// can't pull if we're the master
diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc
index 7f2c4c1d6ce..ced9ebe55e8 100644
--- a/src/rgw/rgw_rados.cc
+++ b/src/rgw/rgw_rados.cc
@@ -97,23 +97,7 @@ static string default_bucket_index_pool_suffix = "rgw.buckets.index";
static string default_storage_extra_pool_suffix = "rgw.buckets.non-ec";
static string avail_pools = ".pools.avail";
-static string zone_info_oid_prefix = "zone_info.";
-static string zone_names_oid_prefix = "zone_names.";
-static string region_info_oid_prefix = "region_info.";
-static string zone_group_info_oid_prefix = "zonegroup_info.";
-static string realm_names_oid_prefix = "realms_names.";
-static string realm_info_oid_prefix = "realms.";
-static string default_region_info_oid = "default.region";
-static string default_zone_group_info_oid = "default.zonegroup";
-static string period_info_oid_prefix = "periods.";
-static string period_latest_epoch_info_oid = ".latest_epoch";
-static string region_map_oid = "region_map";
-static string zonegroup_map_oid = "zonegroup_map";
static string log_lock_name = "rgw_log_lock";
-static string default_realm_info_oid = "default.realm";
-const string default_zonegroup_name = "default";
-const string default_zone_name = "default";
-static string zonegroup_names_oid_prefix = "zonegroups_names.";
static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN;
#define RGW_USAGE_OBJ_PREFIX "usage."
#define FIRST_EPOCH 1
@@ -831,7 +815,7 @@ public:
int notify_all(map<string, RGWRESTConn *>& conn_map, map<int, set<string> >& shards) {
rgw_http_param_pair pairs[] = { { "type", "data" },
{ "notify", NULL },
- { "source-zone", store->get_zone_params().get_id().c_str() },
+ { "source-zone", store->svc.zone->get_zone_params().get_id().c_str() },
{ NULL, NULL } };
list<RGWCoroutinesStack *> stacks;
@@ -936,7 +920,7 @@ int RGWMetaNotifier::process()
ldout(cct, 20) << __func__ << "(): notifying mdlog change, shard_id=" << *iter << dendl;
}
- notify_mgr.notify_all(store->zone_conn_map, shards);
+ notify_mgr.notify_all(store->svc.zone->get_zone_conn_map(), shards);
return 0;
}
@@ -974,7 +958,7 @@ int RGWDataNotifier::process()
ldout(cct, 20) << __func__ << "(): notifying datalog change, shard_id=" << iter->first << ": " << iter->second << dendl;
}
- notify_mgr.notify_all(store->zone_data_notify_to_map, shards);
+ notify_mgr.notify_all(store->svc.zone->get_zone_data_notify_to_map(), shards);
return 0;
}
@@ -1476,7 +1460,7 @@ void RGWIndexCompletionManager::create_completion(const rgw_obj& obj,
if (zones_trace) {
entry->zones_trace = *zones_trace;
} else {
- entry->zones_trace.insert(store->get_zone().id);
+ entry->zones_trace.insert(store->svc.zone->get_zone().id);
}
*result = entry;
@@ -1580,18 +1564,6 @@ void RGWRados::finalize()
delete obj_expirer;
obj_expirer = NULL;
- delete rest_master_conn;
-
- map<string, RGWRESTConn *>::iterator iter;
- for (iter = zone_conn_map.begin(); iter != zone_conn_map.end(); ++iter) {
- RGWRESTConn *conn = iter->second;
- delete conn;
- }
-
- for (iter = zonegroup_conn_map.begin(); iter != zonegroup_conn_map.end(); ++iter) {
- RGWRESTConn *conn = iter->second;
- delete conn;
- }
RGWQuotaHandler::free_handler(quota_handler);
if (cr_registry) {
cr_registry->put();
@@ -1696,487 +1668,6 @@ int RGWRados::update_service_map(std::map<std::string, std::string>&& status)
return 0;
}
-/**
- * Add new connection to connections map
- * @param zonegroup_conn_map map which new connection will be added to
- * @param zonegroup zonegroup which new connection will connect to
- * @param new_connection pointer to new connection instance
- */
-static void add_new_connection_to_map(map<string, RGWRESTConn *> &zonegroup_conn_map,
- const RGWZoneGroup &zonegroup, RGWRESTConn *new_connection)
-{
- // Delete if connection is already exists
- map<string, RGWRESTConn *>::iterator iterZoneGroup = zonegroup_conn_map.find(zonegroup.get_id());
- if (iterZoneGroup != zonegroup_conn_map.end()) {
- delete iterZoneGroup->second;
- }
-
- // Add new connection to connections map
- zonegroup_conn_map[zonegroup.get_id()] = new_connection;
-}
-
-int RGWRados::convert_regionmap()
-{
- RGWZoneGroupMap zonegroupmap;
-
- string pool_name = cct->_conf->rgw_zone_root_pool;
- if (pool_name.empty()) {
- pool_name = RGW_DEFAULT_ZONE_ROOT_POOL;
- }
- string oid = region_map_oid;
-
- rgw_pool pool(pool_name);
- bufferlist bl;
- RGWObjectCtx obj_ctx(this);
- int ret = rgw_get_system_obj(this, obj_ctx, pool, oid, bl, NULL, NULL);
- if (ret < 0 && ret != -ENOENT) {
- return ret;
- } else if (ret == -ENOENT) {
- return 0;
- }
-
- try {
- auto iter = bl.cbegin();
- decode(zonegroupmap, iter);
- } catch (buffer::error& err) {
- ldout(cct, 0) << "error decoding regionmap from " << pool << ":" << oid << dendl;
- return -EIO;
- }
-
- for (map<string, RGWZoneGroup>::iterator iter = zonegroupmap.zonegroups.begin();
- iter != zonegroupmap.zonegroups.end(); ++iter) {
- RGWZoneGroup& zonegroup = iter->second;
- ret = zonegroup.init(cct, this, false);
- ret = zonegroup.update();
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "Error could not update zonegroup " << zonegroup.get_name() << ": " <<
- cpp_strerror(-ret) << dendl;
- return ret;
- } else if (ret == -ENOENT) {
- ret = zonegroup.create();
- if (ret < 0) {
- ldout(cct, 0) << "Error could not create " << zonegroup.get_name() << ": " <<
- cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
- }
-
- current_period.set_user_quota(zonegroupmap.user_quota);
- current_period.set_bucket_quota(zonegroupmap.bucket_quota);
-
- // remove the region_map so we don't try to convert again
- rgw_raw_obj obj(pool, oid);
- ret = delete_system_obj(obj);
- if (ret < 0) {
- ldout(cct, 0) << "Error could not remove " << obj
- << " after upgrading to zonegroup map: " << cpp_strerror(ret) << dendl;
- return ret;
- }
-
- return 0;
-}
-
-/**
- * Replace all region configuration with zonegroup for
- * backward compatability
- * Returns 0 on success, -ERR# on failure.
- */
-int RGWRados::replace_region_with_zonegroup()
-{
- /* copy default region */
- /* convert default region to default zonegroup */
- string default_oid = cct->_conf->rgw_default_region_info_oid;
- if (default_oid.empty()) {
- default_oid = default_region_info_oid;
- }
-
-
- RGWZoneGroup default_zonegroup;
- rgw_pool pool{default_zonegroup.get_pool(cct)};
- string oid = "converted";
- bufferlist bl;
- RGWObjectCtx obj_ctx(this);
-
- int ret = rgw_get_system_obj(this, obj_ctx, pool ,oid, bl, NULL, NULL);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << " failed to read converted: ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- } else if (ret != -ENOENT) {
- ldout(cct, 20) << "System already converted " << dendl;
- return 0;
- }
-
- string default_region;
- ret = default_zonegroup.init(cct, this, false, true);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed init default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = default_zonegroup.read_default_id(default_region, true);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << " failed reading old default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- /* convert regions to zonegroups */
- list<string> regions;
- ret = list_regions(regions);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << " failed to list regions: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- } else if (ret == -ENOENT || regions.empty()) {
- RGWZoneParams zoneparams(default_zone_name);
- int ret = zoneparams.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << ": error initializing default zone params: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- /* update master zone */
- RGWZoneGroup default_zg(default_zonegroup_name);
- ret = default_zg.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << ": error in initializing default zonegroup: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- if (ret != -ENOENT && default_zg.master_zone.empty()) {
- default_zg.master_zone = zoneparams.get_id();
- return default_zg.update();
- }
- return 0;
- }
-
- string master_region, master_zone;
- for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
- if (*iter != default_zonegroup_name){
- RGWZoneGroup region(*iter);
- int ret = region.init(cct, this, true, true);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed init region "<< *iter << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- if (region.is_master_zonegroup()) {
- master_region = region.get_id();
- master_zone = region.master_zone;
- }
- }
- }
-
- /* create realm if there is none.
- The realm name will be the region and zone concatenated
- realm id will be mds of its name */
- if (realm.get_id().empty() && !master_region.empty() && !master_zone.empty()) {
- string new_realm_name = master_region + "." + master_zone;
- unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE];
- char md5_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
- MD5 hash;
- hash.Update((const unsigned char *)new_realm_name.c_str(), new_realm_name.length());
- hash.Final(md5);
- buf_to_hex(md5, CEPH_CRYPTO_MD5_DIGESTSIZE, md5_str);
- string new_realm_id(md5_str);
- RGWRealm new_realm(new_realm_id,new_realm_name);
- ret = new_realm.init(cct, this, false);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " Error initing new realm: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = new_realm.create();
- if (ret < 0 && ret != -EEXIST) {
- ldout(cct, 0) << __func__ << " Error creating new realm: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = new_realm.set_as_default();
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " Error setting realm as default: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = realm.init(cct, this);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " Error initing realm: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = current_period.init(cct, this, realm.get_id(), realm.get_name());
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " Error initing current period: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
-
- list<string>::iterator iter;
- /* create zonegroups */
- for (iter = regions.begin(); iter != regions.end(); ++iter)
- {
- ldout(cct, 0) << __func__ << " Converting " << *iter << dendl;
- /* check to see if we don't have already a zonegroup with this name */
- RGWZoneGroup new_zonegroup(*iter);
- ret = new_zonegroup.init(cct , this);
- if (ret == 0 && new_zonegroup.get_id() != *iter) {
- ldout(cct, 0) << __func__ << " zonegroup "<< *iter << " already exists id " << new_zonegroup.get_id () <<
- " skipping conversion " << dendl;
- continue;
- }
- RGWZoneGroup zonegroup(*iter);
- zonegroup.set_id(*iter);
- int ret = zonegroup.init(cct, this, true, true);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed init zonegroup: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- zonegroup.realm_id = realm.get_id();
- /* fix default region master zone */
- if (*iter == default_zonegroup_name && zonegroup.master_zone.empty()) {
- ldout(cct, 0) << __func__ << " Setting default zone as master for default region" << dendl;
- zonegroup.master_zone = default_zone_name;
- }
- ret = zonegroup.update();
- if (ret < 0 && ret != -EEXIST) {
- ldout(cct, 0) << __func__ << " failed to update zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- ret = zonegroup.update_name();
- if (ret < 0 && ret != -EEXIST) {
- ldout(cct, 0) << __func__ << " failed to update_name for zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- if (zonegroup.get_name() == default_region) {
- ret = zonegroup.set_as_default();
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed to set_as_default " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- }
- for (map<string, RGWZone>::const_iterator iter = zonegroup.zones.begin(); iter != zonegroup.zones.end();
- ++iter) {
- ldout(cct, 0) << __func__ << " Converting zone" << iter->first << dendl;
- RGWZoneParams zoneparams(iter->first, iter->first);
- zoneparams.set_id(iter->first);
- zoneparams.realm_id = realm.get_id();
- ret = zoneparams.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << " failed to init zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- } else if (ret == -ENOENT) {
- ldout(cct, 0) << __func__ << " zone is part of another cluster " << iter->first << " skipping " << dendl;
- continue;
- }
- zonegroup.realm_id = realm.get_id();
- ret = zoneparams.update();
- if (ret < 0 && ret != -EEXIST) {
- ldout(cct, 0) << __func__ << " failed to update zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = zoneparams.update_name();
- if (ret < 0 && ret != -EEXIST) {
- ldout(cct, 0) << __func__ << " failed to init zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
-
- if (!current_period.get_id().empty()) {
- ret = current_period.add_zonegroup(zonegroup);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed to add zonegroup to current_period: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
- }
-
- if (!current_period.get_id().empty()) {
- ret = current_period.update();
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed to update new period: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = current_period.store_info(false);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed to store new period: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = current_period.reflect();
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed to update local objects: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
-
- for (auto const& iter : regions) {
- RGWZoneGroup zonegroup(iter);
- int ret = zonegroup.init(cct, this, true, true);
- if (ret < 0) {
- ldout(cct, 0) << __func__ << " failed init zonegroup" << iter << ": ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = zonegroup.delete_obj(true);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << __func__ << " failed to delete region " << iter << ": ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- }
-
- /* mark as converted */
- ret = rgw_put_system_obj(this, pool, oid, bl,
- true, NULL, real_time(), NULL);
- if (ret < 0 ) {
- ldout(cct, 0) << __func__ << " failed to mark cluster as converted: ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
-
- return 0;
-}
-
-int RGWRados::init_zg_from_period(bool *initialized)
-{
- *initialized = false;
-
- if (current_period.get_id().empty()) {
- return 0;
- }
-
- int ret = zonegroup.init(cct, this);
- ldout(cct, 20) << "period zonegroup init ret " << ret << dendl;
- if (ret == -ENOENT) {
- return 0;
- }
- if (ret < 0) {
- ldout(cct, 0) << "failed reading zonegroup info: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ldout(cct, 20) << "period zonegroup name " << zonegroup.get_name() << dendl;
-
- map<string, RGWZoneGroup>::const_iterator iter =
- current_period.get_map().zonegroups.find(zonegroup.get_id());
-
- if (iter != current_period.get_map().zonegroups.end()) {
- ldout(cct, 20) << "using current period zonegroup " << zonegroup.get_name() << dendl;
- zonegroup = iter->second;
- ret = zonegroup.init(cct, this, false);
- if (ret < 0) {
- ldout(cct, 0) << "failed init zonegroup: " << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ret = zone_params.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "failed reading zone params info: " << " " << cpp_strerror(-ret) << dendl;
- return ret;
- } if (ret ==-ENOENT && zonegroup.get_name() == default_zonegroup_name) {
- ldout(cct, 10) << " Using default name "<< default_zone_name << dendl;
- zone_params.set_name(default_zone_name);
- ret = zone_params.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "failed reading zone params info: " << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
- }
- for (iter = current_period.get_map().zonegroups.begin();
- iter != current_period.get_map().zonegroups.end(); ++iter){
- const RGWZoneGroup& zg = iter->second;
- // use endpoints from the zonegroup's master zone
- auto master = zg.zones.find(zg.master_zone);
- if (master == zg.zones.end()) {
- // fix missing master zone for a single zone zonegroup
- if (zg.master_zone.empty() && zg.zones.size() == 1) {
- master = zg.zones.begin();
- ldout(cct, 0) << "zonegroup " << zg.get_name() << " missing master_zone, setting zone " <<
- master->second.name << " id:" << master->second.id << " as master" << dendl;
- if (zonegroup.get_id() == zg.get_id()) {
- zonegroup.master_zone = master->second.id;
- ret = zonegroup.update();
- if (ret < 0) {
- ldout(cct, 0) << "error updating zonegroup : " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- } else {
- RGWZoneGroup fixed_zg(zg.get_id(),zg.get_name());
- ret = fixed_zg.init(cct, this);
- if (ret < 0) {
- ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- fixed_zg.master_zone = master->second.id;
- ret = fixed_zg.update();
- if (ret < 0) {
- ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- }
- } else {
- ldout(cct, 0) << "zonegroup " << zg.get_name() << " missing zone for master_zone=" <<
- zg.master_zone << dendl;
- return -EINVAL;
- }
- }
- const auto& endpoints = master->second.endpoints;
- add_new_connection_to_map(zonegroup_conn_map, zg, new RGWRESTConn(cct, this, zg.get_id(), endpoints));
- if (!current_period.get_master_zonegroup().empty() &&
- zg.get_id() == current_period.get_master_zonegroup()) {
- rest_master_conn = new RGWRESTConn(cct, this, zg.get_id(), endpoints);
- }
- }
-
- *initialized = true;
-
- return 0;
-}
-
-int RGWRados::init_zg_from_local(bool *creating_defaults)
-{
- int ret = zonegroup.init(cct, this);
- if ( (ret < 0 && ret != -ENOENT) || (ret == -ENOENT && !cct->_conf->rgw_zonegroup.empty())) {
- ldout(cct, 0) << "failed reading zonegroup info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- } else if (ret == -ENOENT) {
- *creating_defaults = true;
- ldout(cct, 10) << "Creating default zonegroup " << dendl;
- ret = zonegroup.create_default();
- if (ret < 0) {
- ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- ret = zonegroup.init(cct, this);
- if (ret < 0) {
- ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
- << dendl;
- return ret;
- }
- }
- ldout(cct, 20) << "zonegroup " << zonegroup.get_name() << dendl;
- if (zonegroup.is_master_zonegroup()) {
- // use endpoints from the zonegroup's master zone
- auto master = zonegroup.zones.find(zonegroup.master_zone);
- if (master == zonegroup.zones.end()) {
- // fix missing master zone for a single zone zonegroup
- if (zonegroup.master_zone.empty() && zonegroup.zones.size() == 1) {
- master = zonegroup.zones.begin();
- ldout(cct, 0) << "zonegroup " << zonegroup.get_name() << " missing master_zone, setting zone " <<
- master->second.name << " id:" << master->second.id << " as master" << dendl;
- zonegroup.master_zone = master->second.id;
- ret = zonegroup.update();
- if (ret < 0) {
- ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- } else {
- ldout(cct, 0) << "zonegroup " << zonegroup.get_name() << " missing zone for "
- "master_zone=" << zonegroup.master_zone << dendl;
- return -EINVAL;
- }
- }
- const auto& endpoints = master->second.endpoints;
- rest_master_conn = new RGWRESTConn(cct, this, zonegroup.get_id(), endpoints);
- }
-
- return 0;
-}
-
-
bool RGWRados::zone_syncs_from(RGWZone& target_zone, RGWZone& source_zone)
{
return target_zone.syncs_from(source_zone.name) &&
@@ -2189,99 +1680,12 @@ bool RGWRados::zone_syncs_from(RGWZone& target_zone, RGWZone& source_zone)
*/
int RGWRados::init_complete()
{
- int ret = realm.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "failed reading realm info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- } else if (ret != -ENOENT) {
- ldout(cct, 20) << "realm " << realm.get_name() << " " << realm.get_id() << dendl;
- ret = current_period.init(cct, this, realm.get_id(), realm.get_name());
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "failed reading current period info: " << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- ldout(cct, 20) << "current period " << current_period.get_id() << dendl;
- }
-
- ret = replace_region_with_zonegroup();
- if (ret < 0) {
- lderr(cct) << "failed converting region to zonegroup : ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- ret = convert_regionmap();
- if (ret < 0) {
- lderr(cct) << "failed converting regionmap: " << cpp_strerror(-ret) << dendl;
- return ret;
- }
-
- bool zg_initialized = false;
-
- if (!current_period.get_id().empty()) {
- ret = init_zg_from_period(&zg_initialized);
- if (ret < 0) {
- return ret;
- }
- }
-
- bool creating_defaults = false;
- bool using_local = (!zg_initialized);
- if (using_local) {
- ldout(cct, 10) << " cannot find current period zonegroup using local zonegroup" << dendl;
- ret = init_zg_from_local(&creating_defaults);
- if (ret < 0) {
- return ret;
- }
- // read period_config into current_period
- auto& period_config = current_period.get_config();
- ret = period_config.read(this, zonegroup.realm_id);
- if (ret < 0 && ret != -ENOENT) {
- ldout(cct, 0) << "ERROR: failed to read period config: "
- << cpp_strerror(ret) << dendl;
- return ret;
- }
- }
-
- ldout(cct, 10) << "Cannot find current period zone using local zone" << dendl;
- if (creating_defaults && cct->_conf->rgw_zone.empty()) {
- ldout(cct, 10) << " Using default name "<< default_zone_name << dendl;
- zone_params.set_name(default_zone_name);
- }
-
- ret = zone_params.init(cct, this);
- if (ret < 0 && ret != -ENOENT) {
- lderr(cct) << "failed reading zone info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
- return ret;
- }
- map<string, RGWZone>::iterator zone_iter = get_zonegroup().zones.find(zone_params.get_id());
- if (zone_iter == get_zonegroup().zones.end()) {
- if (using_local) {
- lderr(cct) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << ")" << dendl;
- return -EINVAL;
- }
- ldout(cct, 1) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << "), switching to local zonegroup configuration" << dendl;
- ret = init_zg_from_local(&creating_defaults);
- if (ret < 0) {
- return ret;
- }
- zone_iter = get_zonegroup().zones.find(zone_params.get_id());
- }
- if (zone_iter != get_zonegroup().zones.end()) {
- zone_public_config = zone_iter->second;
- ldout(cct, 20) << "zone " << zone_params.get_name() << dendl;
- } else {
- lderr(cct) << "Cannot find zone id=" << zone_params.get_id() << " (name=" << zone_params.get_name() << ")" << dendl;
- return -EINVAL;
- }
-
- zone_short_id = current_period.get_map().get_zone_short_id(zone_params.get_id());
-
if (run_sync_thread) {
- ret = sync_modules_manager->create_instance(cct, zone_public_config.tier_type, zone_params.tier_config, &sync_module);
+ ret = sync_modules_manager->create_instance(cct, svc.zone->get_zone_public_config()->tier_type, svc.zone->get_zone_params()->tier_config, &sync_module);
if (ret < 0) {
lderr(cct) << "ERROR: failed to init sync module instance, ret=" << ret << dendl;
if (ret == -ENOENT) {
- lderr(cct) << "ERROR: " << zone_public_config.tier_type
+ lderr(cct) << "ERROR: " << zone_public_config->tier_type
<< " sync module does not exist. valid sync modules: "
<< sync_modules_manager->get_registered_module_names()
<< dendl;
@@ -2290,8 +1694,6 @@ int RGWRados::init_complete()
}
}
- writeable_zone = (zone_public_config.tier_type.empty() || zone_public_config.tier_type == "rgw");
-
finisher = new Finisher(cct);
finisher->start();
@@ -2544,6 +1946,12 @@ int RGWRados::initialize()
return ret;
}
+ JSONFormattable sysobj_svc_conf;
+ ret = svc_registry->get_instance("sys_obj", quota_svc_conf, &svc.sysobj);
+ if (ret < 0) {
+ return ret;
+ }
+
host_id = svc.zone_utils->gen_host_id();
ret = init_rados();
@@ -2591,72 +1999,6 @@ int RGWRados::list_raw_prefixed_objs(const rgw_pool& pool, const string& prefix,
return 0;
}
-int RGWRados::list_regions(list<string>& regions)
-{
- RGWZoneGroup zonegroup;
-
- return list_raw_prefixed_objs(zonegroup.get_pool(cct), region_info_oid_prefix, regions);
-}
-
-int RGWRados::list_zonegroups(list<string>& zonegroups)
-{
- RGWZoneGroup zonegroup;
-
- return list_raw_prefixed_objs(zonegroup.get_pool(cct), zonegroup_names_oid_prefix, zonegroups);
-}
-
-int RGWRados::list_zones(list<string>& zones)
-{
- RGWZoneParams zoneparams;
-
- return list_raw_prefixed_objs(zoneparams.get_pool(cct), zone_names_oid_prefix, zones);
-}
-
-int RGWRados::list_realms(list<string>& realms)
-{
- RGWRealm realm(cct, this);
- return list_raw_prefixed_objs(realm.get_pool(cct), realm_names_oid_prefix, realms);
-}
-
-int RGWRados::list_periods(list<string>& periods)
-{
- RGWPeriod period;
- list<string> raw_periods;
- int ret = list_raw_prefixed_objs(period.get_pool(cct), period.get_info_oid_prefix(), raw_periods);
- if (ret < 0) {
- return ret;
- }
- for (const auto& oid : raw_periods) {
- size_t pos = oid.find(".");
- if (pos != std::string::npos) {
- periods.push_back(oid.substr(0, pos));
- } else {
- periods.push_back(oid);
- }
- }
- periods.sort(); // unique() only detects duplicates if they're adjacent
- periods.unique();
- return 0;
-}
-
-
-int RGWRados::list_periods(const string& current_period, list<string>& periods)
-{
- int ret = 0;
- string period_id = current_period;
- while(!period_id.empty()) {
- RGWPeriod period(period_id);
- ret = period.init(cct, this);
- if (ret < 0) {
- return ret;
- }
- periods.push_back(period.get_id());
- period_id = period.get_predecessor();
- }
-
- return ret;
-}
-
/**
* Open the pool used as root for this gateway
* Returns: 0 on success, -ERR# otherwise.
diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h
index 04f68dca959..c0429ddc329 100644
--- a/src/rgw/rgw_rados.h
+++ b/src/rgw/rgw_rados.h
@@ -49,6 +49,7 @@ class RGWReshardWait;
class RGWSI_Zone;
class RGWSI_ZoneUtils;
class RGWSI_Quota;
+class RGWSI_SysObj;
/* flags for put_obj_meta() */
#define PUT_OBJ_CREATE 0x01
@@ -1352,6 +1353,7 @@ public:
std::shared_ptr<RGWSI_Zone> zone;
std::shared_ptr<RGWSI_ZoneUtils> zone_utils;
std::shared_ptr<RGWSI_Quota> quota;
+ std::shared_ptr<RGWSI_SysObj> sysobj;
} svc;
/**
@@ -1411,13 +1413,6 @@ public:
string list_raw_objs_get_cursor(RGWListRawObjsCtx& ctx);
int list_raw_prefixed_objs(const rgw_pool& pool, const string& prefix, list<string>& result);
- int list_zonegroups(list<string>& zonegroups);
- int list_regions(list<string>& regions);
- int list_zones(list<string>& zones);
- int list_realms(list<string>& realms);
- int list_periods(list<string>& periods);
- int list_periods(const string& current_period, list<string>& periods);
- void tick();
CephContext *ctx() { return cct; }
/** do all necessary setup of the storage device */
@@ -1432,11 +1427,7 @@ public:
}
/** Initialize the RADOS instance and prepare to do other ops */
virtual int init_rados();
- int init_zg_from_period(bool *initialized);
- int init_zg_from_local(bool *creating_defaults);
int init_complete();
- int replace_region_with_zonegroup();
- int convert_regionmap();
int initialize();
void finalize();
diff --git a/src/rgw/rgw_service.cc b/src/rgw/rgw_service.cc
index d59361b251e..6b37c68e899 100644
--- a/src/rgw/rgw_service.cc
+++ b/src/rgw/rgw_service.cc
@@ -1,12 +1,17 @@
#include "rgw_service.h"
#include "services/svc_rados.h"
+#include "services/svc_zone.h"
+#include "services/svc_zone_utils.h"
+#include "services/svc_quota.h"
+#include "services/svc_sys_obj.h"
#define dout_subsys ceph_subsys_rgw
RGWServiceInstance::~RGWServiceInstance()
{
if (svc) {
+ shutdown();
svc->svc_registry->remove_instance(this);
}
}
@@ -14,6 +19,10 @@ RGWServiceInstance::~RGWServiceInstance()
void RGWServiceRegistry::register_all(CephContext *cct)
{
services["rados"] = make_shared<RGWS_RADOS>(cct);
+ services["zone"] = make_shared<RGWS_Zone>(cct);
+ services["zone_utils"] = make_shared<RGWS_ZoneUtils>(cct);
+ services["quota"] = make_shared<RGWS_Quota>(cct);
+ services["sys_obj"] = make_shared<RGWS_SysObj>(cct);
}
bool RGWServiceRegistry::find(const string& name, RGWServiceRef *svc)
@@ -76,8 +85,9 @@ int RGWServiceRegistry::get_instance(RGWServiceRef& svc,
dep_refs[dep_id] = dep_ref;
}
- r = instance_ref->init(conf, dep_refs);
+ r = instance_ref->load(conf, dep_refs);
if (r < 0) {
+ ldout(cct, 0) << "ERROR: service instance load return error: service=" << svc->type() << " r=" << r << dendl;
return r;
}
@@ -89,6 +99,12 @@ int RGWServiceRegistry::get_instance(RGWServiceRef& svc,
*ref = iinfo.ref;
+ r = instance_ref->init();
+ if (r < 0) {
+ ldout(cct, 0) << "ERROR: service instance init return error: service=" << svc->type() << " r=" << r << dendl;
+ return r;
+ }
+
return 0;
}
diff --git a/src/rgw/rgw_service.h b/src/rgw/rgw_service.h
index 1681e923a86..da8bce523cf 100644
--- a/src/rgw/rgw_service.h
+++ b/src/rgw/rgw_service.h
@@ -58,12 +58,20 @@ protected:
virtual std::map<std::string, dependency> get_deps() {
return std::map<std::string, dependency>();
}
- virtual int init(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs) = 0;
+ virtual int load(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs) = 0;
+ virtual int init() {
+ return 0;
+ }
+ virtual void shutdown() {}
public:
RGWServiceInstance(RGWService *svc, CephContext *_cct) : cct(_cct) {}
virtual ~RGWServiceInstance();
+ CephContext *ctx() {
+ return cct;
+ }
+
string get_title() {
return svc->type() + ":" + svc_instance;
}
diff --git a/src/rgw/rgw_zone.cc b/src/rgw/rgw_zone.cc
index ce2e9563163..54a90689207 100644
--- a/src/rgw/rgw_zone.cc
+++ b/src/rgw/rgw_zone.cc
@@ -1,5 +1,7 @@
#include "rgw_zone.h"
+#include "services/svc_sys_obj.h"
+
void RGWDefaultZoneGroupInfo::dump(Formatter *f) const {
encode_json("default_zonegroup", default_zonegroup, f);
}
@@ -35,7 +37,7 @@ int RGWZoneGroup::create_default(bool old_format)
RGWZoneParams zone_params(default_zone_name);
- int r = zone_params.init(cct, store, false);
+ int r = zone_params.init(cct, zone_svc, false);
if (r < 0) {
ldout(cct, 0) << "create_default: error initializing zone params: " << cpp_strerror(-r) << dendl;
return r;
@@ -48,7 +50,7 @@ int RGWZoneGroup::create_default(bool old_format)
} else if (r == -EEXIST) {
ldout(cct, 10) << "zone_params::create_default() returned -EEXIST, we raced with another default zone_params creation" << dendl;
zone_params.clear_id();
- r = zone_params.init(cct, store);
+ r = zone_params.init(cct, zone_svc);
if (r < 0) {
ldout(cct, 0) << "create_default: error in init existing zone params: " << cpp_strerror(-r) << dendl;
return r;
@@ -71,7 +73,7 @@ int RGWZoneGroup::create_default(bool old_format)
if (r == -EEXIST) {
ldout(cct, 10) << "create_default() returned -EEXIST, we raced with another zonegroup creation" << dendl;
id.clear();
- r = init(cct, store);
+ r = init(cct, zone_svc);
if (r < 0) {
return r;
}
@@ -172,11 +174,14 @@ int RGWZoneGroup::add_zone(const RGWZoneParams& zone_params, bool *is_master, bo
}
if (ptier_type) {
zone.tier_type = *ptier_type;
+#warning FIXME
+#if 0
if (!store->get_sync_modules_manager()->get_module(*ptier_type, nullptr)) {
ldout(cct, 0) << "ERROR: could not found sync module: " << *ptier_type
<< ", valid sync modules: "
<< store->get_sync_modules_manager()->get_registered_module_names()
<< dendl;
+#endif
return -ENOENT;
}
}
@@ -227,7 +232,7 @@ void RGWZoneGroup::post_process_params()
zone.log_data = log_data;
RGWZoneParams zone_params(zone.id, zone.name);
- int ret = zone_params.init(cct, store);
+ int ret = zone_params.init(cct, zone_svc);
if (ret < 0) {
ldout(cct, 0) << "WARNING: could not read zone params for zone id=" << zone.id << " name=" << zone.name << dendl;
continue;
@@ -270,7 +275,7 @@ int RGWZoneGroup::read_default_id(string& default_id, bool old_format)
if (realm_id.empty()) {
/* try using default realm */
RGWRealm realm;
- int ret = realm.init(cct, store);
+ int ret = realm.init(cct, zone_svc);
// no default realm exist
if (ret < 0) {
return read_id(default_zonegroup_name, default_id);
@@ -286,7 +291,7 @@ int RGWZoneGroup::set_as_default(bool exclusive)
if (realm_id.empty()) {
/* try using default realm */
RGWRealm realm;
- int ret = realm.init(cct, store);
+ int ret = realm.init(cct, zone_svc);
if (ret < 0) {
ldout(cct, 10) << "could not read realm id: " << cpp_strerror(-ret) << dendl;
return -EINVAL;
@@ -297,10 +302,10 @@ int RGWZoneGroup::set_as_default(bool exclusive)
return RGWSystemMetaObj::set_as_default(exclusive);
}
-int RGWSystemMetaObj::init(CephContext *_cct, RGWRados *_store, bool setup_obj, bool old_format)
+int RGWSystemMetaObj::init(CephContext *_cct, RGWSI_Zone *_zone_svc, bool setup_obj, bool old_format)
{
cct = _cct;
- store = _store;
+ zone_svc = _zone_svc;
if (!setup_obj)
return 0;
@@ -338,7 +343,8 @@ int RGWSystemMetaObj::read_default(RGWDefaultSystemMetaObjInfo& default_info, co
using ceph::decode;
auto pool = get_pool(cct);
bufferlist bl;
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
if (ret < 0)
return ret;
@@ -402,7 +408,8 @@ int RGWSystemMetaObj::read_id(const string& obj_name, string& object_id)
string oid = get_names_oid_prefix() + obj_name;
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
if (ret < 0) {
return ret;
@@ -522,7 +529,8 @@ int RGWSystemMetaObj::read_info(const string& obj_id, bool old_format)
string oid = get_info_oid_prefix(old_format) + obj_id;
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL);
if (ret < 0) {
ldout(cct, 0) << "failed reading obj info from " << pool << ":" << oid << ": " << cpp_strerror(-ret) << dendl;
@@ -803,7 +811,8 @@ rgw_pool RGWPeriodConfig::get_pool(CephContext *cct)
int RGWPeriodConfig::read(RGWRados *store, const std::string& realm_id)
{
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
const auto& pool = get_pool(store->ctx());
const auto& oid = get_oid(realm_id);
bufferlist bl;
@@ -954,7 +963,8 @@ int RGWPeriod::read_latest_epoch(RGWPeriodLatestEpochInfo& info,
rgw_pool pool(get_pool(cct));
bufferlist bl;
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, objv, nullptr);
if (ret < 0) {
ldout(cct, 1) << "error read_lastest_epoch " << pool << ":" << oid << dendl;
@@ -1093,7 +1103,9 @@ int RGWPeriod::read_info()
bufferlist bl;
- RGWObjectCtx obj_ctx(store);
+ RGWSysObjectCtx obj_ctx = sysobj_svc->get_obj_ctx();
+
+
int ret = rgw_get_system_obj(store, obj_ctx, pool, get_period_oid(), bl, NULL, NULL);
if (ret < 0) {
ldout(cct, 0) << "failed reading obj info from " << pool << ":" << get_period_oid() << ": " << cpp_strerror(-ret) << dendl;
diff --git a/src/rgw/rgw_zone.h b/src/rgw/rgw_zone.h
index 94708fb7264..48ada717e4c 100644
--- a/src/rgw/rgw_zone.h
+++ b/src/rgw/rgw_zone.h
@@ -41,13 +41,15 @@ struct RGWDefaultSystemMetaObjInfo {
};
WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo)
+class RGWSI_SysObj;
+
class RGWSystemMetaObj {
protected:
string id;
string name;
- CephContext *cct;
- RGWRados *store;
+ CephContext *cct{nullptr};
+ RGWSI_SysObj *sysobj_svc{nullptr};
int store_name(bool exclusive);
int store_info(bool exclusive);
@@ -59,11 +61,12 @@ protected:
int use_default(bool old_format = false);
public:
- RGWSystemMetaObj() : cct(NULL), store(NULL) {}
- RGWSystemMetaObj(const string& _name): name(_name), cct(NULL), store(NULL) {}
- RGWSystemMetaObj(const string& _id, const string& _name) : id(_id), name(_name), cct(NULL), store(NULL) {}
- RGWSystemMetaObj(CephContext *_cct, RGWRados *_store): cct(_cct), store(_store){}
- RGWSystemMetaObj(const string& _name, CephContext *_cct, RGWRados *_store): name(_name), cct(_cct), store(_store){}
+ RGWSystemMetaObj() {}
+ RGWSystemMetaObj(const string& _name): name(_name) {}
+ RGWSystemMetaObj(const string& _id, const string& _name) : id(_id), name(_name) {}
+ RGWSystemMetaObj(CephContext *_cct, RGWSI_SysObj *_sysobj_svc): cct(_cct), sysobj_svc(_sysobj_svc){}
+ RGWSystemMetaObj(const string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): name(_name), cct(_cct), sysobj_svc(_sysobj_svc){}
+
const string& get_name() const { return name; }
const string& get_id() const { return id; }
@@ -87,11 +90,11 @@ public:
DECODE_FINISH(bl);
}
- void reinit_instance(CephContext *_cct, RGWRados *_store) {
+ void reinit_instance(CephContext *_cct, RGWSI_SysObj *_sysobj_svc) {
cct = _cct;
- store = _store;
+ sysobj_svc = _sysobj_svc;
}
- int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true, bool old_format = false);
+ int init(CephContext *_cct, RGWSI_SysObj *_sysobj_svc, bool setup_obj = true, bool old_format = false);
virtual int read_default_id(string& default_id, bool old_format = false);
virtual int set_as_default(bool exclusive = false);
int delete_default();
@@ -205,7 +208,7 @@ struct RGWZoneParams : RGWSystemMetaObj {
const string& get_info_oid_prefix(bool old_format = false) override;
const string& get_predefined_name(CephContext *cct) override;
- int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true,
+ int init(CephContext *_cct, RGWSI_SysObj *_sysobj_svc, bool setup_obj = true,
bool old_format = false);
using RGWSystemMetaObj::init;
int read_default_id(string& default_id, bool old_format = false) override;
@@ -520,9 +523,9 @@ struct RGWZoneGroup : public RGWSystemMetaObj {
RGWZoneGroup(): is_master(false){}
RGWZoneGroup(const std::string &id, const std::string &name):RGWSystemMetaObj(id, name) {}
explicit RGWZoneGroup(const std::string &_name):RGWSystemMetaObj(_name) {}
- RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWRados* store,
+ RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWSI_SysObj* sysobj_svc,
const string& _realm_id, const list<string>& _endpoints)
- : RGWSystemMetaObj(_name, cct , store), endpoints(_endpoints), is_master(_is_master),
+ : RGWSystemMetaObj(_name, cct , sysobj_svc), endpoints(_endpoints), is_master(_is_master),
realm_id(_realm_id) {}
bool is_master_zonegroup() const { return is_master;}
@@ -648,8 +651,8 @@ struct RGWPeriodConfig
// the period config must be stored in a local object outside of the period,
// so that it can be used in a default configuration where no realm/period
// exists
- int read(RGWRados *store, const std::string& realm_id);
- int write(RGWRados *store, const std::string& realm_id);
+ int read(RGWSI_SysObj *sysobj_svc, const std::string& realm_id);
+ int write(RGWSI_SysObj *sysobj_svc, const std::string& realm_id);
static std::string get_oid(const std::string& realm_id);
static rgw_pool get_pool(CephContext *cct);
@@ -685,7 +688,7 @@ struct RGWZoneGroupMap {
RGWQuotaInfo user_quota;
/* construct the map */
- int read(CephContext *cct, RGWRados *store);
+ int read(CephContext *cct, RGWSI_SysObj *sysobj_svc);
void encode(bufferlist& bl) const;
void decode(bufferlist::const_iterator& bl);
@@ -708,8 +711,8 @@ class RGWRealm : public RGWSystemMetaObj
public:
RGWRealm() {}
RGWRealm(const string& _id, const string& _name = "") : RGWSystemMetaObj(_id, _name) {}
- RGWRealm(CephContext *_cct, RGWRados *_store): RGWSystemMetaObj(_cct, _store) {}
- RGWRealm(const string& _name, CephContext *_cct, RGWRados *_store): RGWSystemMetaObj(_name, _cct, _store){}
+ RGWRealm(CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_cct, _sysobj_svc) {}
+ RGWRealm(const string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_name, _cct, _sysobj_svc){}
void encode(bufferlist& bl) const override {
ENCODE_START(1, 1, bl);
@@ -781,7 +784,7 @@ WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo)
class RGWPeriod
{
string id;
- epoch_t epoch;
+ epoch_t epoch{0};
string predecessor_uuid;
std::vector<std::string> sync_status;
RGWPeriodMap period_map;
@@ -793,8 +796,8 @@ class RGWPeriod
string realm_name;
epoch_t realm_epoch{1}; //< realm epoch when period was made current
- CephContext *cct;
- RGWRados *store;
+ CephContext *cct{nullptr};
+ RGWSI_SysObj *sysobj_svc{nullptr};
int read_info();
int read_latest_epoch(RGWPeriodLatestEpochInfo& epoch_info,
@@ -810,11 +813,10 @@ class RGWPeriod
std::ostream& error_stream, bool force_if_stale);
public:
- RGWPeriod() : epoch(0), cct(NULL), store(NULL) {}
+ RGWPeriod() {}
RGWPeriod(const string& period_id, epoch_t _epoch = 0)
- : id(period_id), epoch(_epoch),
- cct(NULL), store(NULL) {}
+ : id(period_id), epoch(_epoch) {}
const string& get_id() const { return id; }
epoch_t get_epoch() const { return epoch; }
@@ -887,9 +889,9 @@ public:
// update latest_epoch if the given epoch is higher, else return -EEXIST
int update_latest_epoch(epoch_t epoch);
- int init(CephContext *_cct, RGWRados *_store, const string &period_realm_id, const string &period_realm_name = "",
+ int init(CephContext *_cct, RGWSI_SysObj *_sysobj_svc, const string &period_realm_id, const string &period_realm_name = "",
bool setup_obj = true);
- int init(CephContext *_cct, RGWRados *_store, bool setup_obj = true);
+ int init(CephContext *_cct, RGWSI_SysObj *_sysobj_svc, bool setup_obj = true);
int create(bool exclusive = true);
int delete_obj();
diff --git a/src/rgw/services/svc_quota.cc b/src/rgw/services/svc_quota.cc
index 8fda921c7a7..267c265babf 100644
--- a/src/rgw/services/svc_quota.cc
+++ b/src/rgw/services/svc_quota.cc
@@ -18,7 +18,7 @@ std::map<string, RGWServiceInstance::dependency> RGWSI_Quota::get_deps()
return deps;
}
-int RGWSI_Quota::init(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs)
+int RGWSI_Quota::load(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs)
{
zone_svc = static_pointer_cast<RGWSI_Zone>(dep_refs["zone_dep"]);
assert(zone_svc);
diff --git a/src/rgw/services/svc_quota.h b/src/rgw/services/svc_quota.h
index 425fc37f18d..a1e56d2c7a7 100644
--- a/src/rgw/services/svc_quota.h
+++ b/src/rgw/services/svc_quota.h
@@ -12,15 +12,15 @@ class RGWS_Quota : public RGWService
public:
RGWS_Quota(CephContext *cct) : RGWService(cct, "quota") {}
- int create_instance(const std::string& conf, RGWServiceInstanceRef *instance);
+ int create_instance(const std::string& conf, RGWServiceInstanceRef *instance) override;
};
class RGWSI_Quota : public RGWServiceInstance
{
std::shared_ptr<RGWSI_Zone> zone_svc;
- std::map<std::string, RGWServiceInstance::dependency> get_deps();
- int init(const std::string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs);
+ std::map<std::string, RGWServiceInstance::dependency> get_deps() override;
+ int load(const std::string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs) override;
public:
RGWSI_Quota(RGWService *svc, CephContext *cct): RGWServiceInstance(svc, cct) {}
diff --git a/src/rgw/services/svc_rados.cc b/src/rgw/services/svc_rados.cc
index 4c587a985e8..b0b4d02da8c 100644
--- a/src/rgw/services/svc_rados.cc
+++ b/src/rgw/services/svc_rados.cc
@@ -47,7 +47,7 @@ static int init_ioctx(CephContext *cct, librados::Rados *rados, const rgw_pool&
return 0;
}
-int RGWSI_RADOS::init(const string& conf, map<string, RGWServiceInstanceRef>& deps)
+int RGWSI_RADOS::load(const string& conf, map<string, RGWServiceInstanceRef>& deps)
{
auto handles = std::vector<librados::Rados>{static_cast<size_t>(cct->_conf->rgw_num_rados_handles)};
@@ -131,3 +131,8 @@ int RGWSI_RADOS::Obj::aio_operate(librados::AioCompletion *c, librados::ObjectWr
{
return ref.ioctx.aio_operate(ref.oid, c, op);
}
+
+uint64_t RGWSI_RADOS::Obj::get_last_version()
+{
+ return ref.ioctx.get_last_version();
+}
diff --git a/src/rgw/services/svc_rados.h b/src/rgw/services/svc_rados.h
index 32585357814..a49f78beb66 100644
--- a/src/rgw/services/svc_rados.h
+++ b/src/rgw/services/svc_rados.h
@@ -12,7 +12,7 @@ class RGWS_RADOS : public RGWService
public:
RGWS_RADOS(CephContext *cct) : RGWService(cct, "rados") {}
- int create_instance(const string& conf, RGWServiceInstanceRef *instance);
+ int create_instance(const string& conf, RGWServiceInstanceRef *instance) override;
};
struct rgw_rados_ref {
@@ -29,7 +29,8 @@ class RGWSI_RADOS : public RGWServiceInstance
RWLock handle_lock;
std::map<pthread_t, int> rados_map;
- int init(const string& conf, std::map<std::string, RGWServiceInstanceRef>& deps);
+ int load(const string& conf, std::map<std::string, RGWServiceInstanceRef>& deps) override;
+
librados::Rados* get_rados_handle();
int open_pool_ctx(const rgw_pool& pool, librados::IoCtx& io_ctx);
public:
@@ -41,7 +42,7 @@ public:
class Obj {
friend class RGWSI_RADOS;
- RGWSI_RADOS *rados_svc;
+ RGWSI_RADOS *rados_svc{nullptr};
rgw_rados_ref ref;
void init(const rgw_raw_obj& obj);
@@ -51,17 +52,20 @@ public:
}
public:
+ Obj() {}
Obj(const Obj& o) : rados_svc(o.rados_svc),
ref(o.ref) {}
- Obj(const Obj&& o) : rados_svc(o.rados_svc),
- ref(std::move(o.ref)) {}
+ Obj(Obj&& o) : rados_svc(o.rados_svc),
+ ref(std::move(o.ref)) {}
int open();
int operate(librados::ObjectWriteOperation *op);
int operate(librados::ObjectReadOperation *op, bufferlist *pbl);
int aio_operate(librados::AioCompletion *c, librados::ObjectWriteOperation *op);
+
+ uint64_t get_last_version();
};
Obj obj(const rgw_raw_obj& o) {
diff --git a/src/rgw/services/svc_sys_obj.cc b/src/rgw/services/svc_sys_obj.cc
new file mode 100644
index 00000000000..e0bd5856719
--- /dev/null
+++ b/src/rgw/services/svc_sys_obj.cc
@@ -0,0 +1,316 @@
+#include "svc_sys_obj.h"
+#include "svc_rados.h"
+
+int RGWS_SysObj::create_instance(const string& conf, RGWServiceInstanceRef *instance)
+{
+ instance->reset(new RGWSI_SysObj(this, cct));
+ return 0;
+}
+
+std::map<string, RGWServiceInstance::dependency> RGWSI_SysObj::get_deps()
+{
+ RGWServiceInstance::dependency dep1 = { .name = "rados",
+ .conf = "{}" };
+ RGWServiceInstance::dependency dep2 = { .name = "zone",
+ .conf = "{}" };
+ map<string, RGWServiceInstance::dependency> deps;
+ deps["rados_dep"] = dep1
+ deps["zone_dep"] = dep2
+ return deps;
+}
+
+int RGWSI_SysObj::load(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs)
+{
+ rados_svc = static_pointer_cast<RGWSI_RADOS>(dep_refs["rados_dep"]);
+ assert(rados_svc);
+
+ zone_svc = static_pointer_cast<RGWSI_Zone>(dep_refs["zone_dep"]);
+ assert(zone_svc);
+
+ return 0;
+}
+
+int RGWSI_SysObj::get_rados_obj(RGWSI_Zone *zone_svc,
+ rgw_raw_obj& obj,
+ RGWSI_Rados::Obj *pobj)
+{
+ zone_svc->canonicalize_raw_obj(&obj);
+
+ *pobj = rados_svc->obj(obj);
+ int r = pobj->open();
+ if (r < 0) {
+ return r;
+ }
+
+ return 0;
+}
+
+int RGWSI_SysObj::get_system_obj_state_impl(RGWSysObjectCtx *rctx, rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker)
+{
+ if (obj.empty()) {
+ return -EINVAL;
+ }
+
+ RGWSysObjState *s = rctx->get_state(obj);
+ ldout(cct, 20) << "get_system_obj_state: rctx=" << (void *)rctx << " obj=" << obj << " state=" << (void *)s << " s->prefetch_data=" << s->prefetch_data << dendl;
+ *state = s;
+ if (s->has_attrs) {
+ return 0;
+ }
+
+ s->obj = obj;
+
+ int r = raw_stat(obj, &s->size, &s->mtime, &s->epoch, &s->attrset, (s->prefetch_data ? &s->data : NULL), objv_tracker);
+ if (r == -ENOENT) {
+ s->exists = false;
+ s->has_attrs = true;
+ s->mtime = real_time();
+ return 0;
+ }
+ if (r < 0)
+ return r;
+
+ s->exists = true;
+ s->has_attrs = true;
+ s->obj_tag = s->attrset[RGW_ATTR_ID_TAG];
+
+ if (s->obj_tag.length())
+ ldout(cct, 20) << "get_system_obj_state: setting s->obj_tag to "
+ << s->obj_tag.c_str() << dendl;
+ else
+ ldout(cct, 20) << "get_system_obj_state: s->obj_tag was set empty" << dendl;
+
+ return 0;
+}
+
+int RGWSI_SysObj::get_system_obj_state(RGWSysObjectCtx *rctx, rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker)
+{
+ int ret;
+
+ do {
+ ret = get_system_obj_state_impl(rctx, obj, state, objv_tracker);
+ } while (ret == -EAGAIN);
+
+ return ret;
+}
+
+int RGWSI_SysObj::raw_stat(rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch,
+ map<string, bufferlist> *attrs, bufferlist *first_chunk,
+ RGWObjVersionTracker *objv_tracker)
+{
+ RGWSI_Rados::Obj rados_obj;
+ int r = get_rados_obj(obj, &rados_obj);
+ if (r < 0) {
+ return r;
+ }
+
+ map<string, bufferlist> unfiltered_attrset;
+ uint64_t size = 0;
+ struct timespec mtime_ts;
+
+ librados::ObjectReadOperation op;
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_read(&op);
+ }
+ if (attrs) {
+ op.getxattrs(&unfiltered_attrset, NULL);
+ }
+ if (psize || pmtime) {
+ op.stat2(&size, &mtime_ts, NULL);
+ }
+ if (first_chunk) {
+ op.read(0, cct->_conf->rgw_max_chunk_size, first_chunk, NULL);
+ }
+ bufferlist outbl;
+ r = rados_obj.operate(&op, &outbl);
+
+ if (epoch) {
+ *epoch = rados_obj.get_last_version();
+ }
+
+ if (r < 0)
+ return r;
+
+ if (psize)
+ *psize = size;
+ if (pmtime)
+ *pmtime = ceph::real_clock::from_timespec(mtime_ts);
+ if (attrs) {
+ filter_attrset(unfiltered_attrset, RGW_ATTR_PREFIX, attrs);
+ }
+
+ return 0;
+}
+
+int RGWSI_SysObj::stat(RGWSysObjectCtx& obj_ctx,
+ RGWSI_SysObj::SystemObject::Read::GetObjState& state,
+ rgw_raw_obj& obj,
+ map<string, bufferlist> *attrs,
+ real_time *lastmod,
+ uint64_t *obj_size,
+ RGWObjVersionTracker *objv_tracker)
+{
+ RGWSysObjState *astate = NULL;
+
+ int r = get_system_obj_state(&obj_ctx, obj, &astate, objv_tracker);
+ if (r < 0)
+ return r;
+
+ if (!astate->exists) {
+ return -ENOENT;
+ }
+
+ if (attrs) {
+ *attrs = astate->attrset;
+ if (cct->_conf->subsys.should_gather<ceph_subsys_rgw, 20>()) {
+ map<string, bufferlist>::iterator iter;
+ for (iter = attrs->begin(); iter != attrs->end(); ++iter) {
+ ldout(cct, 20) << "Read xattr: " << iter->first << dendl;
+ }
+ }
+ }
+
+ if (obj_size)
+ *obj_size = astate->size;
+ if (lastmod)
+ *lastmod = astate->mtime;
+
+ return 0;
+}
+
+int RGWSI_SysObj::read_obj(RGWObjectCtx& obj_ctx,
+ Obj::Read::GetObjState& read_state,
+ RGWObjVersionTracker *objv_tracker,
+ rgw_raw_obj& obj,
+ bufferlist *bl, off_t ofs, off_t end,
+ map<string, bufferlist> *attrs,
+ boost::optional<obj_version>)
+{
+ uint64_t len;
+ librados::ObjectReadOperation op;
+
+ if (end < 0)
+ len = 0;
+ else
+ len = end - ofs + 1;
+
+ if (objv_tracker) {
+ objv_tracker->prepare_op_for_read(&op);
+ }
+
+ ldout(cct, 20) << "rados->read ofs=" << ofs << " len=" << len << dendl;
+ op.read(ofs, len, bl, NULL);
+
+ if (attrs) {
+ op.getxattrs(attrs, NULL);
+ }
+
+ RGWSI_Rados::Obj rados_obj;
+ int r = get_rados_obj(obj, &rados_obj);
+ if (r < 0) {
+ ldout(cct, 20) << "get_rados_obj() on obj=" << obj << " returned " << r << dendl;
+ return r;
+ }
+ r = rados_obj.operate(&op, NULL);
+ if (r < 0) {
+ ldout(cct, 20) << "rados_obj.operate() r=" << r << " bl.length=" << bl->length() << dendl;
+ return r;
+ }
+ ldout(cct, 20) << "rados_obj.operate() r=" << r << " bl.length=" << bl->length() << dendl;
+
+ uint64_t op_ver = rados_obj.get_last_version();
+
+ if (read_state.last_ver > 0 &&
+ read_state.last_ver != op_ver) {
+ ldout(cct, 5) << "raced with an object write, abort" << dendl;
+ return -ECANCELED;
+ }
+
+ read_state.last_ver = op_ver;
+
+ return bl.length();
+}
+
+/**
+ * Get an attribute for a system object.
+ * obj: the object to get attr
+ * name: name of the attr to retrieve
+ * dest: bufferlist to store the result in
+ * Returns: 0 on success, -ERR# otherwise.
+ */
+int RGWSI_SysObj::get_attr(rgw_raw_obj& obj, std::string_view name, bufferlist *dest)
+{
+ RGWSI_Rados::Obj rados_obj;
+ int r = get_rados_obj(obj, &rados_obj);
+ if (r < 0) {
+ ldout(cct, 20) << "get_rados_obj() on obj=" << obj << " returned " << r << dendl;
+ return r;
+ }
+
+ librados::ObjectReadOperation op;
+
+ int rval;
+ op.getxattr(name, dest, &rval);
+
+ r = rados_obj.operate(&op, nullptr);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+void RGWSI_SysObj::Obj::invalidate_state()
+{
+ ctx.invalidate(obj);
+}
+
+int RGWSI_SysObj::Obj::Read::GetObjState::get_rados_obj(RGWSI_RADOS *rados_svc,
+ RGWSI_Zone *zone_svc,
+ rgw_raw_obj& obj,
+ RGWSI_Rados::Obj **pobj)
+{
+ if (!has_rados_obj) {
+ zone_svc->canonicalize_raw_obj(&obj);
+
+ rados_obj = rados_svc->obj(obj);
+ int r = rados_obj.open();
+ if (r < 0) {
+ return r;
+ }
+ has_rados_obj = true;
+ }
+ *pobj = &rados_obj;
+ return 0;
+}
+
+int RGWSI_SysObj::Obj::Read::stat()
+{
+ RGWSI_SysObj *svc = source.sysobj_svc;
+ rgw_raw_obj& obj = source.obj;
+
+ return sysobj_svc->stat(source.ctx(), state, obj, stat_params.attrs,
+ stat_params.lastmod, stat_params.obj_size,
+ stat_params.objv_tracker);
+}
+
+
+int RGWSI_SysObj::Obj::Read::read(int64_t ofs, int64_t end, bufferlist *bl)
+{
+ RGWSI_SysObj *svc = source.sysobj_svc;
+ rgw_raw_obj& obj = source.get_obj();
+
+ return svc->read(source.get_ctx(), state,
+ read_params.objv_tracker,
+ obj, bl, ofs, end,
+ read_params.attrs,
+ refresh_version);
+}
+
+int RGWSI_SysObj::Obj::Read::get_attr(std::string_view name, bufferlist *dest)
+{
+ RGWSI_SysObj *svc = source.sysobj_svc;
+ rgw_raw_obj& obj = source.get_obj();
+
+ return svc->get_attr(obj, name, dest);
+}
+
diff --git a/src/rgw/services/svc_sys_obj.h b/src/rgw/services/svc_sys_obj.h
new file mode 100644
index 00000000000..1a38cc268f4
--- /dev/null
+++ b/src/rgw/services/svc_sys_obj.h
@@ -0,0 +1,269 @@
+#ifndef CEPH_RGW_SERVICES_SYS_OBJ_H
+#define CEPH_RGW_SERVICES_SYS_OBJ_H
+
+
+#include "rgw/rgw_service.h"
+
+#include "svc_rados.h"
+
+
+class RGWSI_Zone;
+class RGWSI_SysObj;
+
+struct RGWSysObjState {
+ rgw_raw_obj obj;
+ bool has_attrs{false};
+ bool exists{false};
+ uint64_t size{0};
+ ceph::real_time mtime;
+ uint64_t epoch{0};
+ bufferlist obj_tag;
+ bool has_data{false};
+ bufferlist data;
+ bool prefetch_data{false};
+ uint64_t pg_ver{0};
+
+ /* important! don't forget to update copy constructor */
+
+ RGWObjVersionTracker objv_tracker;
+
+ map<string, bufferlist> attrset;
+ RGWSysObjState() {}
+ RGWSysObjState(const RGWSysObjState& rhs) : obj (rhs.obj) {
+ has_attrs = rhs.has_attrs;
+ exists = rhs.exists;
+ size = rhs.size;
+ mtime = rhs.mtime;
+ epoch = rhs.epoch;
+ if (rhs.obj_tag.length()) {
+ obj_tag = rhs.obj_tag;
+ }
+ has_data = rhs.has_data;
+ if (rhs.data.length()) {
+ data = rhs.data;
+ }
+ prefetch_data = rhs.prefetch_data;
+ pg_ver = rhs.pg_ver;
+ objv_tracker = rhs.objv_tracker;
+ }
+};
+
+template <class T, class S>
+class RGWSysObjectCtxImpl {
+ RGWSI_SysObj *sysobj_svc;
+ std::map<T, S> objs_state;
+ RWLock lock;
+
+public:
+ explicit RGWSysObjectCtxImpl(RGWSI_SysObj *_sysobj_svc) : sysobj_svc(_sysobj_svc), lock("RGWSysObjectCtxImpl") {}
+
+ RGWSysObjectCtxImpl(const RGWSysObjectCtxImpl& rhs) : sysobj_svc(rhs.sysobj_svc),
+ objs_state(rhs.objs_state),
+ lock("RGWSysObjectCtxImpl") {}
+ RGWSysObjectCtxImpl(const RGWSysObjectCtxImpl&& rhs) : sysobj_svc(rhs.sysobj_svc),
+ objs_state(std::move(rhs.objs_state)),
+ lock("RGWSysObjectCtxImpl") {}
+
+ S *get_state(const T& obj) {
+ S *result;
+ typename std::map<T, S>::iterator iter;
+ lock.get_read();
+ assert (!obj.empty());
+ iter = objs_state.find(obj);
+ if (iter != objs_state.end()) {
+ result = &iter->second;
+ lock.unlock();
+ } else {
+ lock.unlock();
+ lock.get_write();
+ result = &objs_state[obj];
+ lock.unlock();
+ }
+ return result;
+ }
+
+ void set_atomic(T& obj) {
+ RWLock::WLocker wl(lock);
+ assert (!obj.empty());
+ objs_state[obj].is_atomic = true;
+ }
+ void set_prefetch_data(T& obj) {
+ RWLock::WLocker wl(lock);
+ assert (!obj.empty());
+ objs_state[obj].prefetch_data = true;
+ }
+ void invalidate(T& obj) {
+ RWLock::WLocker wl(lock);
+ auto iter = objs_state.find(obj);
+ if (iter == objs_state.end()) {
+ return;
+ }
+ bool is_atomic = iter->second.is_atomic;
+ bool prefetch_data = iter->second.prefetch_data;
+
+ objs_state.erase(iter);
+
+ if (is_atomic || prefetch_data) {
+ auto& s = objs_state[obj];
+ s.is_atomic = is_atomic;
+ s.prefetch_data = prefetch_data;
+ }
+ }
+};
+
+using RGWSysObjectCtx = RGWSysObjectCtxImpl<rgw_raw_obj, RGWSysObjState>;
+
+class RGWS_SysObj : public RGWService
+{
+public:
+ RGWS_SysObj(CephContext *cct) : RGWService(cct, "sys_obj") {}
+
+ int create_instance(const std::string& conf, RGWServiceInstanceRef *instance) override;
+};
+
+class RGWSI_SysObj : public RGWServiceInstance
+{
+public:
+ class Obj {
+ friend class Read;
+
+ RGWSI_SysObj *sysobj_svc;
+ RGWSysObjectCtx& ctx;
+ rgw_raw_obj obj;
+
+ RGWSI_RADOS *get_rados_svc();
+
+ public:
+ Obj(RGWSI_SysObj *_sysobj_svc,
+ RGWSysObjectCtx& _ctx,
+ const rgw_raw_obj& _obj) : sysobj_svc(_sysobj_svc),
+ ctx(_ctx),
+ obj(_obj) {}
+
+ void invalidate_state();
+
+ RGWSysObjectCtx& get_ctx() {
+ return ctx;
+ }
+
+ rgw_raw_obj& get_obj() {
+ return obj;
+ }
+
+ struct Read {
+ Obj& source;
+
+ struct GetObjState {
+ RGWSI_RADOS::Obj rados_obj;
+ bool has_rados_obj{false};
+ uint64_t last_ver{0};
+
+ GetObjState() {}
+
+ int get_rados_obj(RGWSI_SysObj *sysobj_svc, rgw_raw_obj& obj, RGWSI_RADOS::Obj **pobj);
+ } state;
+
+ struct StatParams {
+ RGWObjVersionTracker *objv_tracker{nullptr};
+ ceph::real_time *lastmod{nullptr};
+ uint64_t *obj_size{nullptr};
+ map<string, bufferlist> *attrs{nullptr};
+
+ StatParams& set_last_mod(ceph::real_time *_lastmod) {
+ lastmod = _lastmod;
+ return *this;
+ }
+ StatParams& set_obj_size(uint64_t *_obj_size) {
+ obj_size = _obj_size;
+ return *this;
+ }
+ StatParams& set_attrs(map<string, bufferlist> *_attrs) {
+ attrs = _attrs;
+ return *this;
+ }
+ } stat_params;
+
+ struct ReadParams {
+ RGWObjVersionTracker *objv_tracker{nullptr};
+ map<string, bufferlist> *attrs{nullptr};
+ boost::optional<obj_version> refresh_version{boost::none};
+
+ ReadParams& set_attrs(map<string, bufferlist> *_attrs) {
+ attrs = _attrs;
+ return *this;
+ }
+ ReadParams& set_obj_tracker(RGWObjVersionTracker *_objv_tracker) {
+ objv_tracker = _objv_tracker;
+ return *this;
+ }
+ ReadParams& set_refresh_version(const obj_version& rf) {
+ refresh_version = rf;
+ return *this;
+ }
+ } read_params;
+
+ Read(Obj& _source) : source(_source) {}
+
+ int stat();
+ int read(int64_t ofs, int64_t end, bufferlist *pbl);
+ int read(bufferlist *pbl) {
+ return read(0, -1, pbl);
+ }
+ int get_attr(std::string_view name, bufferlist *dest);
+ };
+ };
+
+ friend class Obj;
+ friend class Obj::Read;
+
+private:
+ std::shared_ptr<RGWSI_RADOS> rados_svc;
+ std::shared_ptr<RGWSI_Zone> zone_svc;
+
+ std::map<std::string, RGWServiceInstance::dependency> get_deps() override;
+ int load(const std::string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs) override;
+
+ int get_rados_obj(RGWSI_Zone *zone_svc, rgw_raw_obj& obj, RGWSI_RADOS::Obj *pobj);
+
+ int get_system_obj_state_impl(RGWSysObjectCtx *rctx, rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker);
+ int get_system_obj_state(RGWSysObjectCtx *rctx, rgw_raw_obj& obj, RGWSysObjState **state, RGWObjVersionTracker *objv_tracker);
+
+ int raw_stat(rgw_raw_obj& obj, uint64_t *psize, real_time *pmtime, uint64_t *epoch,
+ map<string, bufferlist> *attrs, bufferlist *first_chunk,
+ RGWObjVersionTracker *objv_tracker);
+
+ int stat(RGWSysObjectCtx& obj_ctx,
+ RGWSI_SysObj::Obj::Read::GetObjState& state,
+ rgw_raw_obj& obj,
+ map<string, bufferlist> *attrs,
+ real_time *lastmod,
+ uint64_t *obj_size,
+ RGWObjVersionTracker *objv_tracker);
+
+ int read(RGWSysObjectCtx& obj_ctx,
+ Obj::Read::GetObjState& read_state,
+ RGWObjVersionTracker *objv_tracker,
+ rgw_raw_obj& obj,
+ bufferlist *bl, off_t ofs, off_t end,
+ map<string, bufferlist> *attrs,
+ boost::optional<obj_version>);
+
+ int get_attr(rgw_raw_obj& obj, std::string_view name, bufferlist *dest);
+
+public:
+ RGWSI_SysObj(RGWService *svc, CephContext *cct): RGWServiceInstance(svc, cct) {}
+
+ RGWSysObjectCtx&& init_obj_ctx() {
+ return std::move(RGWSysObjectCtx(this));
+ }
+
+ Obj&& get_obj(RGWSysObjectCtx& obj_ctx, const rgw_raw_obj& obj) {
+ return std::move(Obj(this, obj_ctx, obj));
+ }
+
+};
+
+using RGWSysObj = RGWSI_SysObj::Obj;
+
+#endif
+
diff --git a/src/rgw/services/svc_zone.cc b/src/rgw/services/svc_zone.cc
index 22e516d9438..ab9f63031f3 100644
--- a/src/rgw/services/svc_zone.cc
+++ b/src/rgw/services/svc_zone.cc
@@ -1,7 +1,26 @@
#include "svc_zone.h"
#include "svc_rados.h"
+#include "svc_sys_obj.h"
#include "rgw/rgw_zone.h"
+#include "rgw/rgw_rest_conn.h"
+
+#include "common/errno.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+static string zone_names_oid_prefix = "zone_names.";
+static string region_info_oid_prefix = "region_info.";
+static string realm_names_oid_prefix = "realms_names.";
+static string default_region_info_oid = "default.region";
+static string region_map_oid = "region_map";
+const string default_zonegroup_name = "default";
+const string default_zone_name = "default";
+static string zonegroup_names_oid_prefix = "zonegroups_names.";
+static string RGW_DEFAULT_ZONE_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_ZONEGROUP_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_REALM_ROOT_POOL = "rgw.root";
+static string RGW_DEFAULT_PERIOD_ROOT_POOL = "rgw.root";
int RGWS_Zone::create_instance(const string& conf, RGWServiceInstanceRef *instance)
{
@@ -11,17 +30,692 @@ int RGWS_Zone::create_instance(const string& conf, RGWServiceInstanceRef *instan
std::map<string, RGWServiceInstance::dependency> RGWSI_Zone::get_deps()
{
- RGWServiceInstance::dependency dep = { .name = "rados",
- .conf = "{}" };
+ RGWServiceInstance::dependency dep1 = { .name = "rados",
+ .conf = "{}" };
+ RGWServiceInstance::dependency dep2 = { .name = "sys_obj",
+ .conf = "{}" };
map<string, RGWServiceInstance::dependency> deps;
- deps["rados_dep"] = dep;
+ deps["rados_dep"] = dep1;
+ deps["sys_obj_dep"] = dep2;
return deps;
}
-int RGWSI_Zone::init(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs)
+int RGWSI_Zone::load(const string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs)
{
rados_svc = static_pointer_cast<RGWSI_RADOS>(dep_refs["rados_dep"]);
assert(rados_svc);
+
+ sysobj_svc = static_pointer_cast<RGWSI_SysObj>(dep_refs["sys_obj_dep"]);
+ assert(sysobj_svc);
+
+ realm = make_shared<RGWRealm>();
+ zonegroup = make_shared<RGWZoneGroup>();
+ zone_public_config = make_shared<RGWZone>();
+ zone_params = make_shared<RGWZoneParams>();
+ current_period = make_shared<RGWPeriod>();
+
+ return 0;
+}
+
+int RGWSI_Zone::init()
+{
+ int ret = realm->init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "failed reading realm info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ } else if (ret != -ENOENT) {
+ ldout(cct, 20) << "realm " << realm->get_name() << " " << realm->get_id() << dendl;
+ ret = current_period->init(cct, sysobj_svc.get(), realm->get_id(), realm->get_name());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "failed reading current period info: " << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ldout(cct, 20) << "current period " << current_period->get_id() << dendl;
+ }
+
+ ret = replace_region_with_zonegroup();
+ if (ret < 0) {
+ lderr(cct) << "failed converting region to zonegroup : ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ ret = convert_regionmap();
+ if (ret < 0) {
+ lderr(cct) << "failed converting regionmap: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ bool zg_initialized = false;
+
+ if (!current_period->get_id().empty()) {
+ ret = init_zg_from_period(&zg_initialized);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ bool creating_defaults = false;
+ bool using_local = (!zg_initialized);
+ if (using_local) {
+ ldout(cct, 10) << " cannot find current period zonegroup using local zonegroup" << dendl;
+ ret = init_zg_from_local(&creating_defaults);
+ if (ret < 0) {
+ return ret;
+ }
+ // read period_config into current_period
+ auto& period_config = current_period->get_config();
+ ret = period_config.read(sysobj_svc.get(), zonegroup->realm_id);
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "ERROR: failed to read period config: "
+ << cpp_strerror(ret) << dendl;
+ return ret;
+ }
+ }
+
+ ldout(cct, 10) << "Cannot find current period zone using local zone" << dendl;
+ if (creating_defaults && cct->_conf->rgw_zone.empty()) {
+ ldout(cct, 10) << " Using default name "<< default_zone_name << dendl;
+ zone_params->set_name(default_zone_name);
+ }
+
+ ret = zone_params->init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ lderr(cct) << "failed reading zone info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ map<string, RGWZone>::iterator zone_iter = get_zonegroup().zones.find(zone_params->get_id());
+ if (zone_iter == get_zonegroup().zones.end()) {
+ if (using_local) {
+ lderr(cct) << "Cannot find zone id=" << zone_params->get_id() << " (name=" << zone_params->get_name() << ")" << dendl;
+ return -EINVAL;
+ }
+ ldout(cct, 1) << "Cannot find zone id=" << zone_params->get_id() << " (name=" << zone_params->get_name() << "), switching to local zonegroup configuration" << dendl;
+ ret = init_zg_from_local(&creating_defaults);
+ if (ret < 0) {
+ return ret;
+ }
+ zone_iter = get_zonegroup().zones.find(zone_params->get_id());
+ }
+ if (zone_iter != get_zonegroup().zones.end()) {
+ *zone_public_config = zone_iter->second;
+ ldout(cct, 20) << "zone " << zone_params->get_name() << dendl;
+ } else {
+ lderr(cct) << "Cannot find zone id=" << zone_params->get_id() << " (name=" << zone_params->get_name() << ")" << dendl;
+ return -EINVAL;
+ }
+
+ zone_short_id = current_period->get_map().get_zone_short_id(zone_params->get_id());
+
+ writeable_zone = (zone_public_config->tier_type.empty() || zone_public_config->tier_type == "rgw");
+
+ return 0;
+}
+
+void RGWSI_Zone::shutdown()
+{
+ delete rest_master_conn;
+
+ map<string, RGWRESTConn *>::iterator iter;
+ for (iter = zone_conn_map.begin(); iter != zone_conn_map.end(); ++iter) {
+ RGWRESTConn *conn = iter->second;
+ delete conn;
+ }
+
+ for (iter = zonegroup_conn_map.begin(); iter != zonegroup_conn_map.end(); ++iter) {
+ RGWRESTConn *conn = iter->second;
+ delete conn;
+ }
+}
+
+int RGWSI_Zone::list_regions(list<string>& regions)
+{
+ RGWZoneGroup zonegroup;
+
+ return list_raw_prefixed_objs(zonegroup.get_pool(cct), region_info_oid_prefix, regions);
+}
+
+int RGWSI_Zone::list_zonegroups(list<string>& zonegroups)
+{
+ RGWZoneGroup zonegroup;
+
+ return list_raw_prefixed_objs(zonegroup.get_pool(cct), zonegroup_names_oid_prefix, zonegroups);
+}
+
+int RGWSI_Zone::list_zones(list<string>& zones)
+{
+ RGWZoneParams zoneparams;
+
+ return list_raw_prefixed_objs(zoneparams.get_pool(cct), zone_names_oid_prefix, zones);
+}
+
+int RGWSI_Zone::list_realms(list<string>& realms)
+{
+ RGWRealm realm(cct, sysobj_svc.get());
+ return list_raw_prefixed_objs(realm.get_pool(cct), realm_names_oid_prefix, realms);
+}
+
+int RGWSI_Zone::list_periods(list<string>& periods)
+{
+ RGWPeriod period;
+ list<string> raw_periods;
+ int ret = list_raw_prefixed_objs(period.get_pool(cct), period.get_info_oid_prefix(), raw_periods);
+ if (ret < 0) {
+ return ret;
+ }
+ for (const auto& oid : raw_periods) {
+ size_t pos = oid.find(".");
+ if (pos != std::string::npos) {
+ periods.push_back(oid.substr(0, pos));
+ } else {
+ periods.push_back(oid);
+ }
+ }
+ periods.sort(); // unique() only detects duplicates if they're adjacent
+ periods.unique();
+ return 0;
+}
+
+
+int RGWSI_Zone::list_periods(const string& current_period, list<string>& periods)
+{
+ int ret = 0;
+ string period_id = current_period;
+ while(!period_id.empty()) {
+ RGWPeriod period(period_id);
+ ret = period.init(cct, sysobj_svc.get());
+ if (ret < 0) {
+ return ret;
+ }
+ periods.push_back(period.get_id());
+ period_id = period.get_predecessor();
+ }
+
+ return ret;
+}
+
+/**
+ * Replace all region configuration with zonegroup for
+ * backward compatability
+ * Returns 0 on success, -ERR# on failure.
+ */
+int RGWSI_Zone::replace_region_with_zonegroup()
+{
+ /* copy default region */
+ /* convert default region to default zonegroup */
+ string default_oid = cct->_conf->rgw_default_region_info_oid;
+ if (default_oid.empty()) {
+ default_oid = default_region_info_oid;
+ }
+
+ RGWZoneGroup default_zonegroup;
+ rgw_pool pool{default_zonegroup.get_pool(cct)};
+ string oid = "converted";
+ bufferlist bl;
+
+ RGWSysObjectCtx obj_ctx = sysobj_svc->init_obj_ctx();
+ RGWSysObj sysobj = sysobj_svc->get_obj(obj_ctx, rgw_raw_obj(pool, oid));
+ RGWSysObj::Read rop(sysobj);
+
+ int ret = rop.read(&bl);
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << " failed to read converted: ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ } else if (ret != -ENOENT) {
+ ldout(cct, 20) << "System already converted " << dendl;
+ return 0;
+ }
+
+ string default_region;
+ ret = default_zonegroup.init(cct, sysobj_svc.get(), false, true);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed init default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = default_zonegroup.read_default_id(default_region, true);
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << " failed reading old default region: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+
+ /* convert regions to zonegroups */
+ list<string> regions;
+ ret = list_regions(regions);
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << " failed to list regions: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ } else if (ret == -ENOENT || regions.empty()) {
+ RGWZoneParams zoneparams(default_zone_name);
+ int ret = zoneparams.init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << ": error initializing default zone params: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ /* update master zone */
+ RGWZoneGroup default_zg(default_zonegroup_name);
+ ret = default_zg.init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << ": error in initializing default zonegroup: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ if (ret != -ENOENT && default_zg.master_zone.empty()) {
+ default_zg.master_zone = zoneparams.get_id();
+ return default_zg.update();
+ }
+ return 0;
+ }
+
+ string master_region, master_zone;
+ for (list<string>::iterator iter = regions.begin(); iter != regions.end(); ++iter) {
+ if (*iter != default_zonegroup_name){
+ RGWZoneGroup region(*iter);
+ int ret = region.init(cct, sysobj_svc.get(), true, true);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed init region "<< *iter << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ if (region.is_master_zonegroup()) {
+ master_region = region.get_id();
+ master_zone = region.master_zone;
+ }
+ }
+ }
+
+ /* create realm if there is none.
+ The realm name will be the region and zone concatenated
+ realm id will be mds of its name */
+ if (realm->get_id().empty() && !master_region.empty() && !master_zone.empty()) {
+ string new_realm_name = master_region + "." + master_zone;
+ unsigned char md5[CEPH_CRYPTO_MD5_DIGESTSIZE];
+ char md5_str[CEPH_CRYPTO_MD5_DIGESTSIZE * 2 + 1];
+ MD5 hash;
+ hash.Update((const unsigned char *)new_realm_name.c_str(), new_realm_name.length());
+ hash.Final(md5);
+ buf_to_hex(md5, CEPH_CRYPTO_MD5_DIGESTSIZE, md5_str);
+ string new_realm_id(md5_str);
+ RGWRealm new_realm(new_realm_id,new_realm_name);
+ ret = new_realm.init(cct, sysobj_svc.get(), false);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " Error initing new realm: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = new_realm.create();
+ if (ret < 0 && ret != -EEXIST) {
+ ldout(cct, 0) << __func__ << " Error creating new realm: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = new_realm.set_as_default();
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " Error setting realm as default: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = realm.init(cct, this);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " Error initing realm: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = current_period->init(cct, this, realm->get_id(), realm->get_name());
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " Error initing current period: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+
+ list<string>::iterator iter;
+ /* create zonegroups */
+ for (iter = regions.begin(); iter != regions.end(); ++iter)
+ {
+ ldout(cct, 0) << __func__ << " Converting " << *iter << dendl;
+ /* check to see if we don't have already a zonegroup with this name */
+ RGWZoneGroup new_zonegroup(*iter);
+ ret = new_zonegroup.init(cct , sysobj_svc.get());
+ if (ret == 0 && new_zonegroup.get_id() != *iter) {
+ ldout(cct, 0) << __func__ << " zonegroup "<< *iter << " already exists id " << new_zonegroup.get_id () <<
+ " skipping conversion " << dendl;
+ continue;
+ }
+ RGWZoneGroup zonegroup(*iter);
+ zonegroup.set_id(*iter);
+ int ret = zonegroup.init(cct, this, true, true);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed init zonegroup: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ zonegroup.realm_id = realm->get_id();
+ /* fix default region master zone */
+ if (*iter == default_zonegroup_name && zonegroup.master_zone.empty()) {
+ ldout(cct, 0) << __func__ << " Setting default zone as master for default region" << dendl;
+ zonegroup.master_zone = default_zone_name;
+ }
+ ret = zonegroup.update();
+ if (ret < 0 && ret != -EEXIST) {
+ ldout(cct, 0) << __func__ << " failed to update zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ ret = zonegroup.update_name();
+ if (ret < 0 && ret != -EEXIST) {
+ ldout(cct, 0) << __func__ << " failed to update_name for zonegroup " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ if (zonegroup.get_name() == default_region) {
+ ret = zonegroup.set_as_default();
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed to set_as_default " << *iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ }
+ for (map<string, RGWZone>::const_iterator iter = zonegroup.zones.begin(); iter != zonegroup.zones.end();
+ ++iter) {
+ ldout(cct, 0) << __func__ << " Converting zone" << iter->first << dendl;
+ RGWZoneParams zoneparams(iter->first, iter->first);
+ zoneparams.set_id(iter->first);
+ zoneparams.realm_id = realm->get_id();
+ ret = zoneparams.init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << " failed to init zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ } else if (ret == -ENOENT) {
+ ldout(cct, 0) << __func__ << " zone is part of another cluster " << iter->first << " skipping " << dendl;
+ continue;
+ }
+ zonegroup.realm_id = realm->get_id();
+ ret = zoneparams.update();
+ if (ret < 0 && ret != -EEXIST) {
+ ldout(cct, 0) << __func__ << " failed to update zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = zoneparams.update_name();
+ if (ret < 0 && ret != -EEXIST) {
+ ldout(cct, 0) << __func__ << " failed to init zoneparams " << iter->first << ": " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+
+ if (!current_period->get_id().empty()) {
+ ret = current_period->add_zonegroup(zonegroup);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed to add zonegroup to current_period: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+ }
+
+ if (!current_period->get_id().empty()) {
+ ret = current_period->update();
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed to update new period: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = current_period->store_info(false);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed to store new period: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = current_period->reflect();
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed to update local objects: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+
+ for (auto const& iter : regions) {
+ RGWZoneGroup zonegroup(iter);
+ int ret = zonegroup.init(cct, this, true, true);
+ if (ret < 0) {
+ ldout(cct, 0) << __func__ << " failed init zonegroup" << iter << ": ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = zonegroup.delete_obj(true);
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << __func__ << " failed to delete region " << iter << ": ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ }
+
+ /* mark as converted */
+ ret = rgw_put_system_obj(this, pool, oid, bl,
+ true, NULL, real_time(), NULL);
+ if (ret < 0 ) {
+ ldout(cct, 0) << __func__ << " failed to mark cluster as converted: ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * Add new connection to connections map
+ * @param zonegroup_conn_map map which new connection will be added to
+ * @param zonegroup zonegroup which new connection will connect to
+ * @param new_connection pointer to new connection instance
+ */
+static void add_new_connection_to_map(map<string, RGWRESTConn *> &zonegroup_conn_map,
+ const RGWZoneGroup &zonegroup, RGWRESTConn *new_connection)
+{
+ // Delete if connection is already exists
+ map<string, RGWRESTConn *>::iterator iterZoneGroup = zonegroup_conn_map.find(zonegroup.get_id());
+ if (iterZoneGroup != zonegroup_conn_map.end()) {
+ delete iterZoneGroup->second;
+ }
+
+ // Add new connection to connections map
+ zonegroup_conn_map[zonegroup.get_id()] = new_connection;
+}
+
+int RGWSI_Zone::init_zg_from_period(bool *initialized)
+{
+ *initialized = false;
+
+ if (current_period->get_id().empty()) {
+ return 0;
+ }
+
+ int ret = zonegroup->init(cct, sysobj_svc.get());
+ ldout(cct, 20) << "period zonegroup init ret " << ret << dendl;
+ if (ret == -ENOENT) {
+ return 0;
+ }
+ if (ret < 0) {
+ ldout(cct, 0) << "failed reading zonegroup info: " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ldout(cct, 20) << "period zonegroup name " << zonegroup->get_name() << dendl;
+
+ map<string, RGWZoneGroup>::const_iterator iter =
+ current_period->get_map().zonegroups.find(zonegroup->get_id());
+
+ if (iter != current_period->get_map().zonegroups.end()) {
+ ldout(cct, 20) << "using current period zonegroup " << zonegroup->get_name() << dendl;
+ *zonegroup = iter->second;
+ ret = zonegroup->init(cct, sysobj_svc.get(), false);
+ if (ret < 0) {
+ ldout(cct, 0) << "failed init zonegroup: " << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ ret = zone_params->init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "failed reading zone params info: " << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ } if (ret ==-ENOENT && zonegroup->get_name() == default_zonegroup_name) {
+ ldout(cct, 10) << " Using default name "<< default_zone_name << dendl;
+ zone_params->set_name(default_zone_name);
+ ret = zone_params->init(cct, sysobj_svc.get());
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "failed reading zone params info: " << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+ }
+ for (iter = current_period->get_map().zonegroups.begin();
+ iter != current_period->get_map().zonegroups.end(); ++iter){
+ const RGWZoneGroup& zg = iter->second;
+ // use endpoints from the zonegroup's master zone
+ auto master = zg.zones.find(zg.master_zone);
+ if (master == zg.zones.end()) {
+ // fix missing master zone for a single zone zonegroup
+ if (zg.master_zone.empty() && zg.zones.size() == 1) {
+ master = zg.zones.begin();
+ ldout(cct, 0) << "zonegroup " << zg.get_name() << " missing master_zone, setting zone " <<
+ master->second.name << " id:" << master->second.id << " as master" << dendl;
+ if (zonegroup->get_id() == zg.get_id()) {
+ zonegroup->master_zone = master->second.id;
+ ret = zonegroup->update();
+ if (ret < 0) {
+ ldout(cct, 0) << "error updating zonegroup : " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ } else {
+ RGWZoneGroup fixed_zg(zg.get_id(),zg.get_name());
+ ret = fixed_zg.init(cct, sysobj_svc.get());
+ if (ret < 0) {
+ ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ fixed_zg.master_zone = master->second.id;
+ ret = fixed_zg.update();
+ if (ret < 0) {
+ ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+ } else {
+ ldout(cct, 0) << "zonegroup " << zg.get_name() << " missing zone for master_zone=" <<
+ zg.master_zone << dendl;
+ return -EINVAL;
+ }
+ }
+ const auto& endpoints = master->second.endpoints;
+ add_new_connection_to_map(zonegroup_conn_map, zg, new RGWRESTConn(cct, this, zg.get_id(), endpoints));
+ if (!current_period->get_master_zonegroup().empty() &&
+ zg.get_id() == current_period->get_master_zonegroup()) {
+ rest_master_conn = new RGWRESTConn(cct, this, zg.get_id(), endpoints);
+ }
+ }
+
+ *initialized = true;
+
+ return 0;
+}
+
+int RGWSI_Zone::init_zg_from_local(bool *creating_defaults)
+{
+ int ret = zonegroup->init(cct, sysobj_svc.get());
+ if ( (ret < 0 && ret != -ENOENT) || (ret == -ENOENT && !cct->_conf->rgw_zonegroup.empty())) {
+ ldout(cct, 0) << "failed reading zonegroup info: ret "<< ret << " " << cpp_strerror(-ret) << dendl;
+ return ret;
+ } else if (ret == -ENOENT) {
+ *creating_defaults = true;
+ ldout(cct, 10) << "Creating default zonegroup " << dendl;
+ ret = zonegroup->create_default();
+ if (ret < 0) {
+ ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ ret = zonegroup->init(cct, sysobj_svc.get());
+ if (ret < 0) {
+ ldout(cct, 0) << "failure in zonegroup create_default: ret "<< ret << " " << cpp_strerror(-ret)
+ << dendl;
+ return ret;
+ }
+ }
+ ldout(cct, 20) << "zonegroup " << zonegroup->get_name() << dendl;
+ if (zonegroup->is_master_zonegroup()) {
+ // use endpoints from the zonegroup's master zone
+ auto master = zonegroup->zones.find(zonegroup->master_zone);
+ if (master == zonegroup->zones.end()) {
+ // fix missing master zone for a single zone zonegroup
+ if (zonegroup->master_zone.empty() && zonegroup->zones.size() == 1) {
+ master = zonegroup->zones.begin();
+ ldout(cct, 0) << "zonegroup " << zonegroup->get_name() << " missing master_zone, setting zone " <<
+ master->second.name << " id:" << master->second.id << " as master" << dendl;
+ zonegroup->master_zone = master->second.id;
+ ret = zonegroup->update();
+ if (ret < 0) {
+ ldout(cct, 0) << "error initializing zonegroup : " << cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ } else {
+ ldout(cct, 0) << "zonegroup " << zonegroup->get_name() << " missing zone for "
+ "master_zone=" << zonegroup->master_zone << dendl;
+ return -EINVAL;
+ }
+ }
+ const auto& endpoints = master->second.endpoints;
+ rest_master_conn = new RGWRESTConn(cct, this, zonegroup->get_id(), endpoints);
+ }
+
+ return 0;
+}
+
+int RGWSI_Zone::convert_regionmap()
+{
+ RGWZoneGroupMap zonegroupmap;
+
+ string pool_name = cct->_conf->rgw_zone_root_pool;
+ if (pool_name.empty()) {
+ pool_name = RGW_DEFAULT_ZONE_ROOT_POOL;
+ }
+ string oid = region_map_oid;
+
+ rgw_pool pool(pool_name);
+ bufferlist bl;
+
+ RGWSysObjectCtx obj_ctx = sysobj_svc->init_obj_ctx();
+ RGWSysObj sysobj = sysobj_svc->get_obj(obj_ctx, rgw_raw_obj(pool, oid));
+ RGWSysObj::Read rop(sysobj);
+
+ int ret = rop.read(&bl);
+ if (ret < 0 && ret != -ENOENT) {
+ return ret;
+ } else if (ret == -ENOENT) {
+ return 0;
+ }
+
+ try {
+ auto iter = bl.cbegin();
+ decode(zonegroupmap, iter);
+ } catch (buffer::error& err) {
+ ldout(cct, 0) << "error decoding regionmap from " << pool << ":" << oid << dendl;
+ return -EIO;
+ }
+
+ for (map<string, RGWZoneGroup>::iterator iter = zonegroupmap.zonegroups.begin();
+ iter != zonegroupmap.zonegroups.end(); ++iter) {
+ RGWZoneGroup& zonegroup = iter->second;
+ ret = zonegroup.init(cct, sysobj_svc.get(), false);
+ ret = zonegroup.update();
+ if (ret < 0 && ret != -ENOENT) {
+ ldout(cct, 0) << "Error could not update zonegroup " << zonegroup.get_name() << ": " <<
+ cpp_strerror(-ret) << dendl;
+ return ret;
+ } else if (ret == -ENOENT) {
+ ret = zonegroup.create();
+ if (ret < 0) {
+ ldout(cct, 0) << "Error could not create " << zonegroup.get_name() << ": " <<
+ cpp_strerror(-ret) << dendl;
+ return ret;
+ }
+ }
+ }
+
+ current_period->set_user_quota(zonegroupmap.user_quota);
+ current_period->set_bucket_quota(zonegroupmap.bucket_quota);
+
+ // remove the region_map so we don't try to convert again
+ rgw_raw_obj obj(pool, oid);
+ ret = delete_system_obj(obj);
+ if (ret < 0) {
+ ldout(cct, 0) << "Error could not remove " << obj
+ << " after upgrading to zonegroup map: " << cpp_strerror(ret) << dendl;
+ return ret;
+ }
+
return 0;
}
@@ -160,3 +854,11 @@ bool RGWSI_Zone::can_reshard() const
(zonegroup->zones.size() == 1 && current_period->is_single_zonegroup());
}
+
+void RGWSI_Zone::canonicalize_raw_obj(rgw_raw_obj *obj)
+{
+ if (obj->oid.empty()) {
+ obj->oid = obj->pool.to_str();
+ obj->pool = zone_params->domain_root;
+ }
+}
diff --git a/src/rgw/services/svc_zone.h b/src/rgw/services/svc_zone.h
index 1304c2475da..646d9084b9a 100644
--- a/src/rgw/services/svc_zone.h
+++ b/src/rgw/services/svc_zone.h
@@ -3,16 +3,11 @@
#include "rgw/rgw_service.h"
+#include "rgw/rgw_zone.h"
class RGWSI_RADOS;
-
-struct RGWZoneGroup;
-struct RGWZone;
-struct RGWZoneParams;
-struct RGWPeriod;
-struct RGWRealm;
-struct RGWZonePlacementInfo;
+class RGWSI_SysObj;
class RGWRESTConn;
@@ -21,12 +16,13 @@ class RGWS_Zone : public RGWService
public:
RGWS_Zone(CephContext *cct) : RGWService(cct, "zone") {}
- int create_instance(const std::string& conf, RGWServiceInstanceRef *instance);
+ int create_instance(const std::string& conf, RGWServiceInstanceRef *instance) override;
};
class RGWSI_Zone : public RGWServiceInstance
{
std::shared_ptr<RGWSI_RADOS> rados_svc;
+ std::shared_ptr<RGWSI_SysObj> sysobj_svc;
std::shared_ptr<RGWRealm> realm;
std::shared_ptr<RGWZoneGroup> zonegroup;
@@ -36,9 +32,6 @@ class RGWSI_Zone : public RGWServiceInstance
uint32_t zone_short_id{0};
bool writeable_zone{false};
- std::map<std::string, RGWServiceInstance::dependency> get_deps();
- int init(const std::string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs);
-
RGWRESTConn *rest_master_conn{nullptr};
map<string, RGWRESTConn *> zone_conn_map;
map<string, RGWRESTConn *> zone_data_sync_from_map;
@@ -48,6 +41,16 @@ class RGWSI_Zone : public RGWServiceInstance
map<string, string> zone_id_by_name;
map<string, RGWZone> zone_by_id;
+ std::map<std::string, RGWServiceInstance::dependency> get_deps() override;
+ int load(const std::string& conf, std::map<std::string, RGWServiceInstanceRef>& dep_refs) override;
+ int init() override;
+ void shutdown() override;
+
+ int replace_region_with_zonegroup();
+ int init_zg_from_period(bool *initialized);
+ int init_zg_from_local(bool *creating_defaults);
+ int convert_regionmap();
+
public:
RGWSI_Zone(RGWService *svc, CephContext *cct): RGWServiceInstance(svc, cct) {}
@@ -77,6 +80,10 @@ public:
return zone_conn_map;
}
+ map<string, RGWRESTConn *>& get_zone_data_notify_to_map() {
+ return zone_data_notify_to_map;
+ }
+
bool find_zone_by_id(const string& id, RGWZone **zone);
RGWRESTConn *get_zone_conn_by_id(const string& id);
@@ -95,6 +102,13 @@ public:
bool need_to_log_data() const;
bool need_to_log_metadata() const;
bool can_reshard() const;
+
+ int list_zonegroups(list<string>& zonegroups);
+ int list_regions(list<string>& regions);
+ int list_zones(list<string>& zones);
+ int list_realms(list<string>& realms);
+ int list_periods(list<string>& periods);
+ int list_periods(const string& current_period, list<string>& periods);
};
#endif