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 #define dout_subsys ceph_subsys_rgw
16 namespace rgw_zone_defaults
{
18 std::string zone_info_oid_prefix
= "zone_info.";
19 std::string zone_names_oid_prefix
= "zone_names.";
20 std::string region_info_oid_prefix
= "region_info.";
21 std::string realm_names_oid_prefix
= "realms_names.";
22 std::string zone_group_info_oid_prefix
= "zonegroup_info.";
23 std::string realm_info_oid_prefix
= "realms.";
24 std::string default_region_info_oid
= "default.region";
25 std::string default_zone_group_info_oid
= "default.zonegroup";
26 std::string period_info_oid_prefix
= "periods.";
27 std::string period_latest_epoch_info_oid
= ".latest_epoch";
28 std::string region_map_oid
= "region_map";
29 std::string default_realm_info_oid
= "default.realm";
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_REALM_ROOT_POOL
= "rgw.root";
36 std::string RGW_DEFAULT_PERIOD_ROOT_POOL
= "rgw.root";
37 std::string default_bucket_index_pool_suffix
= "rgw.buckets.index";
38 std::string default_storage_extra_pool_suffix
= "rgw.buckets.non-ec";
39 std::string avail_pools
= ".pools.avail";
40 std::string default_storage_pool_suffix
= "rgw.buckets.data";
44 using namespace rgw_zone_defaults
;
48 void RGWDefaultZoneGroupInfo::dump(Formatter
*f
) const {
49 encode_json("default_zonegroup", default_zonegroup
, f
);
52 void RGWDefaultZoneGroupInfo::decode_json(JSONObj
*obj
) {
54 JSONDecoder::decode_json("default_zonegroup", default_zonegroup
, obj
);
55 /* backward compatability with region */
56 if (default_zonegroup
.empty()) {
57 JSONDecoder::decode_json("default_region", default_zonegroup
, obj
);
61 rgw_pool
RGWZoneGroup::get_pool(CephContext
*cct_
) const
63 if (cct_
->_conf
->rgw_zonegroup_root_pool
.empty()) {
64 return rgw_pool(RGW_DEFAULT_ZONEGROUP_ROOT_POOL
);
67 return rgw_pool(cct_
->_conf
->rgw_zonegroup_root_pool
);
70 int RGWZoneGroup::create_default(bool old_format
)
72 name
= default_zonegroup_name
;
73 api_name
= default_zonegroup_name
;
76 RGWZoneGroupPlacementTarget placement_target
;
77 placement_target
.name
= "default-placement";
78 placement_targets
[placement_target
.name
] = placement_target
;
79 default_placement
.name
= "default-placement";
81 RGWZoneParams
zone_params(default_zone_name
);
83 int r
= zone_params
.init(cct
, sysobj_svc
, false);
85 ldout(cct
, 0) << "create_default: error initializing zone params: " << cpp_strerror(-r
) << dendl
;
89 r
= zone_params
.create_default();
90 if (r
< 0 && r
!= -EEXIST
) {
91 ldout(cct
, 0) << "create_default: error in create_default zone params: " << cpp_strerror(-r
) << dendl
;
93 } else if (r
== -EEXIST
) {
94 ldout(cct
, 10) << "zone_params::create_default() returned -EEXIST, we raced with another default zone_params creation" << dendl
;
95 zone_params
.clear_id();
96 r
= zone_params
.init(cct
, sysobj_svc
);
98 ldout(cct
, 0) << "create_default: error in init existing zone params: " << cpp_strerror(-r
) << dendl
;
101 ldout(cct
, 20) << "zone_params::create_default() " << zone_params
.get_name() << " id " << zone_params
.get_id()
105 RGWZone
& default_zone
= zones
[zone_params
.get_id()];
106 default_zone
.name
= zone_params
.get_name();
107 default_zone
.id
= zone_params
.get_id();
108 master_zone
= default_zone
.id
;
111 if (r
< 0 && r
!= -EEXIST
) {
112 ldout(cct
, 0) << "error storing zone group info: " << cpp_strerror(-r
) << dendl
;
117 ldout(cct
, 10) << "create_default() returned -EEXIST, we raced with another zonegroup creation" << dendl
;
119 r
= init(cct
, sysobj_svc
);
129 post_process_params();
134 const string
RGWZoneGroup::get_default_oid(bool old_region_format
) const
136 if (old_region_format
) {
137 if (cct
->_conf
->rgw_default_region_info_oid
.empty()) {
138 return default_region_info_oid
;
140 return cct
->_conf
->rgw_default_region_info_oid
;
143 string default_oid
= cct
->_conf
->rgw_default_zonegroup_info_oid
;
145 if (cct
->_conf
->rgw_default_zonegroup_info_oid
.empty()) {
146 default_oid
= default_zone_group_info_oid
;
149 default_oid
+= "." + realm_id
;
154 const string
& RGWZoneGroup::get_info_oid_prefix(bool old_region_format
) const
156 if (old_region_format
) {
157 return region_info_oid_prefix
;
159 return zone_group_info_oid_prefix
;
162 const string
& RGWZoneGroup::get_names_oid_prefix() const
164 return zonegroup_names_oid_prefix
;
167 const string
& RGWZoneGroup::get_predefined_name(CephContext
*cct
) const {
168 return cct
->_conf
->rgw_zonegroup
;
171 int RGWZoneGroup::equals(const string
& other_zonegroup
) const
173 if (is_master
&& other_zonegroup
.empty())
176 return (id
== other_zonegroup
);
179 int RGWZoneGroup::add_zone(const RGWZoneParams
& zone_params
, bool *is_master
, bool *read_only
,
180 const list
<string
>& endpoints
, const string
*ptier_type
,
181 bool *psync_from_all
, list
<string
>& sync_from
, list
<string
>& sync_from_rm
,
182 string
*predirect_zone
, std::optional
<int> bucket_index_max_shards
,
183 RGWSyncModulesManager
*sync_mgr
)
185 auto& zone_id
= zone_params
.get_id();
186 auto& zone_name
= zone_params
.get_name();
188 // check for duplicate zone name on insert
189 if (!zones
.count(zone_id
)) {
190 for (const auto& zone
: zones
) {
191 if (zone
.second
.name
== zone_name
) {
192 ldout(cct
, 0) << "ERROR: found existing zone name " << zone_name
193 << " (" << zone
.first
<< ") in zonegroup " << get_name() << dendl
;
201 if (!master_zone
.empty() && master_zone
!= zone_id
) {
202 ldout(cct
, 0) << "NOTICE: overriding master zone: " << master_zone
<< dendl
;
204 master_zone
= zone_id
;
205 } else if (master_zone
== zone_id
) {
210 RGWZone
& zone
= zones
[zone_id
];
211 zone
.name
= zone_name
;
213 if (!endpoints
.empty()) {
214 zone
.endpoints
= endpoints
;
217 zone
.read_only
= *read_only
;
220 zone
.tier_type
= *ptier_type
;
221 if (!sync_mgr
->get_module(*ptier_type
, nullptr)) {
222 ldout(cct
, 0) << "ERROR: could not found sync module: " << *ptier_type
223 << ", valid sync modules: "
224 << sync_mgr
->get_registered_module_names()
230 if (psync_from_all
) {
231 zone
.sync_from_all
= *psync_from_all
;
234 if (predirect_zone
) {
235 zone
.redirect_zone
= *predirect_zone
;
238 if (bucket_index_max_shards
) {
239 zone
.bucket_index_max_shards
= *bucket_index_max_shards
;
242 for (auto add
: sync_from
) {
243 zone
.sync_from
.insert(add
);
246 for (auto rm
: sync_from_rm
) {
247 zone
.sync_from
.erase(rm
);
250 post_process_params();
256 int RGWZoneGroup::rename_zone(const RGWZoneParams
& zone_params
)
258 RGWZone
& zone
= zones
[zone_params
.get_id()];
259 zone
.name
= zone_params
.get_name();
264 void RGWZoneGroup::post_process_params()
266 bool log_data
= zones
.size() > 1;
268 if (master_zone
.empty()) {
269 auto iter
= zones
.begin();
270 if (iter
!= zones
.end()) {
271 master_zone
= iter
->first
;
275 for (auto& item
: zones
) {
276 RGWZone
& zone
= item
.second
;
277 zone
.log_data
= log_data
;
279 RGWZoneParams
zone_params(zone
.id
, zone
.name
);
280 int ret
= zone_params
.init(cct
, sysobj_svc
);
282 ldout(cct
, 0) << "WARNING: could not read zone params for zone id=" << zone
.id
<< " name=" << zone
.name
<< dendl
;
286 for (auto& pitem
: zone_params
.placement_pools
) {
287 const string
& placement_name
= pitem
.first
;
288 if (placement_targets
.find(placement_name
) == placement_targets
.end()) {
289 RGWZoneGroupPlacementTarget placement_target
;
290 placement_target
.name
= placement_name
;
291 placement_targets
[placement_name
] = placement_target
;
296 if (default_placement
.empty() && !placement_targets
.empty()) {
297 default_placement
.init(placement_targets
.begin()->first
, RGW_STORAGE_CLASS_STANDARD
);
301 int RGWZoneGroup::remove_zone(const std::string
& zone_id
)
303 auto iter
= zones
.find(zone_id
);
304 if (iter
== zones
.end()) {
305 ldout(cct
, 0) << "zone id " << zone_id
<< " is not a part of zonegroup "
312 post_process_params();
317 int RGWZoneGroup::read_default_id(string
& default_id
, bool old_format
)
319 if (realm_id
.empty()) {
320 /* try using default realm */
322 int ret
= realm
.init(cct
, sysobj_svc
);
323 // no default realm exist
325 return read_id(default_zonegroup_name
, default_id
);
327 realm_id
= realm
.get_id();
330 return RGWSystemMetaObj::read_default_id(default_id
, old_format
);
333 int RGWZoneGroup::set_as_default(bool exclusive
)
335 if (realm_id
.empty()) {
336 /* try using default realm */
338 int ret
= realm
.init(cct
, sysobj_svc
);
340 ldout(cct
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
343 realm_id
= realm
.get_id();
346 return RGWSystemMetaObj::set_as_default(exclusive
);
349 void RGWSystemMetaObj::reinit_instance(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
)
352 sysobj_svc
= _sysobj_svc
;
353 zone_svc
= _sysobj_svc
->get_zone_svc();
356 int RGWSystemMetaObj::init(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
, bool setup_obj
, bool old_format
)
358 reinit_instance(_cct
, _sysobj_svc
);
363 if (old_format
&& id
.empty()) {
370 name
= get_predefined_name(cct
);
373 r
= use_default(old_format
);
377 } else if (!old_format
) {
378 r
= read_id(name
, id
);
381 ldout(cct
, 0) << "error in read_id for object name: " << name
<< " : " << cpp_strerror(-r
) << dendl
;
388 return read_info(id
, old_format
);
391 int RGWSystemMetaObj::read_default(RGWDefaultSystemMetaObjInfo
& default_info
, const string
& oid
)
394 auto pool
= get_pool(cct
);
397 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
398 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
399 int ret
= sysobj
.rop().read(&bl
, null_yield
);
404 auto iter
= bl
.cbegin();
405 decode(default_info
, iter
);
406 } catch (buffer::error
& err
) {
407 ldout(cct
, 0) << "error decoding data from " << pool
<< ":" << oid
<< dendl
;
414 int RGWSystemMetaObj::read_default_id(string
& default_id
, bool old_format
)
416 RGWDefaultSystemMetaObjInfo default_info
;
418 int ret
= read_default(default_info
, get_default_oid(old_format
));
423 default_id
= default_info
.default_id
;
428 int RGWSystemMetaObj::use_default(bool old_format
)
430 return read_default_id(id
, old_format
);
433 int RGWSystemMetaObj::set_as_default(bool exclusive
)
436 string oid
= get_default_oid();
438 rgw_pool
pool(get_pool(cct
));
441 RGWDefaultSystemMetaObjInfo default_info
;
442 default_info
.default_id
= id
;
444 encode(default_info
, bl
);
446 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
447 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
448 int ret
= sysobj
.wop()
449 .set_exclusive(exclusive
)
450 .write(bl
, null_yield
);
457 int RGWSystemMetaObj::read_id(const string
& obj_name
, string
& object_id
)
460 rgw_pool
pool(get_pool(cct
));
463 string oid
= get_names_oid_prefix() + obj_name
;
465 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
466 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
467 int ret
= sysobj
.rop().read(&bl
, null_yield
);
472 RGWNameToId nameToId
;
474 auto iter
= bl
.cbegin();
475 decode(nameToId
, iter
);
476 } catch (buffer::error
& err
) {
477 ldout(cct
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
480 object_id
= nameToId
.obj_id
;
484 int RGWSystemMetaObj::delete_obj(bool old_format
)
486 rgw_pool
pool(get_pool(cct
));
488 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
490 /* check to see if obj is the default */
491 RGWDefaultSystemMetaObjInfo default_info
;
492 int ret
= read_default(default_info
, get_default_oid(old_format
));
493 if (ret
< 0 && ret
!= -ENOENT
)
495 if (default_info
.default_id
== id
|| (old_format
&& default_info
.default_id
== name
)) {
496 string oid
= get_default_oid(old_format
);
497 rgw_raw_obj
default_named_obj(pool
, oid
);
498 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, default_named_obj
);
499 ret
= sysobj
.wop().remove(null_yield
);
501 ldout(cct
, 0) << "Error delete default obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
506 string oid
= get_names_oid_prefix() + name
;
507 rgw_raw_obj
object_name(pool
, oid
);
508 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, object_name
);
509 ret
= sysobj
.wop().remove(null_yield
);
511 ldout(cct
, 0) << "Error delete obj name " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
516 string oid
= get_info_oid_prefix(old_format
);
523 rgw_raw_obj
object_id(pool
, oid
);
524 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, object_id
);
525 ret
= sysobj
.wop().remove(null_yield
);
527 ldout(cct
, 0) << "Error delete object id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
533 int RGWSystemMetaObj::store_name(bool exclusive
)
535 rgw_pool
pool(get_pool(cct
));
536 string oid
= get_names_oid_prefix() + name
;
538 RGWNameToId nameToId
;
539 nameToId
.obj_id
= id
;
543 encode(nameToId
, bl
);
544 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
545 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
547 .set_exclusive(exclusive
)
548 .write(bl
, null_yield
);
551 int RGWSystemMetaObj::rename(const string
& new_name
)
554 int ret
= read_id(new_name
, new_id
);
558 if (ret
< 0 && ret
!= -ENOENT
) {
559 ldout(cct
, 0) << "Error read_id " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
562 string old_name
= name
;
566 ldout(cct
, 0) << "Error storing new obj info " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
569 ret
= store_name(true);
571 ldout(cct
, 0) << "Error storing new name " << new_name
<< ": " << cpp_strerror(-ret
) << dendl
;
574 /* delete old name */
575 rgw_pool
pool(get_pool(cct
));
576 string oid
= get_names_oid_prefix() + old_name
;
577 rgw_raw_obj
old_name_obj(pool
, oid
);
578 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
579 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, old_name_obj
);
580 ret
= sysobj
.wop().remove(null_yield
);
582 ldout(cct
, 0) << "Error delete old obj name " << old_name
<< ": " << cpp_strerror(-ret
) << dendl
;
589 int RGWSystemMetaObj::read_info(const string
& obj_id
, bool old_format
)
591 rgw_pool
pool(get_pool(cct
));
595 string oid
= get_info_oid_prefix(old_format
) + obj_id
;
597 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
598 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
599 int ret
= sysobj
.rop().read(&bl
, null_yield
);
601 ldout(cct
, 0) << "failed reading obj info from " << pool
<< ":" << oid
<< ": " << cpp_strerror(-ret
) << dendl
;
607 auto iter
= bl
.cbegin();
609 } catch (buffer::error
& err
) {
610 ldout(cct
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << oid
<< dendl
;
617 int RGWSystemMetaObj::read()
619 int ret
= read_id(name
, id
);
624 return read_info(id
);
627 int RGWSystemMetaObj::create(bool exclusive
)
631 /* check to see the name is not used */
632 ret
= read_id(name
, id
);
633 if (exclusive
&& ret
== 0) {
634 ldout(cct
, 10) << "ERROR: name " << name
<< " already in use for obj id " << id
<< dendl
;
636 } else if ( ret
< 0 && ret
!= -ENOENT
) {
637 ldout(cct
, 0) << "failed reading obj id " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
642 /* create unique id */
645 new_uuid
.generate_random();
646 new_uuid
.print(uuid_str
);
650 ret
= store_info(exclusive
);
652 ldout(cct
, 0) << "ERROR: storing info for " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
656 return store_name(exclusive
);
659 int RGWSystemMetaObj::store_info(bool exclusive
)
661 rgw_pool
pool(get_pool(cct
));
663 string oid
= get_info_oid_prefix() + id
;
668 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
669 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
671 .set_exclusive(exclusive
)
672 .write(bl
, null_yield
);
675 int RGWSystemMetaObj::write(bool exclusive
)
677 int ret
= store_info(exclusive
);
679 ldout(cct
, 20) << __func__
<< "(): store_info() returned ret=" << ret
<< dendl
;
682 ret
= store_name(exclusive
);
684 ldout(cct
, 20) << __func__
<< "(): store_name() returned ret=" << ret
<< dendl
;
691 const string
& RGWRealm::get_predefined_name(CephContext
*cct
) const {
692 return cct
->_conf
->rgw_realm
;
695 int RGWRealm::create(bool exclusive
)
697 int ret
= RGWSystemMetaObj::create(exclusive
);
699 ldout(cct
, 0) << "ERROR creating new realm object " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
702 // create the control object for watch/notify
703 ret
= create_control(exclusive
);
705 ldout(cct
, 0) << "ERROR creating control for new realm " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
709 if (current_period
.empty()) {
710 /* create new period for the realm */
711 ret
= period
.init(cct
, sysobj_svc
, id
, name
, false);
715 ret
= period
.create(true);
717 ldout(cct
, 0) << "ERROR: creating new period for realm " << name
<< ": " << cpp_strerror(-ret
) << dendl
;
721 period
= RGWPeriod(current_period
, 0);
722 int ret
= period
.init(cct
, sysobj_svc
, id
, name
);
724 ldout(cct
, 0) << "ERROR: failed to init period " << current_period
<< dendl
;
728 ret
= set_current_period(period
);
730 ldout(cct
, 0) << "ERROR: failed set current period " << current_period
<< dendl
;
733 // try to set as default. may race with another create, so pass exclusive=true
734 // so we don't override an existing default
735 ret
= set_as_default(true);
736 if (ret
< 0 && ret
!= -EEXIST
) {
737 ldout(cct
, 0) << "WARNING: failed to set realm as default realm, ret=" << ret
<< dendl
;
743 int RGWRealm::delete_obj()
745 int ret
= RGWSystemMetaObj::delete_obj();
749 return delete_control();
752 int RGWRealm::create_control(bool exclusive
)
754 auto pool
= rgw_pool
{get_pool(cct
)};
755 auto oid
= get_control_oid();
757 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
758 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
760 .set_exclusive(exclusive
)
761 .write(bl
, null_yield
);
764 int RGWRealm::delete_control()
766 auto pool
= rgw_pool
{get_pool(cct
)};
767 auto obj
= rgw_raw_obj
{pool
, get_control_oid()};
768 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
769 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, obj
);
770 return sysobj
.wop().remove(null_yield
);
773 rgw_pool
RGWRealm::get_pool(CephContext
*cct
) const
775 if (cct
->_conf
->rgw_realm_root_pool
.empty()) {
776 return rgw_pool(RGW_DEFAULT_REALM_ROOT_POOL
);
778 return rgw_pool(cct
->_conf
->rgw_realm_root_pool
);
781 const string
RGWRealm::get_default_oid(bool old_format
) const
783 if (cct
->_conf
->rgw_default_realm_info_oid
.empty()) {
784 return default_realm_info_oid
;
786 return cct
->_conf
->rgw_default_realm_info_oid
;
789 const string
& RGWRealm::get_names_oid_prefix() const
791 return realm_names_oid_prefix
;
794 const string
& RGWRealm::get_info_oid_prefix(bool old_format
) const
796 return realm_info_oid_prefix
;
799 int RGWRealm::set_current_period(RGWPeriod
& period
)
801 // update realm epoch to match the period's
802 if (epoch
> period
.get_realm_epoch()) {
803 ldout(cct
, 0) << "ERROR: set_current_period with old realm epoch "
804 << period
.get_realm_epoch() << ", current epoch=" << epoch
<< dendl
;
807 if (epoch
== period
.get_realm_epoch() && current_period
!= period
.get_id()) {
808 ldout(cct
, 0) << "ERROR: set_current_period with same realm epoch "
809 << period
.get_realm_epoch() << ", but different period id "
810 << period
.get_id() << " != " << current_period
<< dendl
;
814 epoch
= period
.get_realm_epoch();
815 current_period
= period
.get_id();
819 ldout(cct
, 0) << "ERROR: period update: " << cpp_strerror(-ret
) << dendl
;
823 ret
= period
.reflect();
825 ldout(cct
, 0) << "ERROR: period.reflect(): " << cpp_strerror(-ret
) << dendl
;
832 string
RGWRealm::get_control_oid() const
834 return get_info_oid_prefix() + id
+ ".control";
837 int RGWRealm::notify_zone(bufferlist
& bl
)
839 rgw_pool pool
{get_pool(cct
)};
840 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
841 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, get_control_oid()});
842 int ret
= sysobj
.wn().notify(bl
, 0, nullptr, null_yield
);
849 int RGWRealm::notify_new_period(const RGWPeriod
& period
)
853 // push the period to dependent zonegroups/zones
854 encode(RGWRealmNotify::ZonesNeedPeriod
, bl
);
856 // reload the gateway with the new period
857 encode(RGWRealmNotify::Reload
, bl
);
859 return notify_zone(bl
);
862 std::string
RGWPeriodConfig::get_oid(const std::string
& realm_id
)
864 if (realm_id
.empty()) {
865 return "period_config.default";
867 return "period_config." + realm_id
;
870 rgw_pool
RGWPeriodConfig::get_pool(CephContext
*cct
)
872 const auto& pool_name
= cct
->_conf
->rgw_period_root_pool
;
873 if (pool_name
.empty()) {
874 return {RGW_DEFAULT_PERIOD_ROOT_POOL
};
879 int RGWPeriodConfig::read(RGWSI_SysObj
*sysobj_svc
, const std::string
& realm_id
)
881 const auto& pool
= get_pool(sysobj_svc
->ctx());
882 const auto& oid
= get_oid(realm_id
);
885 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
886 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
887 int ret
= sysobj
.rop().read(&bl
, null_yield
);
893 auto iter
= bl
.cbegin();
895 } catch (buffer::error
& err
) {
901 int RGWPeriodConfig::write(RGWSI_SysObj
*sysobj_svc
, const std::string
& realm_id
)
903 const auto& pool
= get_pool(sysobj_svc
->ctx());
904 const auto& oid
= get_oid(realm_id
);
908 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
909 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
911 .set_exclusive(false)
912 .write(bl
, null_yield
);
915 int RGWPeriod::init(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
, const string
& period_realm_id
,
916 const string
& period_realm_name
, bool setup_obj
)
919 sysobj_svc
= _sysobj_svc
;
921 realm_id
= period_realm_id
;
922 realm_name
= period_realm_name
;
927 return init(_cct
, _sysobj_svc
, setup_obj
);
931 int RGWPeriod::init(CephContext
*_cct
, RGWSI_SysObj
*_sysobj_svc
, bool setup_obj
)
934 sysobj_svc
= _sysobj_svc
;
940 RGWRealm
realm(realm_id
, realm_name
);
941 int ret
= realm
.init(cct
, sysobj_svc
);
943 ldout(cct
, 0) << "RGWPeriod::init failed to init realm " << realm_name
<< " id " << realm_id
<< " : " <<
944 cpp_strerror(-ret
) << dendl
;
947 id
= realm
.get_current_period();
948 realm_id
= realm
.get_id();
952 int ret
= use_latest_epoch();
954 ldout(cct
, 0) << "failed to use_latest_epoch period id " << id
<< " realm " << realm_name
<< " id " << realm_id
955 << " : " << cpp_strerror(-ret
) << dendl
;
964 int RGWPeriod::get_zonegroup(RGWZoneGroup
& zonegroup
,
965 const string
& zonegroup_id
) const
967 map
<string
, RGWZoneGroup
>::const_iterator iter
;
968 if (!zonegroup_id
.empty()) {
969 iter
= period_map
.zonegroups
.find(zonegroup_id
);
971 iter
= period_map
.zonegroups
.find("default");
973 if (iter
!= period_map
.zonegroups
.end()) {
974 zonegroup
= iter
->second
;
981 const string
& RGWPeriod::get_latest_epoch_oid() const
983 if (cct
->_conf
->rgw_period_latest_epoch_info_oid
.empty()) {
984 return period_latest_epoch_info_oid
;
986 return cct
->_conf
->rgw_period_latest_epoch_info_oid
;
989 const string
& RGWPeriod::get_info_oid_prefix() const
991 return period_info_oid_prefix
;
994 const string
RGWPeriod::get_period_oid_prefix() const
996 return get_info_oid_prefix() + id
;
999 const string
RGWPeriod::get_period_oid() const
1001 std::ostringstream oss
;
1002 oss
<< get_period_oid_prefix();
1003 // skip the epoch for the staging period
1004 if (id
!= get_staging_id(realm_id
))
1005 oss
<< "." << epoch
;
1009 int RGWPeriod::read_latest_epoch(RGWPeriodLatestEpochInfo
& info
,
1010 RGWObjVersionTracker
*objv
)
1012 string oid
= get_period_oid_prefix() + get_latest_epoch_oid();
1014 rgw_pool
pool(get_pool(cct
));
1016 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1017 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, oid
});
1018 int ret
= sysobj
.rop().read(&bl
, null_yield
);
1020 ldout(cct
, 1) << "error read_lastest_epoch " << pool
<< ":" << oid
<< dendl
;
1024 auto iter
= bl
.cbegin();
1027 } catch (buffer::error
& err
) {
1028 ldout(cct
, 0) << "error decoding data from " << pool
<< ":" << oid
<< dendl
;
1035 int RGWPeriod::get_latest_epoch(epoch_t
& latest_epoch
)
1037 RGWPeriodLatestEpochInfo info
;
1039 int ret
= read_latest_epoch(info
);
1044 latest_epoch
= info
.epoch
;
1049 int RGWPeriod::use_latest_epoch()
1051 RGWPeriodLatestEpochInfo info
;
1052 int ret
= read_latest_epoch(info
);
1062 int RGWPeriod::set_latest_epoch(epoch_t epoch
, bool exclusive
,
1063 RGWObjVersionTracker
*objv
)
1065 string oid
= get_period_oid_prefix() + get_latest_epoch_oid();
1067 rgw_pool
pool(get_pool(cct
));
1070 RGWPeriodLatestEpochInfo info
;
1076 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1077 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
1079 .set_exclusive(exclusive
)
1080 .write(bl
, null_yield
);
1083 int RGWPeriod::update_latest_epoch(epoch_t epoch
)
1085 static constexpr int MAX_RETRIES
= 20;
1087 for (int i
= 0; i
< MAX_RETRIES
; i
++) {
1088 RGWPeriodLatestEpochInfo info
;
1089 RGWObjVersionTracker objv
;
1090 bool exclusive
= false;
1092 // read existing epoch
1093 int r
= read_latest_epoch(info
, &objv
);
1095 // use an exclusive create to set the epoch atomically
1097 ldout(cct
, 20) << "creating initial latest_epoch=" << epoch
1098 << " for period=" << id
<< dendl
;
1100 ldout(cct
, 0) << "ERROR: failed to read latest_epoch" << dendl
;
1102 } else if (epoch
<= info
.epoch
) {
1103 r
= -EEXIST
; // fail with EEXIST if epoch is not newer
1104 ldout(cct
, 10) << "found existing latest_epoch " << info
.epoch
1105 << " >= given epoch " << epoch
<< ", returning r=" << r
<< dendl
;
1108 ldout(cct
, 20) << "updating latest_epoch from " << info
.epoch
1109 << " -> " << epoch
<< " on period=" << id
<< dendl
;
1112 r
= set_latest_epoch(epoch
, exclusive
, &objv
);
1114 continue; // exclusive create raced with another update, retry
1115 } else if (r
== -ECANCELED
) {
1116 continue; // write raced with a conflicting version, retry
1119 ldout(cct
, 0) << "ERROR: failed to write latest_epoch" << dendl
;
1122 return 0; // return success
1125 return -ECANCELED
; // fail after max retries
1128 int RGWPeriod::delete_obj()
1130 rgw_pool
pool(get_pool(cct
));
1132 // delete the object for each period epoch
1133 for (epoch_t e
= 1; e
<= epoch
; e
++) {
1134 RGWPeriod p
{get_id(), e
};
1135 rgw_raw_obj oid
{pool
, p
.get_period_oid()};
1136 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1137 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, oid
);
1138 int ret
= sysobj
.wop().remove(null_yield
);
1140 ldout(cct
, 0) << "WARNING: failed to delete period object " << oid
1141 << ": " << cpp_strerror(-ret
) << dendl
;
1145 // delete the .latest_epoch object
1146 rgw_raw_obj oid
{pool
, get_period_oid_prefix() + get_latest_epoch_oid()};
1147 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1148 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, oid
);
1149 int ret
= sysobj
.wop().remove(null_yield
);
1151 ldout(cct
, 0) << "WARNING: failed to delete period object " << oid
1152 << ": " << cpp_strerror(-ret
) << dendl
;
1157 int RGWPeriod::read_info()
1159 rgw_pool
pool(get_pool(cct
));
1163 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1164 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj
{pool
, get_period_oid()});
1165 int ret
= sysobj
.rop().read(&bl
, null_yield
);
1167 ldout(cct
, 0) << "failed reading obj info from " << pool
<< ":" << get_period_oid() << ": " << cpp_strerror(-ret
) << dendl
;
1173 auto iter
= bl
.cbegin();
1174 decode(*this, iter
);
1175 } catch (buffer::error
& err
) {
1176 ldout(cct
, 0) << "ERROR: failed to decode obj from " << pool
<< ":" << get_period_oid() << dendl
;
1183 int RGWPeriod::create(bool exclusive
)
1187 /* create unique id */
1190 new_uuid
.generate_random();
1191 new_uuid
.print(uuid_str
);
1194 epoch
= FIRST_EPOCH
;
1198 ret
= store_info(exclusive
);
1200 ldout(cct
, 0) << "ERROR: storing info for " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1204 ret
= set_latest_epoch(epoch
);
1206 ldout(cct
, 0) << "ERROR: setting latest epoch " << id
<< ": " << cpp_strerror(-ret
) << dendl
;
1212 int RGWPeriod::store_info(bool exclusive
)
1214 rgw_pool
pool(get_pool(cct
));
1216 string oid
= get_period_oid();
1221 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1222 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, rgw_raw_obj(pool
, oid
));
1224 .set_exclusive(exclusive
)
1225 .write(bl
, null_yield
);
1228 rgw_pool
RGWPeriod::get_pool(CephContext
*cct
) const
1230 if (cct
->_conf
->rgw_period_root_pool
.empty()) {
1231 return rgw_pool(RGW_DEFAULT_PERIOD_ROOT_POOL
);
1233 return rgw_pool(cct
->_conf
->rgw_period_root_pool
);
1236 int RGWPeriod::add_zonegroup(const RGWZoneGroup
& zonegroup
)
1238 if (zonegroup
.realm_id
!= realm_id
) {
1241 int ret
= period_map
.update(zonegroup
, cct
);
1243 ldout(cct
, 0) << "ERROR: updating period map: " << cpp_strerror(-ret
) << dendl
;
1247 return store_info(false);
1250 int RGWPeriod::update()
1252 auto zone_svc
= sysobj_svc
->get_zone_svc();
1253 ldout(cct
, 20) << __func__
<< " realm " << realm_id
<< " period " << get_id() << dendl
;
1254 list
<string
> zonegroups
;
1255 int ret
= zone_svc
->list_zonegroups(zonegroups
);
1257 ldout(cct
, 0) << "ERROR: failed to list zonegroups: " << cpp_strerror(-ret
) << dendl
;
1261 // clear zone short ids of removed zones. period_map.update() will add the
1262 // remaining zones back
1263 period_map
.short_zone_ids
.clear();
1265 for (auto& iter
: zonegroups
) {
1266 RGWZoneGroup
zg(string(), iter
);
1267 ret
= zg
.init(cct
, sysobj_svc
);
1269 ldout(cct
, 0) << "WARNING: zg.init() failed: " << cpp_strerror(-ret
) << dendl
;
1273 if (zg
.realm_id
!= realm_id
) {
1274 ldout(cct
, 20) << "skipping zonegroup " << zg
.get_name() << " zone realm id " << zg
.realm_id
<< ", not on our realm " << realm_id
<< dendl
;
1278 if (zg
.master_zone
.empty()) {
1279 ldout(cct
, 0) << "ERROR: zonegroup " << zg
.get_name() << " should have a master zone " << dendl
;
1283 if (zg
.zones
.find(zg
.master_zone
) == zg
.zones
.end()) {
1284 ldout(cct
,0) << "ERROR: zonegroup " << zg
.get_name()
1285 << " has a non existent master zone "<< dendl
;
1289 if (zg
.is_master_zonegroup()) {
1290 master_zonegroup
= zg
.get_id();
1291 master_zone
= zg
.master_zone
;
1294 int ret
= period_map
.update(zg
, cct
);
1300 ret
= period_config
.read(sysobj_svc
, realm_id
);
1301 if (ret
< 0 && ret
!= -ENOENT
) {
1302 ldout(cct
, 0) << "ERROR: failed to read period config: "
1303 << cpp_strerror(ret
) << dendl
;
1309 int RGWPeriod::reflect()
1311 for (auto& iter
: period_map
.zonegroups
) {
1312 RGWZoneGroup
& zg
= iter
.second
;
1313 zg
.reinit_instance(cct
, sysobj_svc
);
1314 int r
= zg
.write(false);
1316 ldout(cct
, 0) << "ERROR: failed to store zonegroup info for zonegroup=" << iter
.first
<< ": " << cpp_strerror(-r
) << dendl
;
1319 if (zg
.is_master_zonegroup()) {
1320 // set master as default if no default exists
1321 r
= zg
.set_as_default(true);
1323 ldout(cct
, 1) << "Set the period's master zonegroup " << zg
.get_id()
1324 << " as the default" << dendl
;
1329 int r
= period_config
.write(sysobj_svc
, realm_id
);
1331 ldout(cct
, 0) << "ERROR: failed to store period config: "
1332 << cpp_strerror(-r
) << dendl
;
1338 void RGWPeriod::fork()
1340 ldout(cct
, 20) << __func__
<< " realm " << realm_id
<< " period " << id
<< dendl
;
1341 predecessor_uuid
= id
;
1342 id
= get_staging_id(realm_id
);
1347 static int read_sync_status(rgw::sal::RGWRadosStore
*store
, rgw_meta_sync_status
*sync_status
)
1349 // initialize a sync status manager to read the status
1350 RGWMetaSyncStatusManager
mgr(store
, store
->svc()->rados
->get_async_processor());
1355 r
= mgr
.read_sync_status(sync_status
);
1360 int RGWPeriod::update_sync_status(rgw::sal::RGWRadosStore
*store
, /* for now */
1361 const RGWPeriod
¤t_period
,
1362 std::ostream
& error_stream
,
1363 bool force_if_stale
)
1365 rgw_meta_sync_status status
;
1366 int r
= read_sync_status(store
, &status
);
1368 ldout(cct
, 0) << "period failed to read sync status: "
1369 << cpp_strerror(-r
) << dendl
;
1373 std::vector
<std::string
> markers
;
1375 const auto current_epoch
= current_period
.get_realm_epoch();
1376 if (current_epoch
!= status
.sync_info
.realm_epoch
) {
1377 // no sync status markers for the current period
1378 ceph_assert(current_epoch
> status
.sync_info
.realm_epoch
);
1379 const int behind
= current_epoch
- status
.sync_info
.realm_epoch
;
1380 if (!force_if_stale
&& current_epoch
> 1) {
1381 error_stream
<< "ERROR: This zone is " << behind
<< " period(s) behind "
1382 "the current master zone in metadata sync. If this zone is promoted "
1383 "to master, any metadata changes during that time are likely to "
1385 "Waiting for this zone to catch up on metadata sync (see "
1386 "'radosgw-admin sync status') is recommended.\n"
1387 "To promote this zone to master anyway, add the flag "
1388 "--yes-i-really-mean-it." << std::endl
;
1391 // empty sync status markers - other zones will skip this period during
1392 // incremental metadata sync
1393 markers
.resize(status
.sync_info
.num_shards
);
1395 markers
.reserve(status
.sync_info
.num_shards
);
1396 for (auto& i
: status
.sync_markers
) {
1397 auto& marker
= i
.second
;
1398 // filter out markers from other periods
1399 if (marker
.realm_epoch
!= current_epoch
) {
1400 marker
.marker
.clear();
1402 markers
.emplace_back(std::move(marker
.marker
));
1406 std::swap(sync_status
, markers
);
1410 int RGWPeriod::commit(rgw::sal::RGWRadosStore
*store
,
1411 RGWRealm
& realm
, const RGWPeriod
& current_period
,
1412 std::ostream
& error_stream
, bool force_if_stale
)
1414 auto zone_svc
= sysobj_svc
->get_zone_svc();
1415 ldout(cct
, 20) << __func__
<< " realm " << realm
.get_id() << " period " << current_period
.get_id() << dendl
;
1416 // gateway must be in the master zone to commit
1417 if (master_zone
!= zone_svc
->get_zone_params().get_id()) {
1418 error_stream
<< "Cannot commit period on zone "
1419 << zone_svc
->get_zone_params().get_id() << ", it must be sent to "
1420 "the period's master zone " << master_zone
<< '.' << std::endl
;
1423 // period predecessor must match current period
1424 if (predecessor_uuid
!= current_period
.get_id()) {
1425 error_stream
<< "Period predecessor " << predecessor_uuid
1426 << " does not match current period " << current_period
.get_id()
1427 << ". Use 'period pull' to get the latest period from the master, "
1428 "reapply your changes, and try again." << std::endl
;
1431 // realm epoch must be 1 greater than current period
1432 if (realm_epoch
!= current_period
.get_realm_epoch() + 1) {
1433 error_stream
<< "Period's realm epoch " << realm_epoch
1434 << " does not come directly after current realm epoch "
1435 << current_period
.get_realm_epoch() << ". Use 'realm pull' to get the "
1436 "latest realm and period from the master zone, reapply your changes, "
1437 "and try again." << std::endl
;
1440 // did the master zone change?
1441 if (master_zone
!= current_period
.get_master_zone()) {
1442 // store the current metadata sync status in the period
1443 int r
= update_sync_status(store
, current_period
, error_stream
, force_if_stale
);
1445 ldout(cct
, 0) << "failed to update metadata sync status: "
1446 << cpp_strerror(-r
) << dendl
;
1449 // create an object with a new period id
1452 ldout(cct
, 0) << "failed to create new period: " << cpp_strerror(-r
) << dendl
;
1455 // set as current period
1456 r
= realm
.set_current_period(*this);
1458 ldout(cct
, 0) << "failed to update realm's current period: "
1459 << cpp_strerror(-r
) << dendl
;
1462 ldout(cct
, 4) << "Promoted to master zone and committed new period "
1464 realm
.notify_new_period(*this);
1467 // period must be based on current epoch
1468 if (epoch
!= current_period
.get_epoch()) {
1469 error_stream
<< "Period epoch " << epoch
<< " does not match "
1470 "predecessor epoch " << current_period
.get_epoch()
1471 << ". Use 'period pull' to get the latest epoch from the master zone, "
1472 "reapply your changes, and try again." << std::endl
;
1475 // set period as next epoch
1476 set_id(current_period
.get_id());
1477 set_epoch(current_period
.get_epoch() + 1);
1478 set_predecessor(current_period
.get_predecessor());
1479 realm_epoch
= current_period
.get_realm_epoch();
1480 // write the period to rados
1481 int r
= store_info(false);
1483 ldout(cct
, 0) << "failed to store period: " << cpp_strerror(-r
) << dendl
;
1486 // set as latest epoch
1487 r
= update_latest_epoch(epoch
);
1489 // already have this epoch (or a more recent one)
1493 ldout(cct
, 0) << "failed to set latest epoch: " << cpp_strerror(-r
) << dendl
;
1498 ldout(cct
, 0) << "failed to update local objects: " << cpp_strerror(-r
) << dendl
;
1501 ldout(cct
, 4) << "Committed new epoch " << epoch
1502 << " for period " << id
<< dendl
;
1503 realm
.notify_new_period(*this);
1507 int RGWZoneParams::create_default(bool old_format
)
1509 name
= default_zone_name
;
1524 int get_zones_pool_set(CephContext
* cct
,
1525 RGWSI_SysObj
* sysobj_svc
,
1526 const list
<string
>& zones
,
1527 const string
& my_zone_id
,
1528 set
<rgw_pool
>& pool_names
)
1530 for(auto const& iter
: zones
) {
1531 RGWZoneParams
zone(iter
);
1532 int r
= zone
.init(cct
, sysobj_svc
);
1534 ldout(cct
, 0) << "Error: init zone " << iter
<< ":" << cpp_strerror(-r
) << dendl
;
1537 if (zone
.get_id() != my_zone_id
) {
1538 pool_names
.insert(zone
.domain_root
);
1539 pool_names
.insert(zone
.control_pool
);
1540 pool_names
.insert(zone
.gc_pool
);
1541 pool_names
.insert(zone
.log_pool
);
1542 pool_names
.insert(zone
.intent_log_pool
);
1543 pool_names
.insert(zone
.usage_log_pool
);
1544 pool_names
.insert(zone
.user_keys_pool
);
1545 pool_names
.insert(zone
.user_email_pool
);
1546 pool_names
.insert(zone
.user_swift_pool
);
1547 pool_names
.insert(zone
.user_uid_pool
);
1548 pool_names
.insert(zone
.otp_pool
);
1549 pool_names
.insert(zone
.roles_pool
);
1550 pool_names
.insert(zone
.reshard_pool
);
1551 for(auto& iter
: zone
.placement_pools
) {
1552 pool_names
.insert(iter
.second
.index_pool
);
1553 for (auto& pi
: iter
.second
.storage_classes
.get_all()) {
1554 if (pi
.second
.data_pool
) {
1555 pool_names
.insert(pi
.second
.data_pool
.get());
1558 pool_names
.insert(iter
.second
.data_extra_pool
);
1565 rgw_pool
fix_zone_pool_dup(set
<rgw_pool
> pools
,
1566 const string
& default_prefix
,
1567 const string
& default_suffix
,
1568 const rgw_pool
& suggested_pool
)
1570 string suggested_name
= suggested_pool
.to_str();
1572 string prefix
= default_prefix
;
1573 string suffix
= default_suffix
;
1575 if (!suggested_pool
.empty()) {
1576 prefix
= suggested_name
.substr(0, suggested_name
.find("."));
1577 suffix
= suggested_name
.substr(prefix
.length());
1580 rgw_pool
pool(prefix
+ suffix
);
1582 if (pools
.find(pool
) == pools
.end()) {
1586 pool
= prefix
+ "_" + std::to_string(std::rand()) + suffix
;
1587 if (pools
.find(pool
) == pools
.end()) {
1594 int RGWZoneParams::fix_pool_names()
1598 int r
= zone_svc
->list_zones(zones
);
1600 ldout(cct
, 10) << "WARNING: store->list_zones() returned r=" << r
<< dendl
;
1603 set
<rgw_pool
> pools
;
1604 r
= get_zones_pool_set(cct
, sysobj_svc
, zones
, id
, pools
);
1606 ldout(cct
, 0) << "Error: get_zones_pool_names" << r
<< dendl
;
1610 domain_root
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:root", domain_root
);
1611 control_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.control", control_pool
);
1612 gc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:gc", gc_pool
);
1613 lc_pool
= fix_zone_pool_dup(pools
, name
,".rgw.log:lc", lc_pool
);
1614 log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log", log_pool
);
1615 intent_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:intent", intent_log_pool
);
1616 usage_log_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:usage", usage_log_pool
);
1617 user_keys_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.keys", user_keys_pool
);
1618 user_email_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.email", user_email_pool
);
1619 user_swift_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.swift", user_swift_pool
);
1620 user_uid_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:users.uid", user_uid_pool
);
1621 roles_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.meta:roles", roles_pool
);
1622 reshard_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.log:reshard", reshard_pool
);
1623 otp_pool
= fix_zone_pool_dup(pools
, name
, ".rgw.otp", otp_pool
);
1625 for(auto& iter
: placement_pools
) {
1626 iter
.second
.index_pool
= fix_zone_pool_dup(pools
, name
, "." + default_bucket_index_pool_suffix
,
1627 iter
.second
.index_pool
);
1628 for (auto& pi
: iter
.second
.storage_classes
.get_all()) {
1629 if (pi
.second
.data_pool
) {
1630 rgw_pool
& pool
= pi
.second
.data_pool
.get();
1631 pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_pool_suffix
,
1635 iter
.second
.data_extra_pool
= fix_zone_pool_dup(pools
, name
, "." + default_storage_extra_pool_suffix
,
1636 iter
.second
.data_extra_pool
);
1642 int RGWZoneParams::create(bool exclusive
)
1644 /* check for old pools config */
1645 rgw_raw_obj
obj(domain_root
, avail_pools
);
1646 auto obj_ctx
= sysobj_svc
->init_obj_ctx();
1647 auto sysobj
= sysobj_svc
->get_obj(obj_ctx
, obj
);
1648 int r
= sysobj
.rop().stat(null_yield
);
1650 ldout(cct
, 10) << "couldn't find old data placement pools config, setting up new ones for the zone" << dendl
;
1651 /* a new system, let's set new placement info */
1652 RGWZonePlacementInfo default_placement
;
1653 default_placement
.index_pool
= name
+ "." + default_bucket_index_pool_suffix
;
1654 rgw_pool pool
= name
+ "." + default_storage_pool_suffix
;
1655 default_placement
.storage_classes
.set_storage_class(RGW_STORAGE_CLASS_STANDARD
, &pool
, nullptr);
1656 default_placement
.data_extra_pool
= name
+ "." + default_storage_extra_pool_suffix
;
1657 placement_pools
["default-placement"] = default_placement
;
1660 r
= fix_pool_names();
1662 ldout(cct
, 0) << "ERROR: fix_pool_names returned r=" << r
<< dendl
;
1666 r
= RGWSystemMetaObj::create(exclusive
);
1671 // try to set as default. may race with another create, so pass exclusive=true
1672 // so we don't override an existing default
1673 r
= set_as_default(true);
1674 if (r
< 0 && r
!= -EEXIST
) {
1675 ldout(cct
, 10) << "WARNING: failed to set zone as default, r=" << r
<< dendl
;
1681 rgw_pool
RGWZoneParams::get_pool(CephContext
*cct
) const
1683 if (cct
->_conf
->rgw_zone_root_pool
.empty()) {
1684 return rgw_pool(RGW_DEFAULT_ZONE_ROOT_POOL
);
1687 return rgw_pool(cct
->_conf
->rgw_zone_root_pool
);
1690 const string
RGWZoneParams::get_default_oid(bool old_format
) const
1693 return cct
->_conf
->rgw_default_zone_info_oid
;
1696 return cct
->_conf
->rgw_default_zone_info_oid
+ "." + realm_id
;
1699 const string
& RGWZoneParams::get_names_oid_prefix() const
1701 return zone_names_oid_prefix
;
1704 const string
& RGWZoneParams::get_info_oid_prefix(bool old_format
) const
1706 return zone_info_oid_prefix
;
1709 const string
& RGWZoneParams::get_predefined_name(CephContext
*cct
) const {
1710 return cct
->_conf
->rgw_zone
;
1713 int RGWZoneParams::init(CephContext
*cct
, RGWSI_SysObj
*sysobj_svc
, bool setup_obj
, bool old_format
)
1716 name
= cct
->_conf
->rgw_zone
;
1719 return RGWSystemMetaObj::init(cct
, sysobj_svc
, setup_obj
, old_format
);
1722 int RGWZoneParams::read_default_id(string
& default_id
, bool old_format
)
1724 if (realm_id
.empty()) {
1725 /* try using default realm */
1727 int ret
= realm
.init(cct
, sysobj_svc
);
1728 //no default realm exist
1730 return read_id(default_zone_name
, default_id
);
1732 realm_id
= realm
.get_id();
1735 return RGWSystemMetaObj::read_default_id(default_id
, old_format
);
1739 int RGWZoneParams::set_as_default(bool exclusive
)
1741 if (realm_id
.empty()) {
1742 /* try using default realm */
1744 int ret
= realm
.init(cct
, sysobj_svc
);
1746 ldout(cct
, 10) << "could not read realm id: " << cpp_strerror(-ret
) << dendl
;
1749 realm_id
= realm
.get_id();
1752 return RGWSystemMetaObj::set_as_default(exclusive
);
1755 const string
& RGWZoneParams::get_compression_type(const rgw_placement_rule
& placement_rule
) const
1757 static const std::string NONE
{"none"};
1758 auto p
= placement_pools
.find(placement_rule
.name
);
1759 if (p
== placement_pools
.end()) {
1762 const auto& type
= p
->second
.get_compression_type(placement_rule
.get_storage_class());
1763 return !type
.empty() ? type
: NONE
;
1766 void RGWPeriodMap::encode(bufferlist
& bl
) const {
1767 ENCODE_START(2, 1, bl
);
1769 encode(zonegroups
, bl
);
1770 encode(master_zonegroup
, bl
);
1771 encode(short_zone_ids
, bl
);
1775 void RGWPeriodMap::decode(bufferlist::const_iterator
& bl
) {
1776 DECODE_START(2, bl
);
1778 decode(zonegroups
, bl
);
1779 decode(master_zonegroup
, bl
);
1780 if (struct_v
>= 2) {
1781 decode(short_zone_ids
, bl
);
1785 zonegroups_by_api
.clear();
1786 for (map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.begin();
1787 iter
!= zonegroups
.end(); ++iter
) {
1788 RGWZoneGroup
& zonegroup
= iter
->second
;
1789 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1790 if (zonegroup
.is_master_zonegroup()) {
1791 master_zonegroup
= zonegroup
.get_id();
1796 // run an MD5 hash on the zone_id and return the first 32 bits
1797 static uint32_t gen_short_zone_id(const std::string zone_id
)
1799 unsigned char md5
[CEPH_CRYPTO_MD5_DIGESTSIZE
];
1801 hash
.Update((const unsigned char *)zone_id
.c_str(), zone_id
.size());
1805 memcpy((char *)&short_id
, md5
, sizeof(short_id
));
1806 return std::max(short_id
, 1u);
1809 int RGWPeriodMap::update(const RGWZoneGroup
& zonegroup
, CephContext
*cct
)
1811 if (zonegroup
.is_master_zonegroup() && (!master_zonegroup
.empty() && zonegroup
.get_id() != master_zonegroup
)) {
1812 ldout(cct
,0) << "Error updating periodmap, multiple master zonegroups configured "<< dendl
;
1813 ldout(cct
,0) << "master zonegroup: " << master_zonegroup
<< " and " << zonegroup
.get_id() <<dendl
;
1816 map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.find(zonegroup
.get_id());
1817 if (iter
!= zonegroups
.end()) {
1818 RGWZoneGroup
& old_zonegroup
= iter
->second
;
1819 if (!old_zonegroup
.api_name
.empty()) {
1820 zonegroups_by_api
.erase(old_zonegroup
.api_name
);
1823 zonegroups
[zonegroup
.get_id()] = zonegroup
;
1825 if (!zonegroup
.api_name
.empty()) {
1826 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1829 if (zonegroup
.is_master_zonegroup()) {
1830 master_zonegroup
= zonegroup
.get_id();
1831 } else if (master_zonegroup
== zonegroup
.get_id()) {
1832 master_zonegroup
= "";
1835 for (auto& i
: zonegroup
.zones
) {
1836 auto& zone
= i
.second
;
1837 if (short_zone_ids
.find(zone
.id
) != short_zone_ids
.end()) {
1840 // calculate the zone's short id
1841 uint32_t short_id
= gen_short_zone_id(zone
.id
);
1843 // search for an existing zone with the same short id
1844 for (auto& s
: short_zone_ids
) {
1845 if (s
.second
== short_id
) {
1846 ldout(cct
, 0) << "New zone '" << zone
.name
<< "' (" << zone
.id
1847 << ") generates the same short_zone_id " << short_id
1848 << " as existing zone id " << s
.first
<< dendl
;
1853 short_zone_ids
[zone
.id
] = short_id
;
1859 uint32_t RGWPeriodMap::get_zone_short_id(const string
& zone_id
) const
1861 auto i
= short_zone_ids
.find(zone_id
);
1862 if (i
== short_zone_ids
.end()) {
1868 int RGWZoneGroupMap::read(CephContext
*cct
, RGWSI_SysObj
*sysobj_svc
)
1872 int ret
= period
.init(cct
, sysobj_svc
);
1874 cerr
<< "failed to read current period info: " << cpp_strerror(ret
);
1878 bucket_quota
= period
.get_config().bucket_quota
;
1879 user_quota
= period
.get_config().user_quota
;
1880 zonegroups
= period
.get_map().zonegroups
;
1881 zonegroups_by_api
= period
.get_map().zonegroups_by_api
;
1882 master_zonegroup
= period
.get_map().master_zonegroup
;
1887 void RGWRegionMap::encode(bufferlist
& bl
) const {
1888 ENCODE_START( 3, 1, bl
);
1889 encode(regions
, bl
);
1890 encode(master_region
, bl
);
1891 encode(bucket_quota
, bl
);
1892 encode(user_quota
, bl
);
1896 void RGWRegionMap::decode(bufferlist::const_iterator
& bl
) {
1897 DECODE_START(3, bl
);
1898 decode(regions
, bl
);
1899 decode(master_region
, bl
);
1901 decode(bucket_quota
, bl
);
1903 decode(user_quota
, bl
);
1907 void RGWZoneGroupMap::encode(bufferlist
& bl
) const {
1908 ENCODE_START( 3, 1, bl
);
1909 encode(zonegroups
, bl
);
1910 encode(master_zonegroup
, bl
);
1911 encode(bucket_quota
, bl
);
1912 encode(user_quota
, bl
);
1916 void RGWZoneGroupMap::decode(bufferlist::const_iterator
& bl
) {
1917 DECODE_START(3, bl
);
1918 decode(zonegroups
, bl
);
1919 decode(master_zonegroup
, bl
);
1921 decode(bucket_quota
, bl
);
1923 decode(user_quota
, bl
);
1926 zonegroups_by_api
.clear();
1927 for (map
<string
, RGWZoneGroup
>::iterator iter
= zonegroups
.begin();
1928 iter
!= zonegroups
.end(); ++iter
) {
1929 RGWZoneGroup
& zonegroup
= iter
->second
;
1930 zonegroups_by_api
[zonegroup
.api_name
] = zonegroup
;
1931 if (zonegroup
.is_master_zonegroup()) {
1932 master_zonegroup
= zonegroup
.get_name();