]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_realm.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / rgw_realm.cc
CommitLineData
1e59de90
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab ft=cpp
3
4#include <optional>
5
6#include "common/errno.h"
7
8#include "rgw_zone.h"
9#include "rgw_realm_watcher.h"
10#include "rgw_meta_sync_status.h"
11#include "rgw_sal_config.h"
12#include "rgw_string.h"
13#include "rgw_sync.h"
14
15#include "services/svc_zone.h"
16#include "services/svc_sys_obj.h"
17
18#include "common/ceph_json.h"
19#include "common/Formatter.h"
20
21#define dout_context g_ceph_context
22#define dout_subsys ceph_subsys_rgw
23
24namespace rgw_zone_defaults {
25
26std::string realm_info_oid_prefix = "realms.";
27std::string realm_names_oid_prefix = "realms_names.";
28std::string default_realm_info_oid = "default.realm";
29std::string RGW_DEFAULT_REALM_ROOT_POOL = "rgw.root";
30
31}
32
33using namespace std;
34using namespace rgw_zone_defaults;
35
36RGWRealm::~RGWRealm() {}
37
38RGWRemoteMetaLog::~RGWRemoteMetaLog()
39{
40 delete error_logger;
41}
42
43string RGWRealm::get_predefined_id(CephContext *cct) const {
44 return cct->_conf.get_val<string>("rgw_realm_id");
45}
46
47const string& RGWRealm::get_predefined_name(CephContext *cct) const {
48 return cct->_conf->rgw_realm;
49}
50
51int RGWRealm::create(const DoutPrefixProvider *dpp, optional_yield y, bool exclusive)
52{
53 int ret = RGWSystemMetaObj::create(dpp, y, exclusive);
54 if (ret < 0) {
55 ldpp_dout(dpp, 0) << "ERROR creating new realm object " << name << ": " << cpp_strerror(-ret) << dendl;
56 return ret;
57 }
58 // create the control object for watch/notify
59 ret = create_control(dpp, exclusive, y);
60 if (ret < 0) {
61 ldpp_dout(dpp, 0) << "ERROR creating control for new realm " << name << ": " << cpp_strerror(-ret) << dendl;
62 return ret;
63 }
64 RGWPeriod period;
65 if (current_period.empty()) {
66 /* create new period for the realm */
67 ret = period.init(dpp, cct, sysobj_svc, id, y, name, false);
68 if (ret < 0 ) {
69 return ret;
70 }
71 ret = period.create(dpp, y, true);
72 if (ret < 0) {
73 ldpp_dout(dpp, 0) << "ERROR: creating new period for realm " << name << ": " << cpp_strerror(-ret) << dendl;
74 return ret;
75 }
76 } else {
77 period = RGWPeriod(current_period, 0);
78 int ret = period.init(dpp, cct, sysobj_svc, id, y, name);
79 if (ret < 0) {
80 ldpp_dout(dpp, 0) << "ERROR: failed to init period " << current_period << dendl;
81 return ret;
82 }
83 }
84 ret = set_current_period(dpp, period, y);
85 if (ret < 0) {
86 ldpp_dout(dpp, 0) << "ERROR: failed set current period " << current_period << dendl;
87 return ret;
88 }
89 // try to set as default. may race with another create, so pass exclusive=true
90 // so we don't override an existing default
91 ret = set_as_default(dpp, y, true);
92 if (ret < 0 && ret != -EEXIST) {
93 ldpp_dout(dpp, 0) << "WARNING: failed to set realm as default realm, ret=" << ret << dendl;
94 }
95
96 return 0;
97}
98
99int RGWRealm::delete_obj(const DoutPrefixProvider *dpp, optional_yield y)
100{
101 int ret = RGWSystemMetaObj::delete_obj(dpp, y);
102 if (ret < 0) {
103 return ret;
104 }
105 return delete_control(dpp, y);
106}
107
108int RGWRealm::create_control(const DoutPrefixProvider *dpp, bool exclusive, optional_yield y)
109{
110 auto pool = rgw_pool{get_pool(cct)};
111 auto oid = get_control_oid();
112 bufferlist bl;
113 auto sysobj = sysobj_svc->get_obj(rgw_raw_obj{pool, oid});
114 return sysobj.wop()
115 .set_exclusive(exclusive)
116 .write(dpp, bl, y);
117}
118
119int RGWRealm::delete_control(const DoutPrefixProvider *dpp, optional_yield y)
120{
121 auto pool = rgw_pool{get_pool(cct)};
122 auto obj = rgw_raw_obj{pool, get_control_oid()};
123 auto sysobj = sysobj_svc->get_obj(obj);
124 return sysobj.wop().remove(dpp, y);
125}
126
127rgw_pool RGWRealm::get_pool(CephContext *cct) const
128{
129 if (cct->_conf->rgw_realm_root_pool.empty()) {
130 return rgw_pool(RGW_DEFAULT_REALM_ROOT_POOL);
131 }
132 return rgw_pool(cct->_conf->rgw_realm_root_pool);
133}
134
135const string RGWRealm::get_default_oid(bool old_format) const
136{
137 if (cct->_conf->rgw_default_realm_info_oid.empty()) {
138 return default_realm_info_oid;
139 }
140 return cct->_conf->rgw_default_realm_info_oid;
141}
142
143const string& RGWRealm::get_names_oid_prefix() const
144{
145 return realm_names_oid_prefix;
146}
147
148const string& RGWRealm::get_info_oid_prefix(bool old_format) const
149{
150 return realm_info_oid_prefix;
151}
152
153int RGWRealm::set_current_period(const DoutPrefixProvider *dpp, RGWPeriod& period, optional_yield y)
154{
155 // update realm epoch to match the period's
156 if (epoch > period.get_realm_epoch()) {
157 ldpp_dout(dpp, 0) << "ERROR: set_current_period with old realm epoch "
158 << period.get_realm_epoch() << ", current epoch=" << epoch << dendl;
159 return -EINVAL;
160 }
161 if (epoch == period.get_realm_epoch() && current_period != period.get_id()) {
162 ldpp_dout(dpp, 0) << "ERROR: set_current_period with same realm epoch "
163 << period.get_realm_epoch() << ", but different period id "
164 << period.get_id() << " != " << current_period << dendl;
165 return -EINVAL;
166 }
167
168 epoch = period.get_realm_epoch();
169 current_period = period.get_id();
170
171 int ret = update(dpp, y);
172 if (ret < 0) {
173 ldpp_dout(dpp, 0) << "ERROR: period update: " << cpp_strerror(-ret) << dendl;
174 return ret;
175 }
176
177 ret = period.reflect(dpp, y);
178 if (ret < 0) {
179 ldpp_dout(dpp, 0) << "ERROR: period.reflect(): " << cpp_strerror(-ret) << dendl;
180 return ret;
181 }
182
183 return 0;
184}
185
186string RGWRealm::get_control_oid() const
187{
188 return get_info_oid_prefix() + id + ".control";
189}
190
191int RGWRealm::notify_zone(const DoutPrefixProvider *dpp, bufferlist& bl, optional_yield y)
192{
193 rgw_pool pool{get_pool(cct)};
194 auto sysobj = sysobj_svc->get_obj(rgw_raw_obj{pool, get_control_oid()});
195 int ret = sysobj.wn().notify(dpp, bl, 0, nullptr, y);
196 if (ret < 0) {
197 return ret;
198 }
199 return 0;
200}
201
202int RGWRealm::notify_new_period(const DoutPrefixProvider *dpp, const RGWPeriod& period, optional_yield y)
203{
204 bufferlist bl;
205 using ceph::encode;
206 // push the period to dependent zonegroups/zones
207 encode(RGWRealmNotify::ZonesNeedPeriod, bl);
208 encode(period, bl);
209 // reload the gateway with the new period
210 encode(RGWRealmNotify::Reload, bl);
211
212 return notify_zone(dpp, bl, y);
213}
214
215
216int RGWRealm::find_zone(const DoutPrefixProvider *dpp,
217 const rgw_zone_id& zid,
218 RGWPeriod *pperiod,
219 RGWZoneGroup *pzonegroup,
220 bool *pfound,
221 optional_yield y) const
222{
223 auto& found = *pfound;
224
225 found = false;
226
227 string period_id;
228 epoch_t epoch = 0;
229
230 RGWPeriod period(period_id, epoch);
231 int r = period.init(dpp, cct, sysobj_svc, get_id(), y, get_name());
232 if (r < 0) {
233 ldpp_dout(dpp, 0) << "WARNING: period init failed: " << cpp_strerror(-r) << " ... skipping" << dendl;
234 return r;
235 }
236
237 found = period.find_zone(dpp, zid, pzonegroup, y);
238 if (found) {
239 *pperiod = period;
240 }
241 return 0;
242}
243
244void RGWRealm::generate_test_instances(list<RGWRealm*> &o)
245{
246 RGWRealm *z = new RGWRealm;
247 o.push_back(z);
248 o.push_back(new RGWRealm);
249}
250
251void RGWRealm::dump(Formatter *f) const
252{
253 RGWSystemMetaObj::dump(f);
254 encode_json("current_period", current_period, f);
255 encode_json("epoch", epoch, f);
256}
257
258
259void RGWRealm::decode_json(JSONObj *obj)
260{
261 RGWSystemMetaObj::decode_json(obj);
262 JSONDecoder::decode_json("current_period", current_period, obj);
263 JSONDecoder::decode_json("epoch", epoch, obj);
264}
265