]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw:lc: using midnight time to check obj expiration 17824/head
authorlu.shasha <lu.shasha@eisoo.com>
Wed, 20 Sep 2017 03:15:00 +0000 (11:15 +0800)
committerlu.shasha <lu.shasha@eisoo.com>
Mon, 9 Oct 2017 06:31:15 +0000 (14:31 +0800)
Amazon S3 calculates the expiration time by adding the number of days specified in the rule to the object creation time and rounding the resulting time to the next day midnight.
So rgw should using the rounding down midnight time to compare with the object creation time to check obj expiration.

Fixes: http://tracker.ceph.com/issues/21533
Signed-off-by: Shasha Lu <lu.shasha@eisoo.com>
src/include/utime.h
src/rgw/rgw_lc.cc
src/rgw/rgw_lc.h

index 732eaebcdff0c159b218684ba916632f3a7e8fbd..bb23df52d1db01a12d73b44ee15574416bd3215a 100644 (file)
@@ -171,6 +171,17 @@ public:
     return utime_t(tt, 0);
   }
 
+  utime_t round_to_day() {
+    struct tm bdt;
+    time_t tt = sec();
+    localtime_r(&tt, &bdt);
+    bdt.tm_sec = 0;
+    bdt.tm_min = 0;
+    bdt.tm_hour = 0;
+    tt = mktime(&bdt);
+    return utime_t(tt, 0);
+  }
+
   // cast to double
   operator double() const {
     return (double)sec() + ((double)nsec() / 1000000000.0L);
index cdcfaffff77cc7345352f5ff09f807e3f0a2755a..7030f7ff01e2004916aae3762fe8676c95f67374 100644 (file)
@@ -244,16 +244,20 @@ int RGWLC::bucket_lc_prepare(int index)
   return 0;
 }
 
-bool RGWLC::obj_has_expired(double timediff, int days)
+bool RGWLC::obj_has_expired(ceph::real_time mtime, int days)
 {
-  double cmp;
+  double timediff, cmp;
+  utime_t base_time;
   if (cct->_conf->rgw_lc_debug_interval <= 0) {
     /* Normal case, run properly */
     cmp = days*24*60*60;
+    base_time = ceph_clock_now().round_to_day();
   } else {
     /* We're in debug mode; Treat each rgw_lc_debug_interval seconds as a day */
     cmp = days*cct->_conf->rgw_lc_debug_interval;
+    base_time = ceph_clock_now();
   }
+  timediff = base_time - ceph::real_clock::to_time_t(mtime);
 
   return (timediff >= cmp);
 }
@@ -298,9 +302,8 @@ int RGWLC::handle_multipart_expiration(RGWRados::Bucket *target, const map<strin
           return ret;
       }
 
-      utime_t now = ceph_clock_now();
       for (auto obj_iter = objs.begin(); obj_iter != objs.end(); ++obj_iter) {
-        if (obj_has_expired(now - ceph::real_clock::to_time_t(obj_iter->meta.mtime), prefix_iter->second.mp_expiration)) {
+        if (obj_has_expired(obj_iter->meta.mtime, prefix_iter->second.mp_expiration)) {
           rgw_obj_key key(obj_iter->key);
           if (!mp_obj.from_meta(key.name)) {
             continue;
@@ -384,7 +387,6 @@ int RGWLC::bucket_lc_process(string& shard_id)
           return ret;
         }
         
-        utime_t now = ceph_clock_now();
         bool is_expired;
         for (auto obj_iter = objs.begin(); obj_iter != objs.end(); ++obj_iter) {
           rgw_obj_key key(obj_iter->key);
@@ -396,7 +398,7 @@ int RGWLC::bucket_lc_process(string& shard_id)
             //we have checked it before
             is_expired = true;
           } else {
-            is_expired = obj_has_expired(now - ceph::real_clock::to_time_t(obj_iter->meta.mtime), prefix_iter->second.expiration);
+            is_expired = obj_has_expired(obj_iter->meta.mtime, prefix_iter->second.expiration);
           }
           if (is_expired) {
             RGWObjectCtx rctx(store);
@@ -450,7 +452,6 @@ int RGWLC::bucket_lc_process(string& shard_id)
           return ret;
         }
 
-        utime_t now = ceph_clock_now();
         ceph::real_time mtime;
         bool remove_indeed = true;
         int expiration;
@@ -485,9 +486,9 @@ int RGWLC::bucket_lc_process(string& shard_id)
               continue;
             } else if (!skip_expiration) {
               if (expiration > 0) {
-                is_expired = obj_has_expired(now - ceph::real_clock::to_time_t(mtime), expiration);
+                is_expired = obj_has_expired(mtime, expiration);
               } else {
-                is_expired = now >= ceph::real_clock::to_time_t(*prefix_iter->second.expiration_date);
+                is_expired = ceph_clock_now() >= ceph::real_clock::to_time_t(*prefix_iter->second.expiration_date);
               }
             }
           } else {
@@ -497,7 +498,7 @@ int RGWLC::bucket_lc_process(string& shard_id)
             remove_indeed = true;
             mtime = (obj_iter == objs.begin())?pre_obj.meta.mtime:(obj_iter - 1)->meta.mtime;
             expiration = prefix_iter->second.noncur_expiration;
-            is_expired = obj_has_expired(now - ceph::real_clock::to_time_t(mtime), expiration);
+            is_expired = obj_has_expired(mtime, expiration);
           }
           if (skip_expiration || is_expired) {
             if (obj_iter->is_visible()) {
index 0a655c5c3e32a1d651052953befc55853d19a945..4d7b670bea3da3ab68b72ee0c1b47209c0705017 100644 (file)
@@ -363,7 +363,7 @@ class RGWLC {
 
   private:
   int remove_expired_obj(RGWBucketInfo& bucket_info, rgw_obj_key obj_key, bool remove_indeed = true);
-  bool obj_has_expired(double timediff, int days);
+  bool obj_has_expired(ceph::real_time mtime, int days);
   int handle_multipart_expiration(RGWRados::Bucket *target, const map<string, lc_op>& prefix_map);
 };