Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_lc.h
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"
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"
21
22 #include <atomic>
23
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;
42   //At present only current object has expiration date
43   string date;
44 public:
45   LCExpiration() {}
46   ~LCExpiration() {}
47
48   void encode(bufferlist& bl) const {
49     ENCODE_START(3, 2, bl);
50     ::encode(days, bl);
51     ::encode(date, bl);
52     ENCODE_FINISH(bl);
53   }
54   void decode(bufferlist::iterator& bl) {
55     DECODE_START_LEGACY_COMPAT_LEN(3, 2, 2, bl);
56     ::decode(days, bl);
57     if (struct_v >= 3) {
58       ::decode(date, bl);
59     }
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; }
65   string get_days_str() const {
66     return days;
67   }
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;
90   }
91 };
92 WRITE_CLASS_ENCODER(LCExpiration)
93
94 class LCFilter
95 {
96  protected:
97   std::string prefix;
98   // TODO add support for tagging
99  public:
100   const std::string& get_prefix() const{
101     return prefix;
102   }
103
104   void set_prefix(const string& _prefix){
105     prefix = _prefix;
106   }
107
108   void set_prefix(std::string&& _prefix){
109     prefix = std::move(_prefix);
110   }
111
112   bool empty() const {
113     return prefix.empty();
114   }
115
116   bool has_prefix() const {
117     return !prefix.empty();
118   }
119
120   void encode(bufferlist& bl) const {
121     ENCODE_START(1, 1, bl);
122     ::encode(prefix, bl);
123     ENCODE_FINISH(bl);
124   }
125   void decode(bufferlist::iterator& bl) {
126     DECODE_START(1, bl);
127     ::decode(prefix, bl);
128     DECODE_FINISH(bl);
129   }
130 };
131 WRITE_CLASS_ENCODER(LCFilter);
132
133
134
135 class LCRule
136 {
137 protected:
138   string id;
139   string prefix;
140   string status;
141   LCExpiration expiration;
142   LCExpiration noncur_expiration;
143   LCExpiration mp_expiration;
144   LCFilter filter;
145   bool dm_expiration = false;
146
147 public:
148
149   LCRule(){};
150   ~LCRule(){};
151
152   bool get_id(string& _id) {
153       _id = id;
154       return true;
155   }
156
157   string& get_status() {
158       return status;
159   }
160
161   string& get_prefix() {
162       return prefix;
163   }
164
165   LCFilter& get_filter() {
166     return filter;
167   }
168
169   LCExpiration& get_expiration() {
170     return expiration;
171   }
172
173   LCExpiration& get_noncur_expiration() {
174     return noncur_expiration;
175   }
176
177   LCExpiration& get_mp_expiration() {
178     return mp_expiration;
179   }
180
181   bool get_dm_expiration() {
182     return dm_expiration;
183   }
184
185   void set_id(string*_id) {
186     id = *_id;
187   }
188
189   void set_prefix(string*_prefix) {
190     prefix = *_prefix;
191   }
192
193   void set_status(string*_status) {
194     status = *_status;
195   }
196
197   void set_expiration(LCExpiration*_expiration) {
198     expiration = *_expiration;
199   }
200
201   void set_noncur_expiration(LCExpiration*_noncur_expiration) {
202     noncur_expiration = *_noncur_expiration;
203   }
204
205   void set_mp_expiration(LCExpiration* _mp_expiration) {
206     mp_expiration = *_mp_expiration;
207   }
208
209   void set_dm_expiration(bool _dm_expiration) {
210     dm_expiration = _dm_expiration;
211   }
212
213   bool valid();
214   
215   void encode(bufferlist& bl) const {
216      ENCODE_START(5, 1, bl);
217      ::encode(id, 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);
225      ENCODE_FINISH(bl);
226    }
227    void decode(bufferlist::iterator& bl) {
228      DECODE_START_LEGACY_COMPAT_LEN(5, 1, 1, bl);
229      ::decode(id, bl);
230      ::decode(prefix, bl);
231      ::decode(status, bl);
232      ::decode(expiration, bl);
233      if (struct_v >=2) {
234        ::decode(noncur_expiration, bl);
235      }
236      if (struct_v >= 3) {
237        ::decode(mp_expiration, bl);
238      }
239      if (struct_v >= 4) {
240         ::decode(dm_expiration, bl);
241      }
242      if (struct_v >= 5) {
243        ::decode(filter, bl);
244      }
245      DECODE_FINISH(bl);
246    }
247
248 };
249 WRITE_CLASS_ENCODER(LCRule)
250
251 struct lc_op
252 {
253   bool status;
254   bool dm_expiration;
255   int expiration;
256   int noncur_expiration;
257   int mp_expiration;
258   boost::optional<ceph::real_time> expiration_date;
259
260   lc_op() : status(false), dm_expiration(false), expiration(0), noncur_expiration(0), mp_expiration(0) {}
261   
262 };
263
264 class RGWLifecycleConfiguration
265 {
266 protected:
267   CephContext *cct;
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);
272 public:
273   RGWLifecycleConfiguration(CephContext *_cct) : cct(_cct) {}
274   RGWLifecycleConfiguration() : cct(NULL) {}
275
276   void set_ctx(CephContext *ctx) {
277     cct = ctx;
278   }
279
280   virtual ~RGWLifecycleConfiguration() {}
281
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);
287     ENCODE_FINISH(bl);
288   }
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;
295       _add_rule(&rule);
296     }
297     DECODE_FINISH(bl);
298   }
299   void dump(Formatter *f) const;
300 //  static void generate_test_instances(list<RGWAccessControlList*>& o);
301
302   void add_rule(LCRule* rule);
303
304   int check_and_add_rule(LCRule* rule);
305
306   bool valid();
307
308   multimap<string, LCRule>& get_rule_map() { return rule_map; }
309   map<string, lc_op>& get_prefix_map() { return prefix_map; }
310 /*
311   void create_default(string id, string name) {
312     ACLGrant grant;
313     grant.set_canon(id, name, RGW_PERM_FULL_CONTROL);
314     add_grant(&grant);
315   }
316 */
317 };
318 WRITE_CLASS_ENCODER(RGWLifecycleConfiguration)
319
320 class RGWLC {
321   CephContext *cct;
322   RGWRados *store;
323   int max_objs{0};
324   string *obj_names{nullptr};
325   std::atomic<bool> down_flag = { false };
326   string cookie;
327
328   class LCWorker : public Thread {
329     CephContext *cct;
330     RGWLC *lc;
331     Mutex lock;
332     Cond cond;
333
334   public:
335     LCWorker(CephContext *_cct, RGWLC *_lc) : cct(_cct), lc(_lc), lock("LCWorker") {}
336     void *entry() override;
337     void stop();
338     bool should_work(utime_t& now);
339     int schedule_next_start_time(utime_t& start, utime_t& now);
340   };
341   
342   public:
343   LCWorker *worker;
344   RGWLC() : cct(NULL), store(NULL), worker(NULL) {}
345   ~RGWLC() {
346     stop_processor();
347     finalize();
348   }
349
350   void initialize(CephContext *_cct, RGWRados *_store);
351   void finalize();
352
353   int process();
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);
360   bool going_down();
361   void start_processor();
362   void stop_processor();
363
364   private:
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);
368 };
369
370
371
372 #endif