auto& [target_osd, fi] = *p;
if (can_mark_down(target_osd)) {
found_failure |= check_failure(now, target_osd, fi);
+ ++p;
+ } else if (is_failure_stale(now, fi)) {
+ dout(10) << " dropping stale failure_info for osd." << target_osd
+ << " from " << fi.reporters.size() << " reporters"
+ << dendl;
+ p = failure_info.erase(p);
+ } else {
+ ++p;
}
- ++p;
}
return found_failure;
}
return false;
}
+bool OSDMonitor::is_failure_stale(utime_t now, failure_info_t& fi) const
+{
+ // if it takes too long to either cancel the report to mark the osd down,
+ // some reporters must have failed to cancel their reports. let's just
+ // forget these reports.
+ const utime_t failed_for = now - fi.get_failed_since();
+ auto heartbeat_grace = cct->_conf.get_val<int64_t>("osd_heartbeat_grace");
+ auto heartbeat_stale = cct->_conf.get_val<int64_t>("osd_heartbeat_stale");
+ return failed_for >= (heartbeat_grace + heartbeat_stale);
+}
+
void OSDMonitor::force_failure(int target_osd, int by)
{
// already pending failure?
bool check_failures(utime_t now);
bool check_failure(utime_t now, int target_osd, failure_info_t& fi);
utime_t get_grace_time(utime_t now, int target_osd, failure_info_t& fi) const;
+ bool is_failure_stale(utime_t now, failure_info_t& fi) const;
void force_failure(int target_osd, int by);
bool _have_pending_crush();