]>
Commit | Line | Data |
---|---|---|
20effc67 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 | /* | |
5 | * Ceph - scalable distributed file system | |
6 | * | |
7 | * Copyright (C) 2021 Red Hat, Inc. | |
8 | * | |
9 | * This is free software; you can redistribute it and/or | |
10 | * modify it under the terms of the GNU Lesser General Public | |
11 | * License version 2.1, as published by the Free Software | |
12 | * Foundation. See file COPYING. | |
13 | * | |
14 | */ | |
15 | ||
16 | #pragma once | |
17 | ||
18 | #include "rgw_sal.h" | |
19 | #include "rgw_oidc_provider.h" | |
20 | #include "rgw_role.h" | |
21 | #include "rgw_lc.h" | |
22 | #include "rgw_multi.h" | |
23 | ||
24 | #include "store/dbstore/common/dbstore.h" | |
25 | #include "store/dbstore/dbstore_mgr.h" | |
26 | ||
27 | namespace rgw { namespace sal { | |
28 | ||
29 | class DBStore; | |
30 | ||
31 | class LCDBSerializer : public LCSerializer { | |
32 | const std::string oid; | |
33 | ||
34 | public: | |
35 | LCDBSerializer(DBStore* store, const std::string& oid, const std::string& lock_name, const std::string& cookie) {} | |
36 | ||
37 | virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) override { return 0; } | |
38 | virtual int unlock() override { | |
39 | return 0; | |
40 | } | |
41 | }; | |
42 | ||
43 | class DBLifecycle : public Lifecycle { | |
44 | DBStore* store; | |
45 | ||
46 | public: | |
47 | DBLifecycle(DBStore* _st) : store(_st) {} | |
48 | ||
49 | virtual int get_entry(const std::string& oid, const std::string& marker, LCEntry& entry) override; | |
50 | virtual int get_next_entry(const std::string& oid, std::string& marker, LCEntry& entry) override; | |
51 | virtual int set_entry(const std::string& oid, const LCEntry& entry) override; | |
52 | virtual int list_entries(const std::string& oid, const std::string& marker, | |
53 | uint32_t max_entries, std::vector<LCEntry>& entries) override; | |
54 | virtual int rm_entry(const std::string& oid, const LCEntry& entry) override; | |
55 | virtual int get_head(const std::string& oid, LCHead& head) override; | |
56 | virtual int put_head(const std::string& oid, const LCHead& head) override; | |
57 | virtual LCSerializer* get_serializer(const std::string& lock_name, const std::string& oid, const std::string& cookie) override; | |
58 | }; | |
59 | ||
60 | class DBNotification : public Notification { | |
61 | protected: | |
62 | public: | |
63 | DBNotification(Object* _obj, Object* _src_obj, rgw::notify::EventType _type) | |
64 | : Notification(_obj, _src_obj, _type) {} | |
65 | ~DBNotification() = default; | |
66 | ||
67 | virtual int publish_reserve(const DoutPrefixProvider *dpp, RGWObjTags* obj_tags = nullptr) override { return 0;} | |
68 | virtual int publish_commit(const DoutPrefixProvider* dpp, uint64_t size, | |
69 | const ceph::real_time& mtime, const std::string& etag, const std::string& version) override { return 0; } | |
70 | }; | |
71 | ||
72 | class DBUser : public User { | |
73 | private: | |
74 | DBStore *store; | |
75 | ||
76 | public: | |
77 | DBUser(DBStore *_st, const rgw_user& _u) : User(_u), store(_st) { } | |
78 | DBUser(DBStore *_st, const RGWUserInfo& _i) : User(_i), store(_st) { } | |
79 | DBUser(DBStore *_st) : store(_st) { } | |
80 | DBUser(DBUser& _o) = default; | |
81 | DBUser() {} | |
82 | ||
83 | virtual std::unique_ptr<User> clone() override { | |
84 | return std::unique_ptr<User>(new DBUser(*this)); | |
85 | } | |
86 | int list_buckets(const DoutPrefixProvider *dpp, const std::string& marker, const std::string& end_marker, | |
87 | uint64_t max, bool need_stats, BucketList& buckets, optional_yield y) override; | |
88 | virtual int create_bucket(const DoutPrefixProvider* dpp, | |
89 | const rgw_bucket& b, | |
90 | const std::string& zonegroup_id, | |
91 | rgw_placement_rule& placement_rule, | |
92 | std::string& swift_ver_location, | |
93 | const RGWQuotaInfo* pquota_info, | |
94 | const RGWAccessControlPolicy& policy, | |
95 | Attrs& attrs, | |
96 | RGWBucketInfo& info, | |
97 | obj_version& ep_objv, | |
98 | bool exclusive, | |
99 | bool obj_lock_enabled, | |
100 | bool* existed, | |
101 | req_info& req_info, | |
102 | std::unique_ptr<Bucket>* bucket, | |
103 | optional_yield y) override; | |
104 | virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) override; | |
105 | virtual int read_stats(const DoutPrefixProvider *dpp, | |
106 | optional_yield y, RGWStorageStats* stats, | |
107 | ceph::real_time *last_stats_sync = nullptr, | |
108 | ceph::real_time *last_stats_update = nullptr) override; | |
109 | virtual int read_stats_async(const DoutPrefixProvider *dpp, RGWGetUserStats_CB* cb) override; | |
110 | virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override; | |
111 | virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries, | |
112 | bool* is_truncated, RGWUsageIter& usage_iter, | |
113 | map<rgw_user_bucket, rgw_usage_log_entry>& usage) override; | |
114 | virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; | |
115 | ||
116 | /* Placeholders */ | |
117 | virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) override; | |
118 | virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) override; | |
119 | virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; | |
120 | virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; | |
121 | ||
122 | friend class DBBucket; | |
123 | }; | |
124 | ||
125 | class DBBucket : public Bucket { | |
126 | private: | |
127 | DBStore *store; | |
128 | RGWAccessControlPolicy acls; | |
129 | ||
130 | public: | |
131 | DBBucket(DBStore *_st) | |
132 | : store(_st), | |
133 | acls() { | |
134 | } | |
135 | ||
136 | DBBucket(DBStore *_st, User* _u) | |
137 | : Bucket(_u), | |
138 | store(_st), | |
139 | acls() { | |
140 | } | |
141 | ||
142 | DBBucket(DBStore *_st, const rgw_bucket& _b) | |
143 | : Bucket(_b), | |
144 | store(_st), | |
145 | acls() { | |
146 | } | |
147 | ||
148 | DBBucket(DBStore *_st, const RGWBucketEnt& _e) | |
149 | : Bucket(_e), | |
150 | store(_st), | |
151 | acls() { | |
152 | } | |
153 | ||
154 | DBBucket(DBStore *_st, const RGWBucketInfo& _i) | |
155 | : Bucket(_i), | |
156 | store(_st), | |
157 | acls() { | |
158 | } | |
159 | ||
160 | DBBucket(DBStore *_st, const rgw_bucket& _b, User* _u) | |
161 | : Bucket(_b, _u), | |
162 | store(_st), | |
163 | acls() { | |
164 | } | |
165 | ||
166 | DBBucket(DBStore *_st, const RGWBucketEnt& _e, User* _u) | |
167 | : Bucket(_e, _u), | |
168 | store(_st), | |
169 | acls() { | |
170 | } | |
171 | ||
172 | DBBucket(DBStore *_st, const RGWBucketInfo& _i, User* _u) | |
173 | : Bucket(_i, _u), | |
174 | store(_st), | |
175 | acls() { | |
176 | } | |
177 | ||
178 | ~DBBucket() { } | |
179 | ||
180 | virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override; | |
181 | virtual int list(const DoutPrefixProvider *dpp, ListParams&, int, ListResults&, optional_yield y) override; | |
182 | virtual int remove_bucket(const DoutPrefixProvider *dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) override; | |
183 | virtual int remove_bucket_bypass_gc(int concurrent_max, bool | |
184 | keep_index_consistent, | |
185 | optional_yield y, const | |
186 | DoutPrefixProvider *dpp) override; | |
187 | virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } | |
188 | virtual int set_acl(const DoutPrefixProvider *dpp, RGWAccessControlPolicy& acl, optional_yield y) override; | |
189 | virtual int load_bucket(const DoutPrefixProvider *dpp, optional_yield y, bool get_stats = false) override; | |
190 | virtual int read_stats(const DoutPrefixProvider *dpp, int shard_id, | |
191 | std::string *bucket_ver, std::string *master_ver, | |
192 | std::map<RGWObjCategory, RGWStorageStats>& stats, | |
193 | std::string *max_marker = nullptr, | |
194 | bool *syncstopped = nullptr) override; | |
195 | virtual int read_stats_async(const DoutPrefixProvider *dpp, int shard_id, RGWGetBucketStats_CB* ctx) override; | |
196 | virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) override; | |
197 | virtual int update_container_stats(const DoutPrefixProvider *dpp) override; | |
198 | virtual int check_bucket_shards(const DoutPrefixProvider *dpp) override; | |
199 | virtual int chown(const DoutPrefixProvider *dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) override; | |
200 | virtual int put_info(const DoutPrefixProvider *dpp, bool exclusive, ceph::real_time mtime) override; | |
201 | virtual bool is_owner(User* user) override; | |
202 | virtual int check_empty(const DoutPrefixProvider *dpp, optional_yield y) override; | |
203 | virtual int check_quota(const DoutPrefixProvider *dpp, RGWQuotaInfo& user_quota, RGWQuotaInfo& bucket_quota, uint64_t obj_size, optional_yield y, bool check_size_only = false) override; | |
204 | virtual int merge_and_store_attrs(const DoutPrefixProvider *dpp, Attrs& attrs, optional_yield y) override; | |
205 | virtual int try_refresh_info(const DoutPrefixProvider *dpp, ceph::real_time *pmtime) override; | |
206 | virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries, | |
207 | bool *is_truncated, RGWUsageIter& usage_iter, | |
208 | map<rgw_user_bucket, rgw_usage_log_entry>& usage) override; | |
209 | virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; | |
210 | virtual int remove_objs_from_index(const DoutPrefixProvider *dpp, std::list<rgw_obj_index_key>& objs_to_unlink) override; | |
211 | virtual int check_index(const DoutPrefixProvider *dpp, std::map<RGWObjCategory, RGWStorageStats>& existing_stats, std::map<RGWObjCategory, RGWStorageStats>& calculated_stats) override; | |
212 | virtual int rebuild_index(const DoutPrefixProvider *dpp) override; | |
213 | virtual int set_tag_timeout(const DoutPrefixProvider *dpp, uint64_t timeout) override; | |
214 | virtual int purge_instance(const DoutPrefixProvider *dpp) override; | |
215 | virtual std::unique_ptr<Bucket> clone() override { | |
216 | return std::make_unique<DBBucket>(*this); | |
217 | } | |
218 | virtual std::unique_ptr<MultipartUpload> get_multipart_upload( | |
219 | const std::string& oid, std::optional<std::string> upload_id, | |
220 | ACLOwner owner={}, ceph::real_time mtime=ceph::real_clock::now()) override; | |
221 | virtual int list_multiparts(const DoutPrefixProvider *dpp, | |
222 | const string& prefix, | |
223 | string& marker, | |
224 | const string& delim, | |
225 | const int& max_uploads, | |
226 | vector<std::unique_ptr<MultipartUpload>>& uploads, | |
227 | map<string, bool> *common_prefixes, | |
228 | bool *is_truncated) override; | |
229 | virtual int abort_multiparts(const DoutPrefixProvider* dpp, | |
230 | CephContext* cct) override; | |
231 | ||
232 | friend class DBStore; | |
233 | }; | |
234 | ||
235 | class DBZone : public Zone { | |
236 | protected: | |
237 | DBStore* store; | |
238 | RGWRealm *realm{nullptr}; | |
239 | RGWZoneGroup *zonegroup{nullptr}; | |
240 | RGWZone *zone_public_config{nullptr}; /* external zone params, e.g., entrypoints, log flags, etc. */ | |
241 | RGWZoneParams *zone_params{nullptr}; /* internal zone params, e.g., rados pools */ | |
242 | RGWPeriod *current_period{nullptr}; | |
243 | rgw_zone_id cur_zone_id; | |
244 | ||
245 | public: | |
246 | DBZone(DBStore* _store) : store(_store) { | |
247 | realm = new RGWRealm(); | |
248 | zonegroup = new RGWZoneGroup(); | |
249 | zone_public_config = new RGWZone(); | |
250 | zone_params = new RGWZoneParams(); | |
251 | current_period = new RGWPeriod(); | |
252 | cur_zone_id = rgw_zone_id(zone_params->get_id()); | |
253 | ||
254 | // XXX: only default and STANDARD supported for now | |
255 | RGWZonePlacementInfo info; | |
256 | RGWZoneStorageClasses sc; | |
257 | sc.set_storage_class("STANDARD", nullptr, nullptr); | |
258 | info.storage_classes = sc; | |
259 | zone_params->placement_pools["default"] = info; | |
260 | } | |
261 | ~DBZone() = default; | |
262 | ||
263 | virtual const RGWZoneGroup& get_zonegroup() override; | |
264 | virtual int get_zonegroup(const std::string& id, RGWZoneGroup& zonegroup) override; | |
265 | virtual const RGWZoneParams& get_params() override; | |
266 | virtual const rgw_zone_id& get_id() override; | |
267 | virtual const RGWRealm& get_realm() override; | |
268 | virtual const std::string& get_name() const override; | |
269 | virtual bool is_writeable() override; | |
270 | virtual bool get_redirect_endpoint(std::string* endpoint) override; | |
271 | virtual bool has_zonegroup_api(const std::string& api) const override; | |
272 | virtual const std::string& get_current_period_id() override; | |
273 | }; | |
274 | ||
275 | class DBLuaScriptManager : public LuaScriptManager { | |
276 | DBStore* store; | |
277 | ||
278 | public: | |
279 | DBLuaScriptManager(DBStore* _s) : store(_s) | |
280 | { | |
281 | } | |
282 | virtual ~DBLuaScriptManager() = default; | |
283 | ||
284 | virtual int get(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) override { return -ENOENT; } | |
285 | virtual int put(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) override { return -ENOENT; } | |
286 | virtual int del(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) override { return -ENOENT; } | |
287 | }; | |
288 | ||
289 | class DBOIDCProvider : public RGWOIDCProvider { | |
290 | DBStore* store; | |
291 | public: | |
292 | DBOIDCProvider(DBStore* _store) : store(_store) {} | |
293 | ~DBOIDCProvider() = default; | |
294 | ||
295 | virtual int store_url(const DoutPrefixProvider *dpp, const std::string& url, bool exclusive, optional_yield y) override { return 0; } | |
296 | virtual int read_url(const DoutPrefixProvider *dpp, const std::string& url, const std::string& tenant) override { return 0; } | |
297 | virtual int delete_obj(const DoutPrefixProvider *dpp, optional_yield y) override { return 0;} | |
298 | ||
299 | void encode(bufferlist& bl) const { | |
300 | RGWOIDCProvider::encode(bl); | |
301 | } | |
302 | void decode(bufferlist::const_iterator& bl) { | |
303 | RGWOIDCProvider::decode(bl); | |
304 | } | |
305 | }; | |
306 | ||
307 | /* | |
308 | * For multipart upload, below is the process flow - | |
309 | * | |
310 | * MultipartUpload::Init - create head object of meta obj (src_obj_name + "." + upload_id) | |
311 | * [ Meta object stores all the parts upload info] | |
312 | * MultipartWriter::process - create all data/tail objects with obj_name same as | |
313 | * meta obj (so that they can all be identified & deleted | |
314 | * during abort) | |
315 | * MultipartUpload::Abort - Just delete meta obj .. that will indirectly delete all the | |
316 | * uploads associated with that upload id / meta obj so far. | |
317 | * MultipartUpload::Complete - create head object of the original object (if not exists) & | |
318 | * rename all data/tail objects to orig object name and update | |
319 | * metadata of the orig object. | |
320 | */ | |
321 | class DBMultipartPart : public MultipartPart { | |
322 | protected: | |
323 | RGWUploadPartInfo info; /* XXX: info contains manifest also which is not needed */ | |
324 | ||
325 | public: | |
326 | DBMultipartPart() = default; | |
327 | virtual ~DBMultipartPart() = default; | |
328 | ||
329 | virtual RGWUploadPartInfo& get_info() { return info; } | |
330 | virtual void set_info(const RGWUploadPartInfo& _info) { info = _info; } | |
331 | virtual uint32_t get_num() { return info.num; } | |
332 | virtual uint64_t get_size() { return info.accounted_size; } | |
333 | virtual const std::string& get_etag() { return info.etag; } | |
334 | virtual ceph::real_time& get_mtime() { return info.modified; } | |
335 | ||
336 | }; | |
337 | ||
338 | class DBMPObj { | |
339 | std::string oid; // object name | |
340 | std::string upload_id; | |
341 | std::string meta; // multipart meta object = <oid>.<upload_id> | |
342 | public: | |
343 | DBMPObj() {} | |
344 | DBMPObj(const std::string& _oid, const std::string& _upload_id) { | |
345 | init(_oid, _upload_id, _upload_id); | |
346 | } | |
347 | DBMPObj(const std::string& _oid, std::optional<std::string> _upload_id) { | |
348 | if (_upload_id) { | |
349 | init(_oid, *_upload_id, *_upload_id); | |
350 | } else { | |
351 | from_meta(_oid); | |
352 | } | |
353 | } | |
354 | void init(const std::string& _oid, const std::string& _upload_id) { | |
355 | init(_oid, _upload_id, _upload_id); | |
356 | } | |
357 | void init(const std::string& _oid, const std::string& _upload_id, const std::string& part_unique_str) { | |
358 | if (_oid.empty()) { | |
359 | clear(); | |
360 | return; | |
361 | } | |
362 | oid = _oid; | |
363 | upload_id = _upload_id; | |
364 | meta = oid + "." + upload_id; | |
365 | } | |
366 | const std::string& get_upload_id() const { | |
367 | return upload_id; | |
368 | } | |
369 | const std::string& get_key() const { | |
370 | return oid; | |
371 | } | |
372 | const std::string& get_meta() const { return meta; } | |
373 | bool from_meta(const std::string& meta) { | |
374 | int end_pos = meta.length(); | |
375 | int mid_pos = meta.rfind('.', end_pos - 1); // <key>.<upload_id> | |
376 | if (mid_pos < 0) | |
377 | return false; | |
378 | oid = meta.substr(0, mid_pos); | |
379 | upload_id = meta.substr(mid_pos + 1, end_pos - mid_pos - 1); | |
380 | init(oid, upload_id, upload_id); | |
381 | return true; | |
382 | } | |
383 | void clear() { | |
384 | oid = ""; | |
385 | meta = ""; | |
386 | upload_id = ""; | |
387 | } | |
388 | }; | |
389 | ||
390 | class DBMultipartUpload : public MultipartUpload { | |
391 | DBStore* store; | |
392 | DBMPObj mp_obj; | |
393 | ACLOwner owner; | |
394 | ceph::real_time mtime; | |
395 | rgw_placement_rule placement; | |
396 | ||
397 | public: | |
398 | DBMultipartUpload(DBStore* _store, Bucket* _bucket, const std::string& oid, std::optional<std::string> upload_id, ACLOwner _owner, ceph::real_time _mtime) : MultipartUpload(_bucket), store(_store), mp_obj(oid, upload_id), owner(_owner), mtime(_mtime) {} | |
399 | virtual ~DBMultipartUpload() = default; | |
400 | ||
401 | virtual const std::string& get_meta() const { return mp_obj.get_meta(); } | |
402 | virtual const std::string& get_key() const { return mp_obj.get_key(); } | |
403 | virtual const std::string& get_upload_id() const { return mp_obj.get_upload_id(); } | |
404 | virtual const ACLOwner& get_owner() const override { return owner; } | |
405 | virtual ceph::real_time& get_mtime() { return mtime; } | |
406 | virtual std::unique_ptr<rgw::sal::Object> get_meta_obj() override; | |
407 | virtual int init(const DoutPrefixProvider* dpp, optional_yield y, RGWObjectCtx* obj_ctx, ACLOwner& owner, rgw_placement_rule& dest_placement, rgw::sal::Attrs& attrs) override; | |
408 | virtual int list_parts(const DoutPrefixProvider* dpp, CephContext* cct, | |
409 | int num_parts, int marker, | |
410 | int* next_marker, bool* truncated, | |
411 | bool assume_unsorted = false) override; | |
412 | virtual int abort(const DoutPrefixProvider* dpp, CephContext* cct, | |
413 | RGWObjectCtx* obj_ctx) override; | |
414 | virtual int complete(const DoutPrefixProvider* dpp, | |
415 | optional_yield y, CephContext* cct, | |
416 | std::map<int, std::string>& part_etags, | |
417 | std::list<rgw_obj_index_key>& remove_objs, | |
418 | uint64_t& accounted_size, bool& compressed, | |
419 | RGWCompressionInfo& cs_info, off_t& ofs, | |
420 | std::string& tag, ACLOwner& owner, | |
421 | uint64_t olh_epoch, | |
422 | rgw::sal::Object* target_obj, | |
423 | RGWObjectCtx* obj_ctx) override; | |
424 | virtual int get_info(const DoutPrefixProvider *dpp, optional_yield y, RGWObjectCtx* obj_ctx, rgw_placement_rule** rule, rgw::sal::Attrs* attrs = nullptr) override; | |
425 | virtual std::unique_ptr<Writer> get_writer(const DoutPrefixProvider *dpp, | |
426 | optional_yield y, | |
427 | std::unique_ptr<rgw::sal::Object> _head_obj, | |
428 | const rgw_user& owner, RGWObjectCtx& obj_ctx, | |
429 | const rgw_placement_rule *ptail_placement_rule, | |
430 | uint64_t part_num, | |
431 | const std::string& part_num_str) override; | |
432 | }; | |
433 | ||
434 | class DBObject : public Object { | |
435 | private: | |
436 | DBStore* store; | |
437 | RGWAccessControlPolicy acls; | |
438 | /* XXX: to be removed. Till Dan's patch comes, a placeholder | |
439 | * for RGWObjState | |
440 | */ | |
441 | RGWObjState state; | |
442 | ||
443 | public: | |
444 | struct DBReadOp : public ReadOp { | |
445 | private: | |
446 | DBObject* source; | |
447 | RGWObjectCtx* rctx; | |
448 | DB::Object op_target; | |
449 | DB::Object::Read parent_op; | |
450 | ||
451 | public: | |
452 | DBReadOp(DBObject *_source, RGWObjectCtx *_rctx); | |
453 | ||
454 | virtual int prepare(optional_yield y, const DoutPrefixProvider* dpp) override; | |
455 | virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y, const DoutPrefixProvider* dpp) override; | |
456 | virtual int iterate(const DoutPrefixProvider* dpp, int64_t ofs, int64_t end, RGWGetDataCB* cb, optional_yield y) override; | |
457 | virtual int get_attr(const DoutPrefixProvider* dpp, const char* name, bufferlist& dest, optional_yield y) override; | |
458 | }; | |
459 | ||
460 | struct DBDeleteOp : public DeleteOp { | |
461 | private: | |
462 | DBObject* source; | |
463 | RGWObjectCtx* rctx; | |
464 | DB::Object op_target; | |
465 | DB::Object::Delete parent_op; | |
466 | ||
467 | public: | |
468 | DBDeleteOp(DBObject* _source, RGWObjectCtx* _rctx); | |
469 | ||
470 | virtual int delete_obj(const DoutPrefixProvider* dpp, optional_yield y) override; | |
471 | }; | |
472 | ||
473 | DBObject() = default; | |
474 | ||
475 | DBObject(DBStore *_st, const rgw_obj_key& _k) | |
476 | : Object(_k), | |
477 | store(_st), | |
478 | acls() {} | |
479 | ||
480 | DBObject(DBStore *_st, const rgw_obj_key& _k, Bucket* _b) | |
481 | : Object(_k, _b), | |
482 | store(_st), | |
483 | acls() {} | |
484 | ||
485 | DBObject(DBObject& _o) = default; | |
486 | ||
487 | virtual int delete_object(const DoutPrefixProvider* dpp, | |
488 | RGWObjectCtx* obj_ctx, | |
489 | optional_yield y, | |
490 | bool prevent_versioning = false) override; | |
491 | virtual int delete_obj_aio(const DoutPrefixProvider* dpp, RGWObjState* astate, Completions* aio, | |
492 | bool keep_index_consistent, optional_yield y) override; | |
493 | virtual int copy_object(RGWObjectCtx& obj_ctx, User* user, | |
494 | req_info* info, const rgw_zone_id& source_zone, | |
495 | rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket, | |
496 | rgw::sal::Bucket* src_bucket, | |
497 | const rgw_placement_rule& dest_placement, | |
498 | ceph::real_time* src_mtime, ceph::real_time* mtime, | |
499 | const ceph::real_time* mod_ptr, const ceph::real_time* unmod_ptr, | |
500 | bool high_precision_time, | |
501 | const char* if_match, const char* if_nomatch, | |
502 | AttrsMod attrs_mod, bool copy_if_newer, Attrs& attrs, | |
503 | RGWObjCategory category, uint64_t olh_epoch, | |
504 | boost::optional<ceph::real_time> delete_at, | |
505 | std::string* version_id, std::string* tag, std::string* etag, | |
506 | void (*progress_cb)(off_t, void *), void* progress_data, | |
507 | const DoutPrefixProvider* dpp, optional_yield y) override; | |
508 | virtual RGWAccessControlPolicy& get_acl(void) override { return acls; } | |
509 | virtual int set_acl(const RGWAccessControlPolicy& acl) override { acls = acl; return 0; } | |
510 | virtual void set_atomic(RGWObjectCtx* rctx) const override; | |
511 | virtual void set_prefetch_data(RGWObjectCtx* rctx) override; | |
512 | virtual void set_compressed(RGWObjectCtx* rctx) override; | |
513 | ||
514 | virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, RGWObjState **state, optional_yield y, bool follow_olh = true) override; | |
515 | virtual int set_obj_attrs(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, Attrs* setattrs, Attrs* delattrs, optional_yield y, rgw_obj* target_obj = NULL) override; | |
516 | virtual int get_obj_attrs(RGWObjectCtx* rctx, optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) override; | |
517 | virtual int modify_obj_attrs(RGWObjectCtx* rctx, const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) override; | |
518 | virtual int delete_obj_attrs(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, const char* attr_name, optional_yield y) override; | |
519 | virtual bool is_expired() override; | |
520 | virtual void gen_rand_obj_instance_name() override; | |
521 | virtual std::unique_ptr<Object> clone() override { | |
522 | return std::unique_ptr<Object>(new DBObject(*this)); | |
523 | } | |
524 | virtual MPSerializer* get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) override; | |
525 | virtual int transition(RGWObjectCtx& rctx, | |
526 | Bucket* bucket, | |
527 | const rgw_placement_rule& placement_rule, | |
528 | const real_time& mtime, | |
529 | uint64_t olh_epoch, | |
530 | const DoutPrefixProvider* dpp, | |
531 | optional_yield y) override; | |
532 | virtual bool placement_rules_match(rgw_placement_rule& r1, rgw_placement_rule& r2) override; | |
533 | virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f, RGWObjectCtx* obj_ctx) override; | |
534 | ||
535 | /* Swift versioning */ | |
536 | virtual int swift_versioning_restore(RGWObjectCtx* obj_ctx, | |
537 | bool& restored, | |
538 | const DoutPrefixProvider* dpp) override; | |
539 | virtual int swift_versioning_copy(RGWObjectCtx* obj_ctx, | |
540 | const DoutPrefixProvider* dpp, | |
541 | optional_yield y) override; | |
542 | ||
543 | /* OPs */ | |
544 | virtual std::unique_ptr<ReadOp> get_read_op(RGWObjectCtx *) override; | |
545 | virtual std::unique_ptr<DeleteOp> get_delete_op(RGWObjectCtx*) override; | |
546 | ||
547 | /* OMAP */ | |
548 | virtual int omap_get_vals(const DoutPrefixProvider *dpp, const std::string& marker, uint64_t count, | |
549 | std::map<std::string, bufferlist> *m, | |
550 | bool* pmore, optional_yield y) override; | |
551 | virtual int omap_get_all(const DoutPrefixProvider *dpp, std::map<std::string, bufferlist> *m, | |
552 | optional_yield y) override; | |
553 | virtual int omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid, | |
554 | const std::set<std::string>& keys, | |
555 | Attrs* vals) override; | |
556 | virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val, | |
557 | bool must_exist, optional_yield y) override; | |
558 | private: | |
559 | int read_attrs(const DoutPrefixProvider* dpp, DB::Object::Read &read_op, optional_yield y, rgw_obj* target_obj = nullptr); | |
560 | }; | |
561 | ||
562 | class MPDBSerializer : public MPSerializer { | |
563 | ||
564 | public: | |
565 | MPDBSerializer(const DoutPrefixProvider *dpp, DBStore* store, DBObject* obj, const std::string& lock_name) {} | |
566 | ||
567 | virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) override {return 0; } | |
568 | virtual int unlock() override { return 0;} | |
569 | }; | |
570 | ||
571 | class DBAtomicWriter : public Writer { | |
572 | protected: | |
573 | rgw::sal::DBStore* store; | |
574 | const rgw_user& owner; | |
575 | const rgw_placement_rule *ptail_placement_rule; | |
576 | uint64_t olh_epoch; | |
577 | const std::string& unique_tag; | |
578 | DBObject obj; | |
579 | DB::Object op_target; | |
580 | DB::Object::Write parent_op; | |
581 | uint64_t total_data_size = 0; /* for total data being uploaded */ | |
582 | bufferlist head_data; | |
583 | bufferlist tail_part_data; | |
584 | uint64_t tail_part_offset; | |
585 | uint64_t tail_part_size = 0; /* corresponds to each tail part being | |
586 | written to dbstore */ | |
587 | ||
588 | public: | |
589 | DBAtomicWriter(const DoutPrefixProvider *dpp, | |
590 | optional_yield y, | |
591 | std::unique_ptr<rgw::sal::Object> _head_obj, | |
592 | DBStore* _store, | |
593 | const rgw_user& _owner, RGWObjectCtx& obj_ctx, | |
594 | const rgw_placement_rule *_ptail_placement_rule, | |
595 | uint64_t _olh_epoch, | |
596 | const std::string& _unique_tag); | |
597 | ~DBAtomicWriter() = default; | |
598 | ||
599 | // prepare to start processing object data | |
600 | virtual int prepare(optional_yield y) override; | |
601 | ||
602 | // Process a bufferlist | |
603 | virtual int process(bufferlist&& data, uint64_t offset) override; | |
604 | ||
605 | // complete the operation and make its result visible to clients | |
606 | virtual int complete(size_t accounted_size, const std::string& etag, | |
607 | ceph::real_time *mtime, ceph::real_time set_mtime, | |
608 | std::map<std::string, bufferlist>& attrs, | |
609 | ceph::real_time delete_at, | |
610 | const char *if_match, const char *if_nomatch, | |
611 | const std::string *user_data, | |
612 | rgw_zone_set *zones_trace, bool *canceled, | |
613 | optional_yield y) override; | |
614 | }; | |
615 | ||
616 | class DBMultipartWriter : public Writer { | |
617 | protected: | |
618 | rgw::sal::DBStore* store; | |
619 | const rgw_user& owner; | |
620 | const rgw_placement_rule *ptail_placement_rule; | |
621 | uint64_t olh_epoch; | |
622 | std::unique_ptr<rgw::sal::Object> head_obj; | |
623 | string upload_id; | |
624 | string oid; /* object->name() + "." + "upload_id" + "." + part_num */ | |
625 | std::unique_ptr<rgw::sal::Object> meta_obj; | |
626 | DB::Object op_target; | |
627 | DB::Object::Write parent_op; | |
628 | int part_num; | |
629 | string part_num_str; | |
630 | uint64_t total_data_size = 0; /* for total data being uploaded */ | |
631 | bufferlist head_data; | |
632 | bufferlist tail_part_data; | |
633 | uint64_t tail_part_offset; | |
634 | uint64_t tail_part_size = 0; /* corresponds to each tail part being | |
635 | written to dbstore */ | |
636 | ||
637 | public: | |
638 | DBMultipartWriter(const DoutPrefixProvider *dpp, | |
639 | optional_yield y, MultipartUpload* upload, | |
640 | std::unique_ptr<rgw::sal::Object> _head_obj, | |
641 | DBStore* _store, | |
642 | const rgw_user& owner, RGWObjectCtx& obj_ctx, | |
643 | const rgw_placement_rule *ptail_placement_rule, | |
644 | uint64_t part_num, const std::string& part_num_str); | |
645 | ~DBMultipartWriter() = default; | |
646 | ||
647 | // prepare to start processing object data | |
648 | virtual int prepare(optional_yield y) override; | |
649 | ||
650 | // Process a bufferlist | |
651 | virtual int process(bufferlist&& data, uint64_t offset) override; | |
652 | ||
653 | // complete the operation and make its result visible to clients | |
654 | virtual int complete(size_t accounted_size, const std::string& etag, | |
655 | ceph::real_time *mtime, ceph::real_time set_mtime, | |
656 | std::map<std::string, bufferlist>& attrs, | |
657 | ceph::real_time delete_at, | |
658 | const char *if_match, const char *if_nomatch, | |
659 | const std::string *user_data, | |
660 | rgw_zone_set *zones_trace, bool *canceled, | |
661 | optional_yield y) override; | |
662 | }; | |
663 | ||
664 | class DBStore : public Store { | |
665 | private: | |
666 | /* DBStoreManager is used in case multiple | |
667 | * connections are needed one for each tenant. | |
668 | */ | |
669 | DBStoreManager *dbsm; | |
670 | /* default db (single connection). If needed | |
671 | * multiple db handles (for eg., one for each tenant), | |
672 | * use dbsm->getDB(tenant) */ | |
673 | DB *db; | |
674 | string luarocks_path; | |
675 | DBZone zone; | |
676 | RGWSyncModuleInstanceRef sync_module; | |
677 | RGWLC* lc; | |
678 | CephContext *cct; | |
679 | const DoutPrefixProvider *dpp; | |
680 | bool use_lc_thread; | |
681 | ||
682 | public: | |
683 | DBStore(): dbsm(nullptr), zone(this), cct(nullptr), dpp(nullptr), | |
684 | use_lc_thread(false) {} | |
685 | ~DBStore() { delete dbsm; } | |
686 | ||
687 | DBStore& set_run_lc_thread(bool _use_lc_thread) { | |
688 | use_lc_thread = _use_lc_thread; | |
689 | return *this; | |
690 | } | |
691 | ||
692 | int initialize(CephContext *cct, const DoutPrefixProvider *dpp); | |
693 | ||
694 | virtual const char* get_name() const override { | |
695 | return "dbstore"; | |
696 | } | |
697 | ||
698 | virtual std::unique_ptr<User> get_user(const rgw_user& u) override; | |
699 | virtual int get_user_by_access_key(const DoutPrefixProvider *dpp, const std::string& key, optional_yield y, std::unique_ptr<User>* user) override; | |
700 | virtual int get_user_by_email(const DoutPrefixProvider *dpp, const std::string& email, optional_yield y, std::unique_ptr<User>* user) override; | |
701 | virtual int get_user_by_swift(const DoutPrefixProvider *dpp, const std::string& user_str, optional_yield y, std::unique_ptr<User>* user) override; | |
702 | virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) override; | |
703 | virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y); | |
704 | virtual int get_bucket(const DoutPrefixProvider *dpp, User* u, const rgw_bucket& b, std::unique_ptr<Bucket>* bucket, optional_yield y) override; | |
705 | virtual int get_bucket(User* u, const RGWBucketInfo& i, std::unique_ptr<Bucket>* bucket) override; | |
706 | virtual int get_bucket(const DoutPrefixProvider *dpp, User* u, const std::string& tenant, const std::string&name, std::unique_ptr<Bucket>* bucket, optional_yield y) override; | |
707 | virtual bool is_meta_master() override; | |
708 | virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv, | |
709 | bufferlist& in_data, JSONParser *jp, req_info& info, | |
710 | optional_yield y) override; | |
711 | virtual Zone* get_zone() { return &zone; } | |
712 | virtual std::string zone_unique_id(uint64_t unique_num) override; | |
713 | virtual std::string zone_unique_trans_id(const uint64_t unique_num) override; | |
714 | virtual int cluster_stat(RGWClusterStat& stats) override; | |
715 | virtual std::unique_ptr<Lifecycle> get_lifecycle(void) override; | |
716 | virtual std::unique_ptr<Completions> get_completions(void) override; | |
717 | ||
718 | virtual std::unique_ptr<Notification> get_notification( | |
719 | rgw::sal::Object* obj, rgw::sal::Object* src_obj, struct req_state* s, | |
720 | rgw::notify::EventType event_type, const std::string* object_name) override; | |
721 | ||
722 | virtual std::unique_ptr<Notification> get_notification( | |
723 | const DoutPrefixProvider* dpp, rgw::sal::Object* obj, | |
724 | rgw::sal::Object* src_obj, RGWObjectCtx* rctx, | |
725 | rgw::notify::EventType event_type, rgw::sal::Bucket* _bucket, | |
726 | std::string& _user_id, std::string& _user_tenant, std::string& _req_id, | |
727 | optional_yield y) override; | |
728 | ||
729 | virtual RGWLC* get_rgwlc(void) override; | |
730 | virtual RGWCoroutinesManagerRegistry* get_cr_registry() override { return NULL; } | |
731 | virtual int log_usage(const DoutPrefixProvider *dpp, map<rgw_user_bucket, RGWUsageBatch>& usage_info) override; | |
732 | virtual int log_op(const DoutPrefixProvider *dpp, std::string& oid, bufferlist& bl) override; | |
733 | virtual int register_to_service_map(const DoutPrefixProvider *dpp, const string& daemon_type, | |
734 | const map<string, string>& meta) override; | |
735 | virtual void get_ratelimit(RGWRateLimitInfo& bucket_ratelimit, RGWRateLimitInfo& user_ratelimit, RGWRateLimitInfo& anon_ratelimit) override; | |
736 | virtual void get_quota(RGWQuotaInfo& bucket_quota, RGWQuotaInfo& user_quota) override; | |
737 | virtual int set_buckets_enabled(const DoutPrefixProvider *dpp, vector<rgw_bucket>& buckets, bool enabled) override; | |
738 | virtual uint64_t get_new_req_id() override { return 0; } | |
739 | virtual int get_sync_policy_handler(const DoutPrefixProvider *dpp, | |
740 | std::optional<rgw_zone_id> zone, | |
741 | std::optional<rgw_bucket> bucket, | |
742 | RGWBucketSyncPolicyHandlerRef *phandler, | |
743 | optional_yield y) override; | |
744 | virtual RGWDataSyncStatusManager* get_data_sync_manager(const rgw_zone_id& source_zone) override; | |
745 | virtual void wakeup_meta_sync_shards(set<int>& shard_ids) override { return; } | |
746 | virtual void wakeup_data_sync_shards(const DoutPrefixProvider *dpp, const rgw_zone_id& source_zone, map<int, set<string> >& shard_ids) override { return; } | |
747 | virtual int clear_usage(const DoutPrefixProvider *dpp) override { return 0; } | |
748 | virtual int read_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, | |
749 | uint32_t max_entries, bool *is_truncated, | |
750 | RGWUsageIter& usage_iter, | |
751 | map<rgw_user_bucket, rgw_usage_log_entry>& usage) override; | |
752 | virtual int trim_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override; | |
753 | virtual int get_config_key_val(std::string name, bufferlist* bl) override; | |
754 | virtual int meta_list_keys_init(const DoutPrefixProvider *dpp, const std::string& section, const std::string& marker, void** phandle) override; | |
755 | virtual int meta_list_keys_next(const DoutPrefixProvider *dpp, void* handle, int max, list<std::string>& keys, bool* truncated) override; | |
756 | virtual void meta_list_keys_complete(void* handle) override; | |
757 | virtual std::string meta_get_marker(void *handle) override; | |
758 | virtual int meta_remove(const DoutPrefixProvider *dpp, string& metadata_key, optional_yield y) override; | |
759 | ||
760 | virtual const RGWSyncModuleInstanceRef& get_sync_module() { return sync_module; } | |
761 | virtual std::string get_host_id() { return ""; } | |
762 | ||
763 | virtual std::unique_ptr<LuaScriptManager> get_lua_script_manager() override; | |
764 | virtual std::unique_ptr<RGWRole> get_role(std::string name, | |
765 | std::string tenant, | |
766 | std::string path="", | |
767 | std::string trust_policy="", | |
768 | std::string max_session_duration_str="", | |
769 | std::multimap<std::string,std::string> tags={}) override; | |
770 | virtual std::unique_ptr<RGWRole> get_role(std::string id) override; | |
771 | virtual int get_roles(const DoutPrefixProvider *dpp, | |
772 | optional_yield y, | |
773 | const std::string& path_prefix, | |
774 | const std::string& tenant, | |
775 | vector<std::unique_ptr<RGWRole>>& roles) override; | |
776 | virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() override; | |
777 | virtual int get_oidc_providers(const DoutPrefixProvider *dpp, | |
778 | const std::string& tenant, | |
779 | vector<std::unique_ptr<RGWOIDCProvider>>& providers) override; | |
780 | virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp, | |
781 | optional_yield y, | |
782 | std::unique_ptr<rgw::sal::Object> _head_obj, | |
783 | const rgw_user& owner, RGWObjectCtx& obj_ctx, | |
784 | const rgw_placement_rule *ptail_placement_rule, | |
785 | const std::string& unique_tag, | |
786 | uint64_t position, | |
787 | uint64_t *cur_accounted_size) override; | |
788 | virtual std::unique_ptr<Writer> get_atomic_writer(const DoutPrefixProvider *dpp, | |
789 | optional_yield y, | |
790 | std::unique_ptr<rgw::sal::Object> _head_obj, | |
791 | const rgw_user& owner, RGWObjectCtx& obj_ctx, | |
792 | const rgw_placement_rule *ptail_placement_rule, | |
793 | uint64_t olh_epoch, | |
794 | const std::string& unique_tag) override; | |
795 | ||
796 | virtual void finalize(void) override; | |
797 | ||
798 | virtual CephContext *ctx(void) override { | |
799 | return db->ctx(); | |
800 | } | |
801 | ||
802 | virtual const std::string& get_luarocks_path() const override { | |
803 | return luarocks_path; | |
804 | } | |
805 | ||
806 | virtual void set_luarocks_path(const std::string& path) override { | |
807 | luarocks_path = path; | |
808 | } | |
809 | ||
810 | /* Unique to DBStore */ | |
811 | void setDBStoreManager(DBStoreManager *stm) { dbsm = stm; } | |
812 | DBStoreManager *getDBStoreManager(void) { return dbsm; } | |
813 | ||
814 | void setDB(DB * st) { db = st; } | |
815 | DB *getDB(void) { return db; } | |
816 | ||
817 | DB *getDB(string tenant) { return dbsm->getDB(tenant, false); } | |
818 | }; | |
819 | ||
820 | } } // namespace rgw::sal |