]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_tools.h
b842916fd876781ad0b970402ef81c0c0ec800c0
[ceph.git] / ceph / src / rgw / rgw_tools.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 #ifndef CEPH_RGW_TOOLS_H
5 #define CEPH_RGW_TOOLS_H
6
7 #include <string>
8
9 #include "include/types.h"
10 #include "include/ceph_hash.h"
11
12 #include "common/ceph_time.h"
13
14 #include "rgw_common.h"
15
16 class RGWSI_SysObj;
17
18 class RGWRados;
19 class RGWSysObjectCtx;
20 struct RGWObjVersionTracker;
21 class optional_yield;
22 namespace rgw { namespace sal {
23 class Store;
24 } }
25
26 struct obj_version;
27
28
29 int rgw_init_ioctx(const DoutPrefixProvider *dpp,
30 librados::Rados *rados, const rgw_pool& pool,
31 librados::IoCtx& ioctx,
32 bool create = false,
33 bool mostly_omap = false);
34
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
42 inline int rgw_shards_max()
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
57 inline int rgw_shard_id(const std::string& key, int max_shards)
58 {
59 return rgw_shards_mod(ceph_str_hash_linux(key.c_str(), key.size()),
60 max_shards);
61 }
62
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);
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,
73 const std::string& str, uint32_t *perm);
74
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,
79 rgw_cache_entry_info *cache_info = NULL,
80 boost::optional<obj_version> refresh_version = boost::none, bool raw_attrs=false);
81 int rgw_delete_system_obj(const DoutPrefixProvider *dpp,
82 RGWSI_SysObj *sysobj_svc, const rgw_pool& pool, const std::string& oid,
83 RGWObjVersionTracker *objv_tracker, optional_yield y);
84
85 const char *rgw_find_mime_by_ext(std::string& ext);
86
87 void rgw_filter_attrset(std::map<std::string, bufferlist>& unfiltered_attrset, const std::string& check_prefix,
88 std::map<std::string, bufferlist> *attrset);
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
95 int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
96 librados::ObjectReadOperation *op, bufferlist* pbl,
97 optional_yield y, int flags = 0);
98 int rgw_rados_operate(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
99 librados::ObjectWriteOperation *op, optional_yield y,
100 int flags = 0);
101 int rgw_rados_notify(const DoutPrefixProvider *dpp, librados::IoCtx& ioctx, const std::string& oid,
102 bufferlist& bl, uint64_t timeout_ms, bufferlist* pbl,
103 optional_yield y);
104
105 int rgw_tools_init(const DoutPrefixProvider *dpp, CephContext *cct);
106 void rgw_tools_cleanup();
107
108 template<class H, size_t S>
109 class RGWEtag
110 {
111 H hash;
112
113 public:
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 }
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
131 void update(const std::string& s) {
132 if (!s.empty()) {
133 update(s.c_str(), s.size());
134 }
135 }
136 void finish(std::string *etag) {
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 {
152 rgw::sal::Store* store;
153
154 public:
155 RGWDataAccess(rgw::sal::Store* _store);
156
157 class Object;
158 class Bucket;
159
160 using BucketRef = std::shared_ptr<Bucket>;
161 using ObjectRef = std::shared_ptr<Object>;
162
163 class Bucket : public std::enable_shared_from_this<Bucket> {
164 friend class RGWDataAccess;
165 friend class Object;
166
167 RGWDataAccess *sd{nullptr};
168 RGWBucketInfo bucket_info;
169 std::string tenant;
170 std::string name;
171 std::string bucket_id;
172 ceph::real_time mtime;
173 std::map<std::string, bufferlist> attrs;
174
175 RGWAccessControlPolicy policy;
176 int finish_init();
177
178 Bucket(RGWDataAccess *_sd,
179 const std::string& _tenant,
180 const std::string& _name,
181 const std::string& _bucket_id) : sd(_sd),
182 tenant(_tenant),
183 name(_name),
184 bucket_id(_bucket_id) {}
185 Bucket(RGWDataAccess *_sd) : sd(_sd) {}
186 int init(const DoutPrefixProvider *dpp, optional_yield y);
187 int init(const RGWBucketInfo& _bucket_info, const std::map<std::string, bufferlist>& _attrs);
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;
201 std::string etag;
202 uint64_t olh_epoch{0};
203 ceph::real_time delete_at;
204 std::optional<std::string> user_data;
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:
214 int put(bufferlist& data, std::map<std::string, bufferlist>& attrs, const DoutPrefixProvider *dpp, optional_yield y); /* might modify attrs */
215
216 void set_mtime(const ceph::real_time& _mtime) {
217 mtime = _mtime;
218 }
219
220 void set_etag(const std::string& _etag) {
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
232 void set_user_data(const std::string& _user_data) {
233 user_data = _user_data;
234 }
235
236 void set_policy(const RGWAccessControlPolicy& policy);
237
238 friend class Bucket;
239 };
240
241 int get_bucket(const DoutPrefixProvider *dpp,
242 const std::string& tenant,
243 const std::string name,
244 const std::string bucket_id,
245 BucketRef *bucket,
246 optional_yield y) {
247 bucket->reset(new Bucket(this, tenant, name, bucket_id));
248 return (*bucket)->init(dpp, y);
249 }
250
251 int get_bucket(const RGWBucketInfo& bucket_info,
252 const std::map<std::string, bufferlist>& attrs,
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>;
262
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
268 #endif