]>
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); |
39ae355f TL |
84 | int rgw_stat_system_obj(const DoutPrefixProvider *dpp, |
85 | RGWSysObjectCtx& obj_Ctx, const rgw_pool& pool, | |
86 | const std::string& key, RGWObjVersionTracker *objv_tracker, | |
87 | real_time *pmtime, optional_yield y, | |
88 | std::map<std::string, bufferlist> *pattrs = nullptr); | |
7c673cae | 89 | |
20effc67 | 90 | const char *rgw_find_mime_by_ext(std::string& ext); |
11fdf7f2 | 91 | |
20effc67 TL |
92 | void rgw_filter_attrset(std::map<std::string, bufferlist>& unfiltered_attrset, const std::string& check_prefix, |
93 | std::map<std::string, bufferlist> *attrset); | |
11fdf7f2 TL |
94 | |
95 | /// indicates whether the current thread is in boost::asio::io_context::run(), | |
96 | /// used to log warnings if synchronous librados calls are made | |
97 | extern thread_local bool is_asio_thread; | |
98 | ||
99 | /// perform the rados operation, using the yield context when given | |
b3b6e05e | 100 | int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
11fdf7f2 | 101 | librados::ObjectReadOperation *op, bufferlist* pbl, |
f6b5b4d7 | 102 | optional_yield y, int flags = 0); |
b3b6e05e | 103 | int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
f6b5b4d7 TL |
104 | librados::ObjectWriteOperation *op, optional_yield y, |
105 | int flags = 0); | |
b3b6e05e | 106 | int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid, |
9f95a23c TL |
107 | bufferlist& bl, uint64_t timeout_ms, bufferlist* pbl, |
108 | optional_yield y); | |
11fdf7f2 | 109 | |
20effc67 | 110 | int rgw_tools_init(const DoutPrefixProvider *dpp, CephContext *cct); |
7c673cae | 111 | void rgw_tools_cleanup(); |
11fdf7f2 TL |
112 | |
113 | template<class H, size_t S> | |
114 | class RGWEtag | |
115 | { | |
116 | H hash; | |
117 | ||
118 | public: | |
20effc67 TL |
119 | RGWEtag() { |
120 | if constexpr (std::is_same_v<H, MD5>) { | |
121 | // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes | |
122 | hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); | |
123 | } | |
124 | } | |
11fdf7f2 TL |
125 | |
126 | void update(const char *buf, size_t len) { | |
127 | hash.Update((const unsigned char *)buf, len); | |
128 | } | |
129 | ||
130 | void update(bufferlist& bl) { | |
131 | if (bl.length() > 0) { | |
132 | update(bl.c_str(), bl.length()); | |
133 | } | |
134 | } | |
135 | ||
20effc67 | 136 | void update(const std::string& s) { |
11fdf7f2 TL |
137 | if (!s.empty()) { |
138 | update(s.c_str(), s.size()); | |
139 | } | |
140 | } | |
20effc67 | 141 | void finish(std::string *etag) { |
11fdf7f2 TL |
142 | char etag_buf[S]; |
143 | char etag_buf_str[S * 2 + 16]; | |
144 | ||
145 | hash.Final((unsigned char *)etag_buf); | |
146 | buf_to_hex((const unsigned char *)etag_buf, S, | |
147 | etag_buf_str); | |
148 | ||
149 | *etag = etag_buf_str; | |
150 | } | |
151 | }; | |
152 | ||
153 | using RGWMD5Etag = RGWEtag<MD5, CEPH_CRYPTO_MD5_DIGESTSIZE>; | |
154 | ||
155 | class RGWDataAccess | |
156 | { | |
20effc67 | 157 | rgw::sal::Store* store; |
11fdf7f2 TL |
158 | |
159 | public: | |
20effc67 | 160 | RGWDataAccess(rgw::sal::Store* _store); |
11fdf7f2 TL |
161 | |
162 | class Object; | |
163 | class Bucket; | |
164 | ||
165 | using BucketRef = std::shared_ptr<Bucket>; | |
166 | using ObjectRef = std::shared_ptr<Object>; | |
167 | ||
20effc67 | 168 | class Bucket : public std::enable_shared_from_this<Bucket> { |
11fdf7f2 TL |
169 | friend class RGWDataAccess; |
170 | friend class Object; | |
171 | ||
172 | RGWDataAccess *sd{nullptr}; | |
173 | RGWBucketInfo bucket_info; | |
20effc67 TL |
174 | std::string tenant; |
175 | std::string name; | |
176 | std::string bucket_id; | |
11fdf7f2 | 177 | ceph::real_time mtime; |
20effc67 | 178 | std::map<std::string, bufferlist> attrs; |
11fdf7f2 TL |
179 | |
180 | RGWAccessControlPolicy policy; | |
181 | int finish_init(); | |
182 | ||
183 | Bucket(RGWDataAccess *_sd, | |
20effc67 TL |
184 | const std::string& _tenant, |
185 | const std::string& _name, | |
186 | const std::string& _bucket_id) : sd(_sd), | |
11fdf7f2 TL |
187 | tenant(_tenant), |
188 | name(_name), | |
189 | bucket_id(_bucket_id) {} | |
190 | Bucket(RGWDataAccess *_sd) : sd(_sd) {} | |
b3b6e05e | 191 | int init(const DoutPrefixProvider *dpp, optional_yield y); |
20effc67 | 192 | int init(const RGWBucketInfo& _bucket_info, const std::map<std::string, bufferlist>& _attrs); |
11fdf7f2 TL |
193 | public: |
194 | int get_object(const rgw_obj_key& key, | |
195 | ObjectRef *obj); | |
196 | ||
197 | }; | |
198 | ||
199 | ||
200 | class Object { | |
201 | RGWDataAccess *sd{nullptr}; | |
202 | BucketRef bucket; | |
203 | rgw_obj_key key; | |
204 | ||
205 | ceph::real_time mtime; | |
20effc67 TL |
206 | std::string etag; |
207 | uint64_t olh_epoch{0}; | |
11fdf7f2 | 208 | ceph::real_time delete_at; |
20effc67 | 209 | std::optional<std::string> user_data; |
11fdf7f2 TL |
210 | |
211 | std::optional<bufferlist> aclbl; | |
212 | ||
213 | Object(RGWDataAccess *_sd, | |
214 | BucketRef&& _bucket, | |
215 | const rgw_obj_key& _key) : sd(_sd), | |
216 | bucket(_bucket), | |
217 | key(_key) {} | |
218 | public: | |
20effc67 | 219 | int put(bufferlist& data, std::map<std::string, bufferlist>& attrs, const DoutPrefixProvider *dpp, optional_yield y); /* might modify attrs */ |
11fdf7f2 TL |
220 | |
221 | void set_mtime(const ceph::real_time& _mtime) { | |
222 | mtime = _mtime; | |
223 | } | |
224 | ||
20effc67 | 225 | void set_etag(const std::string& _etag) { |
11fdf7f2 TL |
226 | etag = _etag; |
227 | } | |
228 | ||
229 | void set_olh_epoch(uint64_t epoch) { | |
230 | olh_epoch = epoch; | |
231 | } | |
232 | ||
233 | void set_delete_at(ceph::real_time _delete_at) { | |
234 | delete_at = _delete_at; | |
235 | } | |
236 | ||
20effc67 | 237 | void set_user_data(const std::string& _user_data) { |
11fdf7f2 TL |
238 | user_data = _user_data; |
239 | } | |
240 | ||
241 | void set_policy(const RGWAccessControlPolicy& policy); | |
242 | ||
243 | friend class Bucket; | |
244 | }; | |
245 | ||
b3b6e05e | 246 | int get_bucket(const DoutPrefixProvider *dpp, |
20effc67 TL |
247 | const std::string& tenant, |
248 | const std::string name, | |
249 | const std::string bucket_id, | |
f67539c2 TL |
250 | BucketRef *bucket, |
251 | optional_yield y) { | |
11fdf7f2 | 252 | bucket->reset(new Bucket(this, tenant, name, bucket_id)); |
b3b6e05e | 253 | return (*bucket)->init(dpp, y); |
11fdf7f2 TL |
254 | } |
255 | ||
256 | int get_bucket(const RGWBucketInfo& bucket_info, | |
20effc67 | 257 | const std::map<std::string, bufferlist>& attrs, |
11fdf7f2 TL |
258 | BucketRef *bucket) { |
259 | bucket->reset(new Bucket(this)); | |
260 | return (*bucket)->init(bucket_info, attrs); | |
261 | } | |
262 | friend class Bucket; | |
263 | friend class Object; | |
264 | }; | |
265 | ||
266 | using RGWDataAccessRef = std::shared_ptr<RGWDataAccess>; | |
7c673cae | 267 | |
f67539c2 TL |
268 | /// Complete an AioCompletion. To return error values or otherwise |
269 | /// satisfy the caller. Useful for making complicated asynchronous | |
270 | /// calls and error handling. | |
271 | void rgw_complete_aio_completion(librados::AioCompletion* c, int r); | |
272 | ||
7c673cae | 273 | #endif |