Track reachability in sources module
Add new flag to source struct to indicate when source is selectable (packets with good headers are received) and use a reachability register for last 8 samples instead of the reachable flag. Source drivers now provide only reachability updates.
This commit is contained in:
parent
ff69e86559
commit
0c4968ec51
4 changed files with 65 additions and 39 deletions
30
ntp_core.c
30
ntp_core.c
|
@ -636,18 +636,6 @@ transmit_timeout(void *arg)
|
||||||
inst->presend_done = 0; /* Reset for next time */
|
inst->presend_done = 0; /* Reset for next time */
|
||||||
|
|
||||||
++inst->tx_count;
|
++inst->tx_count;
|
||||||
if (inst->tx_count >= 9) {
|
|
||||||
/* Mark source unreachable */
|
|
||||||
SRC_UnsetReachable(inst->source);
|
|
||||||
} else if (inst->tx_count >= 3) {
|
|
||||||
if (inst->auto_offline) {
|
|
||||||
NCR_TakeSourceOffline(inst);
|
|
||||||
}
|
|
||||||
/* Do reselection */
|
|
||||||
SRC_SelectSource(0);
|
|
||||||
} else {
|
|
||||||
/* Nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the source loses connectivity, back off the sampling rate to reduce
|
/* If the source loses connectivity, back off the sampling rate to reduce
|
||||||
wasted sampling. If it's the source to which we are currently locked,
|
wasted sampling. If it's the source to which we are currently locked,
|
||||||
|
@ -655,7 +643,14 @@ transmit_timeout(void *arg)
|
||||||
|
|
||||||
if (inst->tx_count >= 2) {
|
if (inst->tx_count >= 2) {
|
||||||
/* Implies we have missed at least one transmission */
|
/* Implies we have missed at least one transmission */
|
||||||
|
|
||||||
adjust_poll(inst, SRC_IsSyncPeer(inst->source) ? 0.1 : 0.25);
|
adjust_poll(inst, SRC_IsSyncPeer(inst->source) ? 0.1 : 0.25);
|
||||||
|
|
||||||
|
SRC_UpdateReachability(inst->source, 0);
|
||||||
|
|
||||||
|
if (inst->auto_offline && inst->tx_count >= 3) {
|
||||||
|
NCR_TakeSourceOffline(inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my_mode = inst->mode;
|
my_mode = inst->mode;
|
||||||
|
@ -700,7 +695,7 @@ transmit_timeout(void *arg)
|
||||||
case MD_OFFLINE:
|
case MD_OFFLINE:
|
||||||
do_timer = 0;
|
do_timer = 0;
|
||||||
/* Mark source unreachable */
|
/* Mark source unreachable */
|
||||||
SRC_UnsetReachable(inst->source);
|
SRC_ResetReachability(inst->source);
|
||||||
break;
|
break;
|
||||||
case MD_BURST_WAS_ONLINE:
|
case MD_BURST_WAS_ONLINE:
|
||||||
case MD_BURST_WAS_OFFLINE:
|
case MD_BURST_WAS_OFFLINE:
|
||||||
|
@ -1074,16 +1069,17 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
|
||||||
|
|
||||||
if (valid_header && valid_data) {
|
if (valid_header && valid_data) {
|
||||||
inst->tx_count = 0;
|
inst->tx_count = 0;
|
||||||
|
SRC_UpdateReachability(inst->source, 1);
|
||||||
|
|
||||||
/* Mark the source as suitable for synchronisation when both header and
|
/* Mark the source as suitable for synchronisation when both header and
|
||||||
data are good, unmark when header is not good (i.e. the stratum is
|
data are good, unmark when header is not good (i.e. the stratum is
|
||||||
higher than ours) */
|
higher than ours) */
|
||||||
if (good_header) {
|
if (good_header) {
|
||||||
if (good_data) {
|
if (good_data) {
|
||||||
SRC_SetReachable(inst->source);
|
SRC_SetSelectable(inst->source);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SRC_UnsetReachable(inst->source);
|
SRC_UnsetSelectable(inst->source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,7 +1198,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
|
||||||
case MD_OFFLINE:
|
case MD_OFFLINE:
|
||||||
requeue_transmit = 0;
|
requeue_transmit = 0;
|
||||||
/* Mark source unreachable */
|
/* Mark source unreachable */
|
||||||
SRC_UnsetReachable(inst->source);
|
SRC_ResetReachability(inst->source);
|
||||||
break; /* Even if we've received something, we don't want to
|
break; /* Even if we've received something, we don't want to
|
||||||
transmit back. This might be a symmetric active peer
|
transmit back. This might be a symmetric active peer
|
||||||
that is trying to talk to us. */
|
that is trying to talk to us. */
|
||||||
|
@ -1714,7 +1710,7 @@ NCR_TakeSourceOffline(NCR_Instance inst)
|
||||||
inst->timer_running = 0;
|
inst->timer_running = 0;
|
||||||
inst->opmode = MD_OFFLINE;
|
inst->opmode = MD_OFFLINE;
|
||||||
/* Mark source unreachable */
|
/* Mark source unreachable */
|
||||||
SRC_UnsetReachable(inst->source);
|
SRC_ResetReachability(inst->source);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MD_OFFLINE:
|
case MD_OFFLINE:
|
||||||
|
|
10
refclock.c
10
refclock.c
|
@ -69,7 +69,6 @@ struct RCL_Instance_Record {
|
||||||
int driver_poll;
|
int driver_poll;
|
||||||
int driver_polled;
|
int driver_polled;
|
||||||
int poll;
|
int poll;
|
||||||
int missed_samples;
|
|
||||||
int leap_status;
|
int leap_status;
|
||||||
int pps_rate;
|
int pps_rate;
|
||||||
struct MedianFilter filter;
|
struct MedianFilter filter;
|
||||||
|
@ -175,7 +174,6 @@ RCL_AddRefclock(RefclockParameters *params)
|
||||||
inst->driver_parameter_length = 0;
|
inst->driver_parameter_length = 0;
|
||||||
inst->driver_poll = params->driver_poll;
|
inst->driver_poll = params->driver_poll;
|
||||||
inst->poll = params->poll;
|
inst->poll = params->poll;
|
||||||
inst->missed_samples = 0;
|
|
||||||
inst->driver_polled = 0;
|
inst->driver_polled = 0;
|
||||||
inst->leap_status = 0;
|
inst->leap_status = 0;
|
||||||
inst->pps_rate = params->pps_rate;
|
inst->pps_rate = params->pps_rate;
|
||||||
|
@ -255,6 +253,7 @@ RCL_StartRefclocks(void)
|
||||||
for (i = 0; i < n_sources; i++) {
|
for (i = 0; i < n_sources; i++) {
|
||||||
RCL_Instance inst = &refclocks[i];
|
RCL_Instance inst = &refclocks[i];
|
||||||
|
|
||||||
|
SRC_SetSelectable(inst->source);
|
||||||
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
inst->timeout_id = SCH_AddTimeoutByDelay(0.0, poll_timeout, (void *)inst);
|
||||||
|
|
||||||
if (inst->lock_ref) {
|
if (inst->lock_ref) {
|
||||||
|
@ -519,16 +518,13 @@ poll_timeout(void *arg)
|
||||||
else
|
else
|
||||||
stratum = 0;
|
stratum = 0;
|
||||||
|
|
||||||
SRC_SetReachable(inst->source);
|
SRC_UpdateReachability(inst->source, 1);
|
||||||
SRC_AccumulateSample(inst->source, &sample_time, offset,
|
SRC_AccumulateSample(inst->source, &sample_time, offset,
|
||||||
inst->delay, dispersion, inst->delay, dispersion, stratum, inst->leap_status);
|
inst->delay, dispersion, inst->delay, dispersion, stratum, inst->leap_status);
|
||||||
|
|
||||||
log_sample(inst, &sample_time, 1, 0, 0.0, offset, dispersion);
|
log_sample(inst, &sample_time, 1, 0, 0.0, offset, dispersion);
|
||||||
inst->missed_samples = 0;
|
|
||||||
} else {
|
} else {
|
||||||
inst->missed_samples++;
|
SRC_UpdateReachability(inst->source, 0);
|
||||||
if (inst->missed_samples > 9)
|
|
||||||
SRC_UnsetReachable(inst->source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
54
sources.c
54
sources.c
|
@ -90,9 +90,11 @@ struct SRC_Instance_Record {
|
||||||
reference _it_ is sync'd to) */
|
reference _it_ is sync'd to) */
|
||||||
IPAddr *ip_addr; /* Its IP address if NTP source */
|
IPAddr *ip_addr; /* Its IP address if NTP source */
|
||||||
|
|
||||||
/* Flag indicating that we are receiving packets with valid headers
|
/* Flag indicating that we can use this source as a reference */
|
||||||
from this source and can use it as a reference */
|
int selectable;
|
||||||
int reachable;
|
|
||||||
|
/* Reachability register */
|
||||||
|
int reachability;
|
||||||
|
|
||||||
/* Flag indicating the status of the source */
|
/* Flag indicating the status of the source */
|
||||||
SRC_Status status;
|
SRC_Status status;
|
||||||
|
@ -127,6 +129,9 @@ static int selected_source_index; /* Which source index is currently
|
||||||
selected (set to INVALID_SOURCE
|
selected (set to INVALID_SOURCE
|
||||||
if no current valid reference) */
|
if no current valid reference) */
|
||||||
|
|
||||||
|
/* Keep reachability status for last 8 samples */
|
||||||
|
#define REACH_BITS 8
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Forward prototype */
|
/* Forward prototype */
|
||||||
|
|
||||||
|
@ -196,7 +201,8 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_Sele
|
||||||
result->leap_status = LEAP_Normal;
|
result->leap_status = LEAP_Normal;
|
||||||
result->ref_id = ref_id;
|
result->ref_id = ref_id;
|
||||||
result->ip_addr = addr;
|
result->ip_addr = addr;
|
||||||
result->reachable = 0;
|
result->selectable = 0;
|
||||||
|
result->reachability = 0;
|
||||||
result->status = SRC_BAD_STATS;
|
result->status = SRC_BAD_STATS;
|
||||||
result->type = type;
|
result->type = type;
|
||||||
result->sel_option = sel_option;
|
result->sel_option = sel_option;
|
||||||
|
@ -218,10 +224,7 @@ void SRC_DestroyInstance(SRC_Instance instance)
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
if (instance->index == selected_source_index) {
|
SRC_UnsetSelectable(instance);
|
||||||
instance->reachable = 0;
|
|
||||||
SRC_SelectSource(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SST_DeleteInstance(instance->stats);
|
SST_DeleteInstance(instance->stats);
|
||||||
dead_index = instance->index;
|
dead_index = instance->index;
|
||||||
|
@ -304,9 +307,9 @@ void SRC_AccumulateSample
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SRC_SetReachable(SRC_Instance inst)
|
SRC_SetSelectable(SRC_Instance inst)
|
||||||
{
|
{
|
||||||
inst->reachable = 1;
|
inst->selectable = 1;
|
||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s", source_to_string(inst));
|
LOG(LOGS_INFO, LOGF_Sources, "%s", source_to_string(inst));
|
||||||
|
@ -319,9 +322,9 @@ SRC_SetReachable(SRC_Instance inst)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SRC_UnsetReachable(SRC_Instance inst)
|
SRC_UnsetSelectable(SRC_Instance inst)
|
||||||
{
|
{
|
||||||
inst->reachable = 0;
|
inst->selectable = 0;
|
||||||
|
|
||||||
#ifdef TRACEON
|
#ifdef TRACEON
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "%s%s", source_to_string(inst),
|
LOG(LOGS_INFO, LOGF_Sources, "%s%s", source_to_string(inst),
|
||||||
|
@ -338,6 +341,30 @@ SRC_UnsetReachable(SRC_Instance inst)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
SRC_UpdateReachability(SRC_Instance inst, int reachable)
|
||||||
|
{
|
||||||
|
inst->reachability <<= 1;
|
||||||
|
inst->reachability |= !!reachable;
|
||||||
|
inst->reachability &= ~(-1 << REACH_BITS);
|
||||||
|
|
||||||
|
if (!reachable && inst->index == selected_source_index) {
|
||||||
|
/* Try to select a better source */
|
||||||
|
SRC_SelectSource(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
SRC_ResetReachability(SRC_Instance inst)
|
||||||
|
{
|
||||||
|
inst->reachability = 0;
|
||||||
|
SRC_UpdateReachability(inst, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_sort_elements(const void *a, const void *b)
|
compare_sort_elements(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
|
@ -416,7 +443,8 @@ SRC_SelectSource(unsigned long match_addr)
|
||||||
n_sel_sources = 0;
|
n_sel_sources = 0;
|
||||||
for (i=0; i<n_sources; i++) {
|
for (i=0; i<n_sources; i++) {
|
||||||
|
|
||||||
if (sources[i]->reachable && sources[i]->sel_option != SRC_SelectNoselect) {
|
if (sources[i]->selectable && sources[i]->reachability &&
|
||||||
|
sources[i]->sel_option != SRC_SelectNoselect) {
|
||||||
|
|
||||||
si = &(sources[i]->sel_info);
|
si = &(sources[i]->sel_info);
|
||||||
SST_GetSelectionData(sources[i]->stats, &now,
|
SST_GetSelectionData(sources[i]->stats, &now,
|
||||||
|
|
10
sources.h
10
sources.h
|
@ -120,11 +120,17 @@ extern void SRC_AccumulateSample(SRC_Instance instance, struct timeval *sample_t
|
||||||
|
|
||||||
/* This routine indicates that packets with valid headers are being
|
/* This routine indicates that packets with valid headers are being
|
||||||
received from the designated source */
|
received from the designated source */
|
||||||
extern void SRC_SetReachable(SRC_Instance instance);
|
extern void SRC_SetSelectable(SRC_Instance instance);
|
||||||
|
|
||||||
/* This routine indicates that we are no longer receiving packets with
|
/* This routine indicates that we are no longer receiving packets with
|
||||||
valid headers from the designated source */
|
valid headers from the designated source */
|
||||||
extern void SRC_UnsetReachable(SRC_Instance instance);
|
extern void SRC_UnsetSelectable(SRC_Instance instance);
|
||||||
|
|
||||||
|
/* This routine updates the reachability register */
|
||||||
|
extern void SRC_UpdateReachability(SRC_Instance inst, int reachable);
|
||||||
|
|
||||||
|
/* This routine marks the source unreachable */
|
||||||
|
extern void SRC_ResetReachability(SRC_Instance inst);
|
||||||
|
|
||||||
/* This routine is used to select the best source from amongst those
|
/* This routine is used to select the best source from amongst those
|
||||||
we currently have valid data on, and use it as the tracking base
|
we currently have valid data on, and use it as the tracking base
|
||||||
|
|
Loading…
Reference in a new issue