]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/driver/rados/rgw_zone.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / driver / rados / rgw_zone.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #pragma once
5
6 #include <ostream>
7 #include "rgw_zone_types.h"
8 #include "rgw_common.h"
9 #include "rgw_sal_fwd.h"
10 #include "rgw_sync_policy.h"
11
12
13 class RGWSyncModulesManager;
14
15 class RGWSI_SysObj;
16 class RGWSI_Zone;
17
18 class RGWSystemMetaObj {
19 public:
20 std::string id;
21 std::string name;
22
23 CephContext *cct{nullptr};
24 RGWSI_SysObj *sysobj_svc{nullptr};
25 RGWSI_Zone *zone_svc{nullptr};
26
27 int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
28 int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
29 int read_info(const DoutPrefixProvider *dpp, const std::string& obj_id, optional_yield y, bool old_format = false);
30 int read_id(const DoutPrefixProvider *dpp, const std::string& obj_name, std::string& obj_id, optional_yield y);
31 int read_default(const DoutPrefixProvider *dpp,
32 RGWDefaultSystemMetaObjInfo& default_info,
33 const std::string& oid,
34 optional_yield y);
35 /* read and use default id */
36 int use_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
37
38 public:
39 RGWSystemMetaObj() {}
40 RGWSystemMetaObj(const std::string& _name): name(_name) {}
41 RGWSystemMetaObj(const std::string& _id, const std::string& _name) : id(_id), name(_name) {}
42 RGWSystemMetaObj(CephContext *_cct, RGWSI_SysObj *_sysobj_svc) {
43 reinit_instance(_cct, _sysobj_svc);
44 }
45 RGWSystemMetaObj(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): name(_name) {
46 reinit_instance(_cct, _sysobj_svc);
47 }
48
49 const std::string& get_name() const { return name; }
50 const std::string& get_id() const { return id; }
51
52 void set_name(const std::string& _name) { name = _name;}
53 void set_id(const std::string& _id) { id = _id;}
54 void clear_id() { id.clear(); }
55
56 virtual ~RGWSystemMetaObj() {}
57
58 virtual void encode(bufferlist& bl) const {
59 ENCODE_START(1, 1, bl);
60 encode(id, bl);
61 encode(name, bl);
62 ENCODE_FINISH(bl);
63 }
64
65 virtual void decode(bufferlist::const_iterator& bl) {
66 DECODE_START(1, bl);
67 decode(id, bl);
68 decode(name, bl);
69 DECODE_FINISH(bl);
70 }
71
72 void reinit_instance(CephContext *_cct, RGWSI_SysObj *_sysobj_svc);
73 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc,
74 optional_yield y,
75 bool setup_obj = true, bool old_format = false);
76 virtual int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y,
77 bool old_format = false);
78 virtual int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false);
79 int delete_default();
80 virtual int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true);
81 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
82 int rename(const DoutPrefixProvider *dpp, const std::string& new_name, optional_yield y);
83 int update(const DoutPrefixProvider *dpp, optional_yield y) { return store_info(dpp, false, y);}
84 int update_name(const DoutPrefixProvider *dpp, optional_yield y) { return store_name(dpp, false, y);}
85 int read(const DoutPrefixProvider *dpp, optional_yield y);
86 int write(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
87
88 virtual rgw_pool get_pool(CephContext *cct) const = 0;
89 virtual const std::string get_default_oid(bool old_format = false) const = 0;
90 virtual const std::string& get_names_oid_prefix() const = 0;
91 virtual const std::string& get_info_oid_prefix(bool old_format = false) const = 0;
92 virtual std::string get_predefined_id(CephContext *cct) const = 0;
93 virtual const std::string& get_predefined_name(CephContext *cct) const = 0;
94
95 void dump(Formatter *f) const;
96 void decode_json(JSONObj *obj);
97 };
98 WRITE_CLASS_ENCODER(RGWSystemMetaObj)
99
100 struct RGWZoneParams : RGWSystemMetaObj {
101 rgw_pool domain_root;
102 rgw_pool control_pool;
103 rgw_pool gc_pool;
104 rgw_pool lc_pool;
105 rgw_pool log_pool;
106 rgw_pool intent_log_pool;
107 rgw_pool usage_log_pool;
108 rgw_pool user_keys_pool;
109 rgw_pool user_email_pool;
110 rgw_pool user_swift_pool;
111 rgw_pool user_uid_pool;
112 rgw_pool roles_pool;
113 rgw_pool reshard_pool;
114 rgw_pool otp_pool;
115 rgw_pool oidc_pool;
116 rgw_pool notif_pool;
117
118 RGWAccessKey system_key;
119
120 std::map<std::string, RGWZonePlacementInfo> placement_pools;
121
122 std::string realm_id;
123
124 JSONFormattable tier_config;
125
126 RGWZoneParams() : RGWSystemMetaObj() {}
127 explicit RGWZoneParams(const std::string& name) : RGWSystemMetaObj(name){}
128 RGWZoneParams(const rgw_zone_id& id, const std::string& name) : RGWSystemMetaObj(id.id, name) {}
129 RGWZoneParams(const rgw_zone_id& id, const std::string& name, const std::string& _realm_id)
130 : RGWSystemMetaObj(id.id, name), realm_id(_realm_id) {}
131 virtual ~RGWZoneParams();
132
133 rgw_pool get_pool(CephContext *cct) const override;
134 const std::string get_default_oid(bool old_format = false) const override;
135 const std::string& get_names_oid_prefix() const override;
136 const std::string& get_info_oid_prefix(bool old_format = false) const override;
137 std::string get_predefined_id(CephContext *cct) const override;
138 const std::string& get_predefined_name(CephContext *cct) const override;
139
140 int init(const DoutPrefixProvider *dpp,
141 CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y,
142 bool setup_obj = true, bool old_format = false);
143 using RGWSystemMetaObj::init;
144 int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override;
145 int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override;
146 int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
147 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override;
148 int fix_pool_names(const DoutPrefixProvider *dpp, optional_yield y);
149
150 const std::string& get_compression_type(const rgw_placement_rule& placement_rule) const;
151
152 void encode(bufferlist& bl) const override {
153 ENCODE_START(14, 1, bl);
154 encode(domain_root, bl);
155 encode(control_pool, bl);
156 encode(gc_pool, bl);
157 encode(log_pool, bl);
158 encode(intent_log_pool, bl);
159 encode(usage_log_pool, bl);
160 encode(user_keys_pool, bl);
161 encode(user_email_pool, bl);
162 encode(user_swift_pool, bl);
163 encode(user_uid_pool, bl);
164 RGWSystemMetaObj::encode(bl);
165 encode(system_key, bl);
166 encode(placement_pools, bl);
167 rgw_pool unused_metadata_heap;
168 encode(unused_metadata_heap, bl);
169 encode(realm_id, bl);
170 encode(lc_pool, bl);
171 std::map<std::string, std::string, ltstr_nocase> old_tier_config;
172 encode(old_tier_config, bl);
173 encode(roles_pool, bl);
174 encode(reshard_pool, bl);
175 encode(otp_pool, bl);
176 encode(tier_config, bl);
177 encode(oidc_pool, bl);
178 encode(notif_pool, bl);
179 ENCODE_FINISH(bl);
180 }
181
182 void decode(bufferlist::const_iterator& bl) override {
183 DECODE_START(14, bl);
184 decode(domain_root, bl);
185 decode(control_pool, bl);
186 decode(gc_pool, bl);
187 decode(log_pool, bl);
188 decode(intent_log_pool, bl);
189 decode(usage_log_pool, bl);
190 decode(user_keys_pool, bl);
191 decode(user_email_pool, bl);
192 decode(user_swift_pool, bl);
193 decode(user_uid_pool, bl);
194 if (struct_v >= 6) {
195 RGWSystemMetaObj::decode(bl);
196 } else if (struct_v >= 2) {
197 decode(name, bl);
198 id = name;
199 }
200 if (struct_v >= 3)
201 decode(system_key, bl);
202 if (struct_v >= 4)
203 decode(placement_pools, bl);
204 if (struct_v >= 5) {
205 rgw_pool unused_metadata_heap;
206 decode(unused_metadata_heap, bl);
207 }
208 if (struct_v >= 6) {
209 decode(realm_id, bl);
210 }
211 if (struct_v >= 7) {
212 decode(lc_pool, bl);
213 } else {
214 lc_pool = log_pool.name + ":lc";
215 }
216 std::map<std::string, std::string, ltstr_nocase> old_tier_config;
217 if (struct_v >= 8) {
218 decode(old_tier_config, bl);
219 }
220 if (struct_v >= 9) {
221 decode(roles_pool, bl);
222 } else {
223 roles_pool = name + ".rgw.meta:roles";
224 }
225 if (struct_v >= 10) {
226 decode(reshard_pool, bl);
227 } else {
228 reshard_pool = log_pool.name + ":reshard";
229 }
230 if (struct_v >= 11) {
231 ::decode(otp_pool, bl);
232 } else {
233 otp_pool = name + ".rgw.otp";
234 }
235 if (struct_v >= 12) {
236 ::decode(tier_config, bl);
237 } else {
238 for (auto& kv : old_tier_config) {
239 tier_config.set(kv.first, kv.second);
240 }
241 }
242 if (struct_v >= 13) {
243 ::decode(oidc_pool, bl);
244 } else {
245 oidc_pool = name + ".rgw.meta:oidc";
246 }
247 if (struct_v >= 14) {
248 decode(notif_pool, bl);
249 } else {
250 notif_pool = log_pool.name + ":notif";
251 }
252 DECODE_FINISH(bl);
253 }
254 void dump(Formatter *f) const;
255 void decode_json(JSONObj *obj);
256 static void generate_test_instances(std::list<RGWZoneParams*>& o);
257
258 bool get_placement(const std::string& placement_id, RGWZonePlacementInfo *placement) const {
259 auto iter = placement_pools.find(placement_id);
260 if (iter == placement_pools.end()) {
261 return false;
262 }
263 *placement = iter->second;
264 return true;
265 }
266
267 /*
268 * return data pool of the head object
269 */
270 bool get_head_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool* pool) const {
271 const rgw_data_placement_target& explicit_placement = obj.bucket.explicit_placement;
272 if (!explicit_placement.data_pool.empty()) {
273 if (!obj.in_extra_data) {
274 *pool = explicit_placement.data_pool;
275 } else {
276 *pool = explicit_placement.get_data_extra_pool();
277 }
278 return true;
279 }
280 if (placement_rule.empty()) {
281 return false;
282 }
283 auto iter = placement_pools.find(placement_rule.name);
284 if (iter == placement_pools.end()) {
285 return false;
286 }
287 if (!obj.in_extra_data) {
288 *pool = iter->second.get_data_pool(placement_rule.storage_class);
289 } else {
290 *pool = iter->second.get_data_extra_pool();
291 }
292 return true;
293 }
294
295 bool valid_placement(const rgw_placement_rule& rule) const {
296 auto iter = placement_pools.find(rule.name);
297 if (iter == placement_pools.end()) {
298 return false;
299 }
300 return iter->second.storage_class_exists(rule.storage_class);
301 }
302 };
303 WRITE_CLASS_ENCODER(RGWZoneParams)
304
305 struct RGWZoneGroup : public RGWSystemMetaObj {
306 std::string api_name;
307 std::list<std::string> endpoints;
308 bool is_master = false;
309
310 rgw_zone_id master_zone;
311 std::map<rgw_zone_id, RGWZone> zones;
312
313 std::map<std::string, RGWZoneGroupPlacementTarget> placement_targets;
314 rgw_placement_rule default_placement;
315
316 std::list<std::string> hostnames;
317 std::list<std::string> hostnames_s3website;
318 // TODO: Maybe convert hostnames to a map<std::string,std::list<std::string>> for
319 // endpoint_type->hostnames
320 /*
321 20:05 < _robbat21irssi> maybe I do someting like: if (hostname_map.empty()) { populate all map keys from hostnames; };
322 20:05 < _robbat21irssi> but that's a later compatability migration planning bit
323 20:06 < yehudasa> more like if (!hostnames.empty()) {
324 20:06 < yehudasa> for (std::list<std::string>::iterator iter = hostnames.begin(); iter != hostnames.end(); ++iter) {
325 20:06 < yehudasa> hostname_map["s3"].append(iter->second);
326 20:07 < yehudasa> hostname_map["s3website"].append(iter->second);
327 20:07 < yehudasa> s/append/push_back/g
328 20:08 < _robbat21irssi> inner loop over APIs
329 20:08 < yehudasa> yeah, probably
330 20:08 < _robbat21irssi> s3, s3website, swift, swith_auth, swift_website
331 */
332 std::map<std::string, std::list<std::string> > api_hostname_map;
333 std::map<std::string, std::list<std::string> > api_endpoints_map;
334
335 std::string realm_id;
336
337 rgw_sync_policy_info sync_policy;
338 rgw::zone_features::set enabled_features;
339
340 RGWZoneGroup(): is_master(false){}
341 RGWZoneGroup(const std::string &id, const std::string &name):RGWSystemMetaObj(id, name) {}
342 explicit RGWZoneGroup(const std::string &_name):RGWSystemMetaObj(_name) {}
343 RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWSI_SysObj* sysobj_svc,
344 const std::string& _realm_id, const std::list<std::string>& _endpoints)
345 : RGWSystemMetaObj(_name, cct , sysobj_svc), endpoints(_endpoints), is_master(_is_master),
346 realm_id(_realm_id) {}
347 virtual ~RGWZoneGroup();
348
349 bool is_master_zonegroup() const { return is_master;}
350 void update_master(const DoutPrefixProvider *dpp, bool _is_master, optional_yield y) {
351 is_master = _is_master;
352 post_process_params(dpp, y);
353 }
354 void post_process_params(const DoutPrefixProvider *dpp, optional_yield y);
355
356 void encode(bufferlist& bl) const override {
357 ENCODE_START(6, 1, bl);
358 encode(name, bl);
359 encode(api_name, bl);
360 encode(is_master, bl);
361 encode(endpoints, bl);
362 encode(master_zone, bl);
363 encode(zones, bl);
364 encode(placement_targets, bl);
365 encode(default_placement, bl);
366 encode(hostnames, bl);
367 encode(hostnames_s3website, bl);
368 RGWSystemMetaObj::encode(bl);
369 encode(realm_id, bl);
370 encode(sync_policy, bl);
371 encode(enabled_features, bl);
372 ENCODE_FINISH(bl);
373 }
374
375 void decode(bufferlist::const_iterator& bl) override {
376 DECODE_START(6, bl);
377 decode(name, bl);
378 decode(api_name, bl);
379 decode(is_master, bl);
380 decode(endpoints, bl);
381 decode(master_zone, bl);
382 decode(zones, bl);
383 decode(placement_targets, bl);
384 decode(default_placement, bl);
385 if (struct_v >= 2) {
386 decode(hostnames, bl);
387 }
388 if (struct_v >= 3) {
389 decode(hostnames_s3website, bl);
390 }
391 if (struct_v >= 4) {
392 RGWSystemMetaObj::decode(bl);
393 decode(realm_id, bl);
394 } else {
395 id = name;
396 }
397 if (struct_v >= 5) {
398 decode(sync_policy, bl);
399 }
400 if (struct_v >= 6) {
401 decode(enabled_features, bl);
402 }
403 DECODE_FINISH(bl);
404 }
405
406 int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override;
407 int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override;
408 int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
409 int equals(const std::string& other_zonegroup) const;
410 int add_zone(const DoutPrefixProvider *dpp,
411 const RGWZoneParams& zone_params, bool *is_master, bool *read_only,
412 const std::list<std::string>& endpoints, const std::string *ptier_type,
413 bool *psync_from_all, std::list<std::string>& sync_from,
414 std::list<std::string>& sync_from_rm, std::string *predirect_zone,
415 std::optional<int> bucket_index_max_shards, RGWSyncModulesManager *sync_mgr,
416 const rgw::zone_features::set& enable_features,
417 const rgw::zone_features::set& disable_features,
418 optional_yield y);
419 int remove_zone(const DoutPrefixProvider *dpp, const std::string& zone_id, optional_yield y);
420 int rename_zone(const DoutPrefixProvider *dpp, const RGWZoneParams& zone_params, optional_yield y);
421 rgw_pool get_pool(CephContext *cct) const override;
422 const std::string get_default_oid(bool old_region_format = false) const override;
423 const std::string& get_info_oid_prefix(bool old_region_format = false) const override;
424 const std::string& get_names_oid_prefix() const override;
425 std::string get_predefined_id(CephContext *cct) const override;
426 const std::string& get_predefined_name(CephContext *cct) const override;
427
428 void dump(Formatter *f) const;
429 void decode_json(JSONObj *obj);
430 static void generate_test_instances(std::list<RGWZoneGroup*>& o);
431
432 bool supports(std::string_view feature) const {
433 return enabled_features.contains(feature);
434 }
435 };
436 WRITE_CLASS_ENCODER(RGWZoneGroup)
437
438 struct RGWPeriodMap
439 {
440 std::string id;
441 std::map<std::string, RGWZoneGroup> zonegroups;
442 std::map<std::string, RGWZoneGroup> zonegroups_by_api;
443 std::map<std::string, uint32_t> short_zone_ids;
444
445 std::string master_zonegroup;
446
447 void encode(bufferlist& bl) const;
448 void decode(bufferlist::const_iterator& bl);
449
450 int update(const RGWZoneGroup& zonegroup, CephContext *cct);
451
452 void dump(Formatter *f) const;
453 void decode_json(JSONObj *obj);
454
455 void reset() {
456 zonegroups.clear();
457 zonegroups_by_api.clear();
458 master_zonegroup.clear();
459 }
460
461 uint32_t get_zone_short_id(const std::string& zone_id) const;
462
463 bool find_zone_by_id(const rgw_zone_id& zone_id,
464 RGWZoneGroup *zonegroup,
465 RGWZone *zone) const;
466 bool find_zone_by_name(const std::string& zone_id,
467 RGWZoneGroup *zonegroup,
468 RGWZone *zone) const;
469 };
470 WRITE_CLASS_ENCODER(RGWPeriodMap)
471
472 struct RGWPeriodConfig
473 {
474 RGWQuota quota;
475 RGWRateLimitInfo user_ratelimit;
476 RGWRateLimitInfo bucket_ratelimit;
477 // rate limit unauthenticated user
478 RGWRateLimitInfo anon_ratelimit;
479
480 void encode(bufferlist& bl) const {
481 ENCODE_START(2, 1, bl);
482 encode(quota.bucket_quota, bl);
483 encode(quota.user_quota, bl);
484 encode(bucket_ratelimit, bl);
485 encode(user_ratelimit, bl);
486 encode(anon_ratelimit, bl);
487 ENCODE_FINISH(bl);
488 }
489
490 void decode(bufferlist::const_iterator& bl) {
491 DECODE_START(2, bl);
492 decode(quota.bucket_quota, bl);
493 decode(quota.user_quota, bl);
494 if (struct_v >= 2) {
495 decode(bucket_ratelimit, bl);
496 decode(user_ratelimit, bl);
497 decode(anon_ratelimit, bl);
498 }
499 DECODE_FINISH(bl);
500 }
501
502 void dump(Formatter *f) const;
503 void decode_json(JSONObj *obj);
504
505 // the period config must be stored in a local object outside of the period,
506 // so that it can be used in a default configuration where no realm/period
507 // exists
508 int read(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y);
509 int write(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y);
510
511 static std::string get_oid(const std::string& realm_id);
512 static rgw_pool get_pool(CephContext *cct);
513 };
514 WRITE_CLASS_ENCODER(RGWPeriodConfig)
515
516 class RGWRealm;
517 class RGWPeriod;
518
519 class RGWRealm : public RGWSystemMetaObj
520 {
521 public:
522 std::string current_period;
523 epoch_t epoch{0}; //< realm epoch, incremented for each new period
524
525 int create_control(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
526 int delete_control(const DoutPrefixProvider *dpp, optional_yield y);
527 public:
528 RGWRealm() {}
529 RGWRealm(const std::string& _id, const std::string& _name = "") : RGWSystemMetaObj(_id, _name) {}
530 RGWRealm(CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_cct, _sysobj_svc) {}
531 RGWRealm(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_name, _cct, _sysobj_svc){}
532 virtual ~RGWRealm() override;
533
534 void encode(bufferlist& bl) const override {
535 ENCODE_START(1, 1, bl);
536 RGWSystemMetaObj::encode(bl);
537 encode(current_period, bl);
538 encode(epoch, bl);
539 ENCODE_FINISH(bl);
540 }
541
542 void decode(bufferlist::const_iterator& bl) override {
543 DECODE_START(1, bl);
544 RGWSystemMetaObj::decode(bl);
545 decode(current_period, bl);
546 decode(epoch, bl);
547 DECODE_FINISH(bl);
548 }
549
550 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override;
551 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y);
552 rgw_pool get_pool(CephContext *cct) const override;
553 const std::string get_default_oid(bool old_format = false) const override;
554 const std::string& get_names_oid_prefix() const override;
555 const std::string& get_info_oid_prefix(bool old_format = false) const override;
556 std::string get_predefined_id(CephContext *cct) const override;
557 const std::string& get_predefined_name(CephContext *cct) const override;
558
559 using RGWSystemMetaObj::read_id; // expose as public for radosgw-admin
560
561 void dump(Formatter *f) const;
562 void decode_json(JSONObj *obj);
563 static void generate_test_instances(std::list<RGWRealm*>& o);
564
565 const std::string& get_current_period() const {
566 return current_period;
567 }
568 int set_current_period(const DoutPrefixProvider *dpp, RGWPeriod& period, optional_yield y);
569 void clear_current_period_and_epoch() {
570 current_period.clear();
571 epoch = 0;
572 }
573 epoch_t get_epoch() const { return epoch; }
574
575 std::string get_control_oid() const;
576 /// send a notify on the realm control object
577 int notify_zone(const DoutPrefixProvider *dpp, bufferlist& bl, optional_yield y);
578 /// notify the zone of a new period
579 int notify_new_period(const DoutPrefixProvider *dpp, const RGWPeriod& period, optional_yield y);
580
581 int find_zone(const DoutPrefixProvider *dpp,
582 const rgw_zone_id& zid,
583 RGWPeriod *pperiod,
584 RGWZoneGroup *pzonegroup,
585 bool *pfound,
586 optional_yield y) const;
587 };
588 WRITE_CLASS_ENCODER(RGWRealm)
589
590 struct RGWPeriodLatestEpochInfo {
591 epoch_t epoch = 0;
592
593 void encode(bufferlist& bl) const {
594 ENCODE_START(1, 1, bl);
595 encode(epoch, bl);
596 ENCODE_FINISH(bl);
597 }
598
599 void decode(bufferlist::const_iterator& bl) {
600 DECODE_START(1, bl);
601 decode(epoch, bl);
602 DECODE_FINISH(bl);
603 }
604
605 void dump(Formatter *f) const;
606 void decode_json(JSONObj *obj);
607 static void generate_test_instances(std::list<RGWPeriodLatestEpochInfo*>& o);
608 };
609 WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo)
610
611
612 /*
613 * The RGWPeriod object contains the entire configuration of a
614 * RGWRealm, including its RGWZoneGroups and RGWZones. Consistency of
615 * this configuration is maintained across all zones by passing around
616 * the RGWPeriod object in its JSON representation.
617 *
618 * If a new configuration changes which zone is the metadata master
619 * zone (i.e., master zone of the master zonegroup), then a new
620 * RGWPeriod::id (a uuid) is generated, its RGWPeriod::realm_epoch is
621 * incremented, and the RGWRealm object is updated to reflect that new
622 * current_period id and epoch. If the configuration changes BUT which
623 * zone is the metadata master does NOT change, then only the
624 * RGWPeriod::epoch is incremented (and the RGWPeriod::id remains the
625 * same).
626 *
627 * When a new RGWPeriod is created with a new RGWPeriod::id (uuid), it
628 * is linked back to its predecessor RGWPeriod through the
629 * RGWPeriod::predecessor_uuid field, thus creating a "linked
630 * list"-like structure of RGWPeriods back to the cluster's creation.
631 */
632 class RGWPeriod
633 {
634 public:
635 std::string id; //< a uuid
636 epoch_t epoch{0};
637 std::string predecessor_uuid;
638 std::vector<std::string> sync_status;
639 RGWPeriodMap period_map;
640 RGWPeriodConfig period_config;
641 std::string master_zonegroup;
642 rgw_zone_id master_zone;
643
644 std::string realm_id;
645 std::string realm_name;
646 epoch_t realm_epoch{1}; //< realm epoch when period was made current
647
648 CephContext *cct{nullptr};
649 RGWSI_SysObj *sysobj_svc{nullptr};
650
651 int read_info(const DoutPrefixProvider *dpp, optional_yield y);
652 int read_latest_epoch(const DoutPrefixProvider *dpp,
653 RGWPeriodLatestEpochInfo& epoch_info,
654 optional_yield y,
655 RGWObjVersionTracker *objv = nullptr);
656 int use_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y);
657 int use_current_period();
658
659 const std::string get_period_oid() const;
660 const std::string get_period_oid_prefix() const;
661
662 // gather the metadata sync status for each shard; only for use on master zone
663 int update_sync_status(const DoutPrefixProvider *dpp,
664 rgw::sal::Driver* driver,
665 const RGWPeriod &current_period,
666 std::ostream& error_stream, bool force_if_stale);
667
668 public:
669 RGWPeriod() {}
670
671 explicit RGWPeriod(const std::string& period_id, epoch_t _epoch = 0)
672 : id(period_id), epoch(_epoch) {}
673
674 const std::string& get_id() const { return id; }
675 epoch_t get_epoch() const { return epoch; }
676 epoch_t get_realm_epoch() const { return realm_epoch; }
677 const std::string& get_predecessor() const { return predecessor_uuid; }
678 const rgw_zone_id& get_master_zone() const { return master_zone; }
679 const std::string& get_master_zonegroup() const { return master_zonegroup; }
680 const std::string& get_realm() const { return realm_id; }
681 const std::string& get_realm_name() const { return realm_name; }
682 const RGWPeriodMap& get_map() const { return period_map; }
683 RGWPeriodConfig& get_config() { return period_config; }
684 const RGWPeriodConfig& get_config() const { return period_config; }
685 const std::vector<std::string>& get_sync_status() const { return sync_status; }
686 rgw_pool get_pool(CephContext *cct) const;
687 const std::string& get_latest_epoch_oid() const;
688 const std::string& get_info_oid_prefix() const;
689
690 void set_user_quota(RGWQuotaInfo& user_quota) {
691 period_config.quota.user_quota = user_quota;
692 }
693
694 void set_bucket_quota(RGWQuotaInfo& bucket_quota) {
695 period_config.quota.bucket_quota = bucket_quota;
696 }
697
698 void set_id(const std::string& _id) {
699 this->id = _id;
700 period_map.id = _id;
701 }
702 void set_epoch(epoch_t epoch) { this->epoch = epoch; }
703 void set_realm_epoch(epoch_t epoch) { realm_epoch = epoch; }
704
705 void set_predecessor(const std::string& predecessor)
706 {
707 predecessor_uuid = predecessor;
708 }
709
710 void set_realm_id(const std::string& _realm_id) {
711 realm_id = _realm_id;
712 }
713
714 int reflect(const DoutPrefixProvider *dpp, optional_yield y);
715
716 int get_zonegroup(RGWZoneGroup& zonegroup,
717 const std::string& zonegroup_id) const;
718
719 bool is_single_zonegroup() const
720 {
721 return (period_map.zonegroups.size() <= 1);
722 }
723
724 /*
725 returns true if there are several zone groups with a least one zone
726 */
727 bool is_multi_zonegroups_with_zones() const
728 {
729 int count = 0;
730 for (const auto& zg: period_map.zonegroups) {
731 if (zg.second.zones.size() > 0) {
732 if (count++ > 0) {
733 return true;
734 }
735 }
736 }
737 return false;
738 }
739
740 bool find_zone(const DoutPrefixProvider *dpp,
741 const rgw_zone_id& zid,
742 RGWZoneGroup *pzonegroup,
743 optional_yield y) const;
744
745 int get_latest_epoch(const DoutPrefixProvider *dpp, epoch_t& epoch, optional_yield y);
746 int set_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y,
747 epoch_t epoch, bool exclusive = false,
748 RGWObjVersionTracker *objv = nullptr);
749 // update latest_epoch if the given epoch is higher, else return -EEXIST
750 int update_latest_epoch(const DoutPrefixProvider *dpp, epoch_t epoch, optional_yield y);
751
752 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, const std::string &period_realm_id, optional_yield y,
753 const std::string &period_realm_name = "", bool setup_obj = true);
754 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y, bool setup_obj = true);
755
756 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true);
757 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y);
758 int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
759 int add_zonegroup(const DoutPrefixProvider *dpp, const RGWZoneGroup& zonegroup, optional_yield y);
760
761 void fork();
762 int update(const DoutPrefixProvider *dpp, optional_yield y);
763
764 // commit a staging period; only for use on master zone
765 int commit(const DoutPrefixProvider *dpp,
766 rgw::sal::Driver* driver,
767 RGWRealm& realm, const RGWPeriod &current_period,
768 std::ostream& error_stream, optional_yield y,
769 bool force_if_stale = false);
770
771 void encode(bufferlist& bl) const {
772 ENCODE_START(1, 1, bl);
773 encode(id, bl);
774 encode(epoch, bl);
775 encode(realm_epoch, bl);
776 encode(predecessor_uuid, bl);
777 encode(sync_status, bl);
778 encode(period_map, bl);
779 encode(master_zone, bl);
780 encode(master_zonegroup, bl);
781 encode(period_config, bl);
782 encode(realm_id, bl);
783 encode(realm_name, bl);
784 ENCODE_FINISH(bl);
785 }
786
787 void decode(bufferlist::const_iterator& bl) {
788 DECODE_START(1, bl);
789 decode(id, bl);
790 decode(epoch, bl);
791 decode(realm_epoch, bl);
792 decode(predecessor_uuid, bl);
793 decode(sync_status, bl);
794 decode(period_map, bl);
795 decode(master_zone, bl);
796 decode(master_zonegroup, bl);
797 decode(period_config, bl);
798 decode(realm_id, bl);
799 decode(realm_name, bl);
800 DECODE_FINISH(bl);
801 }
802 void dump(Formatter *f) const;
803 void decode_json(JSONObj *obj);
804 static void generate_test_instances(std::list<RGWPeriod*>& o);
805
806 static std::string get_staging_id(const std::string& realm_id) {
807 return realm_id + ":staging";
808 }
809 };
810 WRITE_CLASS_ENCODER(RGWPeriod)
811
812 namespace rgw {
813
814 /// Look up a realm by its id. If no id is given, look it up by name.
815 /// If no name is given, fall back to the cluster's default realm.
816 int read_realm(const DoutPrefixProvider* dpp, optional_yield y,
817 sal::ConfigStore* cfgstore,
818 std::string_view realm_id,
819 std::string_view realm_name,
820 RGWRealm& info,
821 std::unique_ptr<sal::RealmWriter>* writer = nullptr);
822
823 /// Create a realm and its initial period. If the info.id is empty, a
824 /// random uuid will be generated.
825 int create_realm(const DoutPrefixProvider* dpp, optional_yield y,
826 sal::ConfigStore* cfgstore, bool exclusive,
827 RGWRealm& info,
828 std::unique_ptr<sal::RealmWriter>* writer = nullptr);
829
830 /// Set the given realm as the cluster's default realm.
831 int set_default_realm(const DoutPrefixProvider* dpp, optional_yield y,
832 sal::ConfigStore* cfgstore, const RGWRealm& info,
833 bool exclusive = false);
834
835 /// Update the current_period of an existing realm.
836 int realm_set_current_period(const DoutPrefixProvider* dpp, optional_yield y,
837 sal::ConfigStore* cfgstore,
838 sal::RealmWriter& writer, RGWRealm& realm,
839 const RGWPeriod& period);
840
841 /// Overwrite the local zonegroup and period config objects with the new
842 /// configuration contained in the given period.
843 int reflect_period(const DoutPrefixProvider* dpp, optional_yield y,
844 sal::ConfigStore* cfgstore, const RGWPeriod& info);
845
846 /// Return the staging period id for the given realm.
847 std::string get_staging_period_id(std::string_view realm_id);
848
849 /// Convert the given period into a separate staging period, where
850 /// radosgw-admin can make changes to it without effecting the running
851 /// configuration.
852 void fork_period(const DoutPrefixProvider* dpp, RGWPeriod& info);
853
854 /// Read all zonegroups in the period's realm and add them to the period.
855 int update_period(const DoutPrefixProvider* dpp, optional_yield y,
856 sal::ConfigStore* cfgstore, RGWPeriod& info);
857
858 /// Validates the given 'staging' period and tries to commit it as the
859 /// realm's new current period.
860 int commit_period(const DoutPrefixProvider* dpp, optional_yield y,
861 sal::ConfigStore* cfgstore, sal::Driver* driver,
862 RGWRealm& realm, sal::RealmWriter& realm_writer,
863 const RGWPeriod& current_period,
864 RGWPeriod& info, std::ostream& error_stream,
865 bool force_if_stale);
866
867
868 /// Look up a zonegroup by its id. If no id is given, look it up by name.
869 /// If no name is given, fall back to the cluster's default zonegroup.
870 int read_zonegroup(const DoutPrefixProvider* dpp, optional_yield y,
871 sal::ConfigStore* cfgstore,
872 std::string_view zonegroup_id,
873 std::string_view zonegroup_name,
874 RGWZoneGroup& info,
875 std::unique_ptr<sal::ZoneGroupWriter>* writer = nullptr);
876
877 /// Initialize and create the given zonegroup. If the given info.id is empty,
878 /// a random uuid will be generated. May fail with -EEXIST.
879 int create_zonegroup(const DoutPrefixProvider* dpp, optional_yield y,
880 sal::ConfigStore* cfgstore, bool exclusive,
881 RGWZoneGroup& info);
882
883 /// Set the given zonegroup as its realm's default zonegroup.
884 int set_default_zonegroup(const DoutPrefixProvider* dpp, optional_yield y,
885 sal::ConfigStore* cfgstore, const RGWZoneGroup& info,
886 bool exclusive = false);
887
888 /// Add a zone to the zonegroup, or update an existing zone entry.
889 int add_zone_to_group(const DoutPrefixProvider* dpp,
890 RGWZoneGroup& zonegroup,
891 const RGWZoneParams& zone_params,
892 const bool *pis_master, const bool *pread_only,
893 const std::list<std::string>& endpoints,
894 const std::string *ptier_type,
895 const bool *psync_from_all,
896 const std::list<std::string>& sync_from,
897 const std::list<std::string>& sync_from_rm,
898 const std::string *predirect_zone,
899 std::optional<int> bucket_index_max_shards,
900 const rgw::zone_features::set& enable_features,
901 const rgw::zone_features::set& disable_features);
902
903 /// Remove a zone by id from its zonegroup, promoting a new master zone if
904 /// necessary.
905 int remove_zone_from_group(const DoutPrefixProvider* dpp,
906 RGWZoneGroup& info,
907 const rgw_zone_id& zone_id);
908
909
910 /// Look up a zone by its id. If no id is given, look it up by name. If no name
911 /// is given, fall back to the realm's default zone.
912 int read_zone(const DoutPrefixProvider* dpp, optional_yield y,
913 sal::ConfigStore* cfgstore,
914 std::string_view zone_id,
915 std::string_view zone_name,
916 RGWZoneParams& info,
917 std::unique_ptr<sal::ZoneWriter>* writer = nullptr);
918
919 /// Initialize and create a new zone. If the given info.id is empty, a random
920 /// uuid will be generated. Pool names are initialized with the zone name as a
921 /// prefix. If any pool names conflict with existing zones, a random suffix is
922 /// added.
923 int create_zone(const DoutPrefixProvider* dpp, optional_yield y,
924 sal::ConfigStore* cfgstore, bool exclusive,
925 RGWZoneParams& info,
926 std::unique_ptr<sal::ZoneWriter>* writer = nullptr);
927
928 /// Initialize the zone's pool names using the zone name as a prefix. If a pool
929 /// name conflicts with an existing zone's pool, add a unique suffix.
930 int init_zone_pool_names(const DoutPrefixProvider *dpp, optional_yield y,
931 const std::set<rgw_pool>& pools, RGWZoneParams& info);
932
933 /// Set the given zone as its realm's default zone.
934 int set_default_zone(const DoutPrefixProvider* dpp, optional_yield y,
935 sal::ConfigStore* cfgstore, const RGWZoneParams& info,
936 bool exclusive = false);
937
938 /// Delete an existing zone and remove it from any zonegroups that contain it.
939 int delete_zone(const DoutPrefixProvider* dpp, optional_yield y,
940 sal::ConfigStore* cfgstore, const RGWZoneParams& info,
941 sal::ZoneWriter& writer);
942
943 } // namespace rgw