Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utime: fix __32u sec time overflow #21113

Merged
merged 1 commit into from Apr 17, 2018

Conversation

kungf
Copy link

@kungf kungf commented Mar 29, 2018

when i set osd_scrub_min(max)_interval to a very large num, just like 6307200000(20036524*3600), osd still do scrub. finally i find that the utime_t::nsec only __u32, it's max num is 4294967295, and <
6307200000, so scrub sched_time will overflow, and it will be a random time.

related: #20965

Signed-off-by: kungf yang.wang@easystack.cn

@kungf
Copy link
Author

kungf commented Mar 30, 2018

@liewegas need a review please

src/osd/OSD.cc Outdated
@@ -6911,10 +6911,18 @@ OSDService::ScrubJob::ScrubJob(CephContext* cct,
double r = rand() / (double)RAND_MAX;
sched_time +=
scrub_min_interval * cct->_conf->osd_scrub_interval_randomize_ratio * r;
if (sched_time < timestamp) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we update the implementation of utime_t& operator+=(utime_t& l, double f) instead? so if the result will overflow, we can just assign std::limits<uint32_t>::max() to it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, file changed, help review,please

@@ -47,6 +47,11 @@ class utime_t {
bool is_zero() const {
return (tv.tv_sec == 0) && (tv.tv_nsec == 0);
}

void set_max() {
tv.tv_sec = UINT32_MAX;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to use std::limits<decltype(tv.tv_sec)>::max() instead.

@kungf kungf changed the title OSD: fix scrub sched_time overflow utime: fix __32u sec time overflow Apr 2, 2018
@kungf
Copy link
Author

kungf commented Apr 3, 2018

Jenkins retest this please

@kungf
Copy link
Author

kungf commented Apr 4, 2018

@tchaikov need a review, please

(l.nsec()+r.nsec())%1000000000L );
__u64 sec = (__u64)l.sec() + r.sec() + (l.nsec()+r.nsec())/1000000000ul;
__u64 nsec = (l.nsec()+r.nsec())%1000000000ul;
return utime_t( ut_safe_convert(sec), ut_safe_convert(nsec));
Copy link
Contributor

@tchaikov tchaikov Apr 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the second ut_safe_convert() necessary?

remove the space after (.

why are you using different ways to normalize the result in operator+ and operator+=? could you be more consistent ?

@@ -32,6 +32,10 @@
// --------
// utime_t

//from __u64 to __u32
inline __u32 ut_safe_convert(__u64 t) {
return t < std::numeric_limits<uint32_t>::max() ? t : std::numeric_limits<uint32_t>::max();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd suggest rename ut_safe_convert() to cap_to_u32_max(). also might want to use std::min() here.

@branch-predictor
Copy link
Contributor

6307200000 is around 200 years - nobody sane is going to set it so high intentionally. While I agree on the fix, I think it's the osd_scrub_min/max_interval that should be capped to reasonable boundaries.

@kungf
Copy link
Author

kungf commented Apr 12, 2018

@branch-predictor some one who want close scrub may set it, he may not care how may years he set it, but only want set a very large num, then close the scrub through this way.

I think it's the osd_scrub_min/max_interval that should be capped to reasonable boundaries.

what do you mean? only cap osd_scrub_min/max_interval in osd.cc?

@branch-predictor
Copy link
Contributor

@kungf to disable scrub, you can use noscrub/nodeepscrub cluster flags.

I think it's the osd_scrub_min/max_interval that should be capped to reasonable boundaries.

what do you mean? only cap osd_scrub_min/max_interval in osd.cc?

No, add appriopriate .set_min_max at https://github.com/ceph/ceph/blob/master/src/common/options.cc#L3013 .

@@ -32,6 +32,10 @@
// --------
// utime_t

//from __u64 to __u32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kungf could you drop this comment. it's unnecessary and redundant here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

Copy link
Contributor

@tchaikov tchaikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aside from the comment, lgtm

Signed-off-by: kungf <yang.wang@easystack.cn>
@liewegas liewegas merged commit 6cfd3f7 into ceph:master Apr 17, 2018
@tchaikov
Copy link
Contributor

@branch-predictor sorry, i missed your comment. yeah, a min-max bound would be better.

@kungf kungf deleted the scrub_interval_overflow branch April 19, 2018 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants