]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #ifndef CEPH_RGW_LC_H |
2 | #define CEPH_RGW_LC_H | |
3 | ||
4 | #include <map> | |
5 | #include <string> | |
6 | #include <iostream> | |
7 | #include <include/types.h> | |
8 | ||
9 | #include "common/debug.h" | |
10 | ||
11 | #include "include/types.h" | |
12 | #include "include/rados/librados.hpp" | |
13 | #include "common/Mutex.h" | |
14 | #include "common/Cond.h" | |
224ce89b | 15 | #include "common/iso_8601.h" |
7c673cae FG |
16 | #include "common/Thread.h" |
17 | #include "rgw_common.h" | |
18 | #include "rgw_rados.h" | |
19 | #include "rgw_multi.h" | |
20 | #include "cls/rgw/cls_rgw_types.h" | |
21 | ||
22 | #include <atomic> | |
23 | ||
7c673cae FG |
24 | #define HASH_PRIME 7877 |
25 | #define MAX_ID_LEN 255 | |
26 | static string lc_oid_prefix = "lc"; | |
27 | static string lc_index_lock_name = "lc_process"; | |
28 | ||
29 | extern const char* LC_STATUS[]; | |
30 | ||
31 | typedef enum { | |
32 | lc_uninitial = 0, | |
33 | lc_processing, | |
34 | lc_failed, | |
35 | lc_complete, | |
36 | }LC_BUCKET_STATUS; | |
37 | ||
38 | class LCExpiration | |
39 | { | |
40 | protected: | |
41 | string days; | |
224ce89b WB |
42 | //At present only current object has expiration date |
43 | string date; | |
7c673cae FG |
44 | public: |
45 | LCExpiration() {} | |
46 | ~LCExpiration() {} | |
47 | ||
48 | void encode(bufferlist& bl) const { | |
224ce89b | 49 | ENCODE_START(3, 2, bl); |
7c673cae | 50 | ::encode(days, bl); |
224ce89b | 51 | ::encode(date, bl); |
7c673cae FG |
52 | ENCODE_FINISH(bl); |
53 | } | |
54 | void decode(bufferlist::iterator& bl) { | |
224ce89b | 55 | DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl); |
7c673cae | 56 | ::decode(days, bl); |
224ce89b WB |
57 | if (struct_v >= 3) { |
58 | ::decode(date, bl); | |
59 | } | |
7c673cae FG |
60 | DECODE_FINISH(bl); |
61 | } | |
62 | void dump(Formatter *f) const; | |
63 | // static void generate_test_instances(list<ACLOwner*>& o); | |
64 | void set_days(const string& _days) { days = _days; } | |
224ce89b | 65 | string get_days_str() const { |
31f18b77 FG |
66 | return days; |
67 | } | |
224ce89b WB |
68 | int get_days() const {return atoi(days.c_str()); } |
69 | bool has_days() const { | |
70 | return !days.empty(); | |
71 | } | |
72 | void set_date(const string& _date) { date = _date; } | |
73 | string get_date() const { | |
74 | return date; | |
75 | } | |
76 | bool has_date() const { | |
77 | return !date.empty(); | |
78 | } | |
79 | bool empty() const { | |
80 | return days.empty() && date.empty(); | |
81 | } | |
82 | bool valid() const { | |
83 | if (!days.empty() && !date.empty()) { | |
84 | return false; | |
85 | } else if (!days.empty() && get_days() <= 0) { | |
86 | return false; | |
87 | } | |
88 | //We've checked date in xml parsing | |
89 | return true; | |
7c673cae FG |
90 | } |
91 | }; | |
92 | WRITE_CLASS_ENCODER(LCExpiration) | |
93 | ||
94 | class LCRule | |
95 | { | |
96 | protected: | |
97 | string id; | |
98 | string prefix; | |
99 | string status; | |
100 | LCExpiration expiration; | |
101 | LCExpiration noncur_expiration; | |
102 | LCExpiration mp_expiration; | |
224ce89b | 103 | bool dm_expiration = false; |
7c673cae FG |
104 | |
105 | public: | |
106 | ||
107 | LCRule(){}; | |
108 | ~LCRule(){}; | |
109 | ||
110 | bool get_id(string& _id) { | |
111 | _id = id; | |
112 | return true; | |
113 | } | |
114 | ||
115 | string& get_status() { | |
116 | return status; | |
117 | } | |
118 | ||
119 | string& get_prefix() { | |
120 | return prefix; | |
121 | } | |
122 | ||
123 | LCExpiration& get_expiration() { | |
124 | return expiration; | |
125 | } | |
126 | ||
127 | LCExpiration& get_noncur_expiration() { | |
128 | return noncur_expiration; | |
129 | } | |
130 | ||
131 | LCExpiration& get_mp_expiration() { | |
132 | return mp_expiration; | |
133 | } | |
134 | ||
31f18b77 FG |
135 | bool get_dm_expiration() { |
136 | return dm_expiration; | |
137 | } | |
138 | ||
7c673cae FG |
139 | void set_id(string*_id) { |
140 | id = *_id; | |
141 | } | |
142 | ||
143 | void set_prefix(string*_prefix) { | |
144 | prefix = *_prefix; | |
145 | } | |
146 | ||
147 | void set_status(string*_status) { | |
148 | status = *_status; | |
149 | } | |
150 | ||
151 | void set_expiration(LCExpiration*_expiration) { | |
152 | expiration = *_expiration; | |
153 | } | |
154 | ||
155 | void set_noncur_expiration(LCExpiration*_noncur_expiration) { | |
156 | noncur_expiration = *_noncur_expiration; | |
157 | } | |
158 | ||
159 | void set_mp_expiration(LCExpiration* _mp_expiration) { | |
160 | mp_expiration = *_mp_expiration; | |
161 | } | |
162 | ||
31f18b77 FG |
163 | void set_dm_expiration(bool _dm_expiration) { |
164 | dm_expiration = _dm_expiration; | |
165 | } | |
166 | ||
224ce89b | 167 | bool valid(); |
7c673cae FG |
168 | |
169 | void encode(bufferlist& bl) const { | |
31f18b77 | 170 | ENCODE_START(4, 1, bl); |
7c673cae FG |
171 | ::encode(id, bl); |
172 | ::encode(prefix, bl); | |
173 | ::encode(status, bl); | |
174 | ::encode(expiration, bl); | |
175 | ::encode(noncur_expiration, bl); | |
176 | ::encode(mp_expiration, bl); | |
31f18b77 | 177 | ::encode(dm_expiration, bl); |
7c673cae FG |
178 | ENCODE_FINISH(bl); |
179 | } | |
180 | void decode(bufferlist::iterator& bl) { | |
31f18b77 | 181 | DECODE_START_LEGACY_COMPAT_LEN(4, 1, 1, bl); |
7c673cae FG |
182 | ::decode(id, bl); |
183 | ::decode(prefix, bl); | |
184 | ::decode(status, bl); | |
185 | ::decode(expiration, bl); | |
186 | if (struct_v >=2) { | |
187 | ::decode(noncur_expiration, bl); | |
188 | } | |
189 | if (struct_v >= 3) { | |
190 | ::decode(mp_expiration, bl); | |
191 | } | |
31f18b77 FG |
192 | if (struct_v >= 4) { |
193 | ::decode(dm_expiration, bl); | |
194 | } | |
7c673cae FG |
195 | DECODE_FINISH(bl); |
196 | } | |
197 | ||
198 | }; | |
199 | WRITE_CLASS_ENCODER(LCRule) | |
200 | ||
201 | struct lc_op | |
202 | { | |
203 | bool status; | |
31f18b77 | 204 | bool dm_expiration; |
7c673cae FG |
205 | int expiration; |
206 | int noncur_expiration; | |
207 | int mp_expiration; | |
224ce89b | 208 | boost::optional<ceph::real_time> expiration_date; |
7c673cae | 209 | |
31f18b77 | 210 | lc_op() : status(false), dm_expiration(false), expiration(0), noncur_expiration(0), mp_expiration(0) {} |
7c673cae FG |
211 | |
212 | }; | |
213 | ||
214 | class RGWLifecycleConfiguration | |
215 | { | |
216 | protected: | |
217 | CephContext *cct; | |
218 | map<string, lc_op> prefix_map; | |
219 | multimap<string, LCRule> rule_map; | |
220 | bool _add_rule(LCRule *rule); | |
224ce89b | 221 | bool has_same_action(const lc_op& first, const lc_op& second); |
7c673cae FG |
222 | public: |
223 | RGWLifecycleConfiguration(CephContext *_cct) : cct(_cct) {} | |
224 | RGWLifecycleConfiguration() : cct(NULL) {} | |
225 | ||
226 | void set_ctx(CephContext *ctx) { | |
227 | cct = ctx; | |
228 | } | |
229 | ||
230 | virtual ~RGWLifecycleConfiguration() {} | |
231 | ||
232 | // int get_perm(string& id, int perm_mask); | |
233 | // int get_group_perm(ACLGroupTypeEnum group, int perm_mask); | |
234 | void encode(bufferlist& bl) const { | |
235 | ENCODE_START(1, 1, bl); | |
236 | ::encode(rule_map, bl); | |
237 | ENCODE_FINISH(bl); | |
238 | } | |
239 | void decode(bufferlist::iterator& bl) { | |
240 | DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl); | |
241 | ::decode(rule_map, bl); | |
242 | multimap<string, LCRule>::iterator iter; | |
243 | for (iter = rule_map.begin(); iter != rule_map.end(); ++iter) { | |
244 | LCRule& rule = iter->second; | |
245 | _add_rule(&rule); | |
246 | } | |
247 | DECODE_FINISH(bl); | |
248 | } | |
249 | void dump(Formatter *f) const; | |
250 | // static void generate_test_instances(list<RGWAccessControlList*>& o); | |
251 | ||
252 | void add_rule(LCRule* rule); | |
253 | ||
254 | int check_and_add_rule(LCRule* rule); | |
255 | ||
224ce89b | 256 | bool valid(); |
7c673cae FG |
257 | |
258 | multimap<string, LCRule>& get_rule_map() { return rule_map; } | |
259 | map<string, lc_op>& get_prefix_map() { return prefix_map; } | |
260 | /* | |
261 | void create_default(string id, string name) { | |
262 | ACLGrant grant; | |
263 | grant.set_canon(id, name, RGW_PERM_FULL_CONTROL); | |
264 | add_grant(&grant); | |
265 | } | |
266 | */ | |
267 | }; | |
268 | WRITE_CLASS_ENCODER(RGWLifecycleConfiguration) | |
269 | ||
270 | class RGWLC { | |
271 | CephContext *cct; | |
272 | RGWRados *store; | |
224ce89b WB |
273 | int max_objs{0}; |
274 | string *obj_names{nullptr}; | |
7c673cae FG |
275 | std::atomic<bool> down_flag = { false }; |
276 | string cookie; | |
277 | ||
278 | class LCWorker : public Thread { | |
279 | CephContext *cct; | |
280 | RGWLC *lc; | |
281 | Mutex lock; | |
282 | Cond cond; | |
283 | ||
284 | public: | |
285 | LCWorker(CephContext *_cct, RGWLC *_lc) : cct(_cct), lc(_lc), lock("LCWorker") {} | |
286 | void *entry() override; | |
287 | void stop(); | |
288 | bool should_work(utime_t& now); | |
289 | int schedule_next_start_time(utime_t& start, utime_t& now); | |
290 | }; | |
291 | ||
292 | public: | |
293 | LCWorker *worker; | |
294 | RGWLC() : cct(NULL), store(NULL), worker(NULL) {} | |
295 | ~RGWLC() { | |
296 | stop_processor(); | |
297 | finalize(); | |
298 | } | |
299 | ||
300 | void initialize(CephContext *_cct, RGWRados *_store); | |
301 | void finalize(); | |
302 | ||
303 | int process(); | |
304 | int process(int index, int max_secs); | |
305 | bool if_already_run_today(time_t& start_date); | |
306 | int list_lc_progress(const string& marker, uint32_t max_entries, map<string, int> *progress_map); | |
307 | int bucket_lc_prepare(int index); | |
308 | int bucket_lc_process(string& shard_id); | |
309 | int bucket_lc_post(int index, int max_lock_sec, pair<string, int >& entry, int& result); | |
310 | bool going_down(); | |
311 | void start_processor(); | |
312 | void stop_processor(); | |
313 | ||
314 | private: | |
315 | int remove_expired_obj(RGWBucketInfo& bucket_info, rgw_obj_key obj_key, bool remove_indeed = true); | |
316 | bool obj_has_expired(double timediff, int days); | |
317 | int handle_multipart_expiration(RGWRados::Bucket *target, const map<string, lc_op>& prefix_map); | |
318 | }; | |
319 | ||
320 | ||
321 | ||
322 | #endif |