]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
7c673cae FG |
3 | |
4 | #ifndef CEPH_RGW_TOOLS_H | |
5 | #define CEPH_RGW_TOOLS_H | |
6 | ||
7 | #include <string> | |
8 | ||
9 | #include "include/types.h" | |
9f95a23c TL |
10 | #include "include/ceph_hash.h" |
11 | ||
7c673cae | 12 | #include "common/ceph_time.h" |
9f95a23c | 13 | |
7c673cae FG |
14 | #include "rgw_common.h" |
15 | ||
9f95a23c TL |
16 | class RGWSI_SysObj; |
17 | ||
7c673cae | 18 | class RGWRados; |
11fdf7f2 | 19 | class RGWSysObjectCtx; |
7c673cae | 20 | struct RGWObjVersionTracker; |
11fdf7f2 | 21 | class optional_yield; |
9f95a23c | 22 | namespace rgw { namespace sal { |
20effc67 | 23 | class Store; |
9f95a23c | 24 | } } |
7c673cae FG |
25 | |
26 | struct obj_version; | |
27 | ||
9f95a23c | 28 | |
b3b6e05e TL |
29 | int rgw_init_ioctx(const DoutPrefixProvider *dpp, |
30 | librados::Rados *rados, const rgw_pool& pool, | |
494da23a TL |
31 | librados::IoCtx& ioctx, |
32 | bool create = false, | |
33 | bool mostly_omap = false); | |
34 | ||
9f95a23c TL |
35 | #define RGW_NO_SHARD -1 |
36 | ||
37 | #define RGW_SHARDS_PRIME_0 7877 | |
38 | #define RGW_SHARDS_PRIME_1 65521 | |
39 | ||
40 | extern const std::string MP_META_SUFFIX; | |
41 | ||
f67539c2 | 42 | inline int rgw_shards_max() |
9f95a23c TL |
43 | { |
44 | return RGW_SHARDS_PRIME_1; | |
45 | } | |
46 | ||
47 | // only called by rgw_shard_id and rgw_bucket_shard_index | |
48 | static inline int rgw_shards_mod(unsigned hval, int max_shards) | |
49 | { | |
50 | if (max_shards <= RGW_SHARDS_PRIME_0) { | |
51 | return hval % RGW_SHARDS_PRIME_0 % max_shards; | |
52 | } | |
53 | return hval % RGW_SHARDS_PRIME_1 % max_shards; | |
54 | } | |
55 | ||
56 | // used for logging and tagging | |
20effc67 | 57 | inline int rgw_shard_id(const std::string& key, int max_shards) |
9f95a23c TL |
58 | { |
59 | return rgw_shards_mod(ceph_str_hash_linux(key.c_str(), key.size()), | |
60 | max_shards); | |
61 | } | |
62 | ||
20effc67 TL |
63 | void rgw_shard_name(const std::string& prefix, unsigned max_shards, const std::string& key, std::string& name, int *shard_id); |
64 | void rgw_shard_name(const std::string& prefix, unsigned max_shards, const std::string& section, const std::string& key, std::string& name); | |
65 | void rgw_shard_name(const std::string& prefix, unsigned shard_id, std::string& name); | |
9f95a23c TL |
66 | |
67 | struct rgw_name_to_flag { | |
68 | const char *type_name; | |
69 | uint32_t flag; | |
70 | }; | |
71 | ||
72 | int rgw_parse_list_of_flags(struct rgw_name_to_flag *mapping, | |
20effc67 | 73 | const std::string& str, uint32_t *perm); |
9f95a23c | 74 | |
20effc67 TL |
75 | int rgw_put_system_obj(const DoutPrefixProvider *dpp, RGWSysObjectCtx& obj_ctx, const rgw_pool& pool, const std::string& oid, bufferlist& data, bool exclusive, |
76 | RGWObjVersionTracker *objv_tracker, real_time set_mtime, optional_yield y, std::map<std::string, bufferlist> *pattrs = NULL); | |
77 | int rgw_get_system_obj(RGWSysObjectCtx& obj_ctx, const rgw_pool& pool, const std::string& key, bufferlist& bl, | |
78 | RGWObjVersionTracker *objv_tracker, real_time *pmtime, optional_yield y, const DoutPrefixProvider *dpp, std::map<std::string, bufferlist> *pattrs = NULL, | |
b32b8144 | 79 | rgw_cache_entry_info *cache_info = NULL, |
20effc67 | 80 | boost::optional<obj_version> refresh_version = boost::none, bool raw_attrs=false); |
b3b6e05e | 81 | int rgw_delete_system_obj(const DoutPrefixProvider *dpp, |
20effc67 | 82 | RGWSI_SysObj *sysobj_svc, const rgw_pool& pool, const std::string& oid, |
f67539c2 | 83 | RGWObjVersionTracker *objv_tracker, optional_yield y); |
7c673cae | 84 | |
20effc67 | 85 | const char *rgw_find_mime_by_ext(std::string& ext); |
11fdf7f2 | 86 | |
20effc67 TL |
87 | void rgw_filter_attrset(std::map<std::string, bufferlist>& unfiltered_attrset, const std::string& check_prefix, |
88 | std::map<std::string, bufferlist> *attrset); | |
11fdf7f2 TL |
89 | |
90 | /// indicates whether the current thread is in boost::asio::io_context::run(), | |
91 | /// used to log warnings if synchronous librados calls are made | |
92 | extern thread_local bool is_asio_thread; | |
93 | ||
94 | /// perform the rados operation, using the yield context when given | |
b3b6e05e | 95 | int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
11fdf7f2 | 96 | librados::ObjectReadOperation *op, bufferlist* pbl, |
f6b5b4d7 | 97 | optional_yield y, int flags = 0); |
b3b6e05e | 98 | int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
f6b5b4d7 TL |
99 | librados::ObjectWriteOperation *op, optional_yield y, |
100 | int flags = 0); | |
b3b6e05e | 101 | int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
9f95a23c TL |
102 | bufferlist& bl, uint64_t timeout_ms, bufferlist* pbl, |
103 | optional_yield y); | |
11fdf7f2 | 104 | |
20effc67 | 105 | int rgw_tools_init(const DoutPrefixProvider *dpp, CephContext *cct); |
7c673cae | 106 | void rgw_tools_cleanup(); |
11fdf7f2 TL |
107 | |
108 | template<class H, size_t S> | |
109 | class RGWEtag | |
110 | { | |
111 | H hash; | |
112 | ||
113 | public: | |
20effc67 TL |
114 | RGWEtag() { |
115 | if constexpr (std::is_same_v<H, MD5>) { | |
116 | // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes | |
117 | hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); | |
118 | } | |
119 | } | |
11fdf7f2 TL |
120 | |
121 | void update(const char *buf, size_t len) { | |
122 | hash.Update((const unsigned char *)buf, len); | |
123 | } | |
124 | ||
125 | void update(bufferlist& bl) { | |
126 | if (bl.length() > 0) { | |
127 | update(bl.c_str(), bl.length()); | |
128 | } | |
129 | } | |
130 | ||
20effc67 | 131 | void update(const std::string& s) { |
11fdf7f2 TL |
132 | if (!s.empty()) { |
133 | update(s.c_str(), s.size()); | |
134 | } | |
135 | } | |
20effc67 | 136 | void finish(std::string *etag) { |
11fdf7f2 TL |
137 | char etag_buf[S]; |
138 | char etag_buf_str[S * 2 + 16]; | |
139 | ||
140 | hash.Final((unsigned char *)etag_buf); | |
141 | buf_to_hex((const unsigned char *)etag_buf, S, | |
142 | etag_buf_str); | |
143 | ||
144 | *etag = etag_buf_str; | |
145 | } | |
146 | }; | |
147 | ||
148 | using RGWMD5Etag = RGWEtag<MD5, CEPH_CRYPTO_MD5_DIGESTSIZE>; | |
149 | ||
150 | class RGWDataAccess | |
151 | { | |
20effc67 | 152 | rgw::sal::Store* store; |
11fdf7f2 TL |
153 | |
154 | public: | |
20effc67 | 155 | RGWDataAccess(rgw::sal::Store* _store); |
11fdf7f2 TL |
156 | |
157 | class Object; | |
158 | class Bucket; | |
159 | ||
160 | using BucketRef = std::shared_ptr<Bucket>; | |
161 | using ObjectRef = std::shared_ptr<Object>; | |
162 | ||
20effc67 | 163 | class Bucket : public std::enable_shared_from_this<Bucket> { |
11fdf7f2 TL |
164 | friend class RGWDataAccess; |
165 | friend class Object; | |
166 | ||
167 | RGWDataAccess *sd{nullptr}; | |
168 | RGWBucketInfo bucket_info; | |
20effc67 TL |
169 | std::string tenant; |
170 | std::string name; | |
171 | std::string bucket_id; | |
11fdf7f2 | 172 | ceph::real_time mtime; |
20effc67 | 173 | std::map<std::string, bufferlist> attrs; |
11fdf7f2 TL |
174 | |
175 | RGWAccessControlPolicy policy; | |
176 | int finish_init(); | |
177 | ||
178 | Bucket(RGWDataAccess *_sd, | |
20effc67 TL |
179 | const std::string& _tenant, |
180 | const std::string& _name, | |
181 | const std::string& _bucket_id) : sd(_sd), | |
11fdf7f2 TL |
182 | tenant(_tenant), |
183 | name(_name), | |
184 | bucket_id(_bucket_id) {} | |
185 | Bucket(RGWDataAccess *_sd) : sd(_sd) {} | |
b3b6e05e | 186 | int init(const DoutPrefixProvider *dpp, optional_yield y); |
20effc67 | 187 | int init(const RGWBucketInfo& _bucket_info, const std::map<std::string, bufferlist>& _attrs); |
11fdf7f2 TL |
188 | public: |
189 | int get_object(const rgw_obj_key& key, | |
190 | ObjectRef *obj); | |
191 | ||
192 | }; | |
193 | ||
194 | ||
195 | class Object { | |
196 | RGWDataAccess *sd{nullptr}; | |
197 | BucketRef bucket; | |
198 | rgw_obj_key key; | |
199 | ||
200 | ceph::real_time mtime; | |
20effc67 TL |
201 | std::string etag; |
202 | uint64_t olh_epoch{0}; | |
11fdf7f2 | 203 | ceph::real_time delete_at; |
20effc67 | 204 | std::optional<std::string> user_data; |
11fdf7f2 TL |
205 | |
206 | std::optional<bufferlist> aclbl; | |
207 | ||
208 | Object(RGWDataAccess *_sd, | |
209 | BucketRef&& _bucket, | |
210 | const rgw_obj_key& _key) : sd(_sd), | |
211 | bucket(_bucket), | |
212 | key(_key) {} | |
213 | public: | |
20effc67 | 214 | int put(bufferlist& data, std::map<std::string, bufferlist>& attrs, const DoutPrefixProvider *dpp, optional_yield y); /* might modify attrs */ |
11fdf7f2 TL |
215 | |
216 | void set_mtime(const ceph::real_time& _mtime) { | |
217 | mtime = _mtime; | |
218 | } | |
219 | ||
20effc67 | 220 | void set_etag(const std::string& _etag) { |
11fdf7f2 TL |
221 | etag = _etag; |
222 | } | |
223 | ||
224 | void set_olh_epoch(uint64_t epoch) { | |
225 | olh_epoch = epoch; | |
226 | } | |
227 | ||
228 | void set_delete_at(ceph::real_time _delete_at) { | |
229 | delete_at = _delete_at; | |
230 | } | |
231 | ||
20effc67 | 232 | void set_user_data(const std::string& _user_data) { |
11fdf7f2 TL |
233 | user_data = _user_data; |
234 | } | |
235 | ||
236 | void set_policy(const RGWAccessControlPolicy& policy); | |
237 | ||
238 | friend class Bucket; | |
239 | }; | |
240 | ||
b3b6e05e | 241 | int get_bucket(const DoutPrefixProvider *dpp, |
20effc67 TL |
242 | const std::string& tenant, |
243 | const std::string name, | |
244 | const std::string bucket_id, | |
f67539c2 TL |
245 | BucketRef *bucket, |
246 | optional_yield y) { | |
11fdf7f2 | 247 | bucket->reset(new Bucket(this, tenant, name, bucket_id)); |
b3b6e05e | 248 | return (*bucket)->init(dpp, y); |
11fdf7f2 TL |
249 | } |
250 | ||
251 | int get_bucket(const RGWBucketInfo& bucket_info, | |
20effc67 | 252 | const std::map<std::string, bufferlist>& attrs, |
11fdf7f2 TL |
253 | BucketRef *bucket) { |
254 | bucket->reset(new Bucket(this)); | |
255 | return (*bucket)->init(bucket_info, attrs); | |
256 | } | |
257 | friend class Bucket; | |
258 | friend class Object; | |
259 | }; | |
260 | ||
261 | using RGWDataAccessRef = std::shared_ptr<RGWDataAccess>; | |
7c673cae | 262 | |
f67539c2 TL |
263 | /// Complete an AioCompletion. To return error values or otherwise |
264 | /// satisfy the caller. Useful for making complicated asynchronous | |
265 | /// calls and error handling. | |
266 | void rgw_complete_aio_completion(librados::AioCompletion* c, int r); | |
267 | ||
7c673cae | 268 | #endif |