]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_realm.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / rgw_realm.cc
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
24 namespace rgw_zone_defaults {
25
26 std::string realm_info_oid_prefix = "realms.";
27 std::string realm_names_oid_prefix = "realms_names.";
28 std::string default_realm_info_oid = "default.realm";
29 std::string RGW_DEFAULT_REALM_ROOT_POOL = "rgw.root";
30
31 }
32
33 using namespace std;
34 using namespace rgw_zone_defaults;
35
36 RGWRealm::~RGWRealm() {}
37
38 RGWRemoteMetaLog::~RGWRemoteMetaLog()
39 {
40 delete error_logger;
41 }
42
43 string RGWRealm::get_predefined_id(CephContext *cct) const {
44 return cct->_conf.get_val<string>("rgw_realm_id");
45 }
46
47 const string& RGWRealm::get_predefined_name(CephContext *cct) const {
48 return cct->_conf->rgw_realm;
49 }
50
51 int 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
99 int 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
108 int 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
119 int 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
127 rgw_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
135 const 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
143 const string& RGWRealm::get_names_oid_prefix() const
144 {
145 return realm_names_oid_prefix;
146 }
147
148 const string& RGWRealm::get_info_oid_prefix(bool old_format) const
149 {
150 return realm_info_oid_prefix;
151 }
152
153 int 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
186 string RGWRealm::get_control_oid() const
187 {
188 return get_info_oid_prefix() + id + ".control";
189 }
190
191 int 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
202 int 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
216 int 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
244 void 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
251 void 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
259 void 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