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