]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_service.cc
874c2e3e3b34006ce3d530186e3f1151578a995a
[ceph.git] / ceph / src / rgw / rgw_service.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 "rgw_service.h"
5
6 #include "services/svc_finisher.h"
7 #include "services/svc_bi_rados.h"
8 #include "services/svc_bilog_rados.h"
9 #include "services/svc_bucket_sobj.h"
10 #include "services/svc_bucket_sync_sobj.h"
11 #include "services/svc_cls.h"
12 #include "services/svc_config_key_rados.h"
13 #include "services/svc_mdlog.h"
14 #include "services/svc_meta.h"
15 #include "services/svc_meta_be.h"
16 #include "services/svc_meta_be_sobj.h"
17 #include "services/svc_meta_be_otp.h"
18 #include "services/svc_notify.h"
19 #include "services/svc_otp.h"
20 #include "services/svc_rados.h"
21 #include "services/svc_zone.h"
22 #include "services/svc_zone_utils.h"
23 #include "services/svc_quota.h"
24 #include "services/svc_sync_modules.h"
25 #include "services/svc_sys_obj.h"
26 #include "services/svc_sys_obj_cache.h"
27 #include "services/svc_sys_obj_core.h"
28 #include "services/svc_user_rados.h"
29
30 #include "common/errno.h"
31
32 #include "rgw_bucket.h"
33 #include "rgw_datalog.h"
34 #include "rgw_metadata.h"
35 #include "rgw_otp.h"
36 #include "rgw_user.h"
37
38 #define dout_subsys ceph_subsys_rgw
39
40 using namespace std;
41
42 RGWServices_Def::RGWServices_Def() = default;
43 RGWServices_Def::~RGWServices_Def()
44 {
45 shutdown();
46 }
47
48 int RGWServices_Def::init(CephContext *cct,
49 bool have_cache,
50 bool raw,
51 bool run_sync,
52 optional_yield y,
53 const DoutPrefixProvider *dpp)
54 {
55 finisher = std::make_unique<RGWSI_Finisher>(cct);
56 bucket_sobj = std::make_unique<RGWSI_Bucket_SObj>(cct);
57 bucket_sync_sobj = std::make_unique<RGWSI_Bucket_Sync_SObj>(cct);
58 bi_rados = std::make_unique<RGWSI_BucketIndex_RADOS>(cct);
59 bilog_rados = std::make_unique<RGWSI_BILog_RADOS>(cct);
60 cls = std::make_unique<RGWSI_Cls>(cct);
61 config_key_rados = std::make_unique<RGWSI_ConfigKey_RADOS>(cct);
62 datalog_rados = std::make_unique<RGWDataChangesLog>(cct);
63 mdlog = std::make_unique<RGWSI_MDLog>(cct, run_sync);
64 meta = std::make_unique<RGWSI_Meta>(cct);
65 meta_be_sobj = std::make_unique<RGWSI_MetaBackend_SObj>(cct);
66 meta_be_otp = std::make_unique<RGWSI_MetaBackend_OTP>(cct);
67 notify = std::make_unique<RGWSI_Notify>(cct);
68 otp = std::make_unique<RGWSI_OTP>(cct);
69 rados = std::make_unique<RGWSI_RADOS>(cct);
70 zone = std::make_unique<RGWSI_Zone>(cct);
71 zone_utils = std::make_unique<RGWSI_ZoneUtils>(cct);
72 quota = std::make_unique<RGWSI_Quota>(cct);
73 sync_modules = std::make_unique<RGWSI_SyncModules>(cct);
74 sysobj = std::make_unique<RGWSI_SysObj>(cct);
75 sysobj_core = std::make_unique<RGWSI_SysObj_Core>(cct);
76 user_rados = std::make_unique<RGWSI_User_RADOS>(cct);
77
78 if (have_cache) {
79 sysobj_cache = std::make_unique<RGWSI_SysObj_Cache>(dpp, cct);
80 }
81
82 vector<RGWSI_MetaBackend *> meta_bes{meta_be_sobj.get(), meta_be_otp.get()};
83
84 finisher->init();
85 bi_rados->init(zone.get(), rados.get(), bilog_rados.get(), datalog_rados.get());
86 bilog_rados->init(bi_rados.get());
87 bucket_sobj->init(zone.get(), sysobj.get(), sysobj_cache.get(),
88 bi_rados.get(), meta.get(), meta_be_sobj.get(),
89 sync_modules.get(), bucket_sync_sobj.get());
90 bucket_sync_sobj->init(zone.get(),
91 sysobj.get(),
92 sysobj_cache.get(),
93 bucket_sobj.get());
94 cls->init(zone.get(), rados.get());
95 config_key_rados->init(rados.get());
96 mdlog->init(rados.get(), zone.get(), sysobj.get(), cls.get());
97 meta->init(sysobj.get(), mdlog.get(), meta_bes);
98 meta_be_sobj->init(sysobj.get(), mdlog.get());
99 meta_be_otp->init(sysobj.get(), mdlog.get(), cls.get());
100 notify->init(zone.get(), rados.get(), finisher.get());
101 otp->init(zone.get(), meta.get(), meta_be_otp.get());
102 rados->init();
103 zone->init(sysobj.get(), rados.get(), sync_modules.get(), bucket_sync_sobj.get());
104 zone_utils->init(rados.get(), zone.get());
105 quota->init(zone.get());
106 sync_modules->init(zone.get());
107 sysobj_core->core_init(rados.get(), zone.get());
108 if (have_cache) {
109 sysobj_cache->init(rados.get(), zone.get(), notify.get());
110 sysobj->init(rados.get(), sysobj_cache.get());
111 } else {
112 sysobj->init(rados.get(), sysobj_core.get());
113 }
114 user_rados->init(rados.get(), zone.get(), sysobj.get(), sysobj_cache.get(),
115 meta.get(), meta_be_sobj.get(), sync_modules.get());
116
117 can_shutdown = true;
118
119 int r = finisher->start(y, dpp);
120 if (r < 0) {
121 ldpp_dout(dpp, 0) << "ERROR: failed to start finisher service (" << cpp_strerror(-r) << dendl;
122 return r;
123 }
124
125 if (!raw) {
126 r = notify->start(y, dpp);
127 if (r < 0) {
128 ldpp_dout(dpp, 0) << "ERROR: failed to start notify service (" << cpp_strerror(-r) << dendl;
129 return r;
130 }
131 }
132
133 r = rados->start(y, dpp);
134 if (r < 0) {
135 ldpp_dout(dpp, 0) << "ERROR: failed to start rados service (" << cpp_strerror(-r) << dendl;
136 return r;
137 }
138
139 if (!raw) {
140 r = zone->start(y, dpp);
141 if (r < 0) {
142 ldpp_dout(dpp, 0) << "ERROR: failed to start zone service (" << cpp_strerror(-r) << dendl;
143 return r;
144 }
145
146 r = datalog_rados->start(dpp, &zone->get_zone(),
147 zone->get_zone_params(),
148 rados->get_rados_handle());
149 if (r < 0) {
150 ldpp_dout(dpp, 0) << "ERROR: failed to start datalog_rados service (" << cpp_strerror(-r) << dendl;
151 return r;
152 }
153
154 r = mdlog->start(y, dpp);
155 if (r < 0) {
156 ldpp_dout(dpp, 0) << "ERROR: failed to start mdlog service (" << cpp_strerror(-r) << dendl;
157 return r;
158 }
159
160 r = sync_modules->start(y, dpp);
161 if (r < 0) {
162 ldpp_dout(dpp, 0) << "ERROR: failed to start sync modules service (" << cpp_strerror(-r) << dendl;
163 return r;
164 }
165 }
166
167 r = cls->start(y, dpp);
168 if (r < 0) {
169 ldpp_dout(dpp, 0) << "ERROR: failed to start cls service (" << cpp_strerror(-r) << dendl;
170 return r;
171 }
172
173 r = config_key_rados->start(y, dpp);
174 if (r < 0) {
175 ldpp_dout(dpp, 0) << "ERROR: failed to start config_key service (" << cpp_strerror(-r) << dendl;
176 return r;
177 }
178
179 r = zone_utils->start(y, dpp);
180 if (r < 0) {
181 ldpp_dout(dpp, 0) << "ERROR: failed to start zone_utils service (" << cpp_strerror(-r) << dendl;
182 return r;
183 }
184
185 r = quota->start(y, dpp);
186 if (r < 0) {
187 ldpp_dout(dpp, 0) << "ERROR: failed to start quota service (" << cpp_strerror(-r) << dendl;
188 return r;
189 }
190
191 r = sysobj_core->start(y, dpp);
192 if (r < 0) {
193 ldpp_dout(dpp, 0) << "ERROR: failed to start sysobj_core service (" << cpp_strerror(-r) << dendl;
194 return r;
195 }
196
197 if (have_cache) {
198 r = sysobj_cache->start(y, dpp);
199 if (r < 0) {
200 ldpp_dout(dpp, 0) << "ERROR: failed to start sysobj_cache service (" << cpp_strerror(-r) << dendl;
201 return r;
202 }
203 }
204
205 r = sysobj->start(y, dpp);
206 if (r < 0) {
207 ldpp_dout(dpp, 0) << "ERROR: failed to start sysobj service (" << cpp_strerror(-r) << dendl;
208 return r;
209 }
210
211 if (!raw) {
212 r = meta_be_sobj->start(y, dpp);
213 if (r < 0) {
214 ldpp_dout(dpp, 0) << "ERROR: failed to start meta_be_sobj service (" << cpp_strerror(-r) << dendl;
215 return r;
216 }
217
218 r = meta->start(y, dpp);
219 if (r < 0) {
220 ldpp_dout(dpp, 0) << "ERROR: failed to start meta service (" << cpp_strerror(-r) << dendl;
221 return r;
222 }
223
224 r = bucket_sobj->start(y, dpp);
225 if (r < 0) {
226 ldpp_dout(dpp, 0) << "ERROR: failed to start bucket service (" << cpp_strerror(-r) << dendl;
227 return r;
228 }
229
230 r = bucket_sync_sobj->start(y, dpp);
231 if (r < 0) {
232 ldpp_dout(dpp, 0) << "ERROR: failed to start bucket_sync service (" << cpp_strerror(-r) << dendl;
233 return r;
234 }
235
236 r = user_rados->start(y, dpp);
237 if (r < 0) {
238 ldpp_dout(dpp, 0) << "ERROR: failed to start user_rados service (" << cpp_strerror(-r) << dendl;
239 return r;
240 }
241
242 r = otp->start(y, dpp);
243 if (r < 0) {
244 ldpp_dout(dpp, 0) << "ERROR: failed to start otp service (" << cpp_strerror(-r) << dendl;
245 return r;
246 }
247 }
248
249 /* cache or core services will be started by sysobj */
250
251 return 0;
252 }
253
254 void RGWServices_Def::shutdown()
255 {
256 if (!can_shutdown) {
257 return;
258 }
259
260 if (has_shutdown) {
261 return;
262 }
263
264 sysobj->shutdown();
265 sysobj_core->shutdown();
266 notify->shutdown();
267 if (sysobj_cache) {
268 sysobj_cache->shutdown();
269 }
270 quota->shutdown();
271 zone_utils->shutdown();
272 zone->shutdown();
273 rados->shutdown();
274
275 has_shutdown = true;
276
277 }
278
279
280 int RGWServices::do_init(CephContext *_cct, bool have_cache, bool raw, bool run_sync, optional_yield y, const DoutPrefixProvider *dpp)
281 {
282 cct = _cct;
283
284 int r = _svc.init(cct, have_cache, raw, run_sync, y, dpp);
285 if (r < 0) {
286 return r;
287 }
288
289 finisher = _svc.finisher.get();
290 bi_rados = _svc.bi_rados.get();
291 bi = bi_rados;
292 bilog_rados = _svc.bilog_rados.get();
293 bucket_sobj = _svc.bucket_sobj.get();
294 bucket = bucket_sobj;
295 bucket_sync_sobj = _svc.bucket_sync_sobj.get();
296 bucket_sync = bucket_sync_sobj;
297 cls = _svc.cls.get();
298 config_key_rados = _svc.config_key_rados.get();
299 config_key = config_key_rados;
300 datalog_rados = _svc.datalog_rados.get();
301 mdlog = _svc.mdlog.get();
302 meta = _svc.meta.get();
303 meta_be_sobj = _svc.meta_be_sobj.get();
304 meta_be_otp = _svc.meta_be_otp.get();
305 notify = _svc.notify.get();
306 otp = _svc.otp.get();
307 rados = _svc.rados.get();
308 zone = _svc.zone.get();
309 zone_utils = _svc.zone_utils.get();
310 quota = _svc.quota.get();
311 sync_modules = _svc.sync_modules.get();
312 sysobj = _svc.sysobj.get();
313 cache = _svc.sysobj_cache.get();
314 core = _svc.sysobj_core.get();
315 user = _svc.user_rados.get();
316
317 return 0;
318 }
319
320 RGWServiceInstance::~RGWServiceInstance() {}
321
322 int RGWServiceInstance::start(optional_yield y, const DoutPrefixProvider *dpp)
323 {
324 if (start_state != StateInit) {
325 return 0;
326 }
327
328 start_state = StateStarting;; /* setting started prior to do_start() on purpose so that circular
329 references can call start() on each other */
330
331 int r = do_start(y, dpp);
332 if (r < 0) {
333 return r;
334 }
335
336 start_state = StateStarted;
337
338 return 0;
339 }
340
341 RGWCtlDef::RGWCtlDef() {}
342 RGWCtlDef::~RGWCtlDef() {}
343 RGWCtlDef::_meta::_meta() {}
344 RGWCtlDef::_meta::~_meta() {}
345
346
347 int RGWCtlDef::init(RGWServices& svc, const DoutPrefixProvider *dpp)
348 {
349 meta.mgr.reset(new RGWMetadataManager(svc.meta));
350
351 meta.user.reset(RGWUserMetaHandlerAllocator::alloc(svc.user));
352
353 auto sync_module = svc.sync_modules->get_sync_module();
354 if (sync_module) {
355 meta.bucket.reset(sync_module->alloc_bucket_meta_handler());
356 meta.bucket_instance.reset(sync_module->alloc_bucket_instance_meta_handler());
357 } else {
358 meta.bucket.reset(RGWBucketMetaHandlerAllocator::alloc());
359 meta.bucket_instance.reset(RGWBucketInstanceMetaHandlerAllocator::alloc());
360 }
361
362 meta.otp.reset(RGWOTPMetaHandlerAllocator::alloc());
363
364 user.reset(new RGWUserCtl(svc.zone, svc.user, (RGWUserMetadataHandler *)meta.user.get()));
365 bucket.reset(new RGWBucketCtl(svc.zone,
366 svc.bucket,
367 svc.bucket_sync,
368 svc.bi));
369 otp.reset(new RGWOTPCtl(svc.zone, svc.otp));
370
371 RGWBucketMetadataHandlerBase *bucket_meta_handler = static_cast<RGWBucketMetadataHandlerBase *>(meta.bucket.get());
372 RGWBucketInstanceMetadataHandlerBase *bi_meta_handler = static_cast<RGWBucketInstanceMetadataHandlerBase *>(meta.bucket_instance.get());
373
374 bucket_meta_handler->init(svc.bucket, bucket.get());
375 bi_meta_handler->init(svc.zone, svc.bucket, svc.bi);
376
377 RGWOTPMetadataHandlerBase *otp_handler = static_cast<RGWOTPMetadataHandlerBase *>(meta.otp.get());
378 otp_handler->init(svc.zone, svc.meta_be_otp, svc.otp);
379
380 user->init(bucket.get());
381 bucket->init(user.get(),
382 (RGWBucketMetadataHandler *)bucket_meta_handler,
383 (RGWBucketInstanceMetadataHandler *)bi_meta_handler,
384 svc.datalog_rados,
385 dpp);
386
387 otp->init((RGWOTPMetadataHandler *)meta.otp.get());
388
389 return 0;
390 }
391
392 int RGWCtl::init(RGWServices *_svc, const DoutPrefixProvider *dpp)
393 {
394 svc = _svc;
395 cct = svc->cct;
396
397 int r = _ctl.init(*svc, dpp);
398 if (r < 0) {
399 ldpp_dout(dpp, 0) << "ERROR: failed to start init ctls (" << cpp_strerror(-r) << dendl;
400 return r;
401 }
402
403 meta.mgr = _ctl.meta.mgr.get();
404 meta.user = _ctl.meta.user.get();
405 meta.bucket = _ctl.meta.bucket.get();
406 meta.bucket_instance = _ctl.meta.bucket_instance.get();
407 meta.otp = _ctl.meta.otp.get();
408
409 user = _ctl.user.get();
410 bucket = _ctl.bucket.get();
411 otp = _ctl.otp.get();
412
413 r = meta.user->attach(meta.mgr);
414 if (r < 0) {
415 ldout(cct, 0) << "ERROR: failed to start init meta.user ctl (" << cpp_strerror(-r) << dendl;
416 return r;
417 }
418
419 r = meta.bucket->attach(meta.mgr);
420 if (r < 0) {
421 ldout(cct, 0) << "ERROR: failed to start init meta.bucket ctl (" << cpp_strerror(-r) << dendl;
422 return r;
423 }
424
425 r = meta.bucket_instance->attach(meta.mgr);
426 if (r < 0) {
427 ldout(cct, 0) << "ERROR: failed to start init meta.bucket_instance ctl (" << cpp_strerror(-r) << dendl;
428 return r;
429 }
430
431 r = meta.otp->attach(meta.mgr);
432 if (r < 0) {
433 ldout(cct, 0) << "ERROR: failed to start init otp ctl (" << cpp_strerror(-r) << dendl;
434 return r;
435 }
436
437 return 0;
438 }
439