]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_sal.h
9d02cbbfdf501bc914e514f411b6580eb72423e7
[ceph.git] / ceph / src / rgw / rgw_sal.h
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) 2019 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_user.h"
19 #include "rgw_notify_event_type.h"
20 #include "common/tracer.h"
21
22 class RGWGetDataCB;
23 struct RGWObjState;
24 class RGWAccessListFilter;
25 class RGWLC;
26 class RGWObjManifest;
27 struct RGWZoneGroup;
28 struct RGWZoneParams;
29 struct RGWRealm;
30 struct RGWCtl;
31 struct rgw_user_bucket;
32 class RGWUsageBatch;
33 class RGWCoroutinesManagerRegistry;
34 class RGWListRawObjsCtx;
35 class RGWBucketSyncPolicyHandler;
36 using RGWBucketSyncPolicyHandlerRef = std::shared_ptr<RGWBucketSyncPolicyHandler>;
37 class RGWDataSyncStatusManager;
38 class RGWSyncModuleInstance;
39 typedef std::shared_ptr<RGWSyncModuleInstance> RGWSyncModuleInstanceRef;
40 class RGWCompressionInfo;
41
42
43 using RGWBucketListNameFilter = std::function<bool (const std::string&)>;
44
45
46 namespace rgw {
47 class Aio;
48 namespace IAM { struct Policy; }
49 }
50
51 class RGWGetDataCB {
52 public:
53 virtual int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) = 0;
54 RGWGetDataCB() {}
55 virtual ~RGWGetDataCB() {}
56 };
57
58 struct RGWUsageIter {
59 std::string read_iter;
60 uint32_t index;
61
62 RGWUsageIter() : index(0) {}
63 };
64
65 /**
66 * @struct RGWClusterStat
67 * Cluster-wide usage information
68 */
69 struct RGWClusterStat {
70 /// total device size
71 uint64_t kb;
72 /// total used
73 uint64_t kb_used;
74 /// total available/free
75 uint64_t kb_avail;
76 /// number of objects
77 uint64_t num_objects;
78 };
79
80 class RGWGetBucketStats_CB : public RefCountedObject {
81 protected:
82 rgw_bucket bucket;
83 std::map<RGWObjCategory, RGWStorageStats>* stats;
84 public:
85 explicit RGWGetBucketStats_CB(const rgw_bucket& _bucket) : bucket(_bucket), stats(NULL) {}
86 ~RGWGetBucketStats_CB() override {}
87 virtual void handle_response(int r) = 0;
88 virtual void set_response(std::map<RGWObjCategory, RGWStorageStats>* _stats) {
89 stats = _stats;
90 }
91 };
92
93 class RGWGetUserStats_CB : public RefCountedObject {
94 protected:
95 rgw_user user;
96 RGWStorageStats stats;
97 public:
98 explicit RGWGetUserStats_CB(const rgw_user& _user) : user(_user) {}
99 ~RGWGetUserStats_CB() override {}
100 virtual void handle_response(int r) = 0;
101 virtual void set_response(RGWStorageStats& _stats) {
102 stats = _stats;
103 }
104 };
105
106 /**
107 * @defgroup RGWSAL RGW Store Abstraction Layer
108 *
109 * The Store Abstraction Layer is an API that separates the top layer of RGW that
110 * handles client protocols (such as S3 or Swift) from the bottom layer of RGW that
111 * interacts with a backing store. It allows the creation of multiple backing stores
112 * that can co-exist with a single RGW instance, and allows the creation of stacking
113 * layers of translators that can modify operations as they pass down the stack.
114 * Examples of translators might be a cache layer, a duplication layer that copies
115 * operations to multiple stores, or a policy layer that sends some operations to one
116 * store and some to another.
117 *
118 * The basic unit of a SAL implementation is the Store. Whether an actual backing store
119 * or a translator, there will be a Store implementation that represents it. Examples
120 * are the RadosStore that communicates via RADOS with a Ceph cluster, and the DBStore
121 * that uses a SQL db (such as SQLite3) as a backing store. There is a singleton
122 * instance of each Store.
123 *
124 * Data within RGW is owned by a User. The User is the unit of authentication and
125 * access control.
126 *
127 * Data within RGW is stored as an Object. Each Object is a single chunk of data, owned
128 * by a single User, contained within a single Bucket. It has metadata associated with
129 * it, such as size, owner, and so in, and a set of key-value attributes that can
130 * contain anything needed by the top half.
131 *
132 * Data with RGW is organized into Buckets. Each Bucket is owned by a User, and
133 * contains Objects. There is a single, flat layer of Buckets, there is no hierarchy,
134 * and each Object is contained in a single Bucket.
135 *
136 * Instantiations of SAL classes are done as unique pointers, using std::unique_ptr.
137 * Instances of these classes are acquired via getters, and it's up to the caller to
138 * manage the lifetime.
139 *
140 * @note Anything using RGWObjContext is subject to change, as that type will not be
141 * used in the final API.
142 * @{
143 */
144
145 /**
146 * @file rgw_sal.h
147 * @brief Base abstractions and API for SAL
148 */
149
150 namespace rgw { namespace sal {
151
152 /**
153 * @addtogroup RGWSAL
154 * @{
155 */
156
157 #define RGW_SAL_VERSION 1
158
159 class User;
160 class Bucket;
161 class Object;
162 class BucketList;
163 class MultipartUpload;
164 struct MPSerializer;
165 class Lifecycle;
166 class Notification;
167 class GCChain;
168 class Writer;
169 class Zone;
170 class LuaScriptManager;
171 class RGWOIDCProvider;
172 class RGWRole;
173
174 enum AttrsMod {
175 ATTRSMOD_NONE = 0,
176 ATTRSMOD_REPLACE = 1,
177 ATTRSMOD_MERGE = 2
178 };
179
180 // a simple streaming data processing abstraction
181 /**
182 * @brief A simple streaming data processing abstraction
183 */
184 class DataProcessor {
185 public:
186 virtual ~DataProcessor() {}
187
188 /**
189 * @brief Consume a bufferlist in its entirety at the given object offset.
190 *
191 * An empty bufferlist is given to request that any buffered data be flushed, though this doesn't
192 * wait for completions
193 */
194 virtual int process(bufferlist&& data, uint64_t offset) = 0;
195 };
196
197 /**
198 * @brief a data consumer that writes an object in a bucket
199 */
200 class ObjectProcessor : public DataProcessor {
201 public:
202 /** prepare to start processing object data */
203 virtual int prepare(optional_yield y) = 0;
204
205 /** complete the operation and make its result visible to clients */
206 virtual int complete(size_t accounted_size, const std::string& etag,
207 ceph::real_time *mtime, ceph::real_time set_mtime,
208 std::map<std::string, bufferlist>& attrs,
209 ceph::real_time delete_at,
210 const char *if_match, const char *if_nomatch,
211 const std::string *user_data,
212 rgw_zone_set *zones_trace, bool *canceled,
213 optional_yield y) = 0;
214 };
215
216 /** Base class for AIO completions */
217 class Completions {
218 public:
219 Completions() {}
220 virtual ~Completions() = default;
221 virtual int drain() = 0;
222 };
223
224 /** A list of key-value attributes */
225 using Attrs = std::map<std::string, ceph::buffer::list>;
226
227 /**
228 * @brief Base singleton representing a Store or stacking layer
229 *
230 * The Store is the base abstraction of the SAL layer. It represents a base storage
231 * mechanism, or a intermediate stacking layer. There is a single instance of a given
232 * Store per RGW, and this Store mediates all access to it's backing.
233 *
234 * A store contains, loosely, @a User, @a Bucket, and @a Object entities. The @a Object
235 * contains data, and it's associated metadata. The @a Bucket contains Objects, and
236 * metadata about the bucket. Both Buckets and Objects are owned by a @a User, which is
237 * the basic unit of access control.
238 *
239 * A store also has metadata and some global responsibilities. For example, a store is
240 * responsible for managing the LifeCycle activities for it's data.
241 */
242 class Store {
243 public:
244 Store() {}
245 virtual ~Store() = default;
246
247 /** Name of this store provider (e.g., RADOS") */
248 virtual const char* get_name() const = 0;
249 /** Get cluster unique identifier */
250 virtual std::string get_cluster_id(const DoutPrefixProvider* dpp, optional_yield y) = 0;
251 /** Get a User from a rgw_user. Does not query store for user info, so quick */
252 virtual std::unique_ptr<User> get_user(const rgw_user& u) = 0;
253 /** Lookup a User by access key. Queries store for user info. */
254 virtual int get_user_by_access_key(const DoutPrefixProvider* dpp, const std::string& key, optional_yield y, std::unique_ptr<User>* user) = 0;
255 /** Lookup a User by email address. Queries store for user info. */
256 virtual int get_user_by_email(const DoutPrefixProvider* dpp, const std::string& email, optional_yield y, std::unique_ptr<User>* user) = 0;
257 /** Lookup a User by swift username. Queries store for user info. */
258 virtual int get_user_by_swift(const DoutPrefixProvider* dpp, const std::string& user_str, optional_yield y, std::unique_ptr<User>* user) = 0;
259 /** Get a basic Object. This Object is not looked up, and is incomplete, since is
260 * does not have a bucket. This should only be used when an Object is needed before
261 * there is a Bucket, otherwise use the get_object() in the Bucket class. */
262 virtual std::unique_ptr<Object> get_object(const rgw_obj_key& k) = 0;
263 /** Get a Bucket by info. Does not query the store, just uses the give bucket info. */
264 virtual int get_bucket(User* u, const RGWBucketInfo& i, std::unique_ptr<Bucket>* bucket) = 0;
265 /** Lookup a Bucket by key. Queries store for bucket info. */
266 virtual int get_bucket(const DoutPrefixProvider* dpp, User* u, const rgw_bucket& b, std::unique_ptr<Bucket>* bucket, optional_yield y) = 0;
267 /** Lookup a Bucket by name. Queries store for bucket info. */
268 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) = 0;
269 /** For multisite, this Store is the zone's master */
270 virtual bool is_meta_master() = 0;
271 /** For multisite, forward an OP to the zone's master */
272 virtual int forward_request_to_master(const DoutPrefixProvider *dpp, User* user, obj_version* objv,
273 bufferlist& in_data, JSONParser* jp, req_info& info,
274 optional_yield y) = 0;
275 /** Get zone info for this store */
276 virtual Zone* get_zone() = 0;
277 /** Get a unique ID specific to this zone. */
278 virtual std::string zone_unique_id(uint64_t unique_num) = 0;
279 /** Get a unique Swift transaction ID specific to this zone */
280 virtual std::string zone_unique_trans_id(const uint64_t unique_num) = 0;
281 /** Get statistics about the cluster represented by this Store */
282 virtual int cluster_stat(RGWClusterStat& stats) = 0;
283 /** Get a @a Lifecycle object. Used to manage/run lifecycle transitions */
284 virtual std::unique_ptr<Lifecycle> get_lifecycle(void) = 0;
285 /** Get a @a Completions object. Used for Async I/O tracking */
286 virtual std::unique_ptr<Completions> get_completions(void) = 0;
287
288 /** Get a @a Notification object. Used to communicate with non-RGW daemons, such as
289 * management/tracking software */
290 /** RGWOp variant */
291 virtual std::unique_ptr<Notification> get_notification(rgw::sal::Object* obj, rgw::sal::Object* src_obj, struct req_state* s,
292 rgw::notify::EventType event_type, const std::string* object_name=nullptr) = 0;
293 /** No-req_state variant (e.g., rgwlc) */
294 virtual std::unique_ptr<Notification> get_notification(
295 const DoutPrefixProvider* dpp, rgw::sal::Object* obj, rgw::sal::Object* src_obj, RGWObjectCtx* rctx,
296 rgw::notify::EventType event_type, rgw::sal::Bucket* _bucket, std::string& _user_id, std::string& _user_tenant,
297 std::string& _req_id, optional_yield y) = 0;
298
299 /** Get access to the lifecycle management thread */
300 virtual RGWLC* get_rgwlc(void) = 0;
301 /** Get access to the coroutine registry. Used to create new coroutine managers */
302 virtual RGWCoroutinesManagerRegistry* get_cr_registry() = 0;
303
304 /** Log usage data to the store. Usage data is things like bytes sent/received and
305 * op count */
306 virtual int log_usage(const DoutPrefixProvider *dpp, std::map<rgw_user_bucket, RGWUsageBatch>& usage_info) = 0;
307 /** Log OP data to the store. Data is opaque to SAL */
308 virtual int log_op(const DoutPrefixProvider *dpp, std::string& oid, bufferlist& bl) = 0;
309 /** Register this Store to the service map. Somewhat Rados specific; may be removed*/
310 virtual int register_to_service_map(const DoutPrefixProvider *dpp, const std::string& daemon_type,
311 const std::map<std::string, std::string>& meta) = 0;
312 /** Get default quota info. Used as fallback if a user or bucket has no quota set*/
313 virtual void get_quota(RGWQuotaInfo& bucket_quota, RGWQuotaInfo& user_quota) = 0;
314 /** Get global rate limit configuration*/
315 virtual void get_ratelimit(RGWRateLimitInfo& bucket_ratelimit, RGWRateLimitInfo& user_ratelimit, RGWRateLimitInfo& anon_ratelimit) = 0;
316 /** Enable or disable a set of bucket. e.g. if a User is suspended */
317 virtual int set_buckets_enabled(const DoutPrefixProvider* dpp, std::vector<rgw_bucket>& buckets, bool enabled) = 0;
318 /** Get a new request ID */
319 virtual uint64_t get_new_req_id() = 0;
320 /** Get a handler for bucket sync policy. */
321 virtual int get_sync_policy_handler(const DoutPrefixProvider* dpp,
322 std::optional<rgw_zone_id> zone,
323 std::optional<rgw_bucket> bucket,
324 RGWBucketSyncPolicyHandlerRef* phandler,
325 optional_yield y) = 0;
326 /** Get a status manager for bucket sync */
327 virtual RGWDataSyncStatusManager* get_data_sync_manager(const rgw_zone_id& source_zone) = 0;
328 /** Wake up sync threads for bucket metadata sync */
329 virtual void wakeup_meta_sync_shards(std::set<int>& shard_ids) = 0;
330 /** Wake up sync threads for bucket data sync */
331 virtual void wakeup_data_sync_shards(const DoutPrefixProvider *dpp, const rgw_zone_id& source_zone, std::map<int, std::set<std::string> >& shard_ids) = 0;
332 /** Clear all usage statistics globally */
333 virtual int clear_usage(const DoutPrefixProvider *dpp) = 0;
334 /** Get usage statistics for all users and buckets */
335 virtual int read_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch,
336 uint32_t max_entries, bool* is_truncated,
337 RGWUsageIter& usage_iter,
338 std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0;
339 /** Trim usage log for all users and buckets */
340 virtual int trim_all_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0;
341 /** Get a configuration value for the given name */
342 virtual int get_config_key_val(std::string name, bufferlist* bl) = 0;
343 /** Start a metadata listing of the given section */
344 virtual int meta_list_keys_init(const DoutPrefixProvider *dpp, const std::string& section, const std::string& marker, void** phandle) = 0;
345 /** Get the next key from a metadata list */
346 virtual int meta_list_keys_next(const DoutPrefixProvider *dpp, void* handle, int max, std::list<std::string>& keys, bool* truncated) = 0;
347 /** Complete a metadata listing */
348 virtual void meta_list_keys_complete(void* handle) = 0;
349 /** Get the marker associated with the current metadata listing */
350 virtual std::string meta_get_marker(void* handle) = 0;
351 /** Remove a specific metadata key */
352 virtual int meta_remove(const DoutPrefixProvider* dpp, std::string& metadata_key, optional_yield y) = 0;
353 /** Get an instance of the Sync module for bucket sync */
354 virtual const RGWSyncModuleInstanceRef& get_sync_module() = 0;
355 /** Get the ID of the current host */
356 virtual std::string get_host_id() = 0;
357 /** Get a Lua script manager for running lua scripts */
358 virtual std::unique_ptr<LuaScriptManager> get_lua_script_manager() = 0;
359 /** Get an IAM Role by name etc. */
360 virtual std::unique_ptr<RGWRole> get_role(std::string name,
361 std::string tenant,
362 std::string path="",
363 std::string trust_policy="",
364 std::string max_session_duration_str="",
365 std::multimap<std::string,std::string> tags={}) = 0;
366 /** Get an IAM Role by ID */
367 virtual std::unique_ptr<RGWRole> get_role(std::string id) = 0;
368 /** Get all IAM Roles optionally filtered by path */
369 virtual int get_roles(const DoutPrefixProvider *dpp,
370 optional_yield y,
371 const std::string& path_prefix,
372 const std::string& tenant,
373 std::vector<std::unique_ptr<RGWRole>>& roles) = 0;
374 /** Get an empty Open ID Connector provider */
375 virtual std::unique_ptr<RGWOIDCProvider> get_oidc_provider() = 0;
376 /** Get all Open ID Connector providers, optionally filtered by tenant */
377 virtual int get_oidc_providers(const DoutPrefixProvider *dpp,
378 const std::string& tenant,
379 std::vector<std::unique_ptr<RGWOIDCProvider>>& providers) = 0;
380 /** Get a Writer that appends to an object */
381 virtual std::unique_ptr<Writer> get_append_writer(const DoutPrefixProvider *dpp,
382 optional_yield y,
383 std::unique_ptr<rgw::sal::Object> _head_obj,
384 const rgw_user& owner, RGWObjectCtx& obj_ctx,
385 const rgw_placement_rule *ptail_placement_rule,
386 const std::string& unique_tag,
387 uint64_t position,
388 uint64_t *cur_accounted_size) = 0;
389 /** Get a Writer that atomically writes an entire object */
390 virtual std::unique_ptr<Writer> get_atomic_writer(const DoutPrefixProvider *dpp,
391 optional_yield y,
392 std::unique_ptr<rgw::sal::Object> _head_obj,
393 const rgw_user& owner, RGWObjectCtx& obj_ctx,
394 const rgw_placement_rule *ptail_placement_rule,
395 uint64_t olh_epoch,
396 const std::string& unique_tag) = 0;
397
398 /** Clean up a store for termination */
399 virtual void finalize(void) = 0;
400
401 /** Get the Ceph context associated with this store. May be removed. */
402 virtual CephContext* ctx(void) = 0;
403
404 /** Get the location of where lua packages are installed */
405 virtual const std::string& get_luarocks_path() const = 0;
406 /** Set the location of where lua packages are installed */
407 virtual void set_luarocks_path(const std::string& path) = 0;
408 };
409
410 /**
411 * @brief User abstraction
412 *
413 * This represents a user. In general, there will be a @a User associated with an OP
414 * (the user performing the OP), and potentially several others acting as owners.
415 * Lifetime of a User is a bit tricky , since it must last as long as any Buckets
416 * associated with it. A User has associated metadata, including a set of key/value
417 * attributes, and statistics (including usage) about the User.
418 */
419 class User {
420 protected:
421 RGWUserInfo info;
422 RGWObjVersionTracker objv_tracker;
423 Attrs attrs;
424
425 public:
426 User() : info() {}
427 User(const rgw_user& _u) : info() { info.user_id = _u; }
428 User(const RGWUserInfo& _i) : info(_i) {}
429 User(User& _o) = default;
430 virtual ~User() = default;
431
432 /** Clone a copy of this user. Used when modification is necessary of the copy */
433 virtual std::unique_ptr<User> clone() = 0;
434 /** List the buckets owned by a user */
435 virtual int list_buckets(const DoutPrefixProvider* dpp,
436 const std::string& marker, const std::string& end_marker,
437 uint64_t max, bool need_stats, BucketList& buckets,
438 optional_yield y) = 0;
439 /** Create a new bucket owned by this user. Creates in the backing store, not just the instantiation. */
440 virtual int create_bucket(const DoutPrefixProvider* dpp,
441 const rgw_bucket& b,
442 const std::string& zonegroup_id,
443 rgw_placement_rule& placement_rule,
444 std::string& swift_ver_location,
445 const RGWQuotaInfo* pquota_info,
446 const RGWAccessControlPolicy& policy,
447 Attrs& attrs,
448 RGWBucketInfo& info,
449 obj_version& ep_objv,
450 bool exclusive,
451 bool obj_lock_enabled,
452 bool* existed,
453 req_info& req_info,
454 std::unique_ptr<Bucket>* bucket,
455 optional_yield y) = 0;
456
457 /** Get the display name for this User */
458 virtual std::string& get_display_name() { return info.display_name; }
459 /** Get the tenant name for this User */
460 const std::string& get_tenant() { return info.user_id.tenant; }
461 /** Set the tenant name for this User */
462 void set_tenant(std::string& _t) { info.user_id.tenant = _t; }
463 /** Get the namespace for this User */
464 const std::string& get_ns() { return info.user_id.ns; }
465 /** Set the namespace for this User */
466 void set_ns(std::string& _ns) { info.user_id.ns = _ns; }
467 /** Clear the namespace for this User */
468 void clear_ns() { info.user_id.ns.clear(); }
469 /** Get the full ID for this User */
470 const rgw_user& get_id() const { return info.user_id; }
471 /** Get the type of this User */
472 uint32_t get_type() const { return info.type; }
473 /** Get the maximum number of buckets allowed for this User */
474 int32_t get_max_buckets() const { return info.max_buckets; }
475 /** Get the capabilities for this User */
476 const RGWUserCaps& get_caps() const { return info.caps; }
477 /** Get the version tracker for this User */
478 virtual RGWObjVersionTracker& get_version_tracker() { return objv_tracker; }
479 /** Get the cached attributes for this User */
480 virtual Attrs& get_attrs() { return attrs; }
481 /** Set the cached attributes fro this User */
482 virtual void set_attrs(Attrs& _attrs) { attrs = _attrs; }
483 /** Check if a User pointer is empty */
484 static bool empty(User* u) { return (!u || u->info.user_id.id.empty()); }
485 /** Check if a User unique_pointer is empty */
486 static bool empty(std::unique_ptr<User>& u) { return (!u || u->info.user_id.id.empty()); }
487 /** Read the User attributes from the backing Store */
488 virtual int read_attrs(const DoutPrefixProvider* dpp, optional_yield y) = 0;
489 /** Set the attributes in attrs, leaving any other existing attrs set, and
490 * write them to the backing store; a merge operation */
491 virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) = 0;
492 virtual int read_stats(const DoutPrefixProvider *dpp,
493 optional_yield y, RGWStorageStats* stats,
494 ceph::real_time* last_stats_sync = nullptr,
495 ceph::real_time* last_stats_update = nullptr) = 0;
496 /** Read the User stats from the backing Store, asynchronous */
497 virtual int read_stats_async(const DoutPrefixProvider *dpp, RGWGetUserStats_CB* cb) = 0;
498 /** Flush accumulated stat changes for this User to the backing store */
499 virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) = 0;
500 /** Read detailed usage stats for this User from the backing store */
501 virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch,
502 uint64_t end_epoch, uint32_t max_entries,
503 bool* is_truncated, RGWUsageIter& usage_iter,
504 std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0;
505 /** Trim User usage stats to the given epoch range */
506 virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0;
507
508 /** Load this User from the backing store. requires ID to be set, fills all other fields. */
509 virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) = 0;
510 /** Store this User to the backing store */
511 virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) = 0;
512 /** Remove this User from the backing store */
513 virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) = 0;
514
515 /* dang temporary; will be removed when User is complete */
516 RGWUserInfo& get_info() { return info; }
517
518 friend inline std::ostream& operator<<(std::ostream& out, const User& u) {
519 out << u.info.user_id;
520 return out;
521 }
522
523 friend inline std::ostream& operator<<(std::ostream& out, const User* u) {
524 if (!u)
525 out << "<NULL>";
526 else
527 out << u->info.user_id;
528 return out;
529 }
530
531 friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<User>& p) {
532 out << p.get();
533 return out;
534 }
535
536 friend class Bucket;
537 };
538
539 /**
540 * @brief Bucket abstraction
541 *
542 * This represents a bucket. A bucket is a container for objects. It is owned by a user, and has
543 * it's own set of metadata, including a set of key/value attributes. A bucket may not contain
544 * other buckets, only objects. Buckets have Access Control Lists (ACLs) that control what users
545 * can access the contents of the bucket, and in what ways.
546 */
547 class Bucket {
548 protected:
549 RGWBucketEnt ent;
550 RGWBucketInfo info;
551 User* owner = nullptr;
552 Attrs attrs;
553 obj_version bucket_version;
554 ceph::real_time mtime;
555
556 public:
557
558 /**
559 * @brief Parameters for a bucket list operation
560 */
561 struct ListParams {
562 std::string prefix;
563 std::string delim;
564 rgw_obj_key marker;
565 rgw_obj_key end_marker;
566 std::string ns;
567 bool enforce_ns{true};
568 RGWAccessListFilter* access_list_filter{nullptr};
569 RGWBucketListNameFilter force_check_filter;
570 bool list_versions{false};
571 bool allow_unordered{false};
572 int shard_id{RGW_NO_SHARD};
573
574 friend std::ostream& operator<<(std::ostream& out, const ListParams& p) {
575 out << "rgw::sal::Bucket::ListParams{ prefix=\"" << p.prefix <<
576 "\", delim=\"" << p.delim <<
577 "\", marker=\"" << p.marker <<
578 "\", end_marker=\"" << p.end_marker <<
579 "\", ns=\"" << p.ns <<
580 "\", enforce_ns=" << p.enforce_ns <<
581 ", list_versions=" << p.list_versions <<
582 ", allow_unordered=" << p.allow_unordered <<
583 ", shard_id=" << p.shard_id <<
584 " }";
585 return out;
586 }
587 };
588 /**
589 * @brief Results from a bucket list operation
590 */
591 struct ListResults {
592 std::vector<rgw_bucket_dir_entry> objs;
593 std::map<std::string, bool> common_prefixes;
594 bool is_truncated{false};
595 rgw_obj_key next_marker;
596 };
597
598 Bucket() = default;
599 Bucket(User* _u) :
600 owner(_u) { }
601 Bucket(const rgw_bucket& _b) { ent.bucket = _b; info.bucket = _b; }
602 Bucket(const RGWBucketEnt& _e) : ent(_e) {
603 info.bucket = ent.bucket;
604 info.placement_rule = ent.placement_rule;
605 info.creation_time = ent.creation_time;
606 }
607 Bucket(const RGWBucketInfo& _i) : info(_i) {
608 ent.bucket = info.bucket;
609 ent.placement_rule = info.placement_rule;
610 ent.creation_time = info.creation_time;
611 }
612 Bucket(const rgw_bucket& _b, User* _u) :
613 owner(_u) { ent.bucket = _b; info.bucket = _b; }
614 Bucket(const RGWBucketEnt& _e, User* _u) : ent(_e), owner(_u) {
615 info.bucket = ent.bucket;
616 info.placement_rule = ent.placement_rule;
617 info.creation_time = ent.creation_time;
618 }
619 Bucket(const RGWBucketInfo& _i, User* _u) : info(_i), owner(_u) {
620 ent.bucket = info.bucket;
621 ent.placement_rule = info.placement_rule;
622 ent.creation_time = info.creation_time;
623 }
624 virtual ~Bucket() = default;
625
626 /** Get an @a Object belonging to this bucket */
627 virtual std::unique_ptr<Object> get_object(const rgw_obj_key& key) = 0;
628 /** List the contents of this bucket */
629 virtual int list(const DoutPrefixProvider* dpp, ListParams&, int, ListResults&, optional_yield y) = 0;
630 /** Get the cached attributes associated with this bucket */
631 virtual Attrs& get_attrs(void) { return attrs; }
632 /** Set the cached attributes on this bucket */
633 virtual int set_attrs(Attrs a) { attrs = a; return 0; }
634 /** Remove this bucket from the backing store */
635 virtual int remove_bucket(const DoutPrefixProvider* dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) = 0;
636 /** Remove this bucket, bypassing garbage collection. May be removed */
637 virtual int remove_bucket_bypass_gc(int concurrent_max, bool
638 keep_index_consistent,
639 optional_yield y, const
640 DoutPrefixProvider *dpp) = 0;
641 /** Get then ACL for this bucket */
642 virtual RGWAccessControlPolicy& get_acl(void) = 0;
643 /** Set the ACL for this bucket */
644 virtual int set_acl(const DoutPrefixProvider* dpp, RGWAccessControlPolicy& acl, optional_yield y) = 0;
645
646 // XXXX hack
647 void set_owner(rgw::sal::User* _owner) {
648 owner = _owner;
649 }
650
651 /** Load this bucket from the backing store. Requires the key to be set, fills other fields.
652 * If @a get_stats is true, then statistics on the bucket are also looked up. */
653 virtual int load_bucket(const DoutPrefixProvider* dpp, optional_yield y, bool get_stats = false) = 0;
654 /** Read the bucket stats from the backing Store, synchronous */
655 virtual int read_stats(const DoutPrefixProvider *dpp, int shard_id,
656 std::string* bucket_ver, std::string* master_ver,
657 std::map<RGWObjCategory, RGWStorageStats>& stats,
658 std::string* max_marker = nullptr,
659 bool* syncstopped = nullptr) = 0;
660 /** Read the bucket stats from the backing Store, asynchronous */
661 virtual int read_stats_async(const DoutPrefixProvider *dpp, int shard_id, RGWGetBucketStats_CB* ctx) = 0;
662 /** Sync this bucket's stats to the owning user's stats in the backing store */
663 virtual int sync_user_stats(const DoutPrefixProvider *dpp, optional_yield y) = 0;
664 /** Refresh the metadata stats (size, count, and so on) from the backing store */
665 virtual int update_container_stats(const DoutPrefixProvider* dpp) = 0;
666 /** Check if this bucket needs resharding, and schedule it if it does */
667 virtual int check_bucket_shards(const DoutPrefixProvider* dpp) = 0;
668 /** Change the owner of this bucket in the backing store */
669 virtual int chown(const DoutPrefixProvider* dpp, User* new_user, User* old_user, optional_yield y, const std::string* marker = nullptr) = 0;
670 /** Store the cached bucket info into the backing store */
671 virtual int put_info(const DoutPrefixProvider* dpp, bool exclusive, ceph::real_time mtime) = 0;
672 /** Check to see if the given user is the owner of this bucket */
673 virtual bool is_owner(User* user) = 0;
674 /** Get the owner of this bucket */
675 virtual User* get_owner(void) { return owner; };
676 /** Get the owner of this bucket in the form of an ACLOwner object */
677 virtual ACLOwner get_acl_owner(void) { return ACLOwner(info.owner); };
678 /** Check in the backing store if this bucket is empty */
679 virtual int check_empty(const DoutPrefixProvider* dpp, optional_yield y) = 0;
680 /** Chec k if the given size fits within the quota */
681 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) = 0;
682 /** Set the attributes in attrs, leaving any other existing attrs set, and
683 * write them to the backing store; a merge operation */
684 virtual int merge_and_store_attrs(const DoutPrefixProvider* dpp, Attrs& new_attrs, optional_yield y) = 0;
685 /** Try to refresh the cached bucket info from the backing store. Used in
686 * read-modify-update loop. */
687 virtual int try_refresh_info(const DoutPrefixProvider* dpp, ceph::real_time* pmtime) = 0;
688 /** Read usage information about this bucket from the backing store */
689 virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries,
690 bool* is_truncated, RGWUsageIter& usage_iter,
691 std::map<rgw_user_bucket, rgw_usage_log_entry>& usage) = 0;
692 /** Trim the usage information to the given epoch range */
693 virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) = 0;
694 /** Remove objects from the bucket index of this bucket. May be removed from API */
695 virtual int remove_objs_from_index(const DoutPrefixProvider *dpp, std::list<rgw_obj_index_key>& objs_to_unlink) = 0;
696 /** Check the state of the bucket index, and get stats from it. May be removed from API */
697 virtual int check_index(const DoutPrefixProvider *dpp, std::map<RGWObjCategory, RGWStorageStats>& existing_stats, std::map<RGWObjCategory, RGWStorageStats>& calculated_stats) = 0;
698 /** Rebuild the bucket index. May be removed from API */
699 virtual int rebuild_index(const DoutPrefixProvider *dpp) = 0;
700 /** Set a timeout on the check_index() call. May be removed from API */
701 virtual int set_tag_timeout(const DoutPrefixProvider *dpp, uint64_t timeout) = 0;
702 /** Remove this specific bucket instance from the backing store. May be removed from API */
703 virtual int purge_instance(const DoutPrefixProvider* dpp) = 0;
704
705 /** Check if this instantiation is empty */
706 bool empty() const { return info.bucket.name.empty(); }
707 /** Get the cached name of this bucket */
708 const std::string& get_name() const { return info.bucket.name; }
709 /** Get the cached tenant of this bucket */
710 const std::string& get_tenant() const { return info.bucket.tenant; }
711 /** Get the cached marker of this bucket */
712 const std::string& get_marker() const { return info.bucket.marker; }
713 /** Get the cached ID of this bucket */
714 const std::string& get_bucket_id() const { return info.bucket.bucket_id; }
715 /** Get the cached size of this bucket */
716 size_t get_size() const { return ent.size; }
717 /** Get the cached rounded size of this bucket */
718 size_t get_size_rounded() const { return ent.size_rounded; }
719 /** Get the cached object count of this bucket */
720 uint64_t get_count() const { return ent.count; }
721 /** Get the cached placement rule of this bucket */
722 rgw_placement_rule& get_placement_rule() { return info.placement_rule; }
723 /** Get the cached creation time of this bucket */
724 ceph::real_time& get_creation_time() { return info.creation_time; }
725 /** Get the cached modification time of this bucket */
726 ceph::real_time& get_modification_time() { return mtime; }
727 /** Get the cached version of this bucket */
728 obj_version& get_version() { return bucket_version; }
729 /** Set the cached version of this bucket */
730 void set_version(obj_version &ver) { bucket_version = ver; }
731 /** Check if this bucket is versioned */
732 bool versioned() { return info.versioned(); }
733 /** Check if this bucket has versioning enabled */
734 bool versioning_enabled() { return info.versioning_enabled(); }
735
736 /** Check if a Bucket pointer is empty */
737 static bool empty(const Bucket* b) { return (!b || b->empty()); }
738 /** Check if a Bucket unique pointer is empty */
739 static bool empty(const std::unique_ptr<Bucket>& b) { return (!b || b->empty()); }
740 /** Clone a copy of this bucket. Used when modification is necessary of the copy */
741 virtual std::unique_ptr<Bucket> clone() = 0;
742
743 /** Create a multipart upload in this bucket */
744 virtual std::unique_ptr<MultipartUpload> get_multipart_upload(
745 const std::string& oid,
746 std::optional<std::string> upload_id=std::nullopt,
747 ACLOwner owner={}, ceph::real_time mtime=real_clock::now()) = 0;
748 /** List multipart uploads currently in this bucket */
749 virtual int list_multiparts(const DoutPrefixProvider *dpp,
750 const std::string& prefix,
751 std::string& marker,
752 const std::string& delim,
753 const int& max_uploads,
754 std::vector<std::unique_ptr<MultipartUpload>>& uploads,
755 std::map<std::string, bool> *common_prefixes,
756 bool *is_truncated) = 0;
757 /** Abort multipart uploads in a bucket */
758 virtual int abort_multiparts(const DoutPrefixProvider* dpp,
759 CephContext* cct) = 0;
760
761 /* dang - This is temporary, until the API is completed */
762 rgw_bucket& get_key() { return info.bucket; }
763 RGWBucketInfo& get_info() { return info; }
764
765 friend inline std::ostream& operator<<(std::ostream& out, const Bucket& b) {
766 out << b.info.bucket;
767 return out;
768 }
769
770 friend inline std::ostream& operator<<(std::ostream& out, const Bucket* b) {
771 if (!b)
772 out << "<NULL>";
773 else
774 out << b->info.bucket;
775 return out;
776 }
777
778 friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<Bucket>& p) {
779 out << p.get();
780 return out;
781 }
782
783 bool operator==(const Bucket& b) const {
784 return (info.bucket.tenant == b.info.bucket.tenant) &&
785 (info.bucket.name == b.info.bucket.name) &&
786 (info.bucket.bucket_id == b.info.bucket.bucket_id);
787 }
788 bool operator!=(const Bucket& b) const {
789 return (info.bucket.tenant != b.info.bucket.tenant) ||
790 (info.bucket.name != b.info.bucket.name) ||
791 (info.bucket.bucket_id != b.info.bucket.bucket_id);
792 }
793
794 friend class BucketList;
795 protected:
796 virtual void set_ent(RGWBucketEnt& _ent) { ent = _ent; info.bucket = ent.bucket; info.placement_rule = ent.placement_rule; }
797 };
798
799 /**
800 * @brief A list of buckets
801 *
802 * This is the result from a bucket listing operation.
803 */
804 class BucketList {
805 std::map<std::string, std::unique_ptr<Bucket>> buckets;
806 bool truncated;
807
808 public:
809 BucketList() : buckets(), truncated(false) {}
810 BucketList(BucketList&& _bl) :
811 buckets(std::move(_bl.buckets)),
812 truncated(_bl.truncated)
813 { }
814 BucketList& operator=(const BucketList&) = delete;
815 BucketList& operator=(BucketList&& _bl) {
816 for (auto& ent : _bl.buckets) {
817 buckets.emplace(ent.first, std::move(ent.second));
818 }
819 truncated = _bl.truncated;
820 return *this;
821 };
822
823 /** Get the list of buckets. The list is a map of <bucket-name, Bucket> pairs. */
824 std::map<std::string, std::unique_ptr<Bucket>>& get_buckets() { return buckets; }
825 /** True if the list is truncated (that is, there are more buckets to list) */
826 bool is_truncated(void) const { return truncated; }
827 /** Set the truncated state of the list */
828 void set_truncated(bool trunc) { truncated = trunc; }
829 /** Add a bucket to the list. Takes ownership of the bucket */
830 void add(std::unique_ptr<Bucket> bucket) {
831 buckets.emplace(bucket->info.bucket.name, std::move(bucket));
832 }
833 /** The number of buckets in this list */
834 size_t count() const { return buckets.size(); }
835 /** Clear the list */
836 void clear(void) {
837 buckets.clear();
838 truncated = false;
839 }
840 };
841
842 /**
843 * @brief Object abstraction
844 *
845 * This represents an Object. An Object is the basic unit of data storage. It
846 * represents a blob of data, a set of metadata (such as size, owner, ACLs, etc.) and
847 * a set of key/value attributes. Objects may be versioned. If a versioned object
848 * is written to, a new object with the same name but a different version is created,
849 * and the old version of the object is still accessible. If an unversioned object
850 * is written to, it is replaced, and the old data is not accessible.
851 */
852 class Object {
853 protected:
854 rgw_obj_key key;
855 Bucket* bucket;
856 std::string index_hash_source;
857 uint64_t obj_size;
858 Attrs attrs;
859 ceph::real_time mtime;
860 bool delete_marker{false};
861 bool in_extra_data{false};
862
863 public:
864
865 /**
866 * @brief Read operation on an Object
867 *
868 * This represents a Read operation on an Object. Read operations are optionally
869 * asynchronous, using the iterate() API.
870 */
871 struct ReadOp {
872 struct Params {
873 const ceph::real_time* mod_ptr{nullptr};
874 const ceph::real_time* unmod_ptr{nullptr};
875 bool high_precision_time{false};
876 uint32_t mod_zone_id{0};
877 uint64_t mod_pg_ver{0};
878 const char* if_match{nullptr};
879 const char* if_nomatch{nullptr};
880 ceph::real_time* lastmod{nullptr};
881 rgw_obj* target_obj{nullptr}; // XXX dang remove?
882 } params;
883
884 virtual ~ReadOp() = default;
885
886 /** Prepare the Read op. Must be called first */
887 virtual int prepare(optional_yield y, const DoutPrefixProvider* dpp) = 0;
888 /** Synchronous read. Read from @a ofs to @a end into @a bl */
889 virtual int read(int64_t ofs, int64_t end, bufferlist& bl, optional_yield y, const DoutPrefixProvider* dpp) = 0;
890 /** Asynchronous read. Read from @a ofs to @a end calling @a cb on each read
891 * chunk. */
892 virtual int iterate(const DoutPrefixProvider* dpp, int64_t ofs, int64_t end, RGWGetDataCB* cb, optional_yield y) = 0;
893 /** Get an attribute by name */
894 virtual int get_attr(const DoutPrefixProvider* dpp, const char* name, bufferlist& dest, optional_yield y) = 0;
895 };
896
897 /**
898 * @brief Delete operation on an Object
899 *
900 * This deletes an Object from the backing store.
901 */
902 struct DeleteOp {
903 struct Params {
904 ACLOwner bucket_owner;
905 ACLOwner obj_owner;
906 int versioning_status{0};
907 uint64_t olh_epoch{0};
908 std::string marker_version_id;
909 uint32_t bilog_flags{0};
910 std::list<rgw_obj_index_key>* remove_objs{nullptr};
911 ceph::real_time expiration_time;
912 ceph::real_time unmod_since;
913 ceph::real_time mtime;
914 bool high_precision_time{false};
915 rgw_zone_set* zones_trace{nullptr};
916 bool abortmp{false};
917 uint64_t parts_accounted_size{0};
918 } params;
919
920 struct Result {
921 bool delete_marker{false};
922 std::string version_id;
923 } result;
924
925 virtual ~DeleteOp() = default;
926
927 /** Delete the object */
928 virtual int delete_obj(const DoutPrefixProvider* dpp, optional_yield y) = 0;
929 };
930
931 Object()
932 : key(),
933 bucket(nullptr),
934 index_hash_source(),
935 obj_size(),
936 attrs(),
937 mtime() {}
938 Object(const rgw_obj_key& _k)
939 : key(_k),
940 bucket(),
941 index_hash_source(),
942 obj_size(),
943 attrs(),
944 mtime() {}
945 Object(const rgw_obj_key& _k, Bucket* _b)
946 : key(_k),
947 bucket(_b),
948 index_hash_source(),
949 obj_size(),
950 attrs(),
951 mtime() {}
952 Object(Object& _o) = default;
953
954 virtual ~Object() = default;
955
956 /** Shortcut synchronous delete call for common deletes */
957 virtual int delete_object(const DoutPrefixProvider* dpp,
958 RGWObjectCtx* obj_ctx,
959 optional_yield y,
960 bool prevent_versioning = false) = 0;
961 /** Asynchronous delete call */
962 virtual int delete_obj_aio(const DoutPrefixProvider* dpp, RGWObjState* astate, Completions* aio,
963 bool keep_index_consistent, optional_yield y) = 0;
964 /** Copy an this object to another object. */
965 virtual int copy_object(RGWObjectCtx& obj_ctx, User* user,
966 req_info* info, const rgw_zone_id& source_zone,
967 rgw::sal::Object* dest_object, rgw::sal::Bucket* dest_bucket,
968 rgw::sal::Bucket* src_bucket,
969 const rgw_placement_rule& dest_placement,
970 ceph::real_time* src_mtime, ceph::real_time* mtime,
971 const ceph::real_time* mod_ptr, const ceph::real_time* unmod_ptr,
972 bool high_precision_time,
973 const char* if_match, const char* if_nomatch,
974 AttrsMod attrs_mod, bool copy_if_newer, Attrs& attrs,
975 RGWObjCategory category, uint64_t olh_epoch,
976 boost::optional<ceph::real_time> delete_at,
977 std::string* version_id, std::string* tag, std::string* etag,
978 void (*progress_cb)(off_t, void *), void* progress_data,
979 const DoutPrefixProvider* dpp, optional_yield y) = 0;
980 /** Get the ACL for this object */
981 virtual RGWAccessControlPolicy& get_acl(void) = 0;
982 /** Set the ACL for this object */
983 virtual int set_acl(const RGWAccessControlPolicy& acl) = 0;
984 /** Mark further operations on this object as being atomic */
985 virtual void set_atomic(RGWObjectCtx* rctx) const = 0;
986 /** Pre-fetch data when reading */
987 virtual void set_prefetch_data(RGWObjectCtx* rctx) = 0;
988 /** Mark data as compressed */
989 virtual void set_compressed(RGWObjectCtx* rctx) = 0;
990
991 /** Check to see if this object has an empty key. This means it's uninitialized */
992 bool empty() const { return key.empty(); }
993 /** Get the name of this object */
994 const std::string &get_name() const { return key.name; }
995
996 /** Get the object state for this object. Will be removed in the future */
997 virtual int get_obj_state(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, RGWObjState **state, optional_yield y, bool follow_olh = true) = 0;
998 /** Set attributes for this object from the backing store. Attrs can be set or
999 * deleted. @note the attribute APIs may be revisited in the future. */
1000 virtual int set_obj_attrs(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, Attrs* setattrs, Attrs* delattrs, optional_yield y, rgw_obj* target_obj = NULL) = 0;
1001 /** Get attributes for this object */
1002 virtual int get_obj_attrs(RGWObjectCtx* rctx, optional_yield y, const DoutPrefixProvider* dpp, rgw_obj* target_obj = NULL) = 0;
1003 /** Modify attributes for this object. */
1004 virtual int modify_obj_attrs(RGWObjectCtx* rctx, const char* attr_name, bufferlist& attr_val, optional_yield y, const DoutPrefixProvider* dpp) = 0;
1005 /** Delete attributes for this object */
1006 virtual int delete_obj_attrs(const DoutPrefixProvider* dpp, RGWObjectCtx* rctx, const char* attr_name, optional_yield y) = 0;
1007 /** Check to see if this object has expired */
1008 virtual bool is_expired() = 0;
1009 /** Create a randomized instance ID for this object */
1010 virtual void gen_rand_obj_instance_name() = 0;
1011 /** Get a multipart serializer for this object */
1012 virtual MPSerializer* get_serializer(const DoutPrefixProvider *dpp, const std::string& lock_name) = 0;
1013 /** Move the data of an object to new placement storage */
1014 virtual int transition(RGWObjectCtx& rctx,
1015 Bucket* bucket,
1016 const rgw_placement_rule& placement_rule,
1017 const real_time& mtime,
1018 uint64_t olh_epoch,
1019 const DoutPrefixProvider* dpp,
1020 optional_yield y) = 0;
1021 /** Check to see if two placement rules match */
1022 virtual bool placement_rules_match(rgw_placement_rule& r1, rgw_placement_rule& r2) = 0;
1023 /** Dump store-specific object layout info in JSON */
1024 virtual int dump_obj_layout(const DoutPrefixProvider *dpp, optional_yield y, Formatter* f, RGWObjectCtx* obj_ctx) = 0;
1025
1026 /** Get the cached attributes for this object */
1027 Attrs& get_attrs(void) { return attrs; }
1028 /** Get the (const) cached attributes for this object */
1029 const Attrs& get_attrs(void) const { return attrs; }
1030 /** Set the cached attributes for this object */
1031 virtual int set_attrs(Attrs a) { attrs = a; return 0; }
1032 /** Get the cached modification time for this object */
1033 ceph::real_time get_mtime(void) const { return mtime; }
1034 /** Get the cached size for this object */
1035 uint64_t get_obj_size(void) const { return obj_size; }
1036 /** Get the bucket containing this object */
1037 Bucket* get_bucket(void) const { return bucket; }
1038 /** Set the bucket containing this object */
1039 void set_bucket(Bucket* b) { bucket = b; }
1040 /** Get the sharding hash representation of this object */
1041 std::string get_hash_source(void) { return index_hash_source; }
1042 /** Set the sharding hash representation of this object */
1043 void set_hash_source(std::string s) { index_hash_source = s; }
1044 /** Build an Object Identifier string for this object */
1045 std::string get_oid(void) const { return key.get_oid(); }
1046 /** True if this object is a delete marker (newest version is deleted) */
1047 bool get_delete_marker(void) { return delete_marker; }
1048 /** True if this object is stored in the extra data pool */
1049 bool get_in_extra_data(void) { return in_extra_data; }
1050 /** Set the in_extra_data field */
1051 void set_in_extra_data(bool i) { in_extra_data = i; }
1052 /** Helper to sanitize object size, offset, and end values */
1053 int range_to_ofs(uint64_t obj_size, int64_t &ofs, int64_t &end);
1054 /** Set the cached size of this object */
1055 void set_obj_size(uint64_t s) { obj_size = s; }
1056 /** Set the cached name of this object */
1057 virtual void set_name(const std::string& n) { key = n; }
1058 /** Set the cached key of this object */
1059 virtual void set_key(const rgw_obj_key& k) { key = k; }
1060 /** Get an rgw_obj representing this object */
1061 virtual rgw_obj get_obj(void) const {
1062 rgw_obj obj(bucket->get_key(), key);
1063 obj.set_in_extra_data(in_extra_data);
1064 obj.index_hash_source = index_hash_source;
1065 return obj;
1066 }
1067
1068 /** Restore the previous swift version of this object */
1069 virtual int swift_versioning_restore(RGWObjectCtx* obj_ctx,
1070 bool& restored, /* out */
1071 const DoutPrefixProvider* dpp) = 0;
1072 /** Copy the current version of a swift object to the configured destination bucket*/
1073 virtual int swift_versioning_copy(RGWObjectCtx* obj_ctx,
1074 const DoutPrefixProvider* dpp,
1075 optional_yield y) = 0;
1076
1077 /** Get a new ReadOp for this object */
1078 virtual std::unique_ptr<ReadOp> get_read_op(RGWObjectCtx*) = 0;
1079 /** Get a new DeleteOp for this object */
1080 virtual std::unique_ptr<DeleteOp> get_delete_op(RGWObjectCtx*) = 0;
1081
1082 /** Get @a count OMAP values via listing, starting at @a marker for this object */
1083 virtual int omap_get_vals(const DoutPrefixProvider *dpp, const std::string& marker, uint64_t count,
1084 std::map<std::string, bufferlist>* m,
1085 bool* pmore, optional_yield y) = 0;
1086 /** Get all OMAP key/value pairs for this object */
1087 virtual int omap_get_all(const DoutPrefixProvider *dpp, std::map<std::string, bufferlist>* m,
1088 optional_yield y) = 0;
1089 /** Get the OMAP values matching the given set of keys */
1090 virtual int omap_get_vals_by_keys(const DoutPrefixProvider *dpp, const std::string& oid,
1091 const std::set<std::string>& keys,
1092 Attrs* vals) = 0;
1093 /** Get a single OMAP value matching the given key */
1094 virtual int omap_set_val_by_key(const DoutPrefixProvider *dpp, const std::string& key, bufferlist& val,
1095 bool must_exist, optional_yield y) = 0;
1096
1097 /** Check to see if the give object pointer is uninitialized */
1098 static bool empty(Object* o) { return (!o || o->empty()); }
1099 /** Get a unique copy of this object */
1100 virtual std::unique_ptr<Object> clone() = 0;
1101
1102 /* dang - This is temporary, until the API is completed */
1103 /** Get the key for this object */
1104 rgw_obj_key& get_key() { return key; }
1105 /** Set the instance for this object */
1106 void set_instance(const std::string &i) { key.set_instance(i); }
1107 /** Get the instance for this object */
1108 const std::string &get_instance() const { return key.instance; }
1109 /** Check to see if this object has an instance set */
1110 bool have_instance(void) { return key.have_instance(); }
1111
1112 friend inline std::ostream& operator<<(std::ostream& out, const Object& o) {
1113 if (o.bucket)
1114 out << o.bucket << ":";
1115 out << o.key;
1116 return out;
1117 }
1118 friend inline std::ostream& operator<<(std::ostream& out, const Object* o) {
1119 if (!o)
1120 out << "<NULL>";
1121 else
1122 out << *o;
1123 return out;
1124 }
1125 friend inline std::ostream& operator<<(std::ostream& out, const std::unique_ptr<Object>& p) {
1126 out << p.get();
1127 return out;
1128 }
1129 };
1130
1131 /**
1132 * @brief Abstraction of a single part of a multipart upload
1133 */
1134 class MultipartPart {
1135 protected:
1136 std::string oid;
1137
1138 public:
1139 MultipartPart() = default;
1140 virtual ~MultipartPart() = default;
1141
1142 /** Get the part number of this part */
1143 virtual uint32_t get_num() = 0;
1144 /** Get the size of this part */
1145 virtual uint64_t get_size() = 0;
1146 /** Get the etag of this part */
1147 virtual const std::string& get_etag() = 0;
1148 /** Get the modification time of this part */
1149 virtual ceph::real_time& get_mtime() = 0;
1150 };
1151
1152 /**
1153 * @brief Abstraction of a multipart upload
1154 *
1155 * This represents a multipart upload. For large objects, it's inefficient to do a
1156 * single, long-lived upload of the object. Instead, protocols such as S3 allow the
1157 * client to start a multipart upload, and then upload object in smaller parts in
1158 * parallel. A MultipartUpload consists of a target bucket, a unique identifier, and a
1159 * set of upload parts.
1160 */
1161 class MultipartUpload {
1162 protected:
1163 Bucket* bucket;
1164 std::map<uint32_t, std::unique_ptr<MultipartPart>> parts;
1165 jspan_context trace_ctx{false, false};
1166 public:
1167 MultipartUpload(Bucket* _bucket) : bucket(_bucket) {}
1168 virtual ~MultipartUpload() = default;
1169
1170 /** Get the name of the object representing this upload in the backing store */
1171 virtual const std::string& get_meta() const = 0;
1172 /** Get the name of the target object for this upload */
1173 virtual const std::string& get_key() const = 0;
1174 /** Get the unique ID of this upload */
1175 virtual const std::string& get_upload_id() const = 0;
1176 /** Get the owner of this upload */
1177 virtual const ACLOwner& get_owner() const = 0;
1178 /** Get the modification time of this upload */
1179 virtual ceph::real_time& get_mtime() = 0;
1180
1181 /** Get all the cached parts that make up this upload */
1182 std::map<uint32_t, std::unique_ptr<MultipartPart>>& get_parts() { return parts; }
1183
1184 /** Get the trace context of this upload */
1185 const jspan_context& get_trace() { return trace_ctx; }
1186
1187 /** Get the Object that represents this upload */
1188 virtual std::unique_ptr<rgw::sal::Object> get_meta_obj() = 0;
1189
1190 /** Initialize this upload */
1191 virtual int init(const DoutPrefixProvider* dpp, optional_yield y, RGWObjectCtx* obj_ctx, ACLOwner& owner, rgw_placement_rule& dest_placement, rgw::sal::Attrs& attrs) = 0;
1192 /** List all the parts of this upload, filling the parts cache */
1193 virtual int list_parts(const DoutPrefixProvider* dpp, CephContext* cct,
1194 int num_parts, int marker,
1195 int* next_marker, bool* truncated,
1196 bool assume_unsorted = false) = 0;
1197 /** Abort this upload */
1198 virtual int abort(const DoutPrefixProvider* dpp, CephContext* cct,
1199 RGWObjectCtx* obj_ctx) = 0;
1200 /** Complete this upload, making it available as a normal object */
1201 virtual int complete(const DoutPrefixProvider* dpp,
1202 optional_yield y, CephContext* cct,
1203 std::map<int, std::string>& part_etags,
1204 std::list<rgw_obj_index_key>& remove_objs,
1205 uint64_t& accounted_size, bool& compressed,
1206 RGWCompressionInfo& cs_info, off_t& ofs,
1207 std::string& tag, ACLOwner& owner,
1208 uint64_t olh_epoch,
1209 rgw::sal::Object* target_obj,
1210 RGWObjectCtx* obj_ctx) = 0;
1211
1212 /** Get placement and/or attribute info for this upload */
1213 virtual int get_info(const DoutPrefixProvider *dpp, optional_yield y, RGWObjectCtx* obj_ctx, rgw_placement_rule** rule, rgw::sal::Attrs* attrs = nullptr) = 0;
1214
1215 /** Get a Writer to write to a part of this upload */
1216 virtual std::unique_ptr<Writer> get_writer(const DoutPrefixProvider *dpp,
1217 optional_yield y,
1218 std::unique_ptr<rgw::sal::Object> _head_obj,
1219 const rgw_user& owner, RGWObjectCtx& obj_ctx,
1220 const rgw_placement_rule *ptail_placement_rule,
1221 uint64_t part_num,
1222 const std::string& part_num_str) = 0;
1223
1224 friend inline std::ostream& operator<<(std::ostream& out, const MultipartUpload& u) {
1225 out << u.get_meta();
1226 if (!u.get_upload_id().empty())
1227 out << ":" << u.get_upload_id();
1228 return out;
1229 }
1230 friend inline std::ostream& operator<<(std::ostream& out, const MultipartUpload* u) {
1231 if (!u)
1232 out << "<NULL>";
1233 else
1234 out << *u;
1235 return out;
1236 }
1237 friend inline std::ostream& operator<<(std::ostream& out, const
1238 std::unique_ptr<MultipartUpload>& p) {
1239 out << p.get();
1240 return out;
1241 }
1242 };
1243
1244 /**
1245 * @brief Interface of a lock/serialization
1246 */
1247 struct Serializer {
1248 Serializer() = default;
1249 virtual ~Serializer() = default;
1250
1251 /** Try to take the lock for the given amount of time. */
1252 virtual int try_lock(const DoutPrefixProvider *dpp, utime_t dur, optional_yield y) = 0;
1253 /** Unlock the lock */
1254 virtual int unlock() = 0;
1255 };
1256
1257 /** @brief Abstraction of a serializer for multipart uploads
1258 */
1259 struct MPSerializer : Serializer {
1260 bool locked;
1261 std::string oid;
1262 MPSerializer() : locked(false) {}
1263 virtual ~MPSerializer() = default;
1264
1265 void clear_locked() {
1266 locked = false;
1267 }
1268 };
1269
1270 /** @brief Abstraction of a serializer for Lifecycle
1271 */
1272 struct LCSerializer : Serializer {
1273 LCSerializer() {}
1274 virtual ~LCSerializer() = default;
1275 };
1276
1277 /**
1278 * @brief Abstraction for lifecycle processing
1279 *
1280 * Lifecycle processing loops over the objects in a bucket, applying per-bucket policy
1281 * to each object. Examples of policy can be deleting after a certain amount of time,
1282 * deleting extra versions, changing the storage class, and so on.
1283 */
1284 class Lifecycle {
1285 public:
1286 /** Head of a lifecycle run. Used for tracking parallel lifecycle runs. */
1287 struct LCHead {
1288 time_t start_date{0};
1289 std::string marker;
1290
1291 LCHead() = default;
1292 LCHead(time_t _date, std::string& _marker) : start_date(_date), marker(_marker) {}
1293 };
1294
1295 /** Single entry in a lifecycle run. Multiple entries can exist processing different
1296 * buckets. */
1297 struct LCEntry {
1298 std::string bucket;
1299 uint64_t start_time{0};
1300 uint32_t status{0};
1301
1302 LCEntry() = default;
1303 LCEntry(std::string& _bucket, uint64_t _time, uint32_t _status) : bucket(_bucket), start_time(_time), status(_status) {}
1304 };
1305
1306 Lifecycle() = default;
1307 virtual ~Lifecycle() = default;
1308
1309 /** Get an entry matching the given marker */
1310 virtual int get_entry(const std::string& oid, const std::string& marker, LCEntry& entry) = 0;
1311 /** Get the entry following the given marker */
1312 virtual int get_next_entry(const std::string& oid, std::string& marker, LCEntry& entry) = 0;
1313 /** Store a modified entry in then backing store */
1314 virtual int set_entry(const std::string& oid, const LCEntry& entry) = 0;
1315 /** List all known entries */
1316 virtual int list_entries(const std::string& oid, const std::string& marker,
1317 uint32_t max_entries, std::vector<LCEntry>& entries) = 0;
1318 /** Remove an entry from the backing store */
1319 virtual int rm_entry(const std::string& oid, const LCEntry& entry) = 0;
1320 /** Get a head */
1321 virtual int get_head(const std::string& oid, LCHead& head) = 0;
1322 /** Store a modified head to the backing store */
1323 virtual int put_head(const std::string& oid, const LCHead& head) = 0;
1324
1325 /** Get a serializer for lifecycle */
1326 virtual LCSerializer* get_serializer(const std::string& lock_name, const std::string& oid, const std::string& cookie) = 0;
1327 };
1328
1329 /**
1330 * @brief Abstraction for a Notification event
1331 *
1332 * RGW can generate notifications for various events, such as object creation or
1333 * deletion.
1334 */
1335 class Notification {
1336 protected:
1337 Object* obj;
1338 Object* src_obj;
1339 rgw::notify::EventType event_type;
1340
1341 public:
1342 Notification(Object* _obj, Object* _src_obj, rgw::notify::EventType _type)
1343 : obj(_obj), src_obj(_src_obj), event_type(_type)
1344 {}
1345
1346 virtual ~Notification() = default;
1347
1348 /** Indicate the start of the event associated with this notification */
1349 virtual int publish_reserve(const DoutPrefixProvider *dpp, RGWObjTags* obj_tags = nullptr) = 0;
1350 /** Indicate the successful completion of the event associated with this notification */
1351 virtual int publish_commit(const DoutPrefixProvider* dpp, uint64_t size,
1352 const ceph::real_time& mtime, const std::string& etag, const std::string& version) = 0;
1353 };
1354
1355 /**
1356 * @brief Abstraction for an asynchronous writer
1357 *
1358 * Writing is done through a set of filters. This allows chaining filters to do things
1359 * like compression and encryption on async writes. This is the base abstraction for
1360 * those filters.
1361 */
1362 class Writer : public ObjectProcessor {
1363 protected:
1364 const DoutPrefixProvider* dpp;
1365
1366 public:
1367 Writer(const DoutPrefixProvider *_dpp, optional_yield y) : dpp(_dpp) {}
1368 virtual ~Writer() = default;
1369
1370 /** prepare to start processing object data */
1371 virtual int prepare(optional_yield y) = 0;
1372
1373 /** Process a buffer. Called multiple times to write different buffers. */
1374 virtual int process(bufferlist&& data, uint64_t offset) = 0;
1375
1376 /** complete the operation and make its result visible to clients */
1377 virtual int complete(size_t accounted_size, const std::string& etag,
1378 ceph::real_time *mtime, ceph::real_time set_mtime,
1379 std::map<std::string, bufferlist>& attrs,
1380 ceph::real_time delete_at,
1381 const char *if_match, const char *if_nomatch,
1382 const std::string *user_data,
1383 rgw_zone_set *zones_trace, bool *canceled,
1384 optional_yield y) = 0;
1385 };
1386
1387 /**
1388 * @brief Abstraction of a Zone
1389 *
1390 * This abstraction allows access to information about zones. This can be the zone
1391 * containing the RGW, or another zone.
1392 */
1393 class Zone {
1394 public:
1395 virtual ~Zone() = default;
1396
1397 /** Get info about the zonegroup containing this zone */
1398 virtual const RGWZoneGroup& get_zonegroup() = 0;
1399 /** Get info about a zonegroup by ID */
1400 virtual int get_zonegroup(const std::string& id, RGWZoneGroup& zonegroup) = 0;
1401 /** Get the parameters of this zone */
1402 virtual const RGWZoneParams& get_params() = 0;
1403 /** Get the ID of this zone */
1404 virtual const rgw_zone_id& get_id() = 0;
1405 /** Get info about the realm containing this zone */
1406 virtual const RGWRealm& get_realm() = 0;
1407 /** Get the name of this zone */
1408 virtual const std::string& get_name() const = 0;
1409 /** True if this zone is writable */
1410 virtual bool is_writeable() = 0;
1411 /** Get the URL for the endpoint for redirecting to this zone */
1412 virtual bool get_redirect_endpoint(std::string* endpoint) = 0;
1413 /** Check to see if the given API is supported in this zone */
1414 virtual bool has_zonegroup_api(const std::string& api) const = 0;
1415 /** Get the current period ID for this zone */
1416 virtual const std::string& get_current_period_id() = 0;
1417 };
1418
1419 /**
1420 * @brief Abstraction of a manager for Lua scripts
1421 *
1422 * RGW can load and process Lua scripts. This will handle loading/storing scripts.
1423 */
1424 class LuaScriptManager {
1425 public:
1426 virtual ~LuaScriptManager() = default;
1427
1428 /** Get a script named with the given key from the backing store */
1429 virtual int get(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, std::string& script) = 0;
1430 /** Put a script named with the given key to the backing store */
1431 virtual int put(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key, const std::string& script) = 0;
1432 /** Delete a script named with the given key from the backing store */
1433 virtual int del(const DoutPrefixProvider* dpp, optional_yield y, const std::string& key) = 0;
1434 };
1435
1436 /** @} namespace rgw::sal in group RGWSAL */
1437 } } // namespace rgw::sal
1438
1439 /**
1440 * @brief A manager for Stores
1441 *
1442 * This will manage the singleton instances of the various stores. Stores come in two
1443 * varieties: Full and Raw. A full store is suitable for use in a radosgw daemon. It
1444 * has full access to the cluster, if any. A raw store is a stripped down store, used
1445 * for admin commands.
1446 */
1447 class StoreManager {
1448 public:
1449 StoreManager() {}
1450 /** Get a full store by service name */
1451 static rgw::sal::Store* get_storage(const DoutPrefixProvider* dpp, CephContext* cct, const std::string svc, bool use_gc_thread, bool use_lc_thread, bool quota_threads,
1452 bool run_sync_thread, bool run_reshard_thread, bool use_cache = true, bool use_gc = true) {
1453 rgw::sal::Store* store = init_storage_provider(dpp, cct, svc, use_gc_thread, use_lc_thread,
1454 quota_threads, run_sync_thread, run_reshard_thread, use_cache, use_gc);
1455 return store;
1456 }
1457 /** Get a stripped down store by service name */
1458 static rgw::sal::Store* get_raw_storage(const DoutPrefixProvider* dpp, CephContext* cct, const std::string svc) {
1459 rgw::sal::Store* store = init_raw_storage_provider(dpp, cct, svc);
1460 return store;
1461 }
1462 /** Initialize a new full Store */
1463 static rgw::sal::Store* init_storage_provider(const DoutPrefixProvider* dpp, CephContext* cct, const std::string svc, bool use_gc_thread, bool use_lc_thread, bool quota_threads, bool run_sync_thread, bool run_reshard_thread, bool use_metadata_cache, bool use_gc);
1464 /** Initialize a new raw Store */
1465 static rgw::sal::Store* init_raw_storage_provider(const DoutPrefixProvider* dpp, CephContext* cct, const std::string svc);
1466 /** Close a Store when it's no longer needed */
1467 static void close_storage(rgw::sal::Store* store);
1468
1469 };
1470
1471 /** @} */