]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_metadata.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rgw / rgw_metadata.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_metadata.h"
5
6 #include "rgw_mdlog.h"
7
8
9 #include "services/svc_meta.h"
10 #include "services/svc_meta_be_sobj.h"
11
12 #define dout_subsys ceph_subsys_rgw
13
14 using namespace std;
15
16 void LogStatusDump::dump(Formatter *f) const {
17 string s;
18 switch (status) {
19 case MDLOG_STATUS_WRITE:
20 s = "write";
21 break;
22 case MDLOG_STATUS_SETATTRS:
23 s = "set_attrs";
24 break;
25 case MDLOG_STATUS_REMOVE:
26 s = "remove";
27 break;
28 case MDLOG_STATUS_COMPLETE:
29 s = "complete";
30 break;
31 case MDLOG_STATUS_ABORT:
32 s = "abort";
33 break;
34 default:
35 s = "unknown";
36 break;
37 }
38 encode_json("status", s, f);
39 }
40
41 void encode_json(const char *name, const obj_version& v, Formatter *f)
42 {
43 f->open_object_section(name);
44 f->dump_string("tag", v.tag);
45 f->dump_unsigned("ver", v.ver);
46 f->close_section();
47 }
48
49 void decode_json_obj(obj_version& v, JSONObj *obj)
50 {
51 JSONDecoder::decode_json("tag", v.tag, obj);
52 JSONDecoder::decode_json("ver", v.ver, obj);
53 }
54
55 void RGWMetadataLogData::encode(bufferlist& bl) const {
56 ENCODE_START(1, 1, bl);
57 encode(read_version, bl);
58 encode(write_version, bl);
59 uint32_t s = (uint32_t)status;
60 encode(s, bl);
61 ENCODE_FINISH(bl);
62 }
63
64 void RGWMetadataLogData::decode(bufferlist::const_iterator& bl) {
65 DECODE_START(1, bl);
66 decode(read_version, bl);
67 decode(write_version, bl);
68 uint32_t s;
69 decode(s, bl);
70 status = (RGWMDLogStatus)s;
71 DECODE_FINISH(bl);
72 }
73
74 void RGWMetadataLogData::dump(Formatter *f) const {
75 encode_json("read_version", read_version, f);
76 encode_json("write_version", write_version, f);
77 encode_json("status", LogStatusDump(status), f);
78 }
79
80 void decode_json_obj(RGWMDLogStatus& status, JSONObj *obj) {
81 string s;
82 JSONDecoder::decode_json("status", s, obj);
83 if (s == "complete") {
84 status = MDLOG_STATUS_COMPLETE;
85 } else if (s == "write") {
86 status = MDLOG_STATUS_WRITE;
87 } else if (s == "remove") {
88 status = MDLOG_STATUS_REMOVE;
89 } else if (s == "set_attrs") {
90 status = MDLOG_STATUS_SETATTRS;
91 } else if (s == "abort") {
92 status = MDLOG_STATUS_ABORT;
93 } else {
94 status = MDLOG_STATUS_UNKNOWN;
95 }
96 }
97
98 void RGWMetadataLogData::decode_json(JSONObj *obj) {
99 JSONDecoder::decode_json("read_version", read_version, obj);
100 JSONDecoder::decode_json("write_version", write_version, obj);
101 JSONDecoder::decode_json("status", status, obj);
102 }
103
104 RGWMetadataHandler_GenericMetaBE::Put::Put(RGWMetadataHandler_GenericMetaBE *_handler,
105 RGWSI_MetaBackend_Handler::Op *_op,
106 string& _entry, RGWMetadataObject *_obj,
107 RGWObjVersionTracker& _objv_tracker,
108 optional_yield _y,
109 RGWMDLogSyncType _type, bool _from_remote_zone):
110 handler(_handler), op(_op),
111 entry(_entry), obj(_obj),
112 objv_tracker(_objv_tracker),
113 apply_type(_type),
114 y(_y),
115 from_remote_zone(_from_remote_zone)
116 {
117 }
118
119 int RGWMetadataHandler_GenericMetaBE::do_put_operate(Put *put_op, const DoutPrefixProvider *dpp)
120 {
121 int r = put_op->put_pre(dpp);
122 if (r != 0) { /* r can also be STATUS_NO_APPLY */
123 return r;
124 }
125
126 r = put_op->put(dpp);
127 if (r != 0) {
128 return r;
129 }
130
131 r = put_op->put_post(dpp);
132 if (r != 0) { /* e.g., -error or STATUS_APPLIED */
133 return r;
134 }
135
136 return 0;
137 }
138
139 int RGWMetadataHandler_GenericMetaBE::get(string& entry, RGWMetadataObject **obj, optional_yield y, const DoutPrefixProvider *dpp)
140 {
141 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
142 return do_get(op, entry, obj, y, dpp);
143 });
144 }
145
146 int RGWMetadataHandler_GenericMetaBE::put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
147 optional_yield y, const DoutPrefixProvider *dpp, RGWMDLogSyncType type, bool from_remote_zone)
148 {
149 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
150 return do_put(op, entry, obj, objv_tracker, y, dpp, type, from_remote_zone);
151 });
152 }
153
154 int RGWMetadataHandler_GenericMetaBE::remove(string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y, const DoutPrefixProvider *dpp)
155 {
156 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
157 return do_remove(op, entry, objv_tracker, y, dpp);
158 });
159 }
160
161 int RGWMetadataHandler_GenericMetaBE::mutate(const string& entry,
162 const ceph::real_time& mtime,
163 RGWObjVersionTracker *objv_tracker,
164 optional_yield y,
165 const DoutPrefixProvider *dpp,
166 RGWMDLogStatus op_type,
167 std::function<int()> f)
168 {
169 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
170 RGWSI_MetaBackend::MutateParams params(mtime, op_type);
171 return op->mutate(entry,
172 params,
173 objv_tracker,
174 y,
175 f,
176 dpp);
177 });
178 }
179
180 int RGWMetadataHandler_GenericMetaBE::get_shard_id(const string& entry, int *shard_id)
181 {
182 return be_handler->call([&](RGWSI_MetaBackend_Handler::Op *op) {
183 return op->get_shard_id(entry, shard_id);
184 });
185 }
186
187 int RGWMetadataHandler_GenericMetaBE::list_keys_init(const DoutPrefixProvider *dpp, const string& marker, void **phandle)
188 {
189 auto op = std::make_unique<RGWSI_MetaBackend_Handler::Op_ManagedCtx>(be_handler);
190
191 int ret = op->list_init(dpp, marker);
192 if (ret < 0) {
193 return ret;
194 }
195
196 *phandle = (void *)op.release();
197
198 return 0;
199 }
200
201 int RGWMetadataHandler_GenericMetaBE::list_keys_next(const DoutPrefixProvider *dpp, void *handle, int max, list<string>& keys, bool *truncated)
202 {
203 auto op = static_cast<RGWSI_MetaBackend_Handler::Op_ManagedCtx *>(handle);
204
205 int ret = op->list_next(dpp, max, &keys, truncated);
206 if (ret < 0 && ret != -ENOENT) {
207 return ret;
208 }
209 if (ret == -ENOENT) {
210 if (truncated) {
211 *truncated = false;
212 }
213 return 0;
214 }
215
216 return 0;
217 }
218
219 void RGWMetadataHandler_GenericMetaBE::list_keys_complete(void *handle)
220 {
221 auto op = static_cast<RGWSI_MetaBackend_Handler::Op_ManagedCtx *>(handle);
222 delete op;
223 }
224
225 string RGWMetadataHandler_GenericMetaBE::get_marker(void *handle)
226 {
227 auto op = static_cast<RGWSI_MetaBackend_Handler::Op_ManagedCtx *>(handle);
228 string marker;
229 int r = op->list_get_marker(&marker);
230 if (r < 0) {
231 ldout(cct, 0) << "ERROR: " << __func__ << "(): list_get_marker() returned: r=" << r << dendl;
232 /* not much else to do */
233 }
234
235 return marker;
236 }
237
238 RGWMetadataHandlerPut_SObj::RGWMetadataHandlerPut_SObj(RGWMetadataHandler_GenericMetaBE *handler,
239 RGWSI_MetaBackend_Handler::Op *op,
240 string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
241 optional_yield y,
242 RGWMDLogSyncType type, bool from_remote_zone) : Put(handler, op, entry, obj, objv_tracker, y, type, from_remote_zone) {
243 }
244
245 int RGWMetadataHandlerPut_SObj::put_pre(const DoutPrefixProvider *dpp)
246 {
247 int ret = get(&old_obj, dpp);
248 if (ret < 0 && ret != -ENOENT) {
249 return ret;
250 }
251 exists = (ret != -ENOENT);
252
253 oo.reset(old_obj);
254
255 auto old_ver = (!old_obj ? obj_version() : old_obj->get_version());
256 auto old_mtime = (!old_obj ? ceph::real_time() : old_obj->get_mtime());
257
258 // are we actually going to perform this put, or is it too old?
259 if (!handler->check_versions(exists, old_ver, old_mtime,
260 objv_tracker.write_version, obj->get_mtime(),
261 apply_type)) {
262 return STATUS_NO_APPLY;
263 }
264
265 objv_tracker.read_version = old_ver; /* maintain the obj version we just read */
266
267 return 0;
268 }
269
270 int RGWMetadataHandlerPut_SObj::put(const DoutPrefixProvider *dpp)
271 {
272 int ret = put_check(dpp);
273 if (ret != 0) {
274 return ret;
275 }
276
277 return put_checked(dpp);
278 }
279
280 int RGWMetadataHandlerPut_SObj::put_checked(const DoutPrefixProvider *dpp)
281 {
282 RGWSI_MBSObj_PutParams params(obj->get_pattrs(), obj->get_mtime());
283
284 encode_obj(&params.bl);
285
286 int ret = op->put(entry, params, &objv_tracker, y, dpp);
287 if (ret < 0) {
288 return ret;
289 }
290
291 return 0;
292 }
293
294 class RGWMetadataTopHandler : public RGWMetadataHandler {
295 struct iter_data {
296 set<string> sections;
297 set<string>::iterator iter;
298 };
299
300 struct Svc {
301 RGWSI_Meta *meta{nullptr};
302 } svc;
303
304 RGWMetadataManager *mgr;
305
306 public:
307 RGWMetadataTopHandler(RGWSI_Meta *meta_svc,
308 RGWMetadataManager *_mgr) : mgr(_mgr) {
309 base_init(meta_svc->ctx());
310 svc.meta = meta_svc;
311 }
312
313 string get_type() override { return string(); }
314
315 RGWMetadataObject *get_meta_obj(JSONObj *jo, const obj_version& objv, const ceph::real_time& mtime) {
316 return new RGWMetadataObject;
317 }
318
319 int get(string& entry, RGWMetadataObject **obj, optional_yield y, const DoutPrefixProvider *dpp) override {
320 return -ENOTSUP;
321 }
322
323 int put(string& entry, RGWMetadataObject *obj, RGWObjVersionTracker& objv_tracker,
324 optional_yield y, const DoutPrefixProvider *dpp, RGWMDLogSyncType type, bool from_remote_zone) override {
325 return -ENOTSUP;
326 }
327
328 int remove(string& entry, RGWObjVersionTracker& objv_tracker, optional_yield y, const DoutPrefixProvider *dpp) override {
329 return -ENOTSUP;
330 }
331
332 int mutate(const string& entry,
333 const ceph::real_time& mtime,
334 RGWObjVersionTracker *objv_tracker,
335 optional_yield y,
336 const DoutPrefixProvider *dpp,
337 RGWMDLogStatus op_type,
338 std::function<int()> f) {
339 return -ENOTSUP;
340 }
341
342 int list_keys_init(const DoutPrefixProvider *dpp, const string& marker, void **phandle) override {
343 iter_data *data = new iter_data;
344 list<string> sections;
345 mgr->get_sections(sections);
346 for (auto& s : sections) {
347 data->sections.insert(s);
348 }
349 data->iter = data->sections.lower_bound(marker);
350
351 *phandle = data;
352
353 return 0;
354 }
355 int list_keys_next(const DoutPrefixProvider *dpp, void *handle, int max, list<string>& keys, bool *truncated) override {
356 iter_data *data = static_cast<iter_data *>(handle);
357 for (int i = 0; i < max && data->iter != data->sections.end(); ++i, ++(data->iter)) {
358 keys.push_back(*data->iter);
359 }
360
361 *truncated = (data->iter != data->sections.end());
362
363 return 0;
364 }
365 void list_keys_complete(void *handle) override {
366 iter_data *data = static_cast<iter_data *>(handle);
367
368 delete data;
369 }
370
371 virtual string get_marker(void *handle) override {
372 iter_data *data = static_cast<iter_data *>(handle);
373
374 if (data->iter != data->sections.end()) {
375 return *(data->iter);
376 }
377
378 return string();
379 }
380 };
381
382 RGWMetadataHandlerPut_SObj::~RGWMetadataHandlerPut_SObj() {}
383
384 int RGWMetadataHandler::attach(RGWMetadataManager *manager)
385 {
386 return manager->register_handler(this);
387 }
388
389 RGWMetadataHandler::~RGWMetadataHandler() {}
390
391 obj_version& RGWMetadataObject::get_version()
392 {
393 return objv;
394 }
395
396 RGWMetadataManager::RGWMetadataManager(RGWSI_Meta *_meta_svc)
397 : cct(_meta_svc->ctx()), meta_svc(_meta_svc)
398 {
399 md_top_handler.reset(new RGWMetadataTopHandler(meta_svc, this));
400 }
401
402 RGWMetadataManager::~RGWMetadataManager()
403 {
404 }
405
406 int RGWMetadataManager::register_handler(RGWMetadataHandler *handler)
407 {
408 string type = handler->get_type();
409
410 if (handlers.find(type) != handlers.end())
411 return -EEXIST;
412
413 handlers[type] = handler;
414
415 return 0;
416 }
417
418 RGWMetadataHandler *RGWMetadataManager::get_handler(const string& type)
419 {
420 map<string, RGWMetadataHandler *>::iterator iter = handlers.find(type);
421 if (iter == handlers.end())
422 return NULL;
423
424 return iter->second;
425 }
426
427 void RGWMetadataManager::parse_metadata_key(const string& metadata_key, string& type, string& entry)
428 {
429 auto pos = metadata_key.find(':');
430 if (pos == string::npos) {
431 type = metadata_key;
432 } else {
433 type = metadata_key.substr(0, pos);
434 entry = metadata_key.substr(pos + 1);
435 }
436 }
437
438 int RGWMetadataManager::find_handler(const string& metadata_key, RGWMetadataHandler **handler, string& entry)
439 {
440 string type;
441
442 parse_metadata_key(metadata_key, type, entry);
443
444 if (type.empty()) {
445 *handler = md_top_handler.get();
446 return 0;
447 }
448
449 map<string, RGWMetadataHandler *>::iterator iter = handlers.find(type);
450 if (iter == handlers.end())
451 return -ENOENT;
452
453 *handler = iter->second;
454
455 return 0;
456
457 }
458
459 int RGWMetadataManager::get(string& metadata_key, Formatter *f, optional_yield y, const DoutPrefixProvider *dpp)
460 {
461 RGWMetadataHandler *handler;
462 string entry;
463 int ret = find_handler(metadata_key, &handler, entry);
464 if (ret < 0) {
465 return ret;
466 }
467
468 RGWMetadataObject *obj;
469
470 ret = handler->get(entry, &obj, y, dpp);
471 if (ret < 0) {
472 return ret;
473 }
474
475 f->open_object_section("metadata_info");
476 encode_json("key", metadata_key, f);
477 encode_json("ver", obj->get_version(), f);
478 real_time mtime = obj->get_mtime();
479 if (!real_clock::is_zero(mtime)) {
480 utime_t ut(mtime);
481 encode_json("mtime", ut, f);
482 }
483 encode_json("data", *obj, f);
484 f->close_section();
485
486 delete obj;
487
488 return 0;
489 }
490
491 int RGWMetadataManager::put(string& metadata_key, bufferlist& bl,
492 optional_yield y,
493 const DoutPrefixProvider *dpp,
494 RGWMDLogSyncType sync_type,
495 bool from_remote_zone,
496 obj_version *existing_version)
497 {
498 RGWMetadataHandler *handler;
499 string entry;
500
501 int ret = find_handler(metadata_key, &handler, entry);
502 if (ret < 0) {
503 return ret;
504 }
505
506 JSONParser parser;
507 if (!parser.parse(bl.c_str(), bl.length())) {
508 return -EINVAL;
509 }
510
511 RGWObjVersionTracker objv_tracker;
512
513 obj_version *objv = &objv_tracker.write_version;
514
515 utime_t mtime;
516
517 try {
518 JSONDecoder::decode_json("key", metadata_key, &parser);
519 JSONDecoder::decode_json("ver", *objv, &parser);
520 JSONDecoder::decode_json("mtime", mtime, &parser);
521 } catch (JSONDecoder::err& e) {
522 return -EINVAL;
523 }
524
525 JSONObj *jo = parser.find_obj("data");
526 if (!jo) {
527 return -EINVAL;
528 }
529 RGWMetadataObject *obj = handler->get_meta_obj(jo, *objv, mtime.to_real_time());
530 if (!obj) {
531 return -EINVAL;
532 }
533
534 ret = handler->put(entry, obj, objv_tracker, y, dpp, sync_type, from_remote_zone);
535 if (existing_version) {
536 *existing_version = objv_tracker.read_version;
537 }
538
539 delete obj;
540
541 return ret;
542 }
543
544 int RGWMetadataManager::remove(string& metadata_key, optional_yield y, const DoutPrefixProvider *dpp)
545 {
546 RGWMetadataHandler *handler;
547 string entry;
548
549 int ret = find_handler(metadata_key, &handler, entry);
550 if (ret < 0) {
551 return ret;
552 }
553
554 RGWMetadataObject *obj;
555 ret = handler->get(entry, &obj, y, dpp);
556 if (ret < 0) {
557 return ret;
558 }
559 RGWObjVersionTracker objv_tracker;
560 objv_tracker.read_version = obj->get_version();
561 delete obj;
562
563 return handler->remove(entry, objv_tracker, y, dpp);
564 }
565
566 int RGWMetadataManager::mutate(const string& metadata_key,
567 const ceph::real_time& mtime,
568 RGWObjVersionTracker *objv_tracker,
569 optional_yield y,
570 const DoutPrefixProvider *dpp,
571 RGWMDLogStatus op_type,
572 std::function<int()> f)
573 {
574 RGWMetadataHandler *handler;
575 string entry;
576
577 int ret = find_handler(metadata_key, &handler, entry);
578 if (ret < 0) {
579 return ret;
580 }
581
582 return handler->mutate(entry, mtime, objv_tracker, y, dpp, op_type, f);
583 }
584
585 int RGWMetadataManager::get_shard_id(const string& section, const string& entry, int *shard_id)
586 {
587 RGWMetadataHandler *handler = get_handler(section);
588 if (!handler) {
589 return -EINVAL;
590 }
591
592 return handler->get_shard_id(entry, shard_id);
593 }
594
595 struct list_keys_handle {
596 void *handle;
597 RGWMetadataHandler *handler;
598 };
599
600 int RGWMetadataManager::list_keys_init(const DoutPrefixProvider *dpp, const string& section, void **handle)
601 {
602 return list_keys_init(dpp, section, string(), handle);
603 }
604
605 int RGWMetadataManager::list_keys_init(const DoutPrefixProvider *dpp, const string& section,
606 const string& marker, void **handle)
607 {
608 string entry;
609 RGWMetadataHandler *handler;
610
611 int ret;
612
613 ret = find_handler(section, &handler, entry);
614 if (ret < 0) {
615 return -ENOENT;
616 }
617
618 list_keys_handle *h = new list_keys_handle;
619 h->handler = handler;
620 ret = handler->list_keys_init(dpp, marker, &h->handle);
621 if (ret < 0) {
622 delete h;
623 return ret;
624 }
625
626 *handle = (void *)h;
627
628 return 0;
629 }
630
631 int RGWMetadataManager::list_keys_next(const DoutPrefixProvider *dpp, void *handle, int max, list<string>& keys, bool *truncated)
632 {
633 list_keys_handle *h = static_cast<list_keys_handle *>(handle);
634
635 RGWMetadataHandler *handler = h->handler;
636
637 return handler->list_keys_next(dpp, h->handle, max, keys, truncated);
638 }
639
640 void RGWMetadataManager::list_keys_complete(void *handle)
641 {
642 list_keys_handle *h = static_cast<list_keys_handle *>(handle);
643
644 RGWMetadataHandler *handler = h->handler;
645
646 handler->list_keys_complete(h->handle);
647 delete h;
648 }
649
650 string RGWMetadataManager::get_marker(void *handle)
651 {
652 list_keys_handle *h = static_cast<list_keys_handle *>(handle);
653
654 return h->handler->get_marker(h->handle);
655 }
656
657 void RGWMetadataManager::dump_log_entry(cls_log_entry& entry, Formatter *f)
658 {
659 f->open_object_section("entry");
660 f->dump_string("id", entry.id);
661 f->dump_string("section", entry.section);
662 f->dump_string("name", entry.name);
663 entry.timestamp.gmtime_nsec(f->dump_stream("timestamp"));
664
665 try {
666 RGWMetadataLogData log_data;
667 auto iter = entry.data.cbegin();
668 decode(log_data, iter);
669
670 encode_json("data", log_data, f);
671 } catch (buffer::error& err) {
672 lderr(cct) << "failed to decode log entry: " << entry.section << ":" << entry.name<< " ts=" << entry.timestamp << dendl;
673 }
674 f->close_section();
675 }
676
677 void RGWMetadataManager::get_sections(list<string>& sections)
678 {
679 for (map<string, RGWMetadataHandler *>::iterator iter = handlers.begin(); iter != handlers.end(); ++iter) {
680 sections.push_back(iter->first);
681 }
682 }
683