From 76c9c4231400245864addfc7a8aabaa79843b4bd Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Wed, 6 Apr 2011 17:23:40 -0700 Subject: [PATCH] cfm: Fix broken fault logic. If the last receive time for a remote MP was before the last fault check, the CFM code would not declare a fault. This is, of course, exactly the wrong response. Bug #5303. --- lib/cfm.c | 9 ++++++--- lib/timer.c | 13 +++++++++++++ lib/timer.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/cfm.c b/lib/cfm.c index 5a547d0d..a504714c 100644 --- a/lib/cfm.c +++ b/lib/cfm.c @@ -174,11 +174,14 @@ cfm_run(struct cfm *cfm) if (timer_expired(&cfmi->fault_timer)) { bool fault; struct remote_mp *rmp; + long long int interval; - fault = now < cfmi->x_recv_time + cfm_fault_interval(cfmi); + interval = cfm_fault_interval(cfmi); + fault = now < cfmi->x_recv_time + interval; HMAP_FOR_EACH (rmp, node, &cfm->remote_mps) { - if (timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) { + if (rmp->recv_time < timer_enabled_at(&cfmi->fault_timer, interval) + || timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) { rmp->fault = true; } @@ -188,7 +191,7 @@ cfm_run(struct cfm *cfm) } cfm->fault = fault; - timer_set_duration(&cfmi->fault_timer, cfm_fault_interval(cfmi)); + timer_set_duration(&cfmi->fault_timer, interval); } } diff --git a/lib/timer.c b/lib/timer.c index b640a7be..1c3c0f48 100644 --- a/lib/timer.c +++ b/lib/timer.c @@ -40,3 +40,16 @@ timer_wait(const struct timer *timer) poll_timer_wait_until(timer->t); } } + +/* Returns the time at which 'timer' was set with 'duration'. Infinite timers + * were enabled at time LLONG_MAX. Manually expired timers were enabled at + * LLONG_MIN. */ +long long int +timer_enabled_at(const struct timer *timer, long long int duration) +{ + switch (timer->t) { + case LLONG_MAX: return LLONG_MAX; + case LLONG_MIN: return LLONG_MIN; + default: return timer->t - duration; + } +} diff --git a/lib/timer.h b/lib/timer.h index d2bfd86b..73020556 100644 --- a/lib/timer.h +++ b/lib/timer.h @@ -26,6 +26,7 @@ struct timer { }; long long int timer_msecs_until_expired(const struct timer *); +long long int timer_enabled_at(const struct timer *, long long int duration); void timer_wait(const struct timer *); /* Causes 'timer' to expire when 'duration' milliseconds have passed. -- 2.30.2