]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_zone.h
import ceph quincy 17.2.6
[ceph.git] / ceph / src / rgw / rgw_zone.h
CommitLineData
11fdf7f2 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
11fdf7f2
TL
3
4#ifndef CEPH_RGW_ZONE_H
5#define CEPH_RGW_ZONE_H
6
7#include "rgw_common.h"
9f95a23c 8#include "rgw_sync_policy.h"
11fdf7f2
TL
9
10namespace rgw_zone_defaults {
11
12extern std::string zone_names_oid_prefix;
13extern std::string region_info_oid_prefix;
14extern std::string realm_names_oid_prefix;
15extern std::string zone_group_info_oid_prefix;
16extern std::string realm_info_oid_prefix;
17extern std::string default_region_info_oid;
18extern std::string default_zone_group_info_oid;
19extern std::string region_map_oid;
20extern std::string default_realm_info_oid;
21extern std::string default_zonegroup_name;
22extern std::string default_zone_name;
23extern std::string zonegroup_names_oid_prefix;
24extern std::string RGW_DEFAULT_ZONE_ROOT_POOL;
25extern std::string RGW_DEFAULT_ZONEGROUP_ROOT_POOL;
26extern std::string RGW_DEFAULT_REALM_ROOT_POOL;
27extern std::string RGW_DEFAULT_PERIOD_ROOT_POOL;
28extern std::string avail_pools;
29extern std::string default_storage_pool_suffix;
30
31}
32
33class JSONObj;
34class RGWSyncModulesManager;
35
9f95a23c 36
11fdf7f2
TL
37struct RGWNameToId {
38 std::string obj_id;
39
40 void encode(bufferlist& bl) const {
41 ENCODE_START(1, 1, bl);
42 encode(obj_id, bl);
43 ENCODE_FINISH(bl);
44 }
45
46 void decode(bufferlist::const_iterator& bl) {
47 DECODE_START(1, bl);
48 decode(obj_id, bl);
49 DECODE_FINISH(bl);
50 }
51
52 void dump(Formatter *f) const;
53 void decode_json(JSONObj *obj);
54};
55WRITE_CLASS_ENCODER(RGWNameToId)
56
57struct RGWDefaultSystemMetaObjInfo {
58 std::string default_id;
59
60 void encode(bufferlist& bl) const {
61 ENCODE_START(1, 1, bl);
62 encode(default_id, bl);
63 ENCODE_FINISH(bl);
64 }
65
66 void decode(bufferlist::const_iterator& bl) {
67 DECODE_START(1, bl);
68 decode(default_id, bl);
69 DECODE_FINISH(bl);
70 }
71
72 void dump(Formatter *f) const;
73 void decode_json(JSONObj *obj);
74};
75WRITE_CLASS_ENCODER(RGWDefaultSystemMetaObjInfo)
76
77class RGWSI_SysObj;
78class RGWSI_Zone;
79
80class RGWSystemMetaObj {
81protected:
82 std::string id;
83 std::string name;
84
85 CephContext *cct{nullptr};
86 RGWSI_SysObj *sysobj_svc{nullptr};
87 RGWSI_Zone *zone_svc{nullptr};
88
b3b6e05e
TL
89 int store_name(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
90 int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
91 int read_info(const DoutPrefixProvider *dpp, const std::string& obj_id, optional_yield y, bool old_format = false);
92 int read_id(const DoutPrefixProvider *dpp, const std::string& obj_name, std::string& obj_id, optional_yield y);
93 int read_default(const DoutPrefixProvider *dpp,
94 RGWDefaultSystemMetaObjInfo& default_info,
f67539c2
TL
95 const std::string& oid,
96 optional_yield y);
11fdf7f2 97 /* read and use default id */
b3b6e05e 98 int use_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
11fdf7f2
TL
99
100public:
101 RGWSystemMetaObj() {}
102 RGWSystemMetaObj(const std::string& _name): name(_name) {}
103 RGWSystemMetaObj(const std::string& _id, const std::string& _name) : id(_id), name(_name) {}
104 RGWSystemMetaObj(CephContext *_cct, RGWSI_SysObj *_sysobj_svc) {
105 reinit_instance(_cct, _sysobj_svc);
106 }
107 RGWSystemMetaObj(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): name(_name) {
108 reinit_instance(_cct, _sysobj_svc);
109 }
110
111 const std::string& get_name() const { return name; }
112 const std::string& get_id() const { return id; }
113
114 void set_name(const std::string& _name) { name = _name;}
115 void set_id(const std::string& _id) { id = _id;}
116 void clear_id() { id.clear(); }
117
118 virtual ~RGWSystemMetaObj() {}
119
120 virtual void encode(bufferlist& bl) const {
121 ENCODE_START(1, 1, bl);
122 encode(id, bl);
123 encode(name, bl);
124 ENCODE_FINISH(bl);
125 }
126
127 virtual void decode(bufferlist::const_iterator& bl) {
128 DECODE_START(1, bl);
129 decode(id, bl);
130 decode(name, bl);
131 DECODE_FINISH(bl);
132 }
133
134 void reinit_instance(CephContext *_cct, RGWSI_SysObj *_sysobj_svc);
b3b6e05e 135 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc,
f67539c2
TL
136 optional_yield y,
137 bool setup_obj = true, bool old_format = false);
b3b6e05e 138 virtual int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y,
f67539c2 139 bool old_format = false);
b3b6e05e 140 virtual int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false);
11fdf7f2 141 int delete_default();
b3b6e05e
TL
142 virtual int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true);
143 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
144 int rename(const DoutPrefixProvider *dpp, const std::string& new_name, optional_yield y);
145 int update(const DoutPrefixProvider *dpp, optional_yield y) { return store_info(dpp, false, y);}
146 int update_name(const DoutPrefixProvider *dpp, optional_yield y) { return store_name(dpp, false, y);}
147 int read(const DoutPrefixProvider *dpp, optional_yield y);
148 int write(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
11fdf7f2
TL
149
150 virtual rgw_pool get_pool(CephContext *cct) const = 0;
151 virtual const std::string get_default_oid(bool old_format = false) const = 0;
152 virtual const std::string& get_names_oid_prefix() const = 0;
153 virtual const std::string& get_info_oid_prefix(bool old_format = false) const = 0;
20effc67 154 virtual std::string get_predefined_id(CephContext *cct) const = 0;
11fdf7f2
TL
155 virtual const std::string& get_predefined_name(CephContext *cct) const = 0;
156
157 void dump(Formatter *f) const;
158 void decode_json(JSONObj *obj);
159};
160WRITE_CLASS_ENCODER(RGWSystemMetaObj)
161
162struct RGWZoneStorageClass {
163 boost::optional<rgw_pool> data_pool;
164 boost::optional<std::string> compression_type;
165
166 void encode(bufferlist& bl) const {
167 ENCODE_START(1, 1, bl);
168 encode(data_pool, bl);
169 encode(compression_type, bl);
170 ENCODE_FINISH(bl);
171 }
172
173 void decode(bufferlist::const_iterator& bl) {
174 DECODE_START(1, bl);
175 decode(data_pool, bl);
176 decode(compression_type, bl);
177 DECODE_FINISH(bl);
178 }
179
180 void dump(Formatter *f) const;
181 void decode_json(JSONObj *obj);
182};
183WRITE_CLASS_ENCODER(RGWZoneStorageClass)
184
185
186class RGWZoneStorageClasses {
20effc67 187 std::map<std::string, RGWZoneStorageClass> m;
11fdf7f2
TL
188
189 /* in memory only */
190 RGWZoneStorageClass *standard_class;
191
192public:
193 RGWZoneStorageClasses() {
194 standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
195 }
196 RGWZoneStorageClasses(const RGWZoneStorageClasses& rhs) {
197 m = rhs.m;
198 standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
199 }
200 RGWZoneStorageClasses& operator=(const RGWZoneStorageClasses& rhs) {
201 m = rhs.m;
202 standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
203 return *this;
204 }
205
206 const RGWZoneStorageClass& get_standard() const {
207 return *standard_class;
208 }
209
20effc67 210 bool find(const std::string& sc, const RGWZoneStorageClass **pstorage_class) const {
11fdf7f2
TL
211 auto iter = m.find(sc);
212 if (iter == m.end()) {
213 return false;
214 }
215 *pstorage_class = &iter->second;
216 return true;
217 }
218
20effc67 219 bool exists(const std::string& sc) const {
11fdf7f2
TL
220 if (sc.empty()) {
221 return true;
222 }
223 auto iter = m.find(sc);
224 return (iter != m.end());
225 }
226
20effc67 227 const std::map<std::string, RGWZoneStorageClass>& get_all() const {
11fdf7f2
TL
228 return m;
229 }
230
20effc67 231 std::map<std::string, RGWZoneStorageClass>& get_all() {
11fdf7f2
TL
232 return m;
233 }
234
20effc67
TL
235 void set_storage_class(const std::string& sc, const rgw_pool *data_pool, const std::string *compression_type) {
236 const std::string *psc = &sc;
11fdf7f2
TL
237 if (sc.empty()) {
238 psc = &RGW_STORAGE_CLASS_STANDARD;
239 }
240 RGWZoneStorageClass& storage_class = m[*psc];
241 if (data_pool) {
242 storage_class.data_pool = *data_pool;
243 }
244 if (compression_type) {
245 storage_class.compression_type = *compression_type;
246 }
247 }
248
20effc67 249 void remove_storage_class(const std::string& sc) {
9f95a23c
TL
250 if (!sc.empty()) {
251 m.erase(sc);
252 }
253 }
254
11fdf7f2
TL
255 void encode(bufferlist& bl) const {
256 ENCODE_START(1, 1, bl);
257 encode(m, bl);
258 ENCODE_FINISH(bl);
259 }
260
261 void decode(bufferlist::const_iterator& bl) {
262 DECODE_START(1, bl);
263 decode(m, bl);
264 standard_class = &m[RGW_STORAGE_CLASS_STANDARD];
265 DECODE_FINISH(bl);
266 }
267
268 void dump(Formatter *f) const;
269 void decode_json(JSONObj *obj);
270};
271WRITE_CLASS_ENCODER(RGWZoneStorageClasses)
272
273struct RGWZonePlacementInfo {
274 rgw_pool index_pool;
275 rgw_pool data_extra_pool; /* if not set we should use data_pool */
276 RGWZoneStorageClasses storage_classes;
f67539c2 277 rgw::BucketIndexType index_type;
39ae355f 278 bool inline_data;
11fdf7f2 279
39ae355f 280 RGWZonePlacementInfo() : index_type(rgw::BucketIndexType::Normal), inline_data(true) {}
11fdf7f2
TL
281
282 void encode(bufferlist& bl) const {
39ae355f 283 ENCODE_START(8, 1, bl);
11fdf7f2
TL
284 encode(index_pool.to_str(), bl);
285 rgw_pool standard_data_pool = get_data_pool(RGW_STORAGE_CLASS_STANDARD);
286 encode(standard_data_pool.to_str(), bl);
287 encode(data_extra_pool.to_str(), bl);
288 encode((uint32_t)index_type, bl);
20effc67 289 std::string standard_compression_type = get_compression_type(RGW_STORAGE_CLASS_STANDARD);
11fdf7f2
TL
290 encode(standard_compression_type, bl);
291 encode(storage_classes, bl);
39ae355f 292 encode(inline_data, bl);
11fdf7f2
TL
293 ENCODE_FINISH(bl);
294 }
295
296 void decode(bufferlist::const_iterator& bl) {
39ae355f 297 DECODE_START(8, bl);
20effc67
TL
298 std::string index_pool_str;
299 std::string data_pool_str;
11fdf7f2
TL
300 decode(index_pool_str, bl);
301 index_pool = rgw_pool(index_pool_str);
302 decode(data_pool_str, bl);
303 rgw_pool standard_data_pool(data_pool_str);
304 if (struct_v >= 4) {
20effc67 305 std::string data_extra_pool_str;
11fdf7f2
TL
306 decode(data_extra_pool_str, bl);
307 data_extra_pool = rgw_pool(data_extra_pool_str);
308 }
309 if (struct_v >= 5) {
310 uint32_t it;
311 decode(it, bl);
f67539c2 312 index_type = (rgw::BucketIndexType)it;
11fdf7f2 313 }
20effc67 314 std::string standard_compression_type;
11fdf7f2
TL
315 if (struct_v >= 6) {
316 decode(standard_compression_type, bl);
317 }
318 if (struct_v >= 7) {
319 decode(storage_classes, bl);
320 } else {
321 storage_classes.set_storage_class(RGW_STORAGE_CLASS_STANDARD, &standard_data_pool,
322 (!standard_compression_type.empty() ? &standard_compression_type : nullptr));
323 }
39ae355f
TL
324 if (struct_v >= 8) {
325 decode(inline_data, bl);
326 }
11fdf7f2
TL
327 DECODE_FINISH(bl);
328 }
329 const rgw_pool& get_data_extra_pool() const {
330 static rgw_pool no_pool;
331 if (data_extra_pool.empty()) {
332 return storage_classes.get_standard().data_pool.get_value_or(no_pool);
333 }
334 return data_extra_pool;
335 }
20effc67 336 const rgw_pool& get_data_pool(const std::string& sc) const {
11fdf7f2
TL
337 const RGWZoneStorageClass *storage_class;
338 static rgw_pool no_pool;
339
340 if (!storage_classes.find(sc, &storage_class)) {
341 return storage_classes.get_standard().data_pool.get_value_or(no_pool);
342 }
343
344 return storage_class->data_pool.get_value_or(no_pool);
345 }
346 const rgw_pool& get_standard_data_pool() const {
347 return get_data_pool(RGW_STORAGE_CLASS_STANDARD);
348 }
349
20effc67 350 const std::string& get_compression_type(const std::string& sc) const {
11fdf7f2 351 const RGWZoneStorageClass *storage_class;
20effc67 352 static std::string no_compression;
11fdf7f2
TL
353
354 if (!storage_classes.find(sc, &storage_class)) {
355 return no_compression;
356 }
357 return storage_class->compression_type.get_value_or(no_compression);
358 }
359
20effc67 360 bool storage_class_exists(const std::string& sc) const {
11fdf7f2
TL
361 return storage_classes.exists(sc);
362 }
363
364 void dump(Formatter *f) const;
365 void decode_json(JSONObj *obj);
366
367};
368WRITE_CLASS_ENCODER(RGWZonePlacementInfo)
369
370struct RGWZoneParams : RGWSystemMetaObj {
371 rgw_pool domain_root;
11fdf7f2
TL
372 rgw_pool control_pool;
373 rgw_pool gc_pool;
374 rgw_pool lc_pool;
375 rgw_pool log_pool;
376 rgw_pool intent_log_pool;
377 rgw_pool usage_log_pool;
378
379 rgw_pool user_keys_pool;
380 rgw_pool user_email_pool;
381 rgw_pool user_swift_pool;
382 rgw_pool user_uid_pool;
383 rgw_pool roles_pool;
384 rgw_pool reshard_pool;
385 rgw_pool otp_pool;
f91f0fd5 386 rgw_pool oidc_pool;
11fdf7f2
TL
387
388 RGWAccessKey system_key;
389
20effc67 390 std::map<std::string, RGWZonePlacementInfo> placement_pools;
11fdf7f2
TL
391
392 std::string realm_id;
393
394 JSONFormattable tier_config;
395
f67539c2
TL
396 rgw_pool notif_pool;
397
11fdf7f2
TL
398 RGWZoneParams() : RGWSystemMetaObj() {}
399 explicit RGWZoneParams(const std::string& name) : RGWSystemMetaObj(name){}
9f95a23c
TL
400 RGWZoneParams(const rgw_zone_id& id, const std::string& name) : RGWSystemMetaObj(id.id, name) {}
401 RGWZoneParams(const rgw_zone_id& id, const std::string& name, const std::string& _realm_id)
402 : RGWSystemMetaObj(id.id, name), realm_id(_realm_id) {}
11fdf7f2
TL
403
404 rgw_pool get_pool(CephContext *cct) const override;
405 const std::string get_default_oid(bool old_format = false) const override;
406 const std::string& get_names_oid_prefix() const override;
407 const std::string& get_info_oid_prefix(bool old_format = false) const override;
20effc67 408 std::string get_predefined_id(CephContext *cct) const override;
11fdf7f2
TL
409 const std::string& get_predefined_name(CephContext *cct) const override;
410
b3b6e05e
TL
411 int init(const DoutPrefixProvider *dpp,
412 CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y,
f67539c2 413 bool setup_obj = true, bool old_format = false);
11fdf7f2 414 using RGWSystemMetaObj::init;
b3b6e05e
TL
415 int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override;
416 int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override;
417 int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
418 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override;
419 int fix_pool_names(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2 420
20effc67 421 const std::string& get_compression_type(const rgw_placement_rule& placement_rule) const;
11fdf7f2
TL
422
423 void encode(bufferlist& bl) const override {
f67539c2 424 ENCODE_START(14, 1, bl);
11fdf7f2
TL
425 encode(domain_root, bl);
426 encode(control_pool, bl);
427 encode(gc_pool, bl);
428 encode(log_pool, bl);
429 encode(intent_log_pool, bl);
430 encode(usage_log_pool, bl);
431 encode(user_keys_pool, bl);
432 encode(user_email_pool, bl);
433 encode(user_swift_pool, bl);
434 encode(user_uid_pool, bl);
435 RGWSystemMetaObj::encode(bl);
436 encode(system_key, bl);
437 encode(placement_pools, bl);
9f95a23c
TL
438 rgw_pool unused_metadata_heap;
439 encode(unused_metadata_heap, bl);
11fdf7f2
TL
440 encode(realm_id, bl);
441 encode(lc_pool, bl);
20effc67 442 std::map<std::string, std::string, ltstr_nocase> old_tier_config;
11fdf7f2
TL
443 encode(old_tier_config, bl);
444 encode(roles_pool, bl);
445 encode(reshard_pool, bl);
446 encode(otp_pool, bl);
447 encode(tier_config, bl);
f91f0fd5 448 encode(oidc_pool, bl);
f67539c2 449 encode(notif_pool, bl);
11fdf7f2
TL
450 ENCODE_FINISH(bl);
451 }
452
453 void decode(bufferlist::const_iterator& bl) override {
f67539c2 454 DECODE_START(14, bl);
11fdf7f2
TL
455 decode(domain_root, bl);
456 decode(control_pool, bl);
457 decode(gc_pool, bl);
458 decode(log_pool, bl);
459 decode(intent_log_pool, bl);
460 decode(usage_log_pool, bl);
461 decode(user_keys_pool, bl);
462 decode(user_email_pool, bl);
463 decode(user_swift_pool, bl);
464 decode(user_uid_pool, bl);
465 if (struct_v >= 6) {
466 RGWSystemMetaObj::decode(bl);
467 } else if (struct_v >= 2) {
468 decode(name, bl);
469 id = name;
470 }
471 if (struct_v >= 3)
472 decode(system_key, bl);
473 if (struct_v >= 4)
474 decode(placement_pools, bl);
9f95a23c
TL
475 if (struct_v >= 5) {
476 rgw_pool unused_metadata_heap;
477 decode(unused_metadata_heap, bl);
478 }
11fdf7f2
TL
479 if (struct_v >= 6) {
480 decode(realm_id, bl);
481 }
482 if (struct_v >= 7) {
483 decode(lc_pool, bl);
484 } else {
485 lc_pool = log_pool.name + ":lc";
486 }
20effc67 487 std::map<std::string, std::string, ltstr_nocase> old_tier_config;
11fdf7f2
TL
488 if (struct_v >= 8) {
489 decode(old_tier_config, bl);
490 }
491 if (struct_v >= 9) {
492 decode(roles_pool, bl);
493 } else {
494 roles_pool = name + ".rgw.meta:roles";
495 }
496 if (struct_v >= 10) {
497 decode(reshard_pool, bl);
498 } else {
499 reshard_pool = log_pool.name + ":reshard";
500 }
501 if (struct_v >= 11) {
502 ::decode(otp_pool, bl);
503 } else {
504 otp_pool = name + ".rgw.otp";
505 }
506 if (struct_v >= 12) {
507 ::decode(tier_config, bl);
508 } else {
509 for (auto& kv : old_tier_config) {
510 tier_config.set(kv.first, kv.second);
511 }
512 }
f91f0fd5
TL
513 if (struct_v >= 13) {
514 ::decode(oidc_pool, bl);
515 } else {
516 oidc_pool = name + ".rgw.meta:oidc";
517 }
f67539c2
TL
518 if (struct_v >= 14) {
519 decode(notif_pool, bl);
520 } else {
521 notif_pool = log_pool.name + ":notif";
522 }
11fdf7f2
TL
523 DECODE_FINISH(bl);
524 }
525 void dump(Formatter *f) const;
526 void decode_json(JSONObj *obj);
20effc67 527 static void generate_test_instances(std::list<RGWZoneParams*>& o);
11fdf7f2
TL
528
529 bool get_placement(const std::string& placement_id, RGWZonePlacementInfo *placement) const {
530 auto iter = placement_pools.find(placement_id);
531 if (iter == placement_pools.end()) {
532 return false;
533 }
534 *placement = iter->second;
535 return true;
536 }
537
538 /*
539 * return data pool of the head object
540 */
541 bool get_head_data_pool(const rgw_placement_rule& placement_rule, const rgw_obj& obj, rgw_pool *pool) const {
542 const rgw_data_placement_target& explicit_placement = obj.bucket.explicit_placement;
543 if (!explicit_placement.data_pool.empty()) {
544 if (!obj.in_extra_data) {
545 *pool = explicit_placement.data_pool;
546 } else {
547 *pool = explicit_placement.get_data_extra_pool();
548 }
549 return true;
550 }
551 if (placement_rule.empty()) {
552 return false;
553 }
554 auto iter = placement_pools.find(placement_rule.name);
555 if (iter == placement_pools.end()) {
556 return false;
557 }
558 if (!obj.in_extra_data) {
559 *pool = iter->second.get_data_pool(placement_rule.storage_class);
560 } else {
561 *pool = iter->second.get_data_extra_pool();
562 }
563 return true;
564 }
565
566 bool valid_placement(const rgw_placement_rule& rule) const {
567 auto iter = placement_pools.find(rule.name);
568 if (iter == placement_pools.end()) {
569 return false;
570 }
571 return iter->second.storage_class_exists(rule.storage_class);
572 }
573};
574WRITE_CLASS_ENCODER(RGWZoneParams)
575
576struct RGWZone {
577 std::string id;
578 std::string name;
20effc67 579 std::list<std::string> endpoints;
11fdf7f2
TL
580 bool log_meta;
581 bool log_data;
582 bool read_only;
583 std::string tier_type;
584
585 std::string redirect_zone;
586
587/**
588 * Represents the number of shards for the bucket index object, a value of zero
589 * indicates there is no sharding. By default (no sharding, the name of the object
590 * is '.dir.{marker}', with sharding, the name is '.dir.{marker}.{sharding_id}',
591 * sharding_id is zero-based value. It is not recommended to set a too large value
592 * (e.g. thousand) as it increases the cost for bucket listing.
593 */
594 uint32_t bucket_index_max_shards;
595
9f95a23c
TL
596 // pre-shard buckets on creation to enable some write-parallism by default,
597 // delay the need to reshard as the bucket grows, and (in multisite) get some
598 // bucket index sharding where dynamic resharding is not supported
599 static constexpr uint32_t default_bucket_index_max_shards = 11;
600
11fdf7f2 601 bool sync_from_all;
20effc67 602 std::set<std::string> sync_from; /* list of zones to sync from */
11fdf7f2 603
9f95a23c
TL
604 RGWZone()
605 : log_meta(false), log_data(false), read_only(false),
606 bucket_index_max_shards(default_bucket_index_max_shards),
607 sync_from_all(true) {}
11fdf7f2
TL
608
609 void encode(bufferlist& bl) const {
610 ENCODE_START(7, 1, bl);
611 encode(name, bl);
612 encode(endpoints, bl);
613 encode(log_meta, bl);
614 encode(log_data, bl);
615 encode(bucket_index_max_shards, bl);
616 encode(id, bl);
617 encode(read_only, bl);
618 encode(tier_type, bl);
619 encode(sync_from_all, bl);
620 encode(sync_from, bl);
621 encode(redirect_zone, bl);
622 ENCODE_FINISH(bl);
623 }
624
625 void decode(bufferlist::const_iterator& bl) {
626 DECODE_START(7, bl);
627 decode(name, bl);
628 if (struct_v < 4) {
629 id = name;
630 }
631 decode(endpoints, bl);
632 if (struct_v >= 2) {
633 decode(log_meta, bl);
634 decode(log_data, bl);
635 }
636 if (struct_v >= 3) {
637 decode(bucket_index_max_shards, bl);
638 }
639 if (struct_v >= 4) {
640 decode(id, bl);
641 decode(read_only, bl);
642 }
643 if (struct_v >= 5) {
644 decode(tier_type, bl);
645 }
646 if (struct_v >= 6) {
647 decode(sync_from_all, bl);
648 decode(sync_from, bl);
649 }
650 if (struct_v >= 7) {
651 decode(redirect_zone, bl);
652 }
653 DECODE_FINISH(bl);
654 }
655 void dump(Formatter *f) const;
656 void decode_json(JSONObj *obj);
20effc67 657 static void generate_test_instances(std::list<RGWZone*>& o);
11fdf7f2
TL
658
659 bool is_read_only() const { return read_only; }
660
494da23a
TL
661 bool syncs_from(const std::string& zone_name) const {
662 return (sync_from_all || sync_from.find(zone_name) != sync_from.end());
11fdf7f2
TL
663 }
664};
665WRITE_CLASS_ENCODER(RGWZone)
666
667struct RGWDefaultZoneGroupInfo {
668 std::string default_zonegroup;
669
670 void encode(bufferlist& bl) const {
671 ENCODE_START(1, 1, bl);
672 encode(default_zonegroup, bl);
673 ENCODE_FINISH(bl);
674 }
675
676 void decode(bufferlist::const_iterator& bl) {
677 DECODE_START(1, bl);
678 decode(default_zonegroup, bl);
679 DECODE_FINISH(bl);
680 }
681 void dump(Formatter *f) const;
682 void decode_json(JSONObj *obj);
683 //todo: implement ceph-dencoder
684};
685WRITE_CLASS_ENCODER(RGWDefaultZoneGroupInfo)
686
20effc67
TL
687struct RGWTierACLMapping {
688 ACLGranteeTypeEnum type{ACL_TYPE_CANON_USER};
689 std::string source_id;
690 std::string dest_id;
691
692 RGWTierACLMapping() = default;
693
694 RGWTierACLMapping(ACLGranteeTypeEnum t,
695 const std::string& s,
696 const std::string& d) : type(t),
697 source_id(s),
698 dest_id(d) {}
699
700 void init(const JSONFormattable& config) {
701 const std::string& t = config["type"];
702
703 if (t == "email") {
704 type = ACL_TYPE_EMAIL_USER;
705 } else if (t == "uri") {
706 type = ACL_TYPE_GROUP;
707 } else {
708 type = ACL_TYPE_CANON_USER;
709 }
710
711 source_id = config["source_id"];
712 dest_id = config["dest_id"];
713 }
714
715 void encode(bufferlist& bl) const {
716 ENCODE_START(1, 1, bl);
717 encode((uint32_t)type, bl);
718 encode(source_id, bl);
719 encode(dest_id, bl);
720 ENCODE_FINISH(bl);
721 }
722
723 void decode(bufferlist::const_iterator& bl) {
724 DECODE_START(1, bl);
725 uint32_t it;
726 decode(it, bl);
727 type = (ACLGranteeTypeEnum)it;
728 decode(source_id, bl);
729 decode(dest_id, bl);
730 DECODE_FINISH(bl);
731 }
732 void dump(Formatter *f) const;
733 void decode_json(JSONObj *obj);
734};
735WRITE_CLASS_ENCODER(RGWTierACLMapping)
736
737struct RGWZoneGroupPlacementTierS3 {
738#define DEFAULT_MULTIPART_SYNC_PART_SIZE (32 * 1024 * 1024)
739 std::string endpoint;
740 RGWAccessKey key;
741 std::string region;
742 HostStyle host_style{PathStyle};
743 std::string target_storage_class;
744
745 /* Should below be bucket/zone specific?? */
746 std::string target_path;
747 std::map<std::string, RGWTierACLMapping> acl_mappings;
748
749 uint64_t multipart_sync_threshold{DEFAULT_MULTIPART_SYNC_PART_SIZE};
750 uint64_t multipart_min_part_size{DEFAULT_MULTIPART_SYNC_PART_SIZE};
751
752 int update_params(const JSONFormattable& config);
753 int clear_params(const JSONFormattable& config);
754
755 void encode(bufferlist& bl) const {
756 ENCODE_START(1, 1, bl);
757 encode(endpoint, bl);
758 encode(key, bl);
759 encode(region, bl);
760 encode((uint32_t)host_style, bl);
761 encode(target_storage_class, bl);
762 encode(target_path, bl);
763 encode(acl_mappings, bl);
764 encode(multipart_sync_threshold, bl);
765 encode(multipart_min_part_size, bl);
766 ENCODE_FINISH(bl);
767 }
768
769 void decode(bufferlist::const_iterator& bl) {
770 DECODE_START(1, bl);
771 decode(endpoint, bl);
772 decode(key, bl);
773 decode(region, bl);
774
775 uint32_t it;
776 decode(it, bl);
777 host_style = (HostStyle)it;
778
779 decode(target_storage_class, bl);
780 decode(target_path, bl);
781 decode(acl_mappings, bl);
782 decode(multipart_sync_threshold, bl);
783 decode(multipart_min_part_size, bl);
784 DECODE_FINISH(bl);
785 }
786 void dump(Formatter *f) const;
787 void decode_json(JSONObj *obj);
788};
789WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTierS3)
790
791struct RGWZoneGroupPlacementTier {
792 std::string tier_type;
793 std::string storage_class;
794 bool retain_head_object = false;
795
796 struct _tier {
797 RGWZoneGroupPlacementTierS3 s3;
798 } t;
799
800 int update_params(const JSONFormattable& config);
801 int clear_params(const JSONFormattable& config);
802
803 void encode(bufferlist& bl) const {
804 ENCODE_START(1, 1, bl);
805 encode(tier_type, bl);
806 encode(storage_class, bl);
807 encode(retain_head_object, bl);
808 if (tier_type == "cloud-s3") {
809 encode(t.s3, bl);
810 }
811 ENCODE_FINISH(bl);
812 }
813
814 void decode(bufferlist::const_iterator& bl) {
815 DECODE_START(1, bl);
816 decode(tier_type, bl);
817 decode(storage_class, bl);
818 decode(retain_head_object, bl);
819 if (tier_type == "cloud-s3") {
820 decode(t.s3, bl);
821 }
822 DECODE_FINISH(bl);
823 }
824
825 void dump(Formatter *f) const;
826 void decode_json(JSONObj *obj);
827};
828WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTier)
829
11fdf7f2
TL
830struct RGWZoneGroupPlacementTarget {
831 std::string name;
20effc67
TL
832 std::set<std::string> tags;
833 std::set<std::string> storage_classes;
834 std::map<std::string, RGWZoneGroupPlacementTier> tier_targets;
11fdf7f2 835
20effc67 836 bool user_permitted(const std::list<std::string>& user_tags) const {
11fdf7f2
TL
837 if (tags.empty()) {
838 return true;
839 }
840 for (auto& rule : user_tags) {
841 if (tags.find(rule) != tags.end()) {
842 return true;
843 }
844 }
845 return false;
846 }
847
848 void encode(bufferlist& bl) const {
20effc67 849 ENCODE_START(3, 1, bl);
11fdf7f2
TL
850 encode(name, bl);
851 encode(tags, bl);
852 encode(storage_classes, bl);
20effc67 853 encode(tier_targets, bl);
11fdf7f2
TL
854 ENCODE_FINISH(bl);
855 }
856
857 void decode(bufferlist::const_iterator& bl) {
20effc67 858 DECODE_START(3, bl);
11fdf7f2
TL
859 decode(name, bl);
860 decode(tags, bl);
861 if (struct_v >= 2) {
862 decode(storage_classes, bl);
863 }
864 if (storage_classes.empty()) {
865 storage_classes.insert(RGW_STORAGE_CLASS_STANDARD);
866 }
20effc67
TL
867 if (struct_v >= 3) {
868 decode(tier_targets, bl);
869 }
11fdf7f2
TL
870 DECODE_FINISH(bl);
871 }
872 void dump(Formatter *f) const;
873 void decode_json(JSONObj *obj);
874};
875WRITE_CLASS_ENCODER(RGWZoneGroupPlacementTarget)
876
877struct RGWZoneGroup : public RGWSystemMetaObj {
878 std::string api_name;
20effc67 879 std::list<std::string> endpoints;
11fdf7f2
TL
880 bool is_master = false;
881
9f95a23c 882 rgw_zone_id master_zone;
20effc67 883 std::map<rgw_zone_id, RGWZone> zones;
11fdf7f2 884
20effc67 885 std::map<std::string, RGWZoneGroupPlacementTarget> placement_targets;
11fdf7f2
TL
886 rgw_placement_rule default_placement;
887
20effc67
TL
888 std::list<std::string> hostnames;
889 std::list<std::string> hostnames_s3website;
890 // TODO: Maybe convert hostnames to a map<std::string,std::list<std::string>> for
11fdf7f2
TL
891 // endpoint_type->hostnames
892/*
89320:05 < _robbat21irssi> maybe I do someting like: if (hostname_map.empty()) { populate all map keys from hostnames; };
89420:05 < _robbat21irssi> but that's a later compatability migration planning bit
89520:06 < yehudasa> more like if (!hostnames.empty()) {
20effc67 89620:06 < yehudasa> for (std::list<std::string>::iterator iter = hostnames.begin(); iter != hostnames.end(); ++iter) {
11fdf7f2
TL
89720:06 < yehudasa> hostname_map["s3"].append(iter->second);
89820:07 < yehudasa> hostname_map["s3website"].append(iter->second);
89920:07 < yehudasa> s/append/push_back/g
90020:08 < _robbat21irssi> inner loop over APIs
90120:08 < yehudasa> yeah, probably
90220:08 < _robbat21irssi> s3, s3website, swift, swith_auth, swift_website
903*/
20effc67
TL
904 std::map<std::string, std::list<std::string> > api_hostname_map;
905 std::map<std::string, std::list<std::string> > api_endpoints_map;
11fdf7f2
TL
906
907 std::string realm_id;
908
9f95a23c
TL
909 rgw_sync_policy_info sync_policy;
910
11fdf7f2
TL
911 RGWZoneGroup(): is_master(false){}
912 RGWZoneGroup(const std::string &id, const std::string &name):RGWSystemMetaObj(id, name) {}
913 explicit RGWZoneGroup(const std::string &_name):RGWSystemMetaObj(_name) {}
914 RGWZoneGroup(const std::string &_name, bool _is_master, CephContext *cct, RGWSI_SysObj* sysobj_svc,
20effc67 915 const std::string& _realm_id, const std::list<std::string>& _endpoints)
11fdf7f2
TL
916 : RGWSystemMetaObj(_name, cct , sysobj_svc), endpoints(_endpoints), is_master(_is_master),
917 realm_id(_realm_id) {}
918
919 bool is_master_zonegroup() const { return is_master;}
b3b6e05e 920 void update_master(const DoutPrefixProvider *dpp, bool _is_master, optional_yield y) {
11fdf7f2 921 is_master = _is_master;
b3b6e05e 922 post_process_params(dpp, y);
11fdf7f2 923 }
b3b6e05e 924 void post_process_params(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
925
926 void encode(bufferlist& bl) const override {
9f95a23c 927 ENCODE_START(5, 1, bl);
11fdf7f2
TL
928 encode(name, bl);
929 encode(api_name, bl);
930 encode(is_master, bl);
931 encode(endpoints, bl);
932 encode(master_zone, bl);
933 encode(zones, bl);
934 encode(placement_targets, bl);
935 encode(default_placement, bl);
936 encode(hostnames, bl);
937 encode(hostnames_s3website, bl);
938 RGWSystemMetaObj::encode(bl);
939 encode(realm_id, bl);
9f95a23c 940 encode(sync_policy, bl);
11fdf7f2
TL
941 ENCODE_FINISH(bl);
942 }
943
944 void decode(bufferlist::const_iterator& bl) override {
9f95a23c 945 DECODE_START(5, bl);
11fdf7f2
TL
946 decode(name, bl);
947 decode(api_name, bl);
948 decode(is_master, bl);
949 decode(endpoints, bl);
950 decode(master_zone, bl);
951 decode(zones, bl);
952 decode(placement_targets, bl);
953 decode(default_placement, bl);
954 if (struct_v >= 2) {
955 decode(hostnames, bl);
956 }
957 if (struct_v >= 3) {
958 decode(hostnames_s3website, bl);
959 }
960 if (struct_v >= 4) {
961 RGWSystemMetaObj::decode(bl);
962 decode(realm_id, bl);
963 } else {
964 id = name;
965 }
9f95a23c
TL
966 if (struct_v >= 5) {
967 decode(sync_policy, bl);
968 }
11fdf7f2
TL
969 DECODE_FINISH(bl);
970 }
971
b3b6e05e
TL
972 int read_default_id(const DoutPrefixProvider *dpp, std::string& default_id, optional_yield y, bool old_format = false) override;
973 int set_as_default(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = false) override;
974 int create_default(const DoutPrefixProvider *dpp, optional_yield y, bool old_format = false);
11fdf7f2 975 int equals(const std::string& other_zonegroup) const;
b3b6e05e
TL
976 int add_zone(const DoutPrefixProvider *dpp,
977 const RGWZoneParams& zone_params, bool *is_master, bool *read_only,
20effc67
TL
978 const std::list<std::string>& endpoints, const std::string *ptier_type,
979 bool *psync_from_all, std::list<std::string>& sync_from,
980 std::list<std::string>& sync_from_rm, std::string *predirect_zone,
f67539c2
TL
981 std::optional<int> bucket_index_max_shards, RGWSyncModulesManager *sync_mgr,
982 optional_yield y);
b3b6e05e
TL
983 int remove_zone(const DoutPrefixProvider *dpp, const std::string& zone_id, optional_yield y);
984 int rename_zone(const DoutPrefixProvider *dpp, const RGWZoneParams& zone_params, optional_yield y);
11fdf7f2
TL
985 rgw_pool get_pool(CephContext *cct) const override;
986 const std::string get_default_oid(bool old_region_format = false) const override;
987 const std::string& get_info_oid_prefix(bool old_region_format = false) const override;
988 const std::string& get_names_oid_prefix() const override;
20effc67 989 std::string get_predefined_id(CephContext *cct) const override;
11fdf7f2
TL
990 const std::string& get_predefined_name(CephContext *cct) const override;
991
992 void dump(Formatter *f) const;
993 void decode_json(JSONObj *obj);
20effc67 994 static void generate_test_instances(std::list<RGWZoneGroup*>& o);
11fdf7f2
TL
995};
996WRITE_CLASS_ENCODER(RGWZoneGroup)
997
998struct RGWPeriodMap
999{
1000 std::string id;
20effc67
TL
1001 std::map<std::string, RGWZoneGroup> zonegroups;
1002 std::map<std::string, RGWZoneGroup> zonegroups_by_api;
1003 std::map<std::string, uint32_t> short_zone_ids;
11fdf7f2
TL
1004
1005 std::string master_zonegroup;
1006
1007 void encode(bufferlist& bl) const;
1008 void decode(bufferlist::const_iterator& bl);
1009
1010 int update(const RGWZoneGroup& zonegroup, CephContext *cct);
1011
1012 void dump(Formatter *f) const;
1013 void decode_json(JSONObj *obj);
1014
1015 void reset() {
1016 zonegroups.clear();
1017 zonegroups_by_api.clear();
1018 master_zonegroup.clear();
1019 }
1020
1021 uint32_t get_zone_short_id(const std::string& zone_id) const;
20effc67
TL
1022
1023 bool find_zone_by_id(const rgw_zone_id& zone_id,
1024 RGWZoneGroup *zonegroup,
1025 RGWZone *zone) const;
1026 bool find_zone_by_name(const std::string& zone_id,
1027 RGWZoneGroup *zonegroup,
1028 RGWZone *zone) const;
11fdf7f2
TL
1029};
1030WRITE_CLASS_ENCODER(RGWPeriodMap)
1031
1032struct RGWPeriodConfig
1033{
1034 RGWQuotaInfo bucket_quota;
1035 RGWQuotaInfo user_quota;
20effc67
TL
1036 RGWRateLimitInfo user_ratelimit;
1037 RGWRateLimitInfo bucket_ratelimit;
1038 // rate limit unauthenticated user
1039 RGWRateLimitInfo anon_ratelimit;
11fdf7f2
TL
1040
1041 void encode(bufferlist& bl) const {
20effc67 1042 ENCODE_START(2, 1, bl);
11fdf7f2
TL
1043 encode(bucket_quota, bl);
1044 encode(user_quota, bl);
20effc67
TL
1045 encode(bucket_ratelimit, bl);
1046 encode(user_ratelimit, bl);
1047 encode(anon_ratelimit, bl);
11fdf7f2
TL
1048 ENCODE_FINISH(bl);
1049 }
1050
1051 void decode(bufferlist::const_iterator& bl) {
20effc67 1052 DECODE_START(2, bl);
11fdf7f2
TL
1053 decode(bucket_quota, bl);
1054 decode(user_quota, bl);
20effc67
TL
1055 if (struct_v >= 2) {
1056 decode(bucket_ratelimit, bl);
1057 decode(user_ratelimit, bl);
1058 decode(anon_ratelimit, bl);
1059 }
11fdf7f2
TL
1060 DECODE_FINISH(bl);
1061 }
1062
1063 void dump(Formatter *f) const;
1064 void decode_json(JSONObj *obj);
1065
1066 // the period config must be stored in a local object outside of the period,
1067 // so that it can be used in a default configuration where no realm/period
1068 // exists
b3b6e05e
TL
1069 int read(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y);
1070 int write(const DoutPrefixProvider *dpp, RGWSI_SysObj *sysobj_svc, const std::string& realm_id, optional_yield y);
11fdf7f2
TL
1071
1072 static std::string get_oid(const std::string& realm_id);
1073 static rgw_pool get_pool(CephContext *cct);
1074};
1075WRITE_CLASS_ENCODER(RGWPeriodConfig)
1076
1077/* for backward comaptability */
1078struct RGWRegionMap {
1079
20effc67 1080 std::map<std::string, RGWZoneGroup> regions;
11fdf7f2
TL
1081
1082 std::string master_region;
1083
1084 RGWQuotaInfo bucket_quota;
1085 RGWQuotaInfo user_quota;
1086
1087 void encode(bufferlist& bl) const;
1088 void decode(bufferlist::const_iterator& bl);
1089
1090 void dump(Formatter *f) const;
1091 void decode_json(JSONObj *obj);
1092};
1093WRITE_CLASS_ENCODER(RGWRegionMap)
1094
1095struct RGWZoneGroupMap {
1096
20effc67
TL
1097 std::map<std::string, RGWZoneGroup> zonegroups;
1098 std::map<std::string, RGWZoneGroup> zonegroups_by_api;
11fdf7f2
TL
1099
1100 std::string master_zonegroup;
1101
1102 RGWQuotaInfo bucket_quota;
1103 RGWQuotaInfo user_quota;
1104
1105 /* construct the map */
b3b6e05e 1106 int read(const DoutPrefixProvider *dpp, CephContext *cct, RGWSI_SysObj *sysobj_svc, optional_yield y);
11fdf7f2
TL
1107
1108 void encode(bufferlist& bl) const;
1109 void decode(bufferlist::const_iterator& bl);
1110
1111 void dump(Formatter *f) const;
1112 void decode_json(JSONObj *obj);
1113};
1114WRITE_CLASS_ENCODER(RGWZoneGroupMap)
1115
1116class RGWRealm;
1117class RGWPeriod;
1118
1119class RGWRealm : public RGWSystemMetaObj
1120{
1121 std::string current_period;
1122 epoch_t epoch{0}; //< realm epoch, incremented for each new period
1123
b3b6e05e
TL
1124 int create_control(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
1125 int delete_control(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
1126public:
1127 RGWRealm() {}
1128 RGWRealm(const std::string& _id, const std::string& _name = "") : RGWSystemMetaObj(_id, _name) {}
1129 RGWRealm(CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_cct, _sysobj_svc) {}
1130 RGWRealm(const std::string& _name, CephContext *_cct, RGWSI_SysObj *_sysobj_svc): RGWSystemMetaObj(_name, _cct, _sysobj_svc){}
20effc67 1131 virtual ~RGWRealm() override;
11fdf7f2
TL
1132
1133 void encode(bufferlist& bl) const override {
1134 ENCODE_START(1, 1, bl);
1135 RGWSystemMetaObj::encode(bl);
1136 encode(current_period, bl);
1137 encode(epoch, bl);
1138 ENCODE_FINISH(bl);
1139 }
1140
1141 void decode(bufferlist::const_iterator& bl) override {
1142 DECODE_START(1, bl);
1143 RGWSystemMetaObj::decode(bl);
1144 decode(current_period, bl);
1145 decode(epoch, bl);
1146 DECODE_FINISH(bl);
1147 }
1148
b3b6e05e
TL
1149 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true) override;
1150 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
1151 rgw_pool get_pool(CephContext *cct) const override;
1152 const std::string get_default_oid(bool old_format = false) const override;
1153 const std::string& get_names_oid_prefix() const override;
1154 const std::string& get_info_oid_prefix(bool old_format = false) const override;
20effc67 1155 std::string get_predefined_id(CephContext *cct) const override;
11fdf7f2
TL
1156 const std::string& get_predefined_name(CephContext *cct) const override;
1157
1158 using RGWSystemMetaObj::read_id; // expose as public for radosgw-admin
1159
1160 void dump(Formatter *f) const;
1161 void decode_json(JSONObj *obj);
20effc67 1162 static void generate_test_instances(std::list<RGWRealm*>& o);
11fdf7f2
TL
1163
1164 const std::string& get_current_period() const {
1165 return current_period;
1166 }
b3b6e05e 1167 int set_current_period(const DoutPrefixProvider *dpp, RGWPeriod& period, optional_yield y);
11fdf7f2
TL
1168 void clear_current_period_and_epoch() {
1169 current_period.clear();
1170 epoch = 0;
1171 }
1172 epoch_t get_epoch() const { return epoch; }
1173
1174 std::string get_control_oid() const;
1175 /// send a notify on the realm control object
b3b6e05e 1176 int notify_zone(const DoutPrefixProvider *dpp, bufferlist& bl, optional_yield y);
11fdf7f2 1177 /// notify the zone of a new period
b3b6e05e 1178 int notify_new_period(const DoutPrefixProvider *dpp, const RGWPeriod& period, optional_yield y);
20effc67
TL
1179
1180 int find_zone(const DoutPrefixProvider *dpp,
1181 const rgw_zone_id& zid,
1182 RGWPeriod *pperiod,
1183 RGWZoneGroup *pzonegroup,
1184 bool *pfound,
1185 optional_yield y) const;
11fdf7f2
TL
1186};
1187WRITE_CLASS_ENCODER(RGWRealm)
1188
1189struct RGWPeriodLatestEpochInfo {
9f95a23c 1190 epoch_t epoch = 0;
11fdf7f2
TL
1191
1192 void encode(bufferlist& bl) const {
1193 ENCODE_START(1, 1, bl);
1194 encode(epoch, bl);
1195 ENCODE_FINISH(bl);
1196 }
1197
1198 void decode(bufferlist::const_iterator& bl) {
1199 DECODE_START(1, bl);
1200 decode(epoch, bl);
1201 DECODE_FINISH(bl);
1202 }
1203
1204 void dump(Formatter *f) const;
1205 void decode_json(JSONObj *obj);
20effc67 1206 static void generate_test_instances(std::list<RGWPeriodLatestEpochInfo*>& o);
11fdf7f2
TL
1207};
1208WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo)
1209
9f95a23c
TL
1210
1211/*
1212 * The RGWPeriod object contains the entire configuration of a
1213 * RGWRealm, including its RGWZoneGroups and RGWZones. Consistency of
1214 * this configuration is maintained across all zones by passing around
1215 * the RGWPeriod object in its JSON representation.
1216 *
1217 * If a new configuration changes which zone is the metadata master
1218 * zone (i.e., master zone of the master zonegroup), then a new
1219 * RGWPeriod::id (a uuid) is generated, its RGWPeriod::realm_epoch is
1220 * incremented, and the RGWRealm object is updated to reflect that new
1221 * current_period id and epoch. If the configuration changes BUT which
1222 * zone is the metadata master does NOT change, then only the
1223 * RGWPeriod::epoch is incremented (and the RGWPeriod::id remains the
1224 * same).
1225 *
1226 * When a new RGWPeriod is created with a new RGWPeriod::id (uuid), it
1227 * is linked back to its predecessor RGWPeriod through the
1228 * RGWPeriod::predecessor_uuid field, thus creating a "linked
1229 * list"-like structure of RGWPeriods back to the cluster's creation.
1230 */
11fdf7f2
TL
1231class RGWPeriod
1232{
9f95a23c 1233 std::string id; //< a uuid
11fdf7f2
TL
1234 epoch_t epoch{0};
1235 std::string predecessor_uuid;
1236 std::vector<std::string> sync_status;
1237 RGWPeriodMap period_map;
1238 RGWPeriodConfig period_config;
1239 std::string master_zonegroup;
9f95a23c 1240 rgw_zone_id master_zone;
11fdf7f2
TL
1241
1242 std::string realm_id;
1243 std::string realm_name;
1244 epoch_t realm_epoch{1}; //< realm epoch when period was made current
1245
1246 CephContext *cct{nullptr};
1247 RGWSI_SysObj *sysobj_svc{nullptr};
1248
b3b6e05e
TL
1249 int read_info(const DoutPrefixProvider *dpp, optional_yield y);
1250 int read_latest_epoch(const DoutPrefixProvider *dpp,
1251 RGWPeriodLatestEpochInfo& epoch_info,
f67539c2 1252 optional_yield y,
11fdf7f2 1253 RGWObjVersionTracker *objv = nullptr);
b3b6e05e 1254 int use_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
1255 int use_current_period();
1256
1257 const std::string get_period_oid() const;
1258 const std::string get_period_oid_prefix() const;
1259
1260 // gather the metadata sync status for each shard; only for use on master zone
20effc67
TL
1261 int update_sync_status(const DoutPrefixProvider *dpp,
1262 rgw::sal::Store* store,
11fdf7f2
TL
1263 const RGWPeriod &current_period,
1264 std::ostream& error_stream, bool force_if_stale);
1265
1266public:
1267 RGWPeriod() {}
1268
9f95a23c 1269 explicit RGWPeriod(const std::string& period_id, epoch_t _epoch = 0)
11fdf7f2
TL
1270 : id(period_id), epoch(_epoch) {}
1271
1272 const std::string& get_id() const { return id; }
1273 epoch_t get_epoch() const { return epoch; }
1274 epoch_t get_realm_epoch() const { return realm_epoch; }
1275 const std::string& get_predecessor() const { return predecessor_uuid; }
9f95a23c 1276 const rgw_zone_id& get_master_zone() const { return master_zone; }
11fdf7f2
TL
1277 const std::string& get_master_zonegroup() const { return master_zonegroup; }
1278 const std::string& get_realm() const { return realm_id; }
20effc67 1279 const std::string& get_realm_name() const { return realm_name; }
11fdf7f2
TL
1280 const RGWPeriodMap& get_map() const { return period_map; }
1281 RGWPeriodConfig& get_config() { return period_config; }
1282 const RGWPeriodConfig& get_config() const { return period_config; }
1283 const std::vector<std::string>& get_sync_status() const { return sync_status; }
1284 rgw_pool get_pool(CephContext *cct) const;
1285 const std::string& get_latest_epoch_oid() const;
1286 const std::string& get_info_oid_prefix() const;
1287
1288 void set_user_quota(RGWQuotaInfo& user_quota) {
1289 period_config.user_quota = user_quota;
1290 }
1291
1292 void set_bucket_quota(RGWQuotaInfo& bucket_quota) {
1293 period_config.bucket_quota = bucket_quota;
1294 }
1295
20effc67 1296 void set_id(const std::string& _id) {
9f95a23c
TL
1297 this->id = _id;
1298 period_map.id = _id;
11fdf7f2
TL
1299 }
1300 void set_epoch(epoch_t epoch) { this->epoch = epoch; }
1301 void set_realm_epoch(epoch_t epoch) { realm_epoch = epoch; }
1302
1303 void set_predecessor(const std::string& predecessor)
1304 {
1305 predecessor_uuid = predecessor;
1306 }
1307
1308 void set_realm_id(const std::string& _realm_id) {
1309 realm_id = _realm_id;
1310 }
1311
b3b6e05e 1312 int reflect(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
1313
1314 int get_zonegroup(RGWZoneGroup& zonegroup,
1315 const std::string& zonegroup_id) const;
1316
1317 bool is_single_zonegroup() const
1318 {
9f95a23c 1319 return (period_map.zonegroups.size() <= 1);
11fdf7f2
TL
1320 }
1321
1322 /*
1323 returns true if there are several zone groups with a least one zone
1324 */
1325 bool is_multi_zonegroups_with_zones() const
1326 {
1327 int count = 0;
1328 for (const auto& zg: period_map.zonegroups) {
1329 if (zg.second.zones.size() > 0) {
1330 if (count++ > 0) {
1331 return true;
1332 }
1333 }
1334 }
1335 return false;
1336 }
1337
20effc67
TL
1338 bool find_zone(const DoutPrefixProvider *dpp,
1339 const rgw_zone_id& zid,
1340 RGWZoneGroup *pzonegroup,
1341 optional_yield y) const;
1342
b3b6e05e
TL
1343 int get_latest_epoch(const DoutPrefixProvider *dpp, epoch_t& epoch, optional_yield y);
1344 int set_latest_epoch(const DoutPrefixProvider *dpp, optional_yield y,
f67539c2 1345 epoch_t epoch, bool exclusive = false,
11fdf7f2
TL
1346 RGWObjVersionTracker *objv = nullptr);
1347 // update latest_epoch if the given epoch is higher, else return -EEXIST
b3b6e05e 1348 int update_latest_epoch(const DoutPrefixProvider *dpp, epoch_t epoch, optional_yield y);
11fdf7f2 1349
b3b6e05e 1350 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, const std::string &period_realm_id, optional_yield y,
f67539c2 1351 const std::string &period_realm_name = "", bool setup_obj = true);
b3b6e05e 1352 int init(const DoutPrefixProvider *dpp, CephContext *_cct, RGWSI_SysObj *_sysobj_svc, optional_yield y, bool setup_obj = true);
11fdf7f2 1353
b3b6e05e
TL
1354 int create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive = true);
1355 int delete_obj(const DoutPrefixProvider *dpp, optional_yield y);
1356 int store_info(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y);
1357 int add_zonegroup(const DoutPrefixProvider *dpp, const RGWZoneGroup& zonegroup, optional_yield y);
11fdf7f2
TL
1358
1359 void fork();
b3b6e05e 1360 int update(const DoutPrefixProvider *dpp, optional_yield y);
11fdf7f2
TL
1361
1362 // commit a staging period; only for use on master zone
20effc67
TL
1363 int commit(const DoutPrefixProvider *dpp,
1364 rgw::sal::Store* store,
11fdf7f2 1365 RGWRealm& realm, const RGWPeriod &current_period,
f67539c2
TL
1366 std::ostream& error_stream, optional_yield y,
1367 bool force_if_stale = false);
11fdf7f2
TL
1368
1369 void encode(bufferlist& bl) const {
1370 ENCODE_START(1, 1, bl);
1371 encode(id, bl);
1372 encode(epoch, bl);
1373 encode(realm_epoch, bl);
1374 encode(predecessor_uuid, bl);
1375 encode(sync_status, bl);
1376 encode(period_map, bl);
1377 encode(master_zone, bl);
1378 encode(master_zonegroup, bl);
1379 encode(period_config, bl);
1380 encode(realm_id, bl);
1381 encode(realm_name, bl);
1382 ENCODE_FINISH(bl);
1383 }
1384
1385 void decode(bufferlist::const_iterator& bl) {
1386 DECODE_START(1, bl);
1387 decode(id, bl);
1388 decode(epoch, bl);
1389 decode(realm_epoch, bl);
1390 decode(predecessor_uuid, bl);
1391 decode(sync_status, bl);
1392 decode(period_map, bl);
1393 decode(master_zone, bl);
1394 decode(master_zonegroup, bl);
1395 decode(period_config, bl);
1396 decode(realm_id, bl);
1397 decode(realm_name, bl);
1398 DECODE_FINISH(bl);
1399 }
1400 void dump(Formatter *f) const;
1401 void decode_json(JSONObj *obj);
20effc67 1402 static void generate_test_instances(std::list<RGWPeriod*>& o);
11fdf7f2
TL
1403
1404 static std::string get_staging_id(const std::string& realm_id) {
1405 return realm_id + ":staging";
1406 }
1407};
1408WRITE_CLASS_ENCODER(RGWPeriod)
1409
1410#endif