From: lu.shasha Date: Wed, 20 Sep 2017 03:15:00 +0000 (+0800) Subject: rgw:lc: using midnight time to check obj expiration X-Git-Tag: v13.0.1~598^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4a759c9aaae163940445836ac647d1db85f186c2;p=ceph.git rgw:lc: using midnight time to check obj expiration 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 --- diff --git a/src/include/utime.h b/src/include/utime.h index 732eaebcdff0..bb23df52d1db 100644 --- a/src/include/utime.h +++ b/src/include/utime.h @@ -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); diff --git a/src/rgw/rgw_lc.cc b/src/rgw/rgw_lc.cc index cdcfaffff77c..7030f7ff01e2 100644 --- a/src/rgw/rgw_lc.cc +++ b/src/rgw/rgw_lc.cc @@ -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 mapmeta.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()) { diff --git a/src/rgw/rgw_lc.h b/src/rgw/rgw_lc.h index 0a655c5c3e32..4d7b670bea3d 100644 --- a/src/rgw/rgw_lc.h +++ b/src/rgw/rgw_lc.h @@ -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& prefix_map); };