]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: sys_obj service, move zone init to svc_zone
authorYehuda Sadeh <yehuda@redhat.com>
Fri, 17 Aug 2018 01:30:44 +0000 (18:30 -0700)
committerYehuda Sadeh <yehuda@redhat.com>
Thu, 8 Nov 2018 17:19:29 +0000 (09:19 -0800)
still wip

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
15 files changed:
src/rgw/rgw_period_puller.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_service.cc
src/rgw/rgw_service.h
src/rgw/rgw_zone.cc
src/rgw/rgw_zone.h
src/rgw/services/svc_quota.cc
src/rgw/services/svc_quota.h
src/rgw/services/svc_rados.cc
src/rgw/services/svc_rados.h
src/rgw/services/svc_sys_obj.cc [new file with mode: 0644]
src/rgw/services/svc_sys_obj.h [new file with mode: 0644]
src/rgw/services/svc_zone.cc
src/rgw/services/svc_zone.h

index 0e3a8f90222ff34aca6ffc5a3f136ef9f0edf2e5..0379739bce116e561a466df1de87e9711834a27b 100644 (file)
@@ -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
index 7f2c4c1d6cee55e8d2baa1ed10636eddbb10b081..ced9ebe55e8a6ee3fe8898e8430c910c46245b77 100644 (file)
@@ -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.
index 04f68dca9599d1a7bda06798781dd6727ad4847e..c0429ddc329573a533d1f5fbf902e5b044f145b6 100644 (file)
@@ -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();
 
index d59361b251e2574d364456cad7b342bfe9e7b2d6..6b37c68e899111ad4454b4b9b5319192a7db97b2 100644 (file)
@@ -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;
 }
 
index 1681e923a863a37a81e8ba22ee7e3ee0863d8790..da8bce523cf88682e17dbe67ee26f9a862be9180 100644 (file)
@@ -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;
   }
index ce2e956316394c377b4b948adde6448da246e02a..54a906892073d4b8bcc7b43d15bd4148e7570d56 100644 (file)
@@ -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;
index 94708fb72649da552b2aa44f59ca02b11679de8f..48ada717e4ca488c80858e203fe473f6b4812266 100644 (file)
@@ -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();
index 8fda921c7a7e483bd4a9cdad64bc84bf2ffe84fd..267c265babfe653a3715c37adb5f8eeacc758fde 100644 (file)
@@ -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);
index 425fc37f18d351600bae5a62150ac7438c25acc2..a1e56d2c7a7f2afcff11da72cfec7b46428c8715 100644 (file)
@@ -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) {}
index 4c587a985e8c1c369f16a7e42894bbde039535d8..b0b4d02da8c62e0c230a4b40972333f9b035d205 100644 (file)
@@ -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();
+}
index 32585357814144c97260dc79b85cf4dcf607d52e..a49f78beb660683e6918793b15107f455550d3fa 100644 (file)
@@ -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 (file)
index 0000000..e0bd585
--- /dev/null
@@ -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 (file)
index 0000000..1a38cc2
--- /dev/null
@@ -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
+
index 22e516d9438880bf4b0873ea572ba5bb660ad1fc..ab9f63031f3dbcac3df879cdc617cb7f074c0f56 100644 (file)
@@ -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;
+  }
+}
index 1304c2475da4dc56fff49a46ef28ff370c0e5455..646d9084b9a3d6da813884bd3ee2bb7548f0ac2c 100644 (file)
@@ -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