1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #include "common/errno.h"
9 #include "rgw_sal_config.h"
12 #include "services/svc_zone.h"
15 #define dout_context g_ceph_context
16 #define dout_subsys ceph_subsys_rgw
18 namespace rgw_zone_defaults
{
20 static std::string default_bucket_index_pool_suffix
= "rgw.buckets.index";
21 static std::string default_storage_extra_pool_suffix
= "rgw.buckets.non-ec";
22 static std::string zone_info_oid_prefix
= "zone_info.";
24 std::string zone_names_oid_prefix
= "zone_names.";
25 std::string region_info_oid_prefix
= "region_info.";
26 std::string zone_group_info_oid_prefix
= "zonegroup_info.";
27 std::string default_region_info_oid
= "default.region";
28 std::string default_zone_group_info_oid
= "default.zonegroup";
29 std::string region_map_oid
= "region_map";
30 std::string default_zonegroup_name
= "default";
31 std::string default_zone_name
= "default";
32 std::string zonegroup_names_oid_prefix
= "zonegroups_names.";
33 std::string RGW_DEFAULT_ZONE_ROOT_POOL
= "rgw.root";
34 std::string RGW_DEFAULT_ZONEGROUP_ROOT_POOL
= "rgw.root";
35 std::string RGW_DEFAULT_PERIOD_ROOT_POOL
= "rgw.root";
36 std::string avail_pools
= ".pools.avail";
37 std::string default_storage_pool_suffix
= "rgw.buckets.data";
42 using namespace rgw_zone_defaults
;
44 void encode_json_plain(const char *name
, const RGWAccessKey
& val
, Formatter
*f
)
46 f
->open_object_section(name
);
51 static void decode_zones(map
<rgw_zone_id
, RGWZone
>& zones
, JSONObj
*o
)
58 static void decode_placement_targets(map
<string
, RGWZoneGroupPlacementTarget
>& targets
, JSONObj
*o
)
60 RGWZoneGroupPlacementTarget t
;
65 void RGWZone::generate_test_instances(list
<RGWZone
*> &o
)
67 RGWZone
*z
= new RGWZone
;
69 o
.push_back(new RGWZone
);
72 void RGWZone::dump(Formatter
*f
) const
74 encode_json("id", id
, f
);
75 encode_json("name", name
, f
);
76 encode_json("endpoints", endpoints
, f
);
77 encode_json("log_meta", log_meta
, f
);
78 encode_json("log_data", log_data
, f
);
79 encode_json("bucket_index_max_shards", bucket_index_max_shards
, f
);
80 encode_json("read_only", read_only
, f
);
81 encode_json("tier_type", tier_type
, f
);
82 encode_json("sync_from_all", sync_from_all
, f
);
83 encode_json("sync_from", sync_from
, f
);
84 encode_json("redirect_zone", redirect_zone
, f
);
85 encode_json("supported_features", supported_features
, f
);
88 void RGWZone::decode_json(JSONObj
*obj
)
90 JSONDecoder::decode_json("id", id
, obj
);
91 JSONDecoder::decode_json("name", name
, obj
);
95 JSONDecoder::decode_json("endpoints", endpoints
, obj
);
96 JSONDecoder::decode_json("log_meta", log_meta
, obj
);
97 JSONDecoder::decode_json("log_data", log_data
, obj
);
98 JSONDecoder::decode_json("bucket_index_max_shards", bucket_index_max_shards
, obj
);
99 JSONDecoder::decode_json("read_only", read_only
, obj
);
100 JSONDecoder::decode_json("tier_type", tier_type
, obj
);
101 JSONDecoder::decode_json("sync_from_all", sync_from_all
, true, obj
);
102 JSONDecoder::decode_json("sync_from", sync_from
, obj
);
103 JSONDecoder::decode_json("redirect_zone", redirect_zone
, obj
);
104 JSONDecoder::decode_json("supported_features", supported_features
, obj
);
107 int RGWSystemMetaObj::init(const DoutPrefixProvider
*dpp
, CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
,
109 bool setup_obj
, bool old_format
)
111 reinit_instance(_cct
, _sysobj_svc
);
116 if (old_format
&& id
.empty()) {
121 id
= get_predefined_id(cct
);
127 name
= get_predefined_name(cct
);
130 r
= use_default(dpp
, y
, old_format
);
134 } else if (!old_format
) {
135 r
= read_id(dpp
, name
, id
, y
);
138 ldpp_dout(dpp
, 0) << "error in read_id for object name: " << name
<< " : " << cpp_strerror(-r
) << dendl
;
145 return read_info(dpp
, id
, y
, old_format
);
148 RGWZoneGroup::~RGWZoneGroup() {}
150 const string
RGWZoneGroup::get_default_oid(bool old_region_format
) const
152 if (old_region_format
) {
153 if (cct
->_conf
->rgw_default_region_info_oid
.empty()) {
154 return default_region_info_oid
;
156 return cct
->_conf
->rgw_default_region_info_oid
;
159 string default_oid
= cct
->_conf
->rgw_default_zonegroup_info_oid
;
161 if (cct
->_conf
->rgw_default_zonegroup_info_oid
.empty()) {
162 default_oid
= default_zone_group_info_oid
;
165 default_oid
+= "." + realm_id
;
170 const string
& RGWZoneGroup::get_info_oid_prefix(bool old_region_format
) const
172 if (old_region_format
) {
173 return region_info_oid_prefix
;
175 return zone_group_info_oid_prefix
;
178 const string
& RGWZoneGroup::get_names_oid_prefix() const
180 return zonegroup_names_oid_prefix
;
183 string
RGWZoneGroup::get_predefined_id(CephContext
*cct
) const {
184 return cct
->_conf
.get_val
<string
>("rgw_zonegroup_id");
187 const string
& RGWZoneGroup::get_predefined_name(CephContext
*cct
) const {
188 return cct
->_conf
->rgw_zonegroup
;
191 rgw_pool
RGWZoneGroup::get_pool(CephContext
*cct_
) const
193 if (cct_
->_conf
->rgw_zonegroup_root_pool
.empty()) {
194 return rgw_pool(RGW_DEFAULT_ZONEGROUP_ROOT_POOL
);
197 return rgw_pool(cct_
->_conf
->rgw_zonegroup_root_pool
);
200 int RGWZoneGroup::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
203 if (realm_id
.empty()) {
204 /* try using default realm */
206 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
207 // no default realm exist
209 return read_id(dpp
, default_zonegroup_name
, default_id
, y
);
211 realm_id
= realm
.get_id();
214 return RGWSystemMetaObj::read_default_id(dpp
, default_id
, y
, old_format
);
217 int RGWSystemMetaObj::use_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
219 return read_default_id(dpp
, id
, y
, old_format
);
222 void RGWSystemMetaObj::reinit_instance(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
)
225 sysobj_svc
= _sysobj_svc
;
226 zone_svc
= _sysobj_svc
->get_zone_svc();
229 int RGWSystemMetaObj::read_info(const DoutPrefixProvider
*dpp
, const string
& obj_id
, optional_yield y
,
232 rgw_pool
pool(get_pool(cct
));
236 string oid
= get_info_oid_prefix(old_format
) + obj_id
;
238 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj
{pool
, oid
});
239 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
241 ldpp_dout(dpp
, 0) << "failed reading obj info from " << pool
<< ":" << oid
<< ": " << cpp_strerror(-ret
) << dendl
;
247 auto iter
= bl
.cbegin();
249 } catch (buffer::error
& err
) {
250 ldpp_dout(dpp
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
257 void RGWZoneGroup::decode_json(JSONObj
*obj
)
259 RGWSystemMetaObj::decode_json(obj
);
261 derr
<< "old format " << dendl
;
262 JSONDecoder::decode_json("name", name
, obj
);
265 JSONDecoder::decode_json("api_name", api_name
, obj
);
266 JSONDecoder::decode_json("is_master", is_master
, obj
);
267 JSONDecoder::decode_json("endpoints", endpoints
, obj
);
268 JSONDecoder::decode_json("hostnames", hostnames
, obj
);
269 JSONDecoder::decode_json("hostnames_s3website", hostnames_s3website
, obj
);
270 JSONDecoder::decode_json("master_zone", master_zone
, obj
);
271 JSONDecoder::decode_json("zones", zones
, decode_zones
, obj
);
272 JSONDecoder::decode_json("placement_targets", placement_targets
, decode_placement_targets
, obj
);
274 JSONDecoder::decode_json("default_placement", pr
, obj
);
275 default_placement
.from_str(pr
);
276 JSONDecoder::decode_json("realm_id", realm_id
, obj
);
277 JSONDecoder::decode_json("sync_policy", sync_policy
, obj
);
278 JSONDecoder::decode_json("enabled_features", enabled_features
, obj
);
281 RGWZoneParams::~RGWZoneParams() {}
283 void RGWZoneParams::decode_json(JSONObj
*obj
)
285 RGWSystemMetaObj::decode_json(obj
);
286 JSONDecoder::decode_json("domain_root", domain_root
, obj
);
287 JSONDecoder::decode_json("control_pool", control_pool
, obj
);
288 JSONDecoder::decode_json("gc_pool", gc_pool
, obj
);
289 JSONDecoder::decode_json("lc_pool", lc_pool
, obj
);
290 JSONDecoder::decode_json("log_pool", log_pool
, obj
);
291 JSONDecoder::decode_json("intent_log_pool", intent_log_pool
, obj
);
292 JSONDecoder::decode_json("roles_pool", roles_pool
, obj
);
293 JSONDecoder::decode_json("reshard_pool", reshard_pool
, obj
);
294 JSONDecoder::decode_json("usage_log_pool", usage_log_pool
, obj
);
295 JSONDecoder::decode_json("user_keys_pool", user_keys_pool
, obj
);
296 JSONDecoder::decode_json("user_email_pool", user_email_pool
, obj
);
297 JSONDecoder::decode_json("user_swift_pool", user_swift_pool
, obj
);
298 JSONDecoder::decode_json("user_uid_pool", user_uid_pool
, obj
);
299 JSONDecoder::decode_json("otp_pool", otp_pool
, obj
);
300 JSONDecoder::decode_json("system_key", system_key
, obj
);
301 JSONDecoder::decode_json("placement_pools", placement_pools
, obj
);
302 JSONDecoder::decode_json("tier_config", tier_config
, obj
);
303 JSONDecoder::decode_json("realm_id", realm_id
, obj
);
304 JSONDecoder::decode_json("notif_pool", notif_pool
, obj
);
308 void RGWZoneParams::dump(Formatter
*f
) const
310 RGWSystemMetaObj::dump(f
);
311 encode_json("domain_root", domain_root
, f
);
312 encode_json("control_pool", control_pool
, f
);
313 encode_json("gc_pool", gc_pool
, f
);
314 encode_json("lc_pool", lc_pool
, f
);
315 encode_json("log_pool", log_pool
, f
);
316 encode_json("intent_log_pool", intent_log_pool
, f
);
317 encode_json("usage_log_pool", usage_log_pool
, f
);
318 encode_json("roles_pool", roles_pool
, f
);
319 encode_json("reshard_pool", reshard_pool
, f
);
320 encode_json("user_keys_pool", user_keys_pool
, f
);
321 encode_json("user_email_pool", user_email_pool
, f
);
322 encode_json("user_swift_pool", user_swift_pool
, f
);
323 encode_json("user_uid_pool", user_uid_pool
, f
);
324 encode_json("otp_pool", otp_pool
, f
);
325 encode_json_plain("system_key", system_key
, f
);
326 encode_json("placement_pools", placement_pools
, f
);
327 encode_json("tier_config", tier_config
, f
);
328 encode_json("realm_id", realm_id
, f
);
329 encode_json("notif_pool", notif_pool
, f
);
332 int RGWZoneParams::init(const DoutPrefixProvider
*dpp
,
333 CephContext
*cct
, RGWSI_SysObj
*sysobj_svc
,
334 optional_yield y
, bool setup_obj
, bool old_format
)
337 name
= cct
->_conf
->rgw_zone
;
340 return RGWSystemMetaObj::init(dpp
, cct
, sysobj_svc
, y
, setup_obj
, old_format
);
343 rgw_pool
RGWZoneParams::get_pool(CephContext
*cct
) const
345 if (cct
->_conf
->rgw_zone_root_pool
.empty()) {
346 return rgw_pool(RGW_DEFAULT_ZONE_ROOT_POOL
);
349 return rgw_pool(cct
->_conf
->rgw_zone_root_pool
);
352 const string
RGWZoneParams::get_default_oid(bool old_format
) const
355 return cct
->_conf
->rgw_default_zone_info_oid
;
358 return cct
->_conf
->rgw_default_zone_info_oid
+ "." + realm_id
;
361 const string
& RGWZoneParams::get_names_oid_prefix() const
363 return zone_names_oid_prefix
;
366 const string
& RGWZoneParams::get_info_oid_prefix(bool old_format
) const
368 return zone_info_oid_prefix
;
371 string
RGWZoneParams::get_predefined_id(CephContext
*cct
) const {
372 return cct
->_conf
.get_val
<string
>("rgw_zone_id");
375 const string
& RGWZoneParams::get_predefined_name(CephContext
*cct
) const {
376 return cct
->_conf
->rgw_zone
;
379 int RGWZoneParams::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
382 if (realm_id
.empty()) {
383 /* try using default realm */
385 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
386 //no default realm exist
388 return read_id(dpp
, default_zone_name
, default_id
, y
);
390 realm_id
= realm
.get_id();
393 return RGWSystemMetaObj::read_default_id(dpp
, default_id
, y
, old_format
);
397 int RGWZoneParams::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
399 if (realm_id
.empty()) {
400 /* try using default realm */
402 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
404 ldpp_dout(dpp
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
407 realm_id
= realm
.get_id();
410 return RGWSystemMetaObj::set_as_default(dpp
, y
, exclusive
);
413 int RGWZoneParams::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
415 /* check for old pools config */
416 rgw_raw_obj
obj(domain_root
, avail_pools
);
417 auto sysobj
= sysobj_svc
->get_obj(obj
);
418 int r
= sysobj
.rop().stat(y
, dpp
);
420 ldpp_dout(dpp
, 10) << "couldn't find old data placement pools config, setting up new ones for the zone" << dendl
;
421 /* a new system, let's set new placement info */
422 RGWZonePlacementInfo default_placement
;
423 default_placement
.index_pool
= name
+ "." + default_bucket_index_pool_suffix
;
424 rgw_pool pool
= name
+ "." + default_storage_pool_suffix
;
425 default_placement
.storage_classes
.set_storage_class(RGW_STORAGE_CLASS_STANDARD
, &pool
, nullptr);
426 default_placement
.data_extra_pool
= name
+ "." + default_storage_extra_pool_suffix
;
427 placement_pools
["default-placement"] = default_placement
;
430 r
= fix_pool_names(dpp
, y
);
432 ldpp_dout(dpp
, 0) << "ERROR: fix_pool_names returned r=" << r
<< dendl
;
436 r
= RGWSystemMetaObj::create(dpp
, y
, exclusive
);
441 // try to set as default. may race with another create, so pass exclusive=true
442 // so we don't override an existing default
443 r
= set_as_default(dpp
, y
, true);
444 if (r
< 0 && r
!= -EEXIST
) {
445 ldpp_dout(dpp
, 10) << "WARNING: failed to set zone as default, r=" << r
<< dendl
;
451 rgw_pool
fix_zone_pool_dup(const set
<rgw_pool
>& pools
,
452 const string
& default_prefix
,
453 const string
& default_suffix
,
454 const rgw_pool
& suggested_pool
)
456 string suggested_name
= suggested_pool
.to_str();
458 string prefix
= default_prefix
;
459 string suffix
= default_suffix
;
461 if (!suggested_pool
.empty()) {
462 prefix
= suggested_name
.substr(0, suggested_name
.find("."));
463 suffix
= suggested_name
.substr(prefix
.length());
466 rgw_pool
pool(prefix
+ suffix
);
468 while (pools
.count(pool
)) {
469 pool
= prefix
+ "_" + std::to_string(std::rand()) + suffix
;
474 void add_zone_pools(const RGWZoneParams
& info
,
475 std::set
<rgw_pool
>& pools
)
477 pools
.insert(info
.domain_root
);
478 pools
.insert(info
.control_pool
);
479 pools
.insert(info
.gc_pool
);
480 pools
.insert(info
.log_pool
);
481 pools
.insert(info
.intent_log_pool
);
482 pools
.insert(info
.usage_log_pool
);
483 pools
.insert(info
.user_keys_pool
);
484 pools
.insert(info
.user_email_pool
);
485 pools
.insert(info
.user_swift_pool
);
486 pools
.insert(info
.user_uid_pool
);
487 pools
.insert(info
.otp_pool
);
488 pools
.insert(info
.roles_pool
);
489 pools
.insert(info
.reshard_pool
);
490 pools
.insert(info
.oidc_pool
);
491 pools
.insert(info
.notif_pool
);
493 for (const auto& [pname
, placement
] : info
.placement_pools
) {
494 pools
.insert(placement
.index_pool
);
495 for (const auto& [sname
, sc
] : placement
.storage_classes
.get_all()) {
497 pools
.insert(sc
.data_pool
.get());
500 pools
.insert(placement
.data_extra_pool
);
506 int get_zones_pool_set(const DoutPrefixProvider
*dpp
,
508 rgw::sal::ConfigStore
* cfgstore
,
509 std::string_view my_zone_id
,
510 std::set
<rgw_pool
>& pools
)
512 std::array
<std::string
, 128> zone_names
;
513 rgw::sal::ListResult
<std::string
> listing
;
515 int r
= cfgstore
->list_zone_names(dpp
, y
, listing
.next
,
516 zone_names
, listing
);
518 ldpp_dout(dpp
, 0) << "failed to list zones with " << cpp_strerror(r
) << dendl
;
522 for (const auto& name
: listing
.entries
) {
524 r
= cfgstore
->read_zone_by_name(dpp
, y
, name
, info
, nullptr);
526 ldpp_dout(dpp
, 0) << "failed to load zone " << name
527 << " with " << cpp_strerror(r
) << dendl
;
530 if (info
.get_id() != my_zone_id
) {
531 add_zone_pools(info
, pools
);
534 } while (!listing
.next
.empty());
541 static int get_zones_pool_set(const DoutPrefixProvider
*dpp
,
543 RGWSI_SysObj
* sysobj_svc
,
544 const list
<string
>& zone_names
,
545 const string
& my_zone_id
,
546 set
<rgw_pool
>& pool_names
,
549 for (const auto& name
: zone_names
) {
550 RGWZoneParams
zone(name
);
551 int r
= zone
.init(dpp
, cct
, sysobj_svc
, y
);
553 ldpp_dout(dpp
, 0) << "Error: failed to load zone " << name
554 << " with " << cpp_strerror(-r
) << dendl
;
557 if (zone
.get_id() != my_zone_id
) {
558 add_zone_pools(zone
, pool_names
);
564 int RGWZoneParams::fix_pool_names(const DoutPrefixProvider
*dpp
, optional_yield y
)
568 int r
= zone_svc
->list_zones(dpp
, zones
);
570 ldpp_dout(dpp
, 10) << "WARNING: driver->list_zones() returned r=" << r
<< dendl
;
574 r
= get_zones_pool_set(dpp
, cct
, sysobj_svc
, zones
, id
, pools
, y
);
576 ldpp_dout(dpp
, 0) << "Error: get_zones_pool_names" << r
<< dendl
;
580 domain_root
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:root", domain_root
);
581 control_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.control", control_pool
);
582 gc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:gc", gc_pool
);
583 lc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:lc", lc_pool
);
584 log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log", log_pool
);
585 intent_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:intent", intent_log_pool
);
586 usage_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:usage", usage_log_pool
);
587 user_keys_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.keys", user_keys_pool
);
588 user_email_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.email", user_email_pool
);
589 user_swift_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.swift", user_swift_pool
);
590 user_uid_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.uid", user_uid_pool
);
591 roles_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:roles", roles_pool
);
592 reshard_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:reshard", reshard_pool
);
593 otp_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.otp", otp_pool
);
594 oidc_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:oidc", oidc_pool
);
595 notif_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:notif", notif_pool
);
597 for(auto& iter
: placement_pools
) {
598 iter
.second
.index_pool
= fix_zone_pool_dup(pools
, name
, "." + default_bucket_index_pool_suffix
,
599 iter
.second
.index_pool
);
600 for (auto& pi
: iter
.second
.storage_classes
.get_all()) {
601 if (pi
.second
.data_pool
) {
602 rgw_pool
& pool
= pi
.second
.data_pool
.get();
603 pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_pool_suffix
,
607 iter
.second
.data_extra_pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_extra_pool_suffix
,
608 iter
.second
.data_extra_pool
);
614 int RGWPeriodConfig::read(const DoutPrefixProvider
*dpp
, RGWSI_SysObj
*sysobj_svc
, const std::string
& realm_id
,
617 const auto& pool
= get_pool(sysobj_svc
->ctx());
618 const auto& oid
= get_oid(realm_id
);
621 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj
{pool
, oid
});
622 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
628 auto iter
= bl
.cbegin();
630 } catch (buffer::error
& err
) {
636 int RGWPeriodConfig::write(const DoutPrefixProvider
*dpp
,
637 RGWSI_SysObj
*sysobj_svc
,
638 const std::string
& realm_id
, optional_yield y
)
640 const auto& pool
= get_pool(sysobj_svc
->ctx());
641 const auto& oid
= get_oid(realm_id
);
645 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj
{pool
, oid
});
647 .set_exclusive(false)
651 void RGWPeriodConfig::decode_json(JSONObj
*obj
)
653 JSONDecoder::decode_json("bucket_quota", quota
.bucket_quota
, obj
);
654 JSONDecoder::decode_json("user_quota", quota
.user_quota
, obj
);
655 JSONDecoder::decode_json("user_ratelimit", user_ratelimit
, obj
);
656 JSONDecoder::decode_json("bucket_ratelimit", bucket_ratelimit
, obj
);
657 JSONDecoder::decode_json("anonymous_ratelimit", anon_ratelimit
, obj
);
660 void RGWPeriodConfig::dump(Formatter
*f
) const
662 encode_json("bucket_quota", quota
.bucket_quota
, f
);
663 encode_json("user_quota", quota
.user_quota
, f
);
664 encode_json("user_ratelimit", user_ratelimit
, f
);
665 encode_json("bucket_ratelimit", bucket_ratelimit
, f
);
666 encode_json("anonymous_ratelimit", anon_ratelimit
, f
);
669 std::string
RGWPeriodConfig::get_oid(const std::string
& realm_id
)
671 if (realm_id
.empty()) {
672 return "period_config.default";
674 return "period_config." + realm_id
;
677 rgw_pool
RGWPeriodConfig::get_pool(CephContext
*cct
)
679 const auto& pool_name
= cct
->_conf
->rgw_period_root_pool
;
680 if (pool_name
.empty()) {
681 return {RGW_DEFAULT_PERIOD_ROOT_POOL
};
686 int RGWSystemMetaObj::delete_obj(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
688 rgw_pool
pool(get_pool(cct
));
690 /* check to see if obj is the default */
691 RGWDefaultSystemMetaObjInfo default_info
;
692 int ret
= read_default(dpp
, default_info
, get_default_oid(old_format
), y
);
693 if (ret
< 0 && ret
!= -ENOENT
)
695 if (default_info
.default_id
== id
|| (old_format
&& default_info
.default_id
== name
)) {
696 string oid
= get_default_oid(old_format
);
697 rgw_raw_obj
default_named_obj(pool
, oid
);
698 auto sysobj
= sysobj_svc
->get_obj(default_named_obj
);
699 ret
= sysobj
.wop().remove(dpp
, y
);
701 ldpp_dout(dpp
, 0) << "Error delete default obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
706 string oid
= get_names_oid_prefix() + name
;
707 rgw_raw_obj
object_name(pool
, oid
);
708 auto sysobj
= sysobj_svc
->get_obj(object_name
);
709 ret
= sysobj
.wop().remove(dpp
, y
);
711 ldpp_dout(dpp
, 0) << "Error delete obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
716 string oid
= get_info_oid_prefix(old_format
);
723 rgw_raw_obj
object_id(pool
, oid
);
724 auto sysobj
= sysobj_svc
->get_obj(object_id
);
725 ret
= sysobj
.wop().remove(dpp
, y
);
727 ldpp_dout(dpp
, 0) << "Error delete object id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
733 void RGWZoneGroup::dump(Formatter
*f
) const
735 RGWSystemMetaObj::dump(f
);
736 encode_json("api_name", api_name
, f
);
737 encode_json("is_master", is_master
, f
);
738 encode_json("endpoints", endpoints
, f
);
739 encode_json("hostnames", hostnames
, f
);
740 encode_json("hostnames_s3website", hostnames_s3website
, f
);
741 encode_json("master_zone", master_zone
, f
);
742 encode_json_map("zones", zones
, f
); /* more friendly representation */
743 encode_json_map("placement_targets", placement_targets
, f
); /* more friendly representation */
744 encode_json("default_placement", default_placement
, f
);
745 encode_json("realm_id", realm_id
, f
);
746 encode_json("sync_policy", sync_policy
, f
);
747 encode_json("enabled_features", enabled_features
, f
);
750 void RGWZoneGroupPlacementTarget::decode_json(JSONObj
*obj
)
752 JSONDecoder::decode_json("name", name
, obj
);
753 JSONDecoder::decode_json("tags", tags
, obj
);
754 JSONDecoder::decode_json("storage_classes", storage_classes
, obj
);
755 if (storage_classes
.empty()) {
756 storage_classes
.insert(RGW_STORAGE_CLASS_STANDARD
);
758 JSONDecoder::decode_json("tier_targets", tier_targets
, obj
);
761 void RGWZonePlacementInfo::dump(Formatter
*f
) const
763 encode_json("index_pool", index_pool
, f
);
764 encode_json("storage_classes", storage_classes
, f
);
765 encode_json("data_extra_pool", data_extra_pool
, f
);
766 encode_json("index_type", (uint32_t)index_type
, f
);
767 encode_json("inline_data", inline_data
, f
);
769 /* no real need for backward compatibility of compression_type and data_pool in here,
770 * rather not clutter the output */
773 void RGWZonePlacementInfo::decode_json(JSONObj
*obj
)
775 JSONDecoder::decode_json("index_pool", index_pool
, obj
);
776 JSONDecoder::decode_json("storage_classes", storage_classes
, obj
);
777 JSONDecoder::decode_json("data_extra_pool", data_extra_pool
, obj
);
779 JSONDecoder::decode_json("index_type", it
, obj
);
780 JSONDecoder::decode_json("inline_data", inline_data
, obj
);
781 index_type
= (rgw::BucketIndexType
)it
;
783 /* backward compatibility, these are now defined in storage_classes */
784 string standard_compression_type
;
785 string
*pcompression
= nullptr;
786 if (JSONDecoder::decode_json("compression", standard_compression_type
, obj
)) {
787 pcompression
= &standard_compression_type
;
789 rgw_pool standard_data_pool
;
790 rgw_pool
*ppool
= nullptr;
791 if (JSONDecoder::decode_json("data_pool", standard_data_pool
, obj
)) {
792 ppool
= &standard_data_pool
;
794 if (ppool
|| pcompression
) {
795 storage_classes
.set_storage_class(RGW_STORAGE_CLASS_STANDARD
, ppool
, pcompression
);
799 void RGWSystemMetaObj::dump(Formatter
*f
) const
801 encode_json("id", id
, f
);
802 encode_json("name", name
, f
);
805 void RGWSystemMetaObj::decode_json(JSONObj
*obj
)
807 JSONDecoder::decode_json("id", id
, obj
);
808 JSONDecoder::decode_json("name", name
, obj
);
811 int RGWSystemMetaObj::read_default(const DoutPrefixProvider
*dpp
,
812 RGWDefaultSystemMetaObjInfo
& default_info
,
813 const string
& oid
, optional_yield y
)
816 auto pool
= get_pool(cct
);
819 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj(pool
, oid
));
820 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
825 auto iter
= bl
.cbegin();
826 decode(default_info
, iter
);
827 } catch (buffer::error
& err
) {
828 ldpp_dout(dpp
, 0) << "error decoding data from " << pool
<< ":" << oid
<< dendl
;
835 void RGWZoneGroupPlacementTarget::dump(Formatter
*f
) const
837 encode_json("name", name
, f
);
838 encode_json("tags", tags
, f
);
839 encode_json("storage_classes", storage_classes
, f
);
840 if (!tier_targets
.empty()) {
841 encode_json("tier_targets", tier_targets
, f
);
845 void RGWZoneGroupPlacementTier::decode_json(JSONObj
*obj
)
847 JSONDecoder::decode_json("tier_type", tier_type
, obj
);
848 JSONDecoder::decode_json("storage_class", storage_class
, obj
);
849 JSONDecoder::decode_json("retain_head_object", retain_head_object
, obj
);
851 if (tier_type
== "cloud-s3") {
852 JSONDecoder::decode_json("s3", t
.s3
, obj
);
856 void RGWZoneStorageClasses::dump(Formatter
*f
) const
859 encode_json(i
.first
.c_str(), i
.second
, f
);
863 void RGWZoneStorageClasses::decode_json(JSONObj
*obj
)
866 decode_json_obj(f
, obj
);
868 for (auto& field
: f
.object()) {
869 JSONObj
*field_obj
= obj
->find_obj(field
.first
);
872 decode_json_obj(m
[field
.first
], field_obj
);
874 standard_class
= &m
[RGW_STORAGE_CLASS_STANDARD
];
877 void RGWZoneGroupPlacementTier::dump(Formatter
*f
) const
879 encode_json("tier_type", tier_type
, f
);
880 encode_json("storage_class", storage_class
, f
);
881 encode_json("retain_head_object", retain_head_object
, f
);
883 if (tier_type
== "cloud-s3") {
884 encode_json("s3", t
.s3
, f
);
888 void RGWZoneGroupPlacementTierS3::decode_json(JSONObj
*obj
)
890 JSONDecoder::decode_json("endpoint", endpoint
, obj
);
891 JSONDecoder::decode_json("access_key", key
.id
, obj
);
892 JSONDecoder::decode_json("secret", key
.key
, obj
);
893 JSONDecoder::decode_json("region", region
, obj
);
895 JSONDecoder::decode_json("host_style", s
, obj
);
896 if (s
!= "virtual") {
897 host_style
= PathStyle
;
899 host_style
= VirtualStyle
;
901 JSONDecoder::decode_json("target_storage_class", target_storage_class
, obj
);
902 JSONDecoder::decode_json("target_path", target_path
, obj
);
903 JSONDecoder::decode_json("acl_mappings", acl_mappings
, obj
);
904 JSONDecoder::decode_json("multipart_sync_threshold", multipart_sync_threshold
, obj
);
905 JSONDecoder::decode_json("multipart_min_part_size", multipart_min_part_size
, obj
);
908 void RGWZoneStorageClass::dump(Formatter
*f
) const
911 encode_json("data_pool", data_pool
.get(), f
);
913 if (compression_type
) {
914 encode_json("compression_type", compression_type
.get(), f
);
918 void RGWZoneStorageClass::decode_json(JSONObj
*obj
)
920 JSONDecoder::decode_json("data_pool", data_pool
, obj
);
921 JSONDecoder::decode_json("compression_type", compression_type
, obj
);
924 void RGWTierACLMapping::decode_json(JSONObj
*obj
)
927 JSONDecoder::decode_json("type", s
, obj
);
929 type
= ACL_TYPE_EMAIL_USER
;
930 } else if (s
== "uri") {
931 type
= ACL_TYPE_GROUP
;
933 type
= ACL_TYPE_CANON_USER
;
936 JSONDecoder::decode_json("source_id", source_id
, obj
);
937 JSONDecoder::decode_json("dest_id", dest_id
, obj
);
940 void RGWZoneGroupPlacementTierS3::dump(Formatter
*f
) const
942 encode_json("endpoint", endpoint
, f
);
943 encode_json("access_key", key
.id
, f
);
944 encode_json("secret", key
.key
, f
);
945 encode_json("region", region
, f
);
946 string s
= (host_style
== PathStyle
? "path" : "virtual");
947 encode_json("host_style", s
, f
);
948 encode_json("target_storage_class", target_storage_class
, f
);
949 encode_json("target_path", target_path
, f
);
950 encode_json("acl_mappings", acl_mappings
, f
);
951 encode_json("multipart_sync_threshold", multipart_sync_threshold
, f
);
952 encode_json("multipart_min_part_size", multipart_min_part_size
, f
);
955 void RGWTierACLMapping::dump(Formatter
*f
) const
959 case ACL_TYPE_EMAIL_USER
:
969 encode_json("type", s
, f
);
970 encode_json("source_id", source_id
, f
);
971 encode_json("dest_id", dest_id
, f
);
974 void RGWPeriodMap::dump(Formatter
*f
) const
976 encode_json("id", id
, f
);
977 encode_json_map("zonegroups", zonegroups
, f
);
978 encode_json("short_zone_ids", short_zone_ids
, f
);
981 static void decode_zonegroups(map
<string
, RGWZoneGroup
>& zonegroups
, JSONObj
*o
)
985 zonegroups
[zg
.get_id()] = zg
;
988 void RGWPeriodMap::decode_json(JSONObj
*obj
)
990 JSONDecoder::decode_json("id", id
, obj
);
991 JSONDecoder::decode_json("zonegroups", zonegroups
, decode_zonegroups
, obj
);
992 /* backward compatability with region */
993 if (zonegroups
.empty()) {
994 JSONDecoder::decode_json("regions", zonegroups
, obj
);
996 /* backward compatability with region */
997 if (master_zonegroup
.empty()) {
998 JSONDecoder::decode_json("master_region", master_zonegroup
, obj
);
1000 JSONDecoder::decode_json("short_zone_ids", short_zone_ids
, obj
);
1003 void RGWPeriodMap::decode(bufferlist::const_iterator
& bl
) {
1004 DECODE_START(2, bl
);
1006 decode(zonegroups
, bl
);
1007 decode(master_zonegroup
, bl
);
1008 if (struct_v
>= 2) {
1009 decode(short_zone_ids
, bl
);
1013 zonegroups_by_api
.clear();
1014 for (map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.begin();
1015 iter
!= zonegroups
.end(); ++iter
) {
1016 RGWZoneGroup
& zonegroup
= iter
->second
;
1017 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1018 if (zonegroup
.is_master_zonegroup()) {
1019 master_zonegroup
= zonegroup
.get_id();
1024 void RGWPeriodMap::encode(bufferlist
& bl
) const
1026 ENCODE_START(2, 1, bl
);
1028 encode(zonegroups
, bl
);
1029 encode(master_zonegroup
, bl
);
1030 encode(short_zone_ids
, bl
);
1034 int RGWSystemMetaObj::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1038 /* check to see the name is not used */
1039 ret
= read_id(dpp
, name
, id
, y
);
1040 if (exclusive
&& ret
== 0) {
1041 ldpp_dout(dpp
, 10) << "ERROR: name " << name
<< " already in use for obj id " << id
<< dendl
;
1043 } else if ( ret
< 0 && ret
!= -ENOENT
) {
1044 ldpp_dout(dpp
, 0) << "failed reading obj id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1049 /* create unique id */
1052 new_uuid
.generate_random();
1053 new_uuid
.print(uuid_str
);
1057 ret
= store_info(dpp
, exclusive
, y
);
1059 ldpp_dout(dpp
, 0) << "ERROR: storing info for " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1063 return store_name(dpp
, exclusive
, y
);
1066 int RGWSystemMetaObj::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
1069 RGWDefaultSystemMetaObjInfo default_info
;
1071 int ret
= read_default(dpp
, default_info
, get_default_oid(old_format
), y
);
1076 default_id
= default_info
.default_id
;
1081 int RGWSystemMetaObj::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1084 string oid
= get_default_oid();
1086 rgw_pool
pool(get_pool(cct
));
1089 RGWDefaultSystemMetaObjInfo default_info
;
1090 default_info
.default_id
= id
;
1092 encode(default_info
, bl
);
1094 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj(pool
, oid
));
1095 int ret
= sysobj
.wop()
1096 .set_exclusive(exclusive
)
1104 int RGWSystemMetaObj::store_info(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
1106 rgw_pool
pool(get_pool(cct
));
1108 string oid
= get_info_oid_prefix() + id
;
1113 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj
{pool
, oid
});
1115 .set_exclusive(exclusive
)
1119 int RGWSystemMetaObj::read_id(const DoutPrefixProvider
*dpp
, const string
& obj_name
, string
& object_id
,
1123 rgw_pool
pool(get_pool(cct
));
1126 string oid
= get_names_oid_prefix() + obj_name
;
1128 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj(pool
, oid
));
1129 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
1134 RGWNameToId nameToId
;
1136 auto iter
= bl
.cbegin();
1137 decode(nameToId
, iter
);
1138 } catch (buffer::error
& err
) {
1139 ldpp_dout(dpp
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
1142 object_id
= nameToId
.obj_id
;
1146 int RGWSystemMetaObj::store_name(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
1148 rgw_pool
pool(get_pool(cct
));
1149 string oid
= get_names_oid_prefix() + name
;
1151 RGWNameToId nameToId
;
1152 nameToId
.obj_id
= id
;
1156 encode(nameToId
, bl
);
1157 auto sysobj
= sysobj_svc
->get_obj(rgw_raw_obj(pool
, oid
));
1159 .set_exclusive(exclusive
)
1163 bool RGWPeriodMap::find_zone_by_id(const rgw_zone_id
& zone_id
,
1164 RGWZoneGroup
*zonegroup
,
1165 RGWZone
*zone
) const
1167 for (auto& iter
: zonegroups
) {
1168 auto& zg
= iter
.second
;
1170 auto ziter
= zg
.zones
.find(zone_id
);
1171 if (ziter
!= zg
.zones
.end()) {
1173 *zone
= ziter
->second
;
1181 int RGWZoneGroup::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1183 if (realm_id
.empty()) {
1184 /* try using default realm */
1186 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
1188 ldpp_dout(dpp
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
1191 realm_id
= realm
.get_id();
1194 return RGWSystemMetaObj::set_as_default(dpp
, y
, exclusive
);
1197 int RGWSystemMetaObj::write(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
1199 int ret
= store_info(dpp
, exclusive
, y
);
1201 ldpp_dout(dpp
, 20) << __func__
<< "(): store_info() returned ret=" << ret
<< dendl
;
1204 ret
= store_name(dpp
, exclusive
, y
);
1206 ldpp_dout(dpp
, 20) << __func__
<< "(): store_name() returned ret=" << ret
<< dendl
;
1214 int init_zone_pool_names(const DoutPrefixProvider
*dpp
, optional_yield y
,
1215 const std::set
<rgw_pool
>& pools
, RGWZoneParams
& info
)
1217 info
.domain_root
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:root", info
.domain_root
);
1218 info
.control_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.control", info
.control_pool
);
1219 info
.gc_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:gc", info
.gc_pool
);
1220 info
.lc_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:lc", info
.lc_pool
);
1221 info
.log_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log", info
.log_pool
);
1222 info
.intent_log_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:intent", info
.intent_log_pool
);
1223 info
.usage_log_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:usage", info
.usage_log_pool
);
1224 info
.user_keys_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:users.keys", info
.user_keys_pool
);
1225 info
.user_email_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:users.email", info
.user_email_pool
);
1226 info
.user_swift_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:users.swift", info
.user_swift_pool
);
1227 info
.user_uid_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:users.uid", info
.user_uid_pool
);
1228 info
.roles_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:roles", info
.roles_pool
);
1229 info
.reshard_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:reshard", info
.reshard_pool
);
1230 info
.otp_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.otp", info
.otp_pool
);
1231 info
.oidc_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.meta:oidc", info
.oidc_pool
);
1232 info
.notif_pool
= fix_zone_pool_dup(pools
, info
.name
, ".rgw.log:notif", info
.notif_pool
);
1234 for (auto& [pname
, placement
] : info
.placement_pools
) {
1235 placement
.index_pool
= fix_zone_pool_dup(pools
, info
.name
, "." + default_bucket_index_pool_suffix
, placement
.index_pool
);
1236 placement
.data_extra_pool
= fix_zone_pool_dup(pools
, info
.name
, "." + default_storage_extra_pool_suffix
, placement
.data_extra_pool
);
1237 for (auto& [sname
, sc
] : placement
.storage_classes
.get_all()) {
1239 sc
.data_pool
= fix_zone_pool_dup(pools
, info
.name
, "." + default_storage_pool_suffix
, *sc
.data_pool
);
1247 int add_zone_to_group(const DoutPrefixProvider
* dpp
, RGWZoneGroup
& zonegroup
,
1248 const RGWZoneParams
& zone_params
,
1249 const bool *pis_master
, const bool *pread_only
,
1250 const std::list
<std::string
>& endpoints
,
1251 const std::string
*ptier_type
,
1252 const bool *psync_from_all
,
1253 const std::list
<std::string
>& sync_from
,
1254 const std::list
<std::string
>& sync_from_rm
,
1255 const std::string
*predirect_zone
,
1256 std::optional
<int> bucket_index_max_shards
,
1257 const rgw::zone_features::set
& enable_features
,
1258 const rgw::zone_features::set
& disable_features
)
1260 const std::string
& zone_id
= zone_params
.id
;
1261 const std::string
& zone_name
= zone_params
.name
;
1263 if (zone_id
.empty()) {
1264 ldpp_dout(dpp
, -1) << __func__
<< " requires a zone id" << dendl
;
1267 if (zone_name
.empty()) {
1268 ldpp_dout(dpp
, -1) << __func__
<< " requires a zone name" << dendl
;
1272 // check for duplicate zone name on insert
1273 if (!zonegroup
.zones
.count(zone_id
)) {
1274 for (const auto& [id
, zone
] : zonegroup
.zones
) {
1275 if (zone
.name
== zone_name
) {
1276 ldpp_dout(dpp
, 0) << "ERROR: found existing zone name " << zone_name
1277 << " (" << id
<< ") in zonegroup " << zonegroup
.name
<< dendl
;
1283 rgw_zone_id
& master_zone
= zonegroup
.master_zone
;
1286 if (!master_zone
.empty() && master_zone
!= zone_id
) {
1287 ldpp_dout(dpp
, 0) << "NOTICE: overriding master zone: "
1288 << master_zone
<< dendl
;
1290 master_zone
= zone_id
;
1291 } else if (master_zone
== zone_id
) {
1292 master_zone
.clear();
1294 } else if (master_zone
.empty() && zonegroup
.zones
.empty()) {
1295 ldpp_dout(dpp
, 0) << "NOTICE: promoted " << zone_name
1296 << " as new master_zone of zonegroup " << zonegroup
.name
<< dendl
;
1297 master_zone
= zone_id
;
1300 // make sure the zone's placement targets are named in the zonegroup
1301 for (const auto& [name
, placement
] : zone_params
.placement_pools
) {
1302 auto target
= RGWZoneGroupPlacementTarget
{.name
= name
};
1303 zonegroup
.placement_targets
.emplace(name
, std::move(target
));
1306 RGWZone
& zone
= zonegroup
.zones
[zone_params
.id
];
1307 zone
.id
= zone_params
.id
;
1308 zone
.name
= zone_params
.name
;
1309 if (!endpoints
.empty()) {
1310 zone
.endpoints
= endpoints
;
1313 zone
.read_only
= *pread_only
;
1316 zone
.tier_type
= *ptier_type
;
1318 if (psync_from_all
) {
1319 zone
.sync_from_all
= *psync_from_all
;
1321 if (predirect_zone
) {
1322 zone
.redirect_zone
= *predirect_zone
;
1324 if (bucket_index_max_shards
) {
1325 zone
.bucket_index_max_shards
= *bucket_index_max_shards
;
1328 // add/remove sync_from
1329 for (auto add
: sync_from
) {
1330 zone
.sync_from
.insert(add
);
1333 for (const auto& rm
: sync_from_rm
) {
1334 auto i
= zone
.sync_from
.find(rm
);
1335 if (i
== zone
.sync_from
.end()) {
1336 ldpp_dout(dpp
, 1) << "WARNING: zone \"" << rm
1337 << "\" was not in sync_from" << dendl
;
1340 zone
.sync_from
.erase(i
);
1343 // add/remove supported features
1344 zone
.supported_features
.insert(enable_features
.begin(),
1345 enable_features
.end());
1347 for (const auto& feature
: disable_features
) {
1348 if (zonegroup
.enabled_features
.contains(feature
)) {
1349 ldpp_dout(dpp
, -1) << "ERROR: Cannot disable zone feature \"" << feature
1350 << "\" until it's been disabled in zonegroup " << zonegroup
.name
<< dendl
;
1353 auto i
= zone
.supported_features
.find(feature
);
1354 if (i
== zone
.supported_features
.end()) {
1355 ldpp_dout(dpp
, 1) << "WARNING: zone feature \"" << feature
1356 << "\" was not enabled in zone " << zone
.name
<< dendl
;
1359 zone
.supported_features
.erase(i
);
1362 const bool log_data
= zonegroup
.zones
.size() > 1;
1363 for (auto& [id
, zone
] : zonegroup
.zones
) {
1364 zone
.log_data
= log_data
;