1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #include "common/errno.h"
7 #include "rgw_realm_watcher.h"
8 #include "rgw_meta_sync_status.h"
11 #include "services/svc_zone.h"
12 #include "services/svc_sys_obj.h"
14 #include "common/ceph_json.h"
15 #include "common/Formatter.h"
17 #define dout_context g_ceph_context
18 #define dout_subsys ceph_subsys_rgw
20 namespace rgw_zone_defaults
{
22 std::string zone_info_oid_prefix
= "zone_info.";
23 std::string zone_names_oid_prefix
= "zone_names.";
24 std::string region_info_oid_prefix
= "region_info.";
25 std::string realm_names_oid_prefix
= "realms_names.";
26 std::string zone_group_info_oid_prefix
= "zonegroup_info.";
27 std::string realm_info_oid_prefix
= "realms.";
28 std::string default_region_info_oid
= "default.region";
29 std::string default_zone_group_info_oid
= "default.zonegroup";
30 std::string period_info_oid_prefix
= "periods.";
31 std::string period_latest_epoch_info_oid
= ".latest_epoch";
32 std::string region_map_oid
= "region_map";
33 std::string default_realm_info_oid
= "default.realm";
34 std::string default_zonegroup_name
= "default";
35 std::string default_zone_name
= "default";
36 std::string zonegroup_names_oid_prefix
= "zonegroups_names.";
37 std::string RGW_DEFAULT_ZONE_ROOT_POOL
= "rgw.root";
38 std::string RGW_DEFAULT_ZONEGROUP_ROOT_POOL
= "rgw.root";
39 std::string RGW_DEFAULT_REALM_ROOT_POOL
= "rgw.root";
40 std::string RGW_DEFAULT_PERIOD_ROOT_POOL
= "rgw.root";
41 std::string default_bucket_index_pool_suffix
= "rgw.buckets.index";
42 std::string default_storage_extra_pool_suffix
= "rgw.buckets.non-ec";
43 std::string avail_pools
= ".pools.avail";
44 std::string default_storage_pool_suffix
= "rgw.buckets.data";
49 using namespace rgw_zone_defaults
;
51 RGWMetaSyncStatusManager::~RGWMetaSyncStatusManager(){}
57 void encode_json_plain(const char *name
, const RGWAccessKey
& val
, Formatter
*f
)
59 f
->open_object_section(name
);
64 void RGWDefaultZoneGroupInfo::dump(Formatter
*f
) const {
65 encode_json("default_zonegroup", default_zonegroup
, f
);
68 void RGWDefaultZoneGroupInfo::decode_json(JSONObj
*obj
) {
70 JSONDecoder::decode_json("default_zonegroup", default_zonegroup
, obj
);
71 /* backward compatability with region */
72 if (default_zonegroup
.empty()) {
73 JSONDecoder::decode_json("default_region", default_zonegroup
, obj
);
77 rgw_pool
RGWZoneGroup::get_pool(CephContext
*cct_
) const
79 if (cct_
->_conf
->rgw_zonegroup_root_pool
.empty()) {
80 return rgw_pool(RGW_DEFAULT_ZONEGROUP_ROOT_POOL
);
83 return rgw_pool(cct_
->_conf
->rgw_zonegroup_root_pool
);
86 int RGWZoneGroup::create_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
88 name
= default_zonegroup_name
;
89 api_name
= default_zonegroup_name
;
92 RGWZoneGroupPlacementTarget placement_target
;
93 placement_target
.name
= "default-placement";
94 placement_targets
[placement_target
.name
] = placement_target
;
95 default_placement
.name
= "default-placement";
97 RGWZoneParams
zone_params(default_zone_name
);
99 int r
= zone_params
.init(dpp
, cct
, sysobj_svc
, y
, false);
101 ldpp_dout(dpp
, 0) << "create_default: error initializing zone params: " << cpp_strerror(-r
) << dendl
;
105 r
= zone_params
.create_default(dpp
, y
);
106 if (r
< 0 && r
!= -EEXIST
) {
107 ldpp_dout(dpp
, 0) << "create_default: error in create_default zone params: " << cpp_strerror(-r
) << dendl
;
109 } else if (r
== -EEXIST
) {
110 ldpp_dout(dpp
, 10) << "zone_params::create_default() returned -EEXIST, we raced with another default zone_params creation" << dendl
;
111 zone_params
.clear_id();
112 r
= zone_params
.init(dpp
, cct
, sysobj_svc
, y
);
114 ldpp_dout(dpp
, 0) << "create_default: error in init existing zone params: " << cpp_strerror(-r
) << dendl
;
117 ldpp_dout(dpp
, 20) << "zone_params::create_default() " << zone_params
.get_name() << " id " << zone_params
.get_id()
121 RGWZone
& default_zone
= zones
[zone_params
.get_id()];
122 default_zone
.name
= zone_params
.get_name();
123 default_zone
.id
= zone_params
.get_id();
124 master_zone
= default_zone
.id
;
127 if (r
< 0 && r
!= -EEXIST
) {
128 ldpp_dout(dpp
, 0) << "error storing zone group info: " << cpp_strerror(-r
) << dendl
;
133 ldpp_dout(dpp
, 10) << "create_default() returned -EEXIST, we raced with another zonegroup creation" << dendl
;
135 r
= init(dpp
, cct
, sysobj_svc
, y
);
145 post_process_params(dpp
, y
);
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 int RGWZoneGroup::equals(const string
& other_zonegroup
) const
193 if (is_master
&& other_zonegroup
.empty())
196 return (id
== other_zonegroup
);
199 int RGWZoneGroup::add_zone(const DoutPrefixProvider
*dpp
,
200 const RGWZoneParams
& zone_params
, bool *is_master
, bool *read_only
,
201 const list
<string
>& endpoints
, const string
*ptier_type
,
202 bool *psync_from_all
, list
<string
>& sync_from
, list
<string
>& sync_from_rm
,
203 string
*predirect_zone
, std::optional
<int> bucket_index_max_shards
,
204 RGWSyncModulesManager
*sync_mgr
,
207 auto& zone_id
= zone_params
.get_id();
208 auto& zone_name
= zone_params
.get_name();
210 // check for duplicate zone name on insert
211 if (!zones
.count(zone_id
)) {
212 for (const auto& zone
: zones
) {
213 if (zone
.second
.name
== zone_name
) {
214 ldpp_dout(dpp
, 0) << "ERROR: found existing zone name " << zone_name
215 << " (" << zone
.first
<< ") in zonegroup " << get_name() << dendl
;
223 if (!master_zone
.empty() && master_zone
!= zone_id
) {
224 ldpp_dout(dpp
, 0) << "NOTICE: overriding master zone: " << master_zone
<< dendl
;
226 master_zone
= zone_id
;
227 } else if (master_zone
== zone_id
) {
232 RGWZone
& zone
= zones
[zone_id
];
233 zone
.name
= zone_name
;
235 if (!endpoints
.empty()) {
236 zone
.endpoints
= endpoints
;
239 zone
.read_only
= *read_only
;
242 zone
.tier_type
= *ptier_type
;
243 if (!sync_mgr
->get_module(*ptier_type
, nullptr)) {
244 ldpp_dout(dpp
, 0) << "ERROR: could not found sync module: " << *ptier_type
245 << ", valid sync modules: "
246 << sync_mgr
->get_registered_module_names()
252 if (psync_from_all
) {
253 zone
.sync_from_all
= *psync_from_all
;
256 if (predirect_zone
) {
257 zone
.redirect_zone
= *predirect_zone
;
260 if (bucket_index_max_shards
) {
261 zone
.bucket_index_max_shards
= *bucket_index_max_shards
;
264 for (auto add
: sync_from
) {
265 zone
.sync_from
.insert(add
);
268 for (auto rm
: sync_from_rm
) {
269 zone
.sync_from
.erase(rm
);
272 post_process_params(dpp
, y
);
274 return update(dpp
,y
);
278 int RGWZoneGroup::rename_zone(const DoutPrefixProvider
*dpp
,
279 const RGWZoneParams
& zone_params
,
282 RGWZone
& zone
= zones
[zone_params
.get_id()];
283 zone
.name
= zone_params
.get_name();
285 return update(dpp
, y
);
288 void RGWZoneGroup::post_process_params(const DoutPrefixProvider
*dpp
, optional_yield y
)
290 bool log_data
= zones
.size() > 1;
292 if (master_zone
.empty()) {
293 auto iter
= zones
.begin();
294 if (iter
!= zones
.end()) {
295 master_zone
= iter
->first
;
299 for (auto& item
: zones
) {
300 RGWZone
& zone
= item
.second
;
301 zone
.log_data
= log_data
;
303 RGWZoneParams
zone_params(zone
.id
, zone
.name
);
304 int ret
= zone_params
.init(dpp
, cct
, sysobj_svc
, y
);
306 ldpp_dout(dpp
, 0) << "WARNING: could not read zone params for zone id=" << zone
.id
<< " name=" << zone
.name
<< dendl
;
310 for (auto& pitem
: zone_params
.placement_pools
) {
311 const string
& placement_name
= pitem
.first
;
312 if (placement_targets
.find(placement_name
) == placement_targets
.end()) {
313 RGWZoneGroupPlacementTarget placement_target
;
314 placement_target
.name
= placement_name
;
315 placement_targets
[placement_name
] = placement_target
;
320 if (default_placement
.empty() && !placement_targets
.empty()) {
321 default_placement
.init(placement_targets
.begin()->first
, RGW_STORAGE_CLASS_STANDARD
);
325 int RGWZoneGroup::remove_zone(const DoutPrefixProvider
*dpp
, const std::string
& zone_id
, optional_yield y
)
327 auto iter
= zones
.find(zone_id
);
328 if (iter
== zones
.end()) {
329 ldpp_dout(dpp
, 0) << "zone id " << zone_id
<< " is not a part of zonegroup "
336 post_process_params(dpp
, y
);
338 return update(dpp
, y
);
341 int RGWZoneGroup::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
344 if (realm_id
.empty()) {
345 /* try using default realm */
347 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
348 // no default realm exist
350 return read_id(dpp
, default_zonegroup_name
, default_id
, y
);
352 realm_id
= realm
.get_id();
355 return RGWSystemMetaObj::read_default_id(dpp
, default_id
, y
, old_format
);
358 int RGWZoneGroup::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
360 if (realm_id
.empty()) {
361 /* try using default realm */
363 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
365 ldpp_dout(dpp
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
368 realm_id
= realm
.get_id();
371 return RGWSystemMetaObj::set_as_default(dpp
, y
, exclusive
);
374 void RGWSystemMetaObj::reinit_instance(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
)
377 sysobj_svc
= _sysobj_svc
;
378 zone_svc
= _sysobj_svc
->get_zone_svc();
381 int RGWSystemMetaObj::init(const DoutPrefixProvider
*dpp
, CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
,
383 bool setup_obj
, bool old_format
)
385 reinit_instance(_cct
, _sysobj_svc
);
390 if (old_format
&& id
.empty()) {
395 id
= get_predefined_id(cct
);
401 name
= get_predefined_name(cct
);
404 r
= use_default(dpp
, y
, old_format
);
408 } else if (!old_format
) {
409 r
= read_id(dpp
, name
, id
, y
);
412 ldpp_dout(dpp
, 0) << "error in read_id for object name: " << name
<< " : " << cpp_strerror(-r
) << dendl
;
419 return read_info(dpp
, id
, y
, old_format
);
422 void RGWDefaultSystemMetaObjInfo::dump(Formatter
*f
) const {
423 encode_json("default_id", default_id
, f
);
426 void RGWDefaultSystemMetaObjInfo::decode_json(JSONObj
*obj
) {
427 JSONDecoder::decode_json("default_id", default_id
, obj
);
430 int RGWSystemMetaObj::read_default(const DoutPrefixProvider
*dpp
,
431 RGWDefaultSystemMetaObjInfo
& default_info
,
432 const string
& oid
, optional_yield y
)
435 auto pool
= get_pool(cct
);
438 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
439 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
440 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
445 auto iter
= bl
.cbegin();
446 decode(default_info
, iter
);
447 } catch (buffer::error
& err
) {
448 ldpp_dout(dpp
, 0) << "error decoding data from " << pool
<< ":" << oid
<< dendl
;
455 int RGWSystemMetaObj::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
458 RGWDefaultSystemMetaObjInfo default_info
;
460 int ret
= read_default(dpp
, default_info
, get_default_oid(old_format
), y
);
465 default_id
= default_info
.default_id
;
470 int RGWSystemMetaObj::use_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
472 return read_default_id(dpp
, id
, y
, old_format
);
475 int RGWSystemMetaObj::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
478 string oid
= get_default_oid();
480 rgw_pool
pool(get_pool(cct
));
483 RGWDefaultSystemMetaObjInfo default_info
;
484 default_info
.default_id
= id
;
486 encode(default_info
, bl
);
488 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
489 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
490 int ret
= sysobj
.wop()
491 .set_exclusive(exclusive
)
499 int RGWSystemMetaObj::read_id(const DoutPrefixProvider
*dpp
, const string
& obj_name
, string
& object_id
,
503 rgw_pool
pool(get_pool(cct
));
506 string oid
= get_names_oid_prefix() + obj_name
;
508 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
509 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
510 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
515 RGWNameToId nameToId
;
517 auto iter
= bl
.cbegin();
518 decode(nameToId
, iter
);
519 } catch (buffer::error
& err
) {
520 ldpp_dout(dpp
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
523 object_id
= nameToId
.obj_id
;
527 int RGWSystemMetaObj::delete_obj(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
529 rgw_pool
pool(get_pool(cct
));
531 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
533 /* check to see if obj is the default */
534 RGWDefaultSystemMetaObjInfo default_info
;
535 int ret
= read_default(dpp
, default_info
, get_default_oid(old_format
), y
);
536 if (ret
< 0 && ret
!= -ENOENT
)
538 if (default_info
.default_id
== id
|| (old_format
&& default_info
.default_id
== name
)) {
539 string oid
= get_default_oid(old_format
);
540 rgw_raw_obj
default_named_obj(pool
, oid
);
541 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, default_named_obj
);
542 ret
= sysobj
.wop().remove(dpp
, y
);
544 ldpp_dout(dpp
, 0) << "Error delete default obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
549 string oid
= get_names_oid_prefix() + name
;
550 rgw_raw_obj
object_name(pool
, oid
);
551 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, object_name
);
552 ret
= sysobj
.wop().remove(dpp
, y
);
554 ldpp_dout(dpp
, 0) << "Error delete obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
559 string oid
= get_info_oid_prefix(old_format
);
566 rgw_raw_obj
object_id(pool
, oid
);
567 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, object_id
);
568 ret
= sysobj
.wop().remove(dpp
, y
);
570 ldpp_dout(dpp
, 0) << "Error delete object id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
576 int RGWSystemMetaObj::store_name(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
578 rgw_pool
pool(get_pool(cct
));
579 string oid
= get_names_oid_prefix() + name
;
581 RGWNameToId nameToId
;
582 nameToId
.obj_id
= id
;
586 encode(nameToId
, bl
);
587 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
588 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
590 .set_exclusive(exclusive
)
594 int RGWSystemMetaObj::rename(const DoutPrefixProvider
*dpp
, const string
& new_name
, optional_yield y
)
597 int ret
= read_id(dpp
, new_name
, new_id
, y
);
601 if (ret
< 0 && ret
!= -ENOENT
) {
602 ldpp_dout(dpp
, 0) << "Error read_id " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
605 string old_name
= name
;
607 ret
= update(dpp
, y
);
609 ldpp_dout(dpp
, 0) << "Error storing new obj info " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
612 ret
= store_name(dpp
, true, y
);
614 ldpp_dout(dpp
, 0) << "Error storing new name " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
617 /* delete old name */
618 rgw_pool
pool(get_pool(cct
));
619 string oid
= get_names_oid_prefix() + old_name
;
620 rgw_raw_obj
old_name_obj(pool
, oid
);
621 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
622 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, old_name_obj
);
623 ret
= sysobj
.wop().remove(dpp
, y
);
625 ldpp_dout(dpp
, 0) << "Error delete old obj name " << old_name
<< ": " << cpp_strerror(-ret
) << dendl
;
632 int RGWSystemMetaObj::read_info(const DoutPrefixProvider
*dpp
, const string
& obj_id
, optional_yield y
,
635 rgw_pool
pool(get_pool(cct
));
639 string oid
= get_info_oid_prefix(old_format
) + obj_id
;
641 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
642 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
643 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
645 ldpp_dout(dpp
, 0) << "failed reading obj info from " << pool
<< ":" << oid
<< ": " << cpp_strerror(-ret
) << dendl
;
651 auto iter
= bl
.cbegin();
653 } catch (buffer::error
& err
) {
654 ldpp_dout(dpp
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
661 int RGWSystemMetaObj::read(const DoutPrefixProvider
*dpp
, optional_yield y
)
663 int ret
= read_id(dpp
, name
, id
, y
);
668 return read_info(dpp
, id
, y
);
671 int RGWSystemMetaObj::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
675 /* check to see the name is not used */
676 ret
= read_id(dpp
, name
, id
, y
);
677 if (exclusive
&& ret
== 0) {
678 ldpp_dout(dpp
, 10) << "ERROR: name " << name
<< " already in use for obj id " << id
<< dendl
;
680 } else if ( ret
< 0 && ret
!= -ENOENT
) {
681 ldpp_dout(dpp
, 0) << "failed reading obj id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
686 /* create unique id */
689 new_uuid
.generate_random();
690 new_uuid
.print(uuid_str
);
694 ret
= store_info(dpp
, exclusive
, y
);
696 ldpp_dout(dpp
, 0) << "ERROR: storing info for " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
700 return store_name(dpp
, exclusive
, y
);
703 int RGWSystemMetaObj::store_info(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
705 rgw_pool
pool(get_pool(cct
));
707 string oid
= get_info_oid_prefix() + id
;
712 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
713 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
715 .set_exclusive(exclusive
)
719 int RGWSystemMetaObj::write(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
721 int ret
= store_info(dpp
, exclusive
, y
);
723 ldpp_dout(dpp
, 20) << __func__
<< "(): store_info() returned ret=" << ret
<< dendl
;
726 ret
= store_name(dpp
, exclusive
, y
);
728 ldpp_dout(dpp
, 20) << __func__
<< "(): store_name() returned ret=" << ret
<< dendl
;
735 RGWRealm::~RGWRealm() {}
737 RGWRemoteMetaLog::~RGWRemoteMetaLog()
742 string
RGWRealm::get_predefined_id(CephContext
*cct
) const {
743 return cct
->_conf
.get_val
<string
>("rgw_realm_id");
746 const string
& RGWRealm::get_predefined_name(CephContext
*cct
) const {
747 return cct
->_conf
->rgw_realm
;
750 int RGWRealm::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
752 int ret
= RGWSystemMetaObj::create(dpp
, y
, exclusive
);
754 ldpp_dout(dpp
, 0) << "ERROR creating new realm object " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
757 // create the control object for watch/notify
758 ret
= create_control(dpp
, exclusive
, y
);
760 ldpp_dout(dpp
, 0) << "ERROR creating control for new realm " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
764 if (current_period
.empty()) {
765 /* create new period for the realm */
766 ret
= period
.init(dpp
, cct
, sysobj_svc
, id
, y
, name
, false);
770 ret
= period
.create(dpp
, y
, true);
772 ldpp_dout(dpp
, 0) << "ERROR: creating new period for realm " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
776 period
= RGWPeriod(current_period
, 0);
777 int ret
= period
.init(dpp
, cct
, sysobj_svc
, id
, y
, name
);
779 ldpp_dout(dpp
, 0) << "ERROR: failed to init period " << current_period
<< dendl
;
783 ret
= set_current_period(dpp
, period
, y
);
785 ldpp_dout(dpp
, 0) << "ERROR: failed set current period " << current_period
<< dendl
;
788 // try to set as default. may race with another create, so pass exclusive=true
789 // so we don't override an existing default
790 ret
= set_as_default(dpp
, y
, true);
791 if (ret
< 0 && ret
!= -EEXIST
) {
792 ldpp_dout(dpp
, 0) << "WARNING: failed to set realm as default realm, ret=" << ret
<< dendl
;
798 int RGWRealm::delete_obj(const DoutPrefixProvider
*dpp
, optional_yield y
)
800 int ret
= RGWSystemMetaObj::delete_obj(dpp
, y
);
804 return delete_control(dpp
, y
);
807 int RGWRealm::create_control(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
809 auto pool
= rgw_pool
{get_pool(cct
)};
810 auto oid
= get_control_oid();
812 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
813 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
815 .set_exclusive(exclusive
)
819 int RGWRealm::delete_control(const DoutPrefixProvider
*dpp
, optional_yield y
)
821 auto pool
= rgw_pool
{get_pool(cct
)};
822 auto obj
= rgw_raw_obj
{pool
, get_control_oid()};
823 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
824 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, obj
);
825 return sysobj
.wop().remove(dpp
, y
);
828 rgw_pool
RGWRealm::get_pool(CephContext
*cct
) const
830 if (cct
->_conf
->rgw_realm_root_pool
.empty()) {
831 return rgw_pool(RGW_DEFAULT_REALM_ROOT_POOL
);
833 return rgw_pool(cct
->_conf
->rgw_realm_root_pool
);
836 const string
RGWRealm::get_default_oid(bool old_format
) const
838 if (cct
->_conf
->rgw_default_realm_info_oid
.empty()) {
839 return default_realm_info_oid
;
841 return cct
->_conf
->rgw_default_realm_info_oid
;
844 const string
& RGWRealm::get_names_oid_prefix() const
846 return realm_names_oid_prefix
;
849 const string
& RGWRealm::get_info_oid_prefix(bool old_format
) const
851 return realm_info_oid_prefix
;
854 int RGWRealm::set_current_period(const DoutPrefixProvider
*dpp
, RGWPeriod
& period
, optional_yield y
)
856 // update realm epoch to match the period's
857 if (epoch
> period
.get_realm_epoch()) {
858 ldpp_dout(dpp
, 0) << "ERROR: set_current_period with old realm epoch "
859 << period
.get_realm_epoch() << ", current epoch=" << epoch
<< dendl
;
862 if (epoch
== period
.get_realm_epoch() && current_period
!= period
.get_id()) {
863 ldpp_dout(dpp
, 0) << "ERROR: set_current_period with same realm epoch "
864 << period
.get_realm_epoch() << ", but different period id "
865 << period
.get_id() << " != " << current_period
<< dendl
;
869 epoch
= period
.get_realm_epoch();
870 current_period
= period
.get_id();
872 int ret
= update(dpp
, y
);
874 ldpp_dout(dpp
, 0) << "ERROR: period update: " << cpp_strerror(-ret
) << dendl
;
878 ret
= period
.reflect(dpp
, y
);
880 ldpp_dout(dpp
, 0) << "ERROR: period.reflect(): " << cpp_strerror(-ret
) << dendl
;
887 string
RGWRealm::get_control_oid() const
889 return get_info_oid_prefix() + id
+ ".control";
892 int RGWRealm::notify_zone(const DoutPrefixProvider
*dpp
, bufferlist
& bl
, optional_yield y
)
894 rgw_pool pool
{get_pool(cct
)};
895 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
896 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, get_control_oid()});
897 int ret
= sysobj
.wn().notify(dpp
, bl
, 0, nullptr, y
);
904 int RGWRealm::notify_new_period(const DoutPrefixProvider
*dpp
, const RGWPeriod
& period
, optional_yield y
)
908 // push the period to dependent zonegroups/zones
909 encode(RGWRealmNotify::ZonesNeedPeriod
, bl
);
911 // reload the gateway with the new period
912 encode(RGWRealmNotify::Reload
, bl
);
914 return notify_zone(dpp
, bl
, y
);
918 int RGWRealm::find_zone(const DoutPrefixProvider
*dpp
,
919 const rgw_zone_id
& zid
,
921 RGWZoneGroup
*pzonegroup
,
923 optional_yield y
) const
925 auto& found
= *pfound
;
932 RGWPeriod
period(period_id
, epoch
);
933 int r
= period
.init(dpp
, cct
, sysobj_svc
, get_id(), y
, get_name());
935 ldpp_dout(dpp
, 0) << "WARNING: period init failed: " << cpp_strerror(-r
) << " ... skipping" << dendl
;
939 found
= period
.find_zone(dpp
, zid
, pzonegroup
, y
);
946 std::string
RGWPeriodConfig::get_oid(const std::string
& realm_id
)
948 if (realm_id
.empty()) {
949 return "period_config.default";
951 return "period_config." + realm_id
;
954 rgw_pool
RGWPeriodConfig::get_pool(CephContext
*cct
)
956 const auto& pool_name
= cct
->_conf
->rgw_period_root_pool
;
957 if (pool_name
.empty()) {
958 return {RGW_DEFAULT_PERIOD_ROOT_POOL
};
963 int RGWPeriodConfig::read(const DoutPrefixProvider
*dpp
, RGWSI_SysObj
*sysobj_svc
, const std::string
& realm_id
,
966 const auto& pool
= get_pool(sysobj_svc
->ctx());
967 const auto& oid
= get_oid(realm_id
);
970 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
971 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
972 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
978 auto iter
= bl
.cbegin();
980 } catch (buffer::error
& err
) {
986 int RGWPeriodConfig::write(const DoutPrefixProvider
*dpp
,
987 RGWSI_SysObj
*sysobj_svc
,
988 const std::string
& realm_id
, optional_yield y
)
990 const auto& pool
= get_pool(sysobj_svc
->ctx());
991 const auto& oid
= get_oid(realm_id
);
995 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
996 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
998 .set_exclusive(false)
1002 int RGWPeriod::init(const DoutPrefixProvider
*dpp
, CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
,
1003 const string
& period_realm_id
, optional_yield y
,
1004 const string
& period_realm_name
, bool setup_obj
)
1007 sysobj_svc
= _sysobj_svc
;
1009 realm_id
= period_realm_id
;
1010 realm_name
= period_realm_name
;
1015 return init(dpp
, _cct
, _sysobj_svc
, y
, setup_obj
);
1019 int RGWPeriod::init(const DoutPrefixProvider
*dpp
,
1020 CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
,
1021 optional_yield y
, bool setup_obj
)
1024 sysobj_svc
= _sysobj_svc
;
1030 RGWRealm
realm(realm_id
, realm_name
);
1031 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
1033 ldpp_dout(dpp
, 4) << "RGWPeriod::init failed to init realm " << realm_name
<< " id " << realm_id
<< " : " <<
1034 cpp_strerror(-ret
) << dendl
;
1037 id
= realm
.get_current_period();
1038 realm_id
= realm
.get_id();
1042 int ret
= use_latest_epoch(dpp
, y
);
1044 ldpp_dout(dpp
, 0) << "failed to use_latest_epoch period id " << id
<< " realm " << realm_name
<< " id " << realm_id
1045 << " : " << cpp_strerror(-ret
) << dendl
;
1050 return read_info(dpp
, y
);
1054 int RGWPeriod::get_zonegroup(RGWZoneGroup
& zonegroup
,
1055 const string
& zonegroup_id
) const
1057 map
<string
, RGWZoneGroup
>::const_iterator iter
;
1058 if (!zonegroup_id
.empty()) {
1059 iter
= period_map
.zonegroups
.find(zonegroup_id
);
1061 iter
= period_map
.zonegroups
.find("default");
1063 if (iter
!= period_map
.zonegroups
.end()) {
1064 zonegroup
= iter
->second
;
1071 bool RGWPeriod::find_zone(const DoutPrefixProvider
*dpp
,
1072 const rgw_zone_id
& zid
,
1073 RGWZoneGroup
*pzonegroup
,
1074 optional_yield y
) const
1079 bool found
= period_map
.find_zone_by_id(zid
, &zg
, &zone
);
1087 const string
& RGWPeriod::get_latest_epoch_oid() const
1089 if (cct
->_conf
->rgw_period_latest_epoch_info_oid
.empty()) {
1090 return period_latest_epoch_info_oid
;
1092 return cct
->_conf
->rgw_period_latest_epoch_info_oid
;
1095 const string
& RGWPeriod::get_info_oid_prefix() const
1097 return period_info_oid_prefix
;
1100 const string
RGWPeriod::get_period_oid_prefix() const
1102 return get_info_oid_prefix() + id
;
1105 const string
RGWPeriod::get_period_oid() const
1107 std::ostringstream oss
;
1108 oss
<< get_period_oid_prefix();
1109 // skip the epoch for the staging period
1110 if (id
!= get_staging_id(realm_id
))
1111 oss
<< "." << epoch
;
1115 int RGWPeriod::read_latest_epoch(const DoutPrefixProvider
*dpp
,
1116 RGWPeriodLatestEpochInfo
& info
,
1118 RGWObjVersionTracker
*objv
)
1120 string oid
= get_period_oid_prefix() + get_latest_epoch_oid();
1122 rgw_pool
pool(get_pool(cct
));
1124 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1125 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
1126 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
1128 ldpp_dout(dpp
, 1) << "error read_lastest_epoch " << pool
<< ":" << oid
<< dendl
;
1132 auto iter
= bl
.cbegin();
1135 } catch (buffer::error
& err
) {
1136 ldpp_dout(dpp
, 0) << "error decoding data from " << pool
<< ":" << oid
<< dendl
;
1143 int RGWPeriod::get_latest_epoch(const DoutPrefixProvider
*dpp
, epoch_t
& latest_epoch
, optional_yield y
)
1145 RGWPeriodLatestEpochInfo info
;
1147 int ret
= read_latest_epoch(dpp
, info
, y
);
1152 latest_epoch
= info
.epoch
;
1157 int RGWPeriod::use_latest_epoch(const DoutPrefixProvider
*dpp
, optional_yield y
)
1159 RGWPeriodLatestEpochInfo info
;
1160 int ret
= read_latest_epoch(dpp
, info
, y
);
1170 int RGWPeriod::set_latest_epoch(const DoutPrefixProvider
*dpp
,
1172 epoch_t epoch
, bool exclusive
,
1173 RGWObjVersionTracker
*objv
)
1175 string oid
= get_period_oid_prefix() + get_latest_epoch_oid();
1177 rgw_pool
pool(get_pool(cct
));
1180 RGWPeriodLatestEpochInfo info
;
1186 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1187 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
1189 .set_exclusive(exclusive
)
1193 int RGWPeriod::update_latest_epoch(const DoutPrefixProvider
*dpp
, epoch_t epoch
, optional_yield y
)
1195 static constexpr int MAX_RETRIES
= 20;
1197 for (int i
= 0; i
< MAX_RETRIES
; i
++) {
1198 RGWPeriodLatestEpochInfo info
;
1199 RGWObjVersionTracker objv
;
1200 bool exclusive
= false;
1202 // read existing epoch
1203 int r
= read_latest_epoch(dpp
, info
, y
, &objv
);
1205 // use an exclusive create to set the epoch atomically
1207 ldpp_dout(dpp
, 20) << "creating initial latest_epoch=" << epoch
1208 << " for period=" << id
<< dendl
;
1210 ldpp_dout(dpp
, 0) << "ERROR: failed to read latest_epoch" << dendl
;
1212 } else if (epoch
<= info
.epoch
) {
1213 r
= -EEXIST
; // fail with EEXIST if epoch is not newer
1214 ldpp_dout(dpp
, 10) << "found existing latest_epoch " << info
.epoch
1215 << " >= given epoch " << epoch
<< ", returning r=" << r
<< dendl
;
1218 ldpp_dout(dpp
, 20) << "updating latest_epoch from " << info
.epoch
1219 << " -> " << epoch
<< " on period=" << id
<< dendl
;
1222 r
= set_latest_epoch(dpp
, y
, epoch
, exclusive
, &objv
);
1224 continue; // exclusive create raced with another update, retry
1225 } else if (r
== -ECANCELED
) {
1226 continue; // write raced with a conflicting version, retry
1229 ldpp_dout(dpp
, 0) << "ERROR: failed to write latest_epoch" << dendl
;
1232 return 0; // return success
1235 return -ECANCELED
; // fail after max retries
1238 int RGWPeriod::delete_obj(const DoutPrefixProvider
*dpp
, optional_yield y
)
1240 rgw_pool
pool(get_pool(cct
));
1242 // delete the object for each period epoch
1243 for (epoch_t e
= 1; e
<= epoch
; e
++) {
1244 RGWPeriod p
{get_id(), e
};
1245 rgw_raw_obj oid
{pool
, p
.get_period_oid()};
1246 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1247 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, oid
);
1248 int ret
= sysobj
.wop().remove(dpp
, y
);
1250 ldpp_dout(dpp
, 0) << "WARNING: failed to delete period object " << oid
1251 << ": " << cpp_strerror(-ret
) << dendl
;
1255 // delete the .latest_epoch object
1256 rgw_raw_obj oid
{pool
, get_period_oid_prefix() + get_latest_epoch_oid()};
1257 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1258 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, oid
);
1259 int ret
= sysobj
.wop().remove(dpp
, y
);
1261 ldpp_dout(dpp
, 0) << "WARNING: failed to delete period object " << oid
1262 << ": " << cpp_strerror(-ret
) << dendl
;
1267 int RGWPeriod::read_info(const DoutPrefixProvider
*dpp
, optional_yield y
)
1269 rgw_pool
pool(get_pool(cct
));
1273 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1274 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, get_period_oid()});
1275 int ret
= sysobj
.rop().read(dpp
, &bl
, y
);
1277 ldpp_dout(dpp
, 0) << "failed reading obj info from " << pool
<< ":" << get_period_oid() << ": " << cpp_strerror(-ret
) << dendl
;
1283 auto iter
= bl
.cbegin();
1284 decode(*this, iter
);
1285 } catch (buffer::error
& err
) {
1286 ldpp_dout(dpp
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << get_period_oid() << dendl
;
1293 int RGWPeriod::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1297 /* create unique id */
1300 new_uuid
.generate_random();
1301 new_uuid
.print(uuid_str
);
1304 epoch
= FIRST_EPOCH
;
1308 ret
= store_info(dpp
, exclusive
, y
);
1310 ldpp_dout(dpp
, 0) << "ERROR: storing info for " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1314 ret
= set_latest_epoch(dpp
, y
, epoch
);
1316 ldpp_dout(dpp
, 0) << "ERROR: setting latest epoch " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1322 int RGWPeriod::store_info(const DoutPrefixProvider
*dpp
, bool exclusive
, optional_yield y
)
1324 rgw_pool
pool(get_pool(cct
));
1326 string oid
= get_period_oid();
1331 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1332 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
1334 .set_exclusive(exclusive
)
1338 rgw_pool
RGWPeriod::get_pool(CephContext
*cct
) const
1340 if (cct
->_conf
->rgw_period_root_pool
.empty()) {
1341 return rgw_pool(RGW_DEFAULT_PERIOD_ROOT_POOL
);
1343 return rgw_pool(cct
->_conf
->rgw_period_root_pool
);
1346 int RGWPeriod::add_zonegroup(const DoutPrefixProvider
*dpp
, const RGWZoneGroup
& zonegroup
, optional_yield y
)
1348 if (zonegroup
.realm_id
!= realm_id
) {
1351 int ret
= period_map
.update(zonegroup
, cct
);
1353 ldpp_dout(dpp
, 0) << "ERROR: updating period map: " << cpp_strerror(-ret
) << dendl
;
1357 return store_info(dpp
, false, y
);
1360 int RGWPeriod::update(const DoutPrefixProvider
*dpp
, optional_yield y
)
1362 auto zone_svc
= sysobj_svc
->get_zone_svc();
1363 ldpp_dout(dpp
, 20) << __func__
<< " realm " << realm_id
<< " period " << get_id() << dendl
;
1364 list
<string
> zonegroups
;
1365 int ret
= zone_svc
->list_zonegroups(dpp
, zonegroups
);
1367 ldpp_dout(dpp
, 0) << "ERROR: failed to list zonegroups: " << cpp_strerror(-ret
) << dendl
;
1371 // clear zone short ids of removed zones. period_map.update() will add the
1372 // remaining zones back
1373 period_map
.short_zone_ids
.clear();
1375 for (auto& iter
: zonegroups
) {
1376 RGWZoneGroup
zg(string(), iter
);
1377 ret
= zg
.init(dpp
, cct
, sysobj_svc
, y
);
1379 ldpp_dout(dpp
, 0) << "WARNING: zg.init() failed: " << cpp_strerror(-ret
) << dendl
;
1383 if (zg
.realm_id
!= realm_id
) {
1384 ldpp_dout(dpp
, 20) << "skipping zonegroup " << zg
.get_name() << " zone realm id " << zg
.realm_id
<< ", not on our realm " << realm_id
<< dendl
;
1388 if (zg
.master_zone
.empty()) {
1389 ldpp_dout(dpp
, 0) << "ERROR: zonegroup " << zg
.get_name() << " should have a master zone " << dendl
;
1393 if (zg
.zones
.find(zg
.master_zone
) == zg
.zones
.end()) {
1394 ldpp_dout(dpp
, 0) << "ERROR: zonegroup " << zg
.get_name()
1395 << " has a non existent master zone "<< dendl
;
1399 if (zg
.is_master_zonegroup()) {
1400 master_zonegroup
= zg
.get_id();
1401 master_zone
= zg
.master_zone
;
1404 int ret
= period_map
.update(zg
, cct
);
1410 ret
= period_config
.read(dpp
, sysobj_svc
, realm_id
, y
);
1411 if (ret
< 0 && ret
!= -ENOENT
) {
1412 ldpp_dout(dpp
, 0) << "ERROR: failed to read period config: "
1413 << cpp_strerror(ret
) << dendl
;
1419 int RGWPeriod::reflect(const DoutPrefixProvider
*dpp
, optional_yield y
)
1421 for (auto& iter
: period_map
.zonegroups
) {
1422 RGWZoneGroup
& zg
= iter
.second
;
1423 zg
.reinit_instance(cct
, sysobj_svc
);
1424 int r
= zg
.write(dpp
, false, y
);
1426 ldpp_dout(dpp
, 0) << "ERROR: failed to store zonegroup info for zonegroup=" << iter
.first
<< ": " << cpp_strerror(-r
) << dendl
;
1429 if (zg
.is_master_zonegroup()) {
1430 // set master as default if no default exists
1431 r
= zg
.set_as_default(dpp
, y
, true);
1433 ldpp_dout(dpp
, 1) << "Set the period's master zonegroup " << zg
.get_id()
1434 << " as the default" << dendl
;
1439 int r
= period_config
.write(dpp
, sysobj_svc
, realm_id
, y
);
1441 ldpp_dout(dpp
, 0) << "ERROR: failed to store period config: "
1442 << cpp_strerror(-r
) << dendl
;
1448 void RGWPeriod::fork()
1450 ldout(cct
, 20) << __func__
<< " realm " << realm_id
<< " period " << id
<< dendl
;
1451 predecessor_uuid
= id
;
1452 id
= get_staging_id(realm_id
);
1457 static int read_sync_status(const DoutPrefixProvider
*dpp
, rgw::sal::RadosStore
* store
, rgw_meta_sync_status
*sync_status
)
1459 // initialize a sync status manager to read the status
1460 RGWMetaSyncStatusManager
mgr(store
, store
->svc()->rados
->get_async_processor());
1461 int r
= mgr
.init(dpp
);
1465 r
= mgr
.read_sync_status(dpp
, sync_status
);
1470 int RGWPeriod::update_sync_status(const DoutPrefixProvider
*dpp
,
1471 rgw::sal::Store
* store
, /* for now */
1472 const RGWPeriod
¤t_period
,
1473 std::ostream
& error_stream
,
1474 bool force_if_stale
)
1476 rgw_meta_sync_status status
;
1477 int r
= read_sync_status(dpp
, static_cast<rgw::sal::RadosStore
*>(store
), &status
);
1479 ldpp_dout(dpp
, 0) << "period failed to read sync status: "
1480 << cpp_strerror(-r
) << dendl
;
1484 std::vector
<std::string
> markers
;
1486 const auto current_epoch
= current_period
.get_realm_epoch();
1487 if (current_epoch
!= status
.sync_info
.realm_epoch
) {
1488 // no sync status markers for the current period
1489 ceph_assert(current_epoch
> status
.sync_info
.realm_epoch
);
1490 const int behind
= current_epoch
- status
.sync_info
.realm_epoch
;
1491 if (!force_if_stale
&& current_epoch
> 1) {
1492 error_stream
<< "ERROR: This zone is " << behind
<< " period(s) behind "
1493 "the current master zone in metadata sync. If this zone is promoted "
1494 "to master, any metadata changes during that time are likely to "
1496 "Waiting for this zone to catch up on metadata sync (see "
1497 "'radosgw-admin sync status') is recommended.\n"
1498 "To promote this zone to master anyway, add the flag "
1499 "--yes-i-really-mean-it." << std::endl
;
1502 // empty sync status markers - other zones will skip this period during
1503 // incremental metadata sync
1504 markers
.resize(status
.sync_info
.num_shards
);
1506 markers
.reserve(status
.sync_info
.num_shards
);
1507 for (auto& i
: status
.sync_markers
) {
1508 auto& marker
= i
.second
;
1509 // filter out markers from other periods
1510 if (marker
.realm_epoch
!= current_epoch
) {
1511 marker
.marker
.clear();
1513 markers
.emplace_back(std::move(marker
.marker
));
1517 std::swap(sync_status
, markers
);
1521 int RGWPeriod::commit(const DoutPrefixProvider
*dpp
,
1522 rgw::sal::Store
* store
,
1523 RGWRealm
& realm
, const RGWPeriod
& current_period
,
1524 std::ostream
& error_stream
, optional_yield y
,
1525 bool force_if_stale
)
1527 auto zone_svc
= sysobj_svc
->get_zone_svc();
1528 ldpp_dout(dpp
, 20) << __func__
<< " realm " << realm
.get_id() << " period " << current_period
.get_id() << dendl
;
1529 // gateway must be in the master zone to commit
1530 if (master_zone
!= zone_svc
->get_zone_params().get_id()) {
1531 error_stream
<< "Cannot commit period on zone "
1532 << zone_svc
->get_zone_params().get_id() << ", it must be sent to "
1533 "the period's master zone " << master_zone
<< '.' << std::endl
;
1536 // period predecessor must match current period
1537 if (predecessor_uuid
!= current_period
.get_id()) {
1538 error_stream
<< "Period predecessor " << predecessor_uuid
1539 << " does not match current period " << current_period
.get_id()
1540 << ". Use 'period pull' to get the latest period from the master, "
1541 "reapply your changes, and try again." << std::endl
;
1544 // realm epoch must be 1 greater than current period
1545 if (realm_epoch
!= current_period
.get_realm_epoch() + 1) {
1546 error_stream
<< "Period's realm epoch " << realm_epoch
1547 << " does not come directly after current realm epoch "
1548 << current_period
.get_realm_epoch() << ". Use 'realm pull' to get the "
1549 "latest realm and period from the master zone, reapply your changes, "
1550 "and try again." << std::endl
;
1553 // did the master zone change?
1554 if (master_zone
!= current_period
.get_master_zone()) {
1555 // store the current metadata sync status in the period
1556 int r
= update_sync_status(dpp
, store
, current_period
, error_stream
, force_if_stale
);
1558 ldpp_dout(dpp
, 0) << "failed to update metadata sync status: "
1559 << cpp_strerror(-r
) << dendl
;
1562 // create an object with a new period id
1563 r
= create(dpp
, y
, true);
1565 ldpp_dout(dpp
, 0) << "failed to create new period: " << cpp_strerror(-r
) << dendl
;
1568 // set as current period
1569 r
= realm
.set_current_period(dpp
, *this, y
);
1571 ldpp_dout(dpp
, 0) << "failed to update realm's current period: "
1572 << cpp_strerror(-r
) << dendl
;
1575 ldpp_dout(dpp
, 4) << "Promoted to master zone and committed new period "
1577 realm
.notify_new_period(dpp
, *this, y
);
1580 // period must be based on current epoch
1581 if (epoch
!= current_period
.get_epoch()) {
1582 error_stream
<< "Period epoch " << epoch
<< " does not match "
1583 "predecessor epoch " << current_period
.get_epoch()
1584 << ". Use 'period pull' to get the latest epoch from the master zone, "
1585 "reapply your changes, and try again." << std::endl
;
1588 // set period as next epoch
1589 set_id(current_period
.get_id());
1590 set_epoch(current_period
.get_epoch() + 1);
1591 set_predecessor(current_period
.get_predecessor());
1592 realm_epoch
= current_period
.get_realm_epoch();
1593 // write the period to rados
1594 int r
= store_info(dpp
, false, y
);
1596 ldpp_dout(dpp
, 0) << "failed to store period: " << cpp_strerror(-r
) << dendl
;
1599 // set as latest epoch
1600 r
= update_latest_epoch(dpp
, epoch
, y
);
1602 // already have this epoch (or a more recent one)
1606 ldpp_dout(dpp
, 0) << "failed to set latest epoch: " << cpp_strerror(-r
) << dendl
;
1609 r
= reflect(dpp
, y
);
1611 ldpp_dout(dpp
, 0) << "failed to update local objects: " << cpp_strerror(-r
) << dendl
;
1614 ldpp_dout(dpp
, 4) << "Committed new epoch " << epoch
1615 << " for period " << id
<< dendl
;
1616 realm
.notify_new_period(dpp
, *this, y
);
1620 int RGWZoneParams::create_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool old_format
)
1622 name
= default_zone_name
;
1624 int r
= create(dpp
, y
);
1636 void RGWZoneParams::dump(Formatter
*f
) const
1638 RGWSystemMetaObj::dump(f
);
1639 encode_json("domain_root", domain_root
, f
);
1640 encode_json("control_pool", control_pool
, f
);
1641 encode_json("gc_pool", gc_pool
, f
);
1642 encode_json("lc_pool", lc_pool
, f
);
1643 encode_json("log_pool", log_pool
, f
);
1644 encode_json("intent_log_pool", intent_log_pool
, f
);
1645 encode_json("usage_log_pool", usage_log_pool
, f
);
1646 encode_json("roles_pool", roles_pool
, f
);
1647 encode_json("reshard_pool", reshard_pool
, f
);
1648 encode_json("user_keys_pool", user_keys_pool
, f
);
1649 encode_json("user_email_pool", user_email_pool
, f
);
1650 encode_json("user_swift_pool", user_swift_pool
, f
);
1651 encode_json("user_uid_pool", user_uid_pool
, f
);
1652 encode_json("otp_pool", otp_pool
, f
);
1653 encode_json_plain("system_key", system_key
, f
);
1654 encode_json("placement_pools", placement_pools
, f
);
1655 encode_json("tier_config", tier_config
, f
);
1656 encode_json("realm_id", realm_id
, f
);
1657 encode_json("notif_pool", notif_pool
, f
);
1661 int get_zones_pool_set(const DoutPrefixProvider
*dpp
,
1663 RGWSI_SysObj
* sysobj_svc
,
1664 const list
<string
>& zones
,
1665 const string
& my_zone_id
,
1666 set
<rgw_pool
>& pool_names
,
1669 for(auto const& iter
: zones
) {
1670 RGWZoneParams
zone(iter
);
1671 int r
= zone
.init(dpp
, cct
, sysobj_svc
, y
);
1673 ldpp_dout(dpp
, 0) << "Error: init zone " << iter
<< ":" << cpp_strerror(-r
) << dendl
;
1676 if (zone
.get_id() != my_zone_id
) {
1677 pool_names
.insert(zone
.domain_root
);
1678 pool_names
.insert(zone
.control_pool
);
1679 pool_names
.insert(zone
.gc_pool
);
1680 pool_names
.insert(zone
.log_pool
);
1681 pool_names
.insert(zone
.intent_log_pool
);
1682 pool_names
.insert(zone
.usage_log_pool
);
1683 pool_names
.insert(zone
.user_keys_pool
);
1684 pool_names
.insert(zone
.user_email_pool
);
1685 pool_names
.insert(zone
.user_swift_pool
);
1686 pool_names
.insert(zone
.user_uid_pool
);
1687 pool_names
.insert(zone
.otp_pool
);
1688 pool_names
.insert(zone
.roles_pool
);
1689 pool_names
.insert(zone
.reshard_pool
);
1690 pool_names
.insert(zone
.notif_pool
);
1691 for(auto& iter
: zone
.placement_pools
) {
1692 pool_names
.insert(iter
.second
.index_pool
);
1693 for (auto& pi
: iter
.second
.storage_classes
.get_all()) {
1694 if (pi
.second
.data_pool
) {
1695 pool_names
.insert(pi
.second
.data_pool
.get());
1698 pool_names
.insert(iter
.second
.data_extra_pool
);
1700 pool_names
.insert(zone
.oidc_pool
);
1706 rgw_pool
fix_zone_pool_dup(set
<rgw_pool
> pools
,
1707 const string
& default_prefix
,
1708 const string
& default_suffix
,
1709 const rgw_pool
& suggested_pool
)
1711 string suggested_name
= suggested_pool
.to_str();
1713 string prefix
= default_prefix
;
1714 string suffix
= default_suffix
;
1716 if (!suggested_pool
.empty()) {
1717 prefix
= suggested_name
.substr(0, suggested_name
.find("."));
1718 suffix
= suggested_name
.substr(prefix
.length());
1721 rgw_pool
pool(prefix
+ suffix
);
1723 if (pools
.find(pool
) == pools
.end()) {
1727 pool
= prefix
+ "_" + std::to_string(std::rand()) + suffix
;
1728 if (pools
.find(pool
) == pools
.end()) {
1736 int RGWZoneParams::fix_pool_names(const DoutPrefixProvider
*dpp
, optional_yield y
)
1740 int r
= zone_svc
->list_zones(dpp
, zones
);
1742 ldpp_dout(dpp
, 10) << "WARNING: store->list_zones() returned r=" << r
<< dendl
;
1745 set
<rgw_pool
> pools
;
1746 r
= get_zones_pool_set(dpp
, cct
, sysobj_svc
, zones
, id
, pools
, y
);
1748 ldpp_dout(dpp
, 0) << "Error: get_zones_pool_names" << r
<< dendl
;
1752 domain_root
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:root", domain_root
);
1753 control_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.control", control_pool
);
1754 gc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:gc", gc_pool
);
1755 lc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:lc", lc_pool
);
1756 log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log", log_pool
);
1757 intent_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:intent", intent_log_pool
);
1758 usage_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:usage", usage_log_pool
);
1759 user_keys_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.keys", user_keys_pool
);
1760 user_email_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.email", user_email_pool
);
1761 user_swift_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.swift", user_swift_pool
);
1762 user_uid_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.uid", user_uid_pool
);
1763 roles_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:roles", roles_pool
);
1764 reshard_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:reshard", reshard_pool
);
1765 otp_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.otp", otp_pool
);
1766 oidc_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:oidc", oidc_pool
);
1767 notif_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:notif", notif_pool
);
1769 for(auto& iter
: placement_pools
) {
1770 iter
.second
.index_pool
= fix_zone_pool_dup(pools
, name
, "." + default_bucket_index_pool_suffix
,
1771 iter
.second
.index_pool
);
1772 for (auto& pi
: iter
.second
.storage_classes
.get_all()) {
1773 if (pi
.second
.data_pool
) {
1774 rgw_pool
& pool
= pi
.second
.data_pool
.get();
1775 pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_pool_suffix
,
1779 iter
.second
.data_extra_pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_extra_pool_suffix
,
1780 iter
.second
.data_extra_pool
);
1786 int RGWZoneParams::create(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1788 /* check for old pools config */
1789 rgw_raw_obj
obj(domain_root
, avail_pools
);
1790 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1791 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, obj
);
1792 int r
= sysobj
.rop().stat(y
, dpp
);
1794 ldpp_dout(dpp
, 10) << "couldn't find old data placement pools config, setting up new ones for the zone" << dendl
;
1795 /* a new system, let's set new placement info */
1796 RGWZonePlacementInfo default_placement
;
1797 default_placement
.index_pool
= name
+ "." + default_bucket_index_pool_suffix
;
1798 rgw_pool pool
= name
+ "." + default_storage_pool_suffix
;
1799 default_placement
.storage_classes
.set_storage_class(RGW_STORAGE_CLASS_STANDARD
, &pool
, nullptr);
1800 default_placement
.data_extra_pool
= name
+ "." + default_storage_extra_pool_suffix
;
1801 placement_pools
["default-placement"] = default_placement
;
1804 r
= fix_pool_names(dpp
, y
);
1806 ldpp_dout(dpp
, 0) << "ERROR: fix_pool_names returned r=" << r
<< dendl
;
1810 r
= RGWSystemMetaObj::create(dpp
, y
, exclusive
);
1815 // try to set as default. may race with another create, so pass exclusive=true
1816 // so we don't override an existing default
1817 r
= set_as_default(dpp
, y
, true);
1818 if (r
< 0 && r
!= -EEXIST
) {
1819 ldpp_dout(dpp
, 10) << "WARNING: failed to set zone as default, r=" << r
<< dendl
;
1825 rgw_pool
RGWZoneParams::get_pool(CephContext
*cct
) const
1827 if (cct
->_conf
->rgw_zone_root_pool
.empty()) {
1828 return rgw_pool(RGW_DEFAULT_ZONE_ROOT_POOL
);
1831 return rgw_pool(cct
->_conf
->rgw_zone_root_pool
);
1834 const string
RGWZoneParams::get_default_oid(bool old_format
) const
1837 return cct
->_conf
->rgw_default_zone_info_oid
;
1840 return cct
->_conf
->rgw_default_zone_info_oid
+ "." + realm_id
;
1843 const string
& RGWZoneParams::get_names_oid_prefix() const
1845 return zone_names_oid_prefix
;
1848 const string
& RGWZoneParams::get_info_oid_prefix(bool old_format
) const
1850 return zone_info_oid_prefix
;
1853 string
RGWZoneParams::get_predefined_id(CephContext
*cct
) const {
1854 return cct
->_conf
.get_val
<string
>("rgw_zone_id");
1857 const string
& RGWZoneParams::get_predefined_name(CephContext
*cct
) const {
1858 return cct
->_conf
->rgw_zone
;
1861 int RGWZoneParams::init(const DoutPrefixProvider
*dpp
,
1862 CephContext
*cct
, RGWSI_SysObj
*sysobj_svc
,
1863 optional_yield y
, bool setup_obj
, bool old_format
)
1866 name
= cct
->_conf
->rgw_zone
;
1869 return RGWSystemMetaObj::init(dpp
, cct
, sysobj_svc
, y
, setup_obj
, old_format
);
1872 int RGWZoneParams::read_default_id(const DoutPrefixProvider
*dpp
, string
& default_id
, optional_yield y
,
1875 if (realm_id
.empty()) {
1876 /* try using default realm */
1878 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
1879 //no default realm exist
1881 return read_id(dpp
, default_zone_name
, default_id
, y
);
1883 realm_id
= realm
.get_id();
1886 return RGWSystemMetaObj::read_default_id(dpp
, default_id
, y
, old_format
);
1890 int RGWZoneParams::set_as_default(const DoutPrefixProvider
*dpp
, optional_yield y
, bool exclusive
)
1892 if (realm_id
.empty()) {
1893 /* try using default realm */
1895 int ret
= realm
.init(dpp
, cct
, sysobj_svc
, y
);
1897 ldpp_dout(dpp
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
1900 realm_id
= realm
.get_id();
1903 return RGWSystemMetaObj::set_as_default(dpp
, y
, exclusive
);
1906 const string
& RGWZoneParams::get_compression_type(const rgw_placement_rule
& placement_rule
) const
1908 static const std::string NONE
{"none"};
1909 auto p
= placement_pools
.find(placement_rule
.name
);
1910 if (p
== placement_pools
.end()) {
1913 const auto& type
= p
->second
.get_compression_type(placement_rule
.get_storage_class());
1914 return !type
.empty() ? type
: NONE
;
1917 void RGWPeriodMap::encode(bufferlist
& bl
) const {
1918 ENCODE_START(2, 1, bl
);
1920 encode(zonegroups
, bl
);
1921 encode(master_zonegroup
, bl
);
1922 encode(short_zone_ids
, bl
);
1926 void RGWPeriodMap::decode(bufferlist::const_iterator
& bl
) {
1927 DECODE_START(2, bl
);
1929 decode(zonegroups
, bl
);
1930 decode(master_zonegroup
, bl
);
1931 if (struct_v
>= 2) {
1932 decode(short_zone_ids
, bl
);
1936 zonegroups_by_api
.clear();
1937 for (map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.begin();
1938 iter
!= zonegroups
.end(); ++iter
) {
1939 RGWZoneGroup
& zonegroup
= iter
->second
;
1940 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1941 if (zonegroup
.is_master_zonegroup()) {
1942 master_zonegroup
= zonegroup
.get_id();
1947 // run an MD5 hash on the zone_id and return the first 32 bits
1948 static uint32_t gen_short_zone_id(const std::string zone_id
)
1950 unsigned char md5
[CEPH_CRYPTO_MD5_DIGESTSIZE
];
1952 // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes
1953 hash
.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
);
1954 hash
.Update((const unsigned char *)zone_id
.c_str(), zone_id
.size());
1958 memcpy((char *)&short_id
, md5
, sizeof(short_id
));
1959 return std::max(short_id
, 1u);
1962 int RGWPeriodMap::update(const RGWZoneGroup
& zonegroup
, CephContext
*cct
)
1964 if (zonegroup
.is_master_zonegroup() && (!master_zonegroup
.empty() && zonegroup
.get_id() != master_zonegroup
)) {
1965 ldout(cct
,0) << "Error updating periodmap, multiple master zonegroups configured "<< dendl
;
1966 ldout(cct
,0) << "master zonegroup: " << master_zonegroup
<< " and " << zonegroup
.get_id() <<dendl
;
1969 map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.find(zonegroup
.get_id());
1970 if (iter
!= zonegroups
.end()) {
1971 RGWZoneGroup
& old_zonegroup
= iter
->second
;
1972 if (!old_zonegroup
.api_name
.empty()) {
1973 zonegroups_by_api
.erase(old_zonegroup
.api_name
);
1976 zonegroups
[zonegroup
.get_id()] = zonegroup
;
1978 if (!zonegroup
.api_name
.empty()) {
1979 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1982 if (zonegroup
.is_master_zonegroup()) {
1983 master_zonegroup
= zonegroup
.get_id();
1984 } else if (master_zonegroup
== zonegroup
.get_id()) {
1985 master_zonegroup
= "";
1988 for (auto& i
: zonegroup
.zones
) {
1989 auto& zone
= i
.second
;
1990 if (short_zone_ids
.find(zone
.id
) != short_zone_ids
.end()) {
1993 // calculate the zone's short id
1994 uint32_t short_id
= gen_short_zone_id(zone
.id
);
1996 // search for an existing zone with the same short id
1997 for (auto& s
: short_zone_ids
) {
1998 if (s
.second
== short_id
) {
1999 ldout(cct
, 0) << "New zone '" << zone
.name
<< "' (" << zone
.id
2000 << ") generates the same short_zone_id " << short_id
2001 << " as existing zone id " << s
.first
<< dendl
;
2006 short_zone_ids
[zone
.id
] = short_id
;
2012 uint32_t RGWPeriodMap::get_zone_short_id(const string
& zone_id
) const
2014 auto i
= short_zone_ids
.find(zone_id
);
2015 if (i
== short_zone_ids
.end()) {
2021 bool RGWPeriodMap::find_zone_by_id(const rgw_zone_id
& zone_id
,
2022 RGWZoneGroup
*zonegroup
,
2023 RGWZone
*zone
) const
2025 for (auto& iter
: zonegroups
) {
2026 auto& zg
= iter
.second
;
2028 auto ziter
= zg
.zones
.find(zone_id
);
2029 if (ziter
!= zg
.zones
.end()) {
2031 *zone
= ziter
->second
;
2039 bool RGWPeriodMap::find_zone_by_name(const string
& zone_name
,
2040 RGWZoneGroup
*zonegroup
,
2041 RGWZone
*zone
) const
2043 for (auto& iter
: zonegroups
) {
2044 auto& zg
= iter
.second
;
2045 for (auto& ziter
: zg
.zones
) {
2046 auto& z
= ziter
.second
;
2048 if (z
.name
== zone_name
) {
2059 int RGWZoneGroupMap::read(const DoutPrefixProvider
*dpp
, CephContext
*cct
, RGWSI_SysObj
*sysobj_svc
, optional_yield y
)
2063 int ret
= period
.init(dpp
, cct
, sysobj_svc
, y
);
2065 cerr
<< "failed to read current period info: " << cpp_strerror(ret
);
2069 bucket_quota
= period
.get_config().bucket_quota
;
2070 user_quota
= period
.get_config().user_quota
;
2071 zonegroups
= period
.get_map().zonegroups
;
2072 zonegroups_by_api
= period
.get_map().zonegroups_by_api
;
2073 master_zonegroup
= period
.get_map().master_zonegroup
;
2078 void RGWRegionMap::encode(bufferlist
& bl
) const {
2079 ENCODE_START( 3, 1, bl
);
2080 encode(regions
, bl
);
2081 encode(master_region
, bl
);
2082 encode(bucket_quota
, bl
);
2083 encode(user_quota
, bl
);
2087 void RGWRegionMap::decode(bufferlist::const_iterator
& bl
) {
2088 DECODE_START(3, bl
);
2089 decode(regions
, bl
);
2090 decode(master_region
, bl
);
2092 decode(bucket_quota
, bl
);
2094 decode(user_quota
, bl
);
2098 void RGWZoneGroupMap::encode(bufferlist
& bl
) const {
2099 ENCODE_START( 3, 1, bl
);
2100 encode(zonegroups
, bl
);
2101 encode(master_zonegroup
, bl
);
2102 encode(bucket_quota
, bl
);
2103 encode(user_quota
, bl
);
2107 void RGWZoneGroupMap::decode(bufferlist::const_iterator
& bl
) {
2108 DECODE_START(3, bl
);
2109 decode(zonegroups
, bl
);
2110 decode(master_zonegroup
, bl
);
2112 decode(bucket_quota
, bl
);
2114 decode(user_quota
, bl
);
2117 zonegroups_by_api
.clear();
2118 for (map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.begin();
2119 iter
!= zonegroups
.end(); ++iter
) {
2120 RGWZoneGroup
& zonegroup
= iter
->second
;
2121 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
2122 if (zonegroup
.is_master_zonegroup()) {
2123 master_zonegroup
= zonegroup
.get_name();
2128 static inline int conf_to_uint64(const JSONFormattable
& config
, const string
& key
, uint64_t *pval
)
2131 if (config
.find(key
, &sval
)) {
2133 uint64_t val
= strict_strtoll(sval
.c_str(), 10, &err
);
2142 int RGWZoneGroupPlacementTier::update_params(const JSONFormattable
& config
)
2146 if (config
.exists("retain_head_object")) {
2147 string s
= config
["retain_head_object"];
2149 retain_head_object
= true;
2151 retain_head_object
= false;
2155 if (tier_type
== "cloud-s3") {
2156 r
= t
.s3
.update_params(config
);
2162 void RGWZoneGroupPlacementTier::dump(Formatter
*f
) const
2164 encode_json("tier_type", tier_type
, f
);
2165 encode_json("storage_class", storage_class
, f
);
2166 encode_json("retain_head_object", retain_head_object
, f
);
2168 if (tier_type
== "cloud-s3") {
2169 encode_json("s3", t
.s3
, f
);
2173 void RGWZoneGroupPlacementTier::decode_json(JSONObj
*obj
)
2175 JSONDecoder::decode_json("tier_type", tier_type
, obj
);
2176 JSONDecoder::decode_json("storage_class", storage_class
, obj
);
2177 JSONDecoder::decode_json("retain_head_object", retain_head_object
, obj
);
2179 if (tier_type
== "cloud-s3") {
2180 JSONDecoder::decode_json("s3", t
.s3
, obj
);
2184 int RGWZoneGroupPlacementTier::clear_params(const JSONFormattable
& config
)
2186 if (config
.exists("retain_head_object")) {
2187 retain_head_object
= false;
2190 if (tier_type
== "cloud-s3") {
2191 t
.s3
.clear_params(config
);
2197 int RGWZoneGroupPlacementTierS3::update_params(const JSONFormattable
& config
)
2201 if (config
.exists("endpoint")) {
2202 endpoint
= config
["endpoint"];
2204 if (config
.exists("target_path")) {
2205 target_path
= config
["target_path"];
2207 if (config
.exists("region")) {
2208 region
= config
["region"];
2210 if (config
.exists("host_style")) {
2212 s
= config
["host_style"];
2213 if (s
!= "virtual") {
2214 host_style
= PathStyle
;
2216 host_style
= VirtualStyle
;
2219 if (config
.exists("target_storage_class")) {
2220 target_storage_class
= config
["target_storage_class"];
2222 if (config
.exists("access_key")) {
2223 key
.id
= config
["access_key"];
2225 if (config
.exists("secret")) {
2226 key
.key
= config
["secret"];
2228 if (config
.exists("multipart_sync_threshold")) {
2229 r
= conf_to_uint64(config
, "multipart_sync_threshold", &multipart_sync_threshold
);
2231 multipart_sync_threshold
= DEFAULT_MULTIPART_SYNC_PART_SIZE
;
2235 if (config
.exists("multipart_min_part_size")) {
2236 r
= conf_to_uint64(config
, "multipart_min_part_size", &multipart_min_part_size
);
2238 multipart_min_part_size
= DEFAULT_MULTIPART_SYNC_PART_SIZE
;
2242 if (config
.exists("acls")) {
2243 const JSONFormattable
& cc
= config
["acls"];
2244 if (cc
.is_array()) {
2245 for (auto& c
: cc
.array()) {
2246 RGWTierACLMapping m
;
2248 if (!m
.source_id
.empty()) {
2249 acl_mappings
[m
.source_id
] = m
;
2253 RGWTierACLMapping m
;
2255 if (!m
.source_id
.empty()) {
2256 acl_mappings
[m
.source_id
] = m
;
2263 void RGWZoneGroupPlacementTierS3::dump(Formatter
*f
) const
2265 encode_json("endpoint", endpoint
, f
);
2266 encode_json("access_key", key
.id
, f
);
2267 encode_json("secret", key
.key
, f
);
2268 encode_json("region", region
, f
);
2269 string s
= (host_style
== PathStyle
? "path" : "virtual");
2270 encode_json("host_style", s
, f
);
2271 encode_json("target_storage_class", target_storage_class
, f
);
2272 encode_json("target_path", target_path
, f
);
2273 encode_json("acl_mappings", acl_mappings
, f
);
2274 encode_json("multipart_sync_threshold", multipart_sync_threshold
, f
);
2275 encode_json("multipart_min_part_size", multipart_min_part_size
, f
);
2278 void RGWZoneGroupPlacementTierS3::decode_json(JSONObj
*obj
)
2280 JSONDecoder::decode_json("endpoint", endpoint
, obj
);
2281 JSONDecoder::decode_json("access_key", key
.id
, obj
);
2282 JSONDecoder::decode_json("secret", key
.key
, obj
);
2283 JSONDecoder::decode_json("region", region
, obj
);
2285 JSONDecoder::decode_json("host_style", s
, obj
);
2286 if (s
!= "virtual") {
2287 host_style
= PathStyle
;
2289 host_style
= VirtualStyle
;
2291 JSONDecoder::decode_json("target_storage_class", target_storage_class
, obj
);
2292 JSONDecoder::decode_json("target_path", target_path
, obj
);
2293 JSONDecoder::decode_json("acl_mappings", acl_mappings
, obj
);
2294 JSONDecoder::decode_json("multipart_sync_threshold", multipart_sync_threshold
, obj
);
2295 JSONDecoder::decode_json("multipart_min_part_size", multipart_min_part_size
, obj
);
2298 int RGWZoneGroupPlacementTierS3::clear_params(const JSONFormattable
& config
)
2300 if (config
.exists("endpoint")) {
2303 if (config
.exists("target_path")) {
2304 target_path
.clear();
2306 if (config
.exists("region")) {
2309 if (config
.exists("host_style")) {
2311 host_style
= PathStyle
;
2313 if (config
.exists("target_storage_class")) {
2314 target_storage_class
.clear();
2316 if (config
.exists("access_key")) {
2319 if (config
.exists("secret")) {
2322 if (config
.exists("multipart_sync_threshold")) {
2323 multipart_sync_threshold
= DEFAULT_MULTIPART_SYNC_PART_SIZE
;
2325 if (config
.exists("multipart_min_part_size")) {
2326 multipart_min_part_size
= DEFAULT_MULTIPART_SYNC_PART_SIZE
;
2328 if (config
.exists("acls")) {
2329 const JSONFormattable
& cc
= config
["acls"];
2330 if (cc
.is_array()) {
2331 for (auto& c
: cc
.array()) {
2332 RGWTierACLMapping m
;
2334 acl_mappings
.erase(m
.source_id
);
2337 RGWTierACLMapping m
;
2339 acl_mappings
.erase(m
.source_id
);
2345 void RGWZoneGroupPlacementTarget::dump(Formatter
*f
) const
2347 encode_json("name", name
, f
);
2348 encode_json("tags", tags
, f
);
2349 encode_json("storage_classes", storage_classes
, f
);
2350 if (!tier_targets
.empty()) {
2351 encode_json("tier_targets", tier_targets
, f
);
2355 void RGWZoneGroupPlacementTarget::decode_json(JSONObj
*obj
)
2357 JSONDecoder::decode_json("name", name
, obj
);
2358 JSONDecoder::decode_json("tags", tags
, obj
);
2359 JSONDecoder::decode_json("storage_classes", storage_classes
, obj
);
2360 if (storage_classes
.empty()) {
2361 storage_classes
.insert(RGW_STORAGE_CLASS_STANDARD
);
2363 if (!tier_targets
.empty()) {
2364 JSONDecoder::decode_json("tier_targets", tier_targets
, obj
);
2368 void RGWZoneGroup::dump(Formatter
*f
) const
2370 RGWSystemMetaObj::dump(f
);
2371 encode_json("api_name", api_name
, f
);
2372 encode_json("is_master", is_master
, f
);
2373 encode_json("endpoints", endpoints
, f
);
2374 encode_json("hostnames", hostnames
, f
);
2375 encode_json("hostnames_s3website", hostnames_s3website
, f
);
2376 encode_json("master_zone", master_zone
, f
);
2377 encode_json_map("zones", zones
, f
); /* more friendly representation */
2378 encode_json_map("placement_targets", placement_targets
, f
); /* more friendly representation */
2379 encode_json("default_placement", default_placement
, f
);
2380 encode_json("realm_id", realm_id
, f
);
2381 encode_json("sync_policy", sync_policy
, f
);
2384 static void decode_zones(map
<rgw_zone_id
, RGWZone
>& zones
, JSONObj
*o
)
2391 static void decode_placement_targets(map
<string
, RGWZoneGroupPlacementTarget
>& targets
, JSONObj
*o
)
2393 RGWZoneGroupPlacementTarget t
;
2395 targets
[t
.name
] = t
;
2398 static void decode_zonegroups(map
<string
, RGWZoneGroup
>& zonegroups
, JSONObj
*o
)
2402 zonegroups
[zg
.get_id()] = zg
;
2405 void RGWZoneGroup::decode_json(JSONObj
*obj
)
2407 RGWSystemMetaObj::decode_json(obj
);
2409 derr
<< "old format " << dendl
;
2410 JSONDecoder::decode_json("name", name
, obj
);
2413 JSONDecoder::decode_json("api_name", api_name
, obj
);
2414 JSONDecoder::decode_json("is_master", is_master
, obj
);
2415 JSONDecoder::decode_json("endpoints", endpoints
, obj
);
2416 JSONDecoder::decode_json("hostnames", hostnames
, obj
);
2417 JSONDecoder::decode_json("hostnames_s3website", hostnames_s3website
, obj
);
2418 JSONDecoder::decode_json("master_zone", master_zone
, obj
);
2419 JSONDecoder::decode_json("zones", zones
, decode_zones
, obj
);
2420 JSONDecoder::decode_json("placement_targets", placement_targets
, decode_placement_targets
, obj
);
2422 JSONDecoder::decode_json("default_placement", pr
, obj
);
2423 default_placement
.from_str(pr
);
2424 JSONDecoder::decode_json("realm_id", realm_id
, obj
);
2425 JSONDecoder::decode_json("sync_policy", sync_policy
, obj
);
2428 void rgw_meta_sync_info::generate_test_instances(list
<rgw_meta_sync_info
*>& o
)
2430 auto info
= new rgw_meta_sync_info
;
2431 info
->state
= rgw_meta_sync_info::StateBuildingFullSyncMaps
;
2432 info
->period
= "periodid";
2433 info
->realm_epoch
= 5;
2435 o
.push_back(new rgw_meta_sync_info
);
2438 void rgw_meta_sync_marker::generate_test_instances(list
<rgw_meta_sync_marker
*>& o
)
2440 auto marker
= new rgw_meta_sync_marker
;
2441 marker
->state
= rgw_meta_sync_marker::IncrementalSync
;
2442 marker
->marker
= "01234";
2443 marker
->realm_epoch
= 5;
2444 o
.push_back(marker
);
2445 o
.push_back(new rgw_meta_sync_marker
);
2448 void rgw_meta_sync_status::generate_test_instances(list
<rgw_meta_sync_status
*>& o
)
2450 o
.push_back(new rgw_meta_sync_status
);
2453 void RGWZoneParams::generate_test_instances(list
<RGWZoneParams
*> &o
)
2455 o
.push_back(new RGWZoneParams
);
2456 o
.push_back(new RGWZoneParams
);
2459 void RGWPeriodLatestEpochInfo::generate_test_instances(list
<RGWPeriodLatestEpochInfo
*> &o
)
2461 RGWPeriodLatestEpochInfo
*z
= new RGWPeriodLatestEpochInfo
;
2463 o
.push_back(new RGWPeriodLatestEpochInfo
);
2466 void RGWRealm::generate_test_instances(list
<RGWRealm
*> &o
)
2468 RGWRealm
*z
= new RGWRealm
;
2470 o
.push_back(new RGWRealm
);
2473 void RGWRealm::dump(Formatter
*f
) const
2475 RGWSystemMetaObj::dump(f
);
2476 encode_json("current_period", current_period
, f
);
2477 encode_json("epoch", epoch
, f
);
2481 void RGWRealm::decode_json(JSONObj
*obj
)
2483 RGWSystemMetaObj::decode_json(obj
);
2484 JSONDecoder::decode_json("current_period", current_period
, obj
);
2485 JSONDecoder::decode_json("epoch", epoch
, obj
);
2488 void RGWZoneGroup::generate_test_instances(list
<RGWZoneGroup
*>& o
)
2490 RGWZoneGroup
*r
= new RGWZoneGroup
;
2492 o
.push_back(new RGWZoneGroup
);
2495 void RGWZone::generate_test_instances(list
<RGWZone
*> &o
)
2497 RGWZone
*z
= new RGWZone
;
2499 o
.push_back(new RGWZone
);
2502 void RGWPeriod::generate_test_instances(list
<RGWPeriod
*> &o
)
2504 RGWPeriod
*z
= new RGWPeriod
;
2506 o
.push_back(new RGWPeriod
);
2509 void RGWPeriodLatestEpochInfo::dump(Formatter
*f
) const {
2510 encode_json("latest_epoch", epoch
, f
);
2513 void RGWPeriodLatestEpochInfo::decode_json(JSONObj
*obj
) {
2514 JSONDecoder::decode_json("latest_epoch", epoch
, obj
);
2517 void RGWPeriod::dump(Formatter
*f
) const
2519 encode_json("id", id
, f
);
2520 encode_json("epoch", epoch
, f
);
2521 encode_json("predecessor_uuid", predecessor_uuid
, f
);
2522 encode_json("sync_status", sync_status
, f
);
2523 encode_json("period_map", period_map
, f
);
2524 encode_json("master_zonegroup", master_zonegroup
, f
);
2525 encode_json("master_zone", master_zone
, f
);
2526 encode_json("period_config", period_config
, f
);
2527 encode_json("realm_id", realm_id
, f
);
2528 encode_json("realm_name", realm_name
, f
);
2529 encode_json("realm_epoch", realm_epoch
, f
);
2532 void RGWPeriod::decode_json(JSONObj
*obj
)
2534 JSONDecoder::decode_json("id", id
, obj
);
2535 JSONDecoder::decode_json("epoch", epoch
, obj
);
2536 JSONDecoder::decode_json("predecessor_uuid", predecessor_uuid
, obj
);
2537 JSONDecoder::decode_json("sync_status", sync_status
, obj
);
2538 JSONDecoder::decode_json("period_map", period_map
, obj
);
2539 JSONDecoder::decode_json("master_zonegroup", master_zonegroup
, obj
);
2540 JSONDecoder::decode_json("master_zone", master_zone
, obj
);
2541 JSONDecoder::decode_json("period_config", period_config
, obj
);
2542 JSONDecoder::decode_json("realm_id", realm_id
, obj
);
2543 JSONDecoder::decode_json("realm_name", realm_name
, obj
);
2544 JSONDecoder::decode_json("realm_epoch", realm_epoch
, obj
);
2547 void RGWNameToId::dump(Formatter
*f
) const {
2548 encode_json("obj_id", obj_id
, f
);
2551 void RGWNameToId::decode_json(JSONObj
*obj
) {
2552 JSONDecoder::decode_json("obj_id", obj_id
, obj
);
2555 void RGWSystemMetaObj::dump(Formatter
*f
) const
2557 encode_json("id", id
, f
);
2558 encode_json("name", name
, f
);
2561 void RGWSystemMetaObj::decode_json(JSONObj
*obj
)
2563 JSONDecoder::decode_json("id", id
, obj
);
2564 JSONDecoder::decode_json("name", name
, obj
);
2567 void RGWZoneStorageClass::dump(Formatter
*f
) const
2570 encode_json("data_pool", data_pool
.get(), f
);
2572 if (compression_type
) {
2573 encode_json("compression_type", compression_type
.get(), f
);
2577 void RGWZoneStorageClass::decode_json(JSONObj
*obj
)
2579 JSONDecoder::decode_json("data_pool", data_pool
, obj
);
2580 JSONDecoder::decode_json("compression_type", compression_type
, obj
);
2583 void RGWZoneStorageClasses::dump(Formatter
*f
) const
2586 encode_json(i
.first
.c_str(), i
.second
, f
);
2590 void RGWZoneStorageClasses::decode_json(JSONObj
*obj
)
2593 decode_json_obj(f
, obj
);
2595 for (auto& field
: f
.object()) {
2596 JSONObj
*field_obj
= obj
->find_obj(field
.first
);
2599 decode_json_obj(m
[field
.first
], field_obj
);
2601 standard_class
= &m
[RGW_STORAGE_CLASS_STANDARD
];
2604 void RGWZonePlacementInfo::dump(Formatter
*f
) const
2606 encode_json("index_pool", index_pool
, f
);
2607 encode_json("storage_classes", storage_classes
, f
);
2608 encode_json("data_extra_pool", data_extra_pool
, f
);
2609 encode_json("index_type", (uint32_t)index_type
, f
);
2611 /* no real need for backward compatibility of compression_type and data_pool in here,
2612 * rather not clutter the output */
2615 void RGWZonePlacementInfo::decode_json(JSONObj
*obj
)
2617 JSONDecoder::decode_json("index_pool", index_pool
, obj
);
2618 JSONDecoder::decode_json("storage_classes", storage_classes
, obj
);
2619 JSONDecoder::decode_json("data_extra_pool", data_extra_pool
, obj
);
2621 JSONDecoder::decode_json("index_type", it
, obj
);
2622 index_type
= (rgw::BucketIndexType
)it
;
2624 /* backward compatibility, these are now defined in storage_classes */
2625 string standard_compression_type
;
2626 string
*pcompression
= nullptr;
2627 if (JSONDecoder::decode_json("compression", standard_compression_type
, obj
)) {
2628 pcompression
= &standard_compression_type
;
2630 rgw_pool standard_data_pool
;
2631 rgw_pool
*ppool
= nullptr;
2632 if (JSONDecoder::decode_json("data_pool", standard_data_pool
, obj
)) {
2633 ppool
= &standard_data_pool
;
2635 if (ppool
|| pcompression
) {
2636 storage_classes
.set_storage_class(RGW_STORAGE_CLASS_STANDARD
, ppool
, pcompression
);
2640 void RGWZoneParams::decode_json(JSONObj
*obj
)
2642 RGWSystemMetaObj::decode_json(obj
);
2643 JSONDecoder::decode_json("domain_root", domain_root
, obj
);
2644 JSONDecoder::decode_json("control_pool", control_pool
, obj
);
2645 JSONDecoder::decode_json("gc_pool", gc_pool
, obj
);
2646 JSONDecoder::decode_json("lc_pool", lc_pool
, obj
);
2647 JSONDecoder::decode_json("log_pool", log_pool
, obj
);
2648 JSONDecoder::decode_json("intent_log_pool", intent_log_pool
, obj
);
2649 JSONDecoder::decode_json("roles_pool", roles_pool
, obj
);
2650 JSONDecoder::decode_json("reshard_pool", reshard_pool
, obj
);
2651 JSONDecoder::decode_json("usage_log_pool", usage_log_pool
, obj
);
2652 JSONDecoder::decode_json("user_keys_pool", user_keys_pool
, obj
);
2653 JSONDecoder::decode_json("user_email_pool", user_email_pool
, obj
);
2654 JSONDecoder::decode_json("user_swift_pool", user_swift_pool
, obj
);
2655 JSONDecoder::decode_json("user_uid_pool", user_uid_pool
, obj
);
2656 JSONDecoder::decode_json("otp_pool", otp_pool
, obj
);
2657 JSONDecoder::decode_json("system_key", system_key
, obj
);
2658 JSONDecoder::decode_json("placement_pools", placement_pools
, obj
);
2659 JSONDecoder::decode_json("tier_config", tier_config
, obj
);
2660 JSONDecoder::decode_json("realm_id", realm_id
, obj
);
2661 JSONDecoder::decode_json("notif_pool", notif_pool
, obj
);
2665 void RGWZone::dump(Formatter
*f
) const
2667 encode_json("id", id
, f
);
2668 encode_json("name", name
, f
);
2669 encode_json("endpoints", endpoints
, f
);
2670 encode_json("log_meta", log_meta
, f
);
2671 encode_json("log_data", log_data
, f
);
2672 encode_json("bucket_index_max_shards", bucket_index_max_shards
, f
);
2673 encode_json("read_only", read_only
, f
);
2674 encode_json("tier_type", tier_type
, f
);
2675 encode_json("sync_from_all", sync_from_all
, f
);
2676 encode_json("sync_from", sync_from
, f
);
2677 encode_json("redirect_zone", redirect_zone
, f
);
2680 void RGWZone::decode_json(JSONObj
*obj
)
2682 JSONDecoder::decode_json("id", id
, obj
);
2683 JSONDecoder::decode_json("name", name
, obj
);
2687 JSONDecoder::decode_json("endpoints", endpoints
, obj
);
2688 JSONDecoder::decode_json("log_meta", log_meta
, obj
);
2689 JSONDecoder::decode_json("log_data", log_data
, obj
);
2690 JSONDecoder::decode_json("bucket_index_max_shards", bucket_index_max_shards
, obj
);
2691 JSONDecoder::decode_json("read_only", read_only
, obj
);
2692 JSONDecoder::decode_json("tier_type", tier_type
, obj
);
2693 JSONDecoder::decode_json("sync_from_all", sync_from_all
, true, obj
);
2694 JSONDecoder::decode_json("sync_from", sync_from
, obj
);
2695 JSONDecoder::decode_json("redirect_zone", redirect_zone
, obj
);
2698 void RGWTierACLMapping::dump(Formatter
*f
) const
2702 case ACL_TYPE_EMAIL_USER
:
2705 case ACL_TYPE_GROUP
:
2712 encode_json("type", s
, f
);
2713 encode_json("source_id", source_id
, f
);
2714 encode_json("dest_id", dest_id
, f
);
2717 void RGWTierACLMapping::decode_json(JSONObj
*obj
)
2720 JSONDecoder::decode_json("type", s
, obj
);
2722 type
= ACL_TYPE_EMAIL_USER
;
2723 } else if (s
== "uri") {
2724 type
= ACL_TYPE_GROUP
;
2726 type
= ACL_TYPE_CANON_USER
;
2729 JSONDecoder::decode_json("source_id", source_id
, obj
);
2730 JSONDecoder::decode_json("dest_id", dest_id
, obj
);
2733 void RGWPeriodMap::dump(Formatter
*f
) const
2735 encode_json("id", id
, f
);
2736 encode_json_map("zonegroups", zonegroups
, f
);
2737 encode_json("short_zone_ids", short_zone_ids
, f
);
2740 void RGWPeriodMap::decode_json(JSONObj
*obj
)
2742 JSONDecoder::decode_json("id", id
, obj
);
2743 JSONDecoder::decode_json("zonegroups", zonegroups
, decode_zonegroups
, obj
);
2744 /* backward compatability with region */
2745 if (zonegroups
.empty()) {
2746 JSONDecoder::decode_json("regions", zonegroups
, obj
);
2748 /* backward compatability with region */
2749 if (master_zonegroup
.empty()) {
2750 JSONDecoder::decode_json("master_region", master_zonegroup
, obj
);
2752 JSONDecoder::decode_json("short_zone_ids", short_zone_ids
, obj
);
2755 void RGWPeriodConfig::dump(Formatter
*f
) const
2757 encode_json("bucket_quota", bucket_quota
, f
);
2758 encode_json("user_quota", user_quota
, f
);
2759 encode_json("user_ratelimit", user_ratelimit
, f
);
2760 encode_json("bucket_ratelimit", bucket_ratelimit
, f
);
2761 encode_json("anonymous_ratelimit", anon_ratelimit
, f
);
2764 void RGWPeriodConfig::decode_json(JSONObj
*obj
)
2766 JSONDecoder::decode_json("bucket_quota", bucket_quota
, obj
);
2767 JSONDecoder::decode_json("user_quota", user_quota
, obj
);
2768 JSONDecoder::decode_json("user_ratelimit", user_ratelimit
, obj
);
2769 JSONDecoder::decode_json("bucket_ratelimit", bucket_ratelimit
, obj
);
2770 JSONDecoder::decode_json("anonymous_ratelimit", anon_ratelimit
, obj
);
2773 void RGWRegionMap::dump(Formatter
*f
) const
2775 encode_json("regions", regions
, f
);
2776 encode_json("master_region", master_region
, f
);
2777 encode_json("bucket_quota", bucket_quota
, f
);
2778 encode_json("user_quota", user_quota
, f
);
2781 void RGWRegionMap::decode_json(JSONObj
*obj
)
2783 JSONDecoder::decode_json("regions", regions
, obj
);
2784 JSONDecoder::decode_json("master_region", master_region
, obj
);
2785 JSONDecoder::decode_json("bucket_quota", bucket_quota
, obj
);
2786 JSONDecoder::decode_json("user_quota", user_quota
, obj
);
2789 void RGWZoneGroupMap::dump(Formatter
*f
) const
2791 encode_json("zonegroups", zonegroups
, f
);
2792 encode_json("master_zonegroup", master_zonegroup
, f
);
2793 encode_json("bucket_quota", bucket_quota
, f
);
2794 encode_json("user_quota", user_quota
, f
);
2797 void RGWZoneGroupMap::decode_json(JSONObj
*obj
)
2799 JSONDecoder::decode_json("zonegroups", zonegroups
, obj
);
2800 /* backward compatability with region */
2801 if (zonegroups
.empty()) {
2802 JSONDecoder::decode_json("regions", zonegroups
, obj
);
2804 JSONDecoder::decode_json("master_zonegroup", master_zonegroup
, obj
);
2805 /* backward compatability with region */
2806 if (master_zonegroup
.empty()) {
2807 JSONDecoder::decode_json("master_region", master_zonegroup
, obj
);
2810 JSONDecoder::decode_json("bucket_quota", bucket_quota
, obj
);
2811 JSONDecoder::decode_json("user_quota", user_quota
, obj
);