7 #include <include/types.h>
9 #include "common/debug.h"
11 #include "include/types.h"
12 #include "include/rados/librados.hpp"
13 #include "common/Mutex.h"
14 #include "common/Cond.h"
15 #include "common/iso_8601.h"
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"
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";
29 extern const char* LC_STATUS[];
42 //At present only current object has expiration date
48 void encode(bufferlist& bl) const {
49 ENCODE_START(3, 2, bl);
54 void decode(bufferlist::iterator& bl) {
55 DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
62 void dump(Formatter *f) const;
63 // static void generate_test_instances(list<ACLOwner*>& o);
64 void set_days(const string& _days) { days = _days; }
65 string get_days_str() const {
68 int get_days() const {return atoi(days.c_str()); }
69 bool has_days() const {
72 void set_date(const string& _date) { date = _date; }
73 string get_date() const {
76 bool has_date() const {
80 return days.empty() && date.empty();
83 if (!days.empty() && !date.empty()) {
85 } else if (!days.empty() && get_days() <= 0) {
88 //We've checked date in xml parsing
92 WRITE_CLASS_ENCODER(LCExpiration)
98 // TODO add support for tagging
100 const std::string& get_prefix() const{
104 void set_prefix(const string& _prefix){
108 void set_prefix(std::string&& _prefix){
109 prefix = std::move(_prefix);
113 return prefix.empty();
116 bool has_prefix() const {
117 return !prefix.empty();
120 void encode(bufferlist& bl) const {
121 ENCODE_START(1, 1, bl);
122 ::encode(prefix, bl);
125 void decode(bufferlist::iterator& bl) {
127 ::decode(prefix, bl);
131 WRITE_CLASS_ENCODER(LCFilter);
141 LCExpiration expiration;
142 LCExpiration noncur_expiration;
143 LCExpiration mp_expiration;
145 bool dm_expiration = false;
152 bool get_id(string& _id) {
157 string& get_status() {
161 string& get_prefix() {
165 LCFilter& get_filter() {
169 LCExpiration& get_expiration() {
173 LCExpiration& get_noncur_expiration() {
174 return noncur_expiration;
177 LCExpiration& get_mp_expiration() {
178 return mp_expiration;
181 bool get_dm_expiration() {
182 return dm_expiration;
185 void set_id(string*_id) {
189 void set_prefix(string*_prefix) {
193 void set_status(string*_status) {
197 void set_expiration(LCExpiration*_expiration) {
198 expiration = *_expiration;
201 void set_noncur_expiration(LCExpiration*_noncur_expiration) {
202 noncur_expiration = *_noncur_expiration;
205 void set_mp_expiration(LCExpiration* _mp_expiration) {
206 mp_expiration = *_mp_expiration;
209 void set_dm_expiration(bool _dm_expiration) {
210 dm_expiration = _dm_expiration;
215 void encode(bufferlist& bl) const {
216 ENCODE_START(5, 1, bl);
218 ::encode(prefix, bl);
219 ::encode(status, bl);
220 ::encode(expiration, bl);
221 ::encode(noncur_expiration, bl);
222 ::encode(mp_expiration, bl);
223 ::encode(dm_expiration, bl);
224 ::encode(filter, bl);
227 void decode(bufferlist::iterator& bl) {
228 DECODE_START_LEGACY_COMPAT_LEN(5, 1, 1, bl);
230 ::decode(prefix, bl);
231 ::decode(status, bl);
232 ::decode(expiration, bl);
234 ::decode(noncur_expiration, bl);
237 ::decode(mp_expiration, bl);
240 ::decode(dm_expiration, bl);
243 ::decode(filter, bl);
249 WRITE_CLASS_ENCODER(LCRule)
256 int noncur_expiration;
258 boost::optional<ceph::real_time> expiration_date;
260 lc_op() : status(false), dm_expiration(false), expiration(0), noncur_expiration(0), mp_expiration(0) {}
264 class RGWLifecycleConfiguration
268 map<string, lc_op> prefix_map;
269 multimap<string, LCRule> rule_map;
270 bool _add_rule(LCRule *rule);
271 bool has_same_action(const lc_op& first, const lc_op& second);
273 RGWLifecycleConfiguration(CephContext *_cct) : cct(_cct) {}
274 RGWLifecycleConfiguration() : cct(NULL) {}
276 void set_ctx(CephContext *ctx) {
280 virtual ~RGWLifecycleConfiguration() {}
282 // int get_perm(string& id, int perm_mask);
283 // int get_group_perm(ACLGroupTypeEnum group, int perm_mask);
284 void encode(bufferlist& bl) const {
285 ENCODE_START(1, 1, bl);
286 ::encode(rule_map, bl);
289 void decode(bufferlist::iterator& bl) {
290 DECODE_START_LEGACY_COMPAT_LEN(1, 1, 1, bl);
291 ::decode(rule_map, bl);
292 multimap<string, LCRule>::iterator iter;
293 for (iter = rule_map.begin(); iter != rule_map.end(); ++iter) {
294 LCRule& rule = iter->second;
299 void dump(Formatter *f) const;
300 // static void generate_test_instances(list<RGWAccessControlList*>& o);
302 void add_rule(LCRule* rule);
304 int check_and_add_rule(LCRule* rule);
308 multimap<string, LCRule>& get_rule_map() { return rule_map; }
309 map<string, lc_op>& get_prefix_map() { return prefix_map; }
311 void create_default(string id, string name) {
313 grant.set_canon(id, name, RGW_PERM_FULL_CONTROL);
318 WRITE_CLASS_ENCODER(RGWLifecycleConfiguration)
324 string *obj_names{nullptr};
325 std::atomic<bool> down_flag = { false };
328 class LCWorker : public Thread {
335 LCWorker(CephContext *_cct, RGWLC *_lc) : cct(_cct), lc(_lc), lock("LCWorker") {}
336 void *entry() override;
338 bool should_work(utime_t& now);
339 int schedule_next_start_time(utime_t& start, utime_t& now);
344 RGWLC() : cct(NULL), store(NULL), worker(NULL) {}
350 void initialize(CephContext *_cct, RGWRados *_store);
354 int process(int index, int max_secs);
355 bool if_already_run_today(time_t& start_date);
356 int list_lc_progress(const string& marker, uint32_t max_entries, map<string, int> *progress_map);
357 int bucket_lc_prepare(int index);
358 int bucket_lc_process(string& shard_id);
359 int bucket_lc_post(int index, int max_lock_sec, pair<string, int >& entry, int& result);
361 void start_processor();
362 void stop_processor();
365 int remove_expired_obj(RGWBucketInfo& bucket_info, rgw_obj_key obj_key, bool remove_indeed = true);
366 bool obj_has_expired(double timediff, int days);
367 int handle_multipart_expiration(RGWRados::Bucket *target, const map<string, lc_op>& prefix_map);