Add prefer and noselect options

This commit is contained in:
Miroslav Lichvar 2010-08-25 18:11:52 +02:00
parent 061d497df0
commit f924862e89
11 changed files with 91 additions and 28 deletions

View file

@ -2387,6 +2387,10 @@ nanosecond).
@item precision @item precision
Refclock precision (in seconds). The default is 1e-6 (1 microsecond) Refclock precision (in seconds). The default is 1e-6 (1 microsecond)
for SHM refclock, and 1e-9 (1 nanosecond) for SOCK and PPS refclocks. for SHM refclock, and 1e-9 (1 nanosecond) for SOCK and PPS refclocks.
@item prefer
Prefer this source over sources without prefer option.
@item noselect
Never select this source. This is particularly useful for monitoring.
@end table @end table
@c }}} @c }}}
@ -2625,6 +2629,12 @@ selecting that source. This is useful with low stratum sources that are known
to be unrealiable or inaccurate and which should be used only when other to be unrealiable or inaccurate and which should be used only when other
sources are unreachable. sources are unreachable.
@item prefer
Prefer this source over sources without prefer option.
@item noselect
Never select this source. This is particularly useful for monitoring.
@end table @end table
@c }}} @c }}}
@c {{{ tempcomp @c {{{ tempcomp

View file

@ -934,6 +934,9 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
if (data.params.min_stratum) { if (data.params.min_stratum) {
fprintf(stderr, "Option minstratum not supported\n"); fprintf(stderr, "Option minstratum not supported\n");
break; break;
} else if (data.params.sel_option != SRC_SelectNormal) {
fprintf(stderr, "Options noselect and prefer not supported\n");
break;
} }
msg->data.ntp_source.port = htonl((unsigned long) data.port); msg->data.ntp_source.port = htonl((unsigned long) data.port);

View file

@ -1246,7 +1246,11 @@ handle_add_server(CMD_Request *rx_message, CMD_Reply *tx_message)
params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0; params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay); params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio); params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
params.min_stratum = 0; /* not transmitted in cmdmon protocol yet */
/* not transmitted in cmdmon protocol yet */
params.min_stratum = 0;
params.sel_option = SRC_SelectNormal;
status = NSR_AddSource(&rem_addr, NTP_SERVER, &params); status = NSR_AddSource(&rem_addr, NTP_SERVER, &params);
switch (status) { switch (status) {
case NSR_Success: case NSR_Success:
@ -1288,7 +1292,11 @@ handle_add_peer(CMD_Request *rx_message, CMD_Reply *tx_message)
params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0; params.iburst = ntohl(rx_message->data.ntp_source.flags) & REQ_ADDSRC_IBURST ? 1 : 0;
params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay); params.max_delay = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay);
params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio); params.max_delay_ratio = UTI_FloatNetworkToHost(rx_message->data.ntp_source.max_delay_ratio);
params.min_stratum = 0; /* not transmitted in cmdmon protocol yet */
/* not transmitted in cmdmon protocol yet */
params.min_stratum = 0;
params.sel_option = SRC_SelectNormal;
status = NSR_AddSource(&rem_addr, NTP_PEER, &params); status = NSR_AddSource(&rem_addr, NTP_PEER, &params);
switch (status) { switch (status) {
case NSR_Success: case NSR_Success:

View file

@ -60,6 +60,7 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
src->params.auto_offline = 0; src->params.auto_offline = 0;
src->params.iburst = 0; src->params.iburst = 0;
src->params.min_stratum = 0; src->params.min_stratum = 0;
src->params.sel_option = SRC_SelectNormal;
result = CPS_Success; result = CPS_Success;
@ -164,6 +165,12 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
line += n; line += n;
} }
} else if (!strncasecmp(cmd, "noselect", 8)) {
src->params.sel_option = SRC_SelectNoselect;
} else if (!strncasecmp(cmd, "prefer", 6)) {
src->params.sel_option = SRC_SelectPrefer;
} else { } else {
result = CPS_BadOption; result = CPS_BadOption;
ok = 0; ok = 0;

9
conf.c
View file

@ -448,6 +448,7 @@ parse_refclock(const char *line)
const char *tmp; const char *tmp;
char name[5], cmd[10 + 1], *param; char name[5], cmd[10 + 1], *param;
unsigned char ref[5]; unsigned char ref[5];
SRC_SelectOption sel_option;
i = n_refclock_sources; i = n_refclock_sources;
if (i >= MAX_RCL_SOURCES) if (i >= MAX_RCL_SOURCES)
@ -462,6 +463,7 @@ parse_refclock(const char *line)
precision = 0.0; precision = 0.0;
ref_id = 0; ref_id = 0;
lock_ref_id = 0; lock_ref_id = 0;
sel_option = SRC_SelectNormal;
if (sscanf(line, "%4s%n", name, &n) != 1) { if (sscanf(line, "%4s%n", name, &n) != 1) {
LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name at line %d", line_number); LOG(LOGS_WARN, LOGF_Configure, "Could not read refclock driver name at line %d", line_number);
@ -518,6 +520,12 @@ parse_refclock(const char *line)
} else if (!strncasecmp(cmd, "precision", 9)) { } else if (!strncasecmp(cmd, "precision", 9)) {
if (sscanf(line, "%lf%n", &precision, &n) != 1) if (sscanf(line, "%lf%n", &precision, &n) != 1)
break; break;
} else if (!strncasecmp(cmd, "noselect", 8)) {
n = 0;
sel_option = SRC_SelectNoselect;
} else if (!strncasecmp(cmd, "prefer", 6)) {
n = 0;
sel_option = SRC_SelectPrefer;
} else { } else {
LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number); LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number);
break; break;
@ -534,6 +542,7 @@ parse_refclock(const char *line)
refclock_sources[i].offset = offset; refclock_sources[i].offset = offset;
refclock_sources[i].delay = delay; refclock_sources[i].delay = delay;
refclock_sources[i].precision = precision; refclock_sources[i].precision = precision;
refclock_sources[i].sel_option = sel_option;
refclock_sources[i].ref_id = ref_id; refclock_sources[i].ref_id = ref_id;
refclock_sources[i].lock_ref_id = lock_ref_id; refclock_sources[i].lock_ref_id = lock_ref_id;

View file

@ -312,7 +312,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
result->local_poll = params->minpoll; result->local_poll = params->minpoll;
/* Create a source instance for this NTP source */ /* Create a source instance for this NTP source */
result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, &result->remote_addr.ip_addr); result->source = SRC_CreateNewInstance(UTI_IPToRefid(&remote_addr->ip_addr), SRC_NTP, params->sel_option, &result->remote_addr.ip_addr);
result->local_rx.tv_sec = 0; result->local_rx.tv_sec = 0;
result->local_rx.tv_usec = 0; result->local_rx.tv_usec = 0;

View file

@ -236,7 +236,7 @@ RCL_AddRefclock(RefclockParameters *params)
filter_init(&inst->filter, params->filter_length); filter_init(&inst->filter, params->filter_length);
inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, NULL); inst->source = SRC_CreateNewInstance(inst->ref_id, SRC_REFCLOCK, params->sel_option, NULL);
#if 0 #if 0
LOG(LOGS_INFO, LOGF_Refclock, "refclock added poll=%d dpoll=%d filter=%d", LOG(LOGS_INFO, LOGF_Refclock, "refclock added poll=%d dpoll=%d filter=%d",

View file

@ -43,6 +43,7 @@ typedef struct {
double offset; double offset;
double delay; double delay;
double precision; double precision;
SRC_SelectOption sel_option;
} RefclockParameters; } RefclockParameters;
typedef struct RCL_Instance_Record *RCL_Instance; typedef struct RCL_Instance_Record *RCL_Instance;

View file

@ -100,6 +100,9 @@ struct SRC_Instance_Record {
/* Type of the source */ /* Type of the source */
SRC_Type type; SRC_Type type;
/* Options used when selecting sources */
SRC_SelectOption sel_option;
struct SelectInfo sel_info; struct SelectInfo sel_info;
}; };
@ -165,7 +168,7 @@ void SRC_Finalise(void)
/* Function to create a new instance. This would be called by one of /* Function to create a new instance. This would be called by one of
the individual source-type instance creation routines. */ the individual source-type instance creation routines. */
SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr) SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr)
{ {
SRC_Instance result; SRC_Instance result;
@ -196,6 +199,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *
result->reachable = 0; result->reachable = 0;
result->status = SRC_BAD_STATS; result->status = SRC_BAD_STATS;
result->type = type; result->type = type;
result->sel_option = sel_option;
n_sources++; n_sources++;
@ -414,7 +418,7 @@ SRC_SelectSource(unsigned long match_addr)
n_reachable_sources = 0; n_reachable_sources = 0;
for (i=0; i<n_sources; i++) { for (i=0; i<n_sources; i++) {
if (sources[i]->reachable) { if (sources[i]->reachable && sources[i]->sel_option != SRC_SelectNoselect) {
++n_reachable_sources; ++n_reachable_sources;
@ -638,11 +642,39 @@ SRC_SelectSource(unsigned long match_addr)
} }
n_sel_sources = j; n_sel_sources = j;
if (n_sel_sources > 0) {
/* Accept leap second status if more than half of selectable sources agree */
for (i=j1=j2=0; i<n_sel_sources; i++) {
index = sel_sources[i];
if (sources[index]->leap_status == LEAP_InsertSecond) {
j1++;
} else if (sources[index]->leap_status == LEAP_DeleteSecond) {
j2++;
}
}
if (j1 > n_sel_sources / 2) {
leap_status = LEAP_InsertSecond;
} else if (j2 > n_sel_sources / 2) {
leap_status = LEAP_DeleteSecond;
}
/* If there are any sources with prefer option, reduce the list again
only to the prefer sources */
for (i=j=0; i<n_sel_sources; i++) {
if (sources[sel_sources[i]]->sel_option == SRC_SelectPrefer) {
sel_sources[j++] = sel_sources[i];
}
}
if (j > 0) {
n_sel_sources = j;
}
/* Now find minimum stratum. If none are left now, /* Now find minimum stratum. If none are left now,
tough. RFC1305 is not so harsh on pruning sources due to tough. RFC1305 is not so harsh on pruning sources due to
excess variance, which prevents this from happening */ excess variance, which prevents this from happening */
if (n_sel_sources > 0) {
index = sel_sources[0]; index = sel_sources[0];
min_stratum = sources[index]->sel_info.stratum; min_stratum = sources[index]->sel_info.stratum;
for (i=1; i<n_sel_sources; i++) { for (i=1; i<n_sel_sources; i++) {
@ -709,23 +741,6 @@ SRC_SelectSource(unsigned long match_addr)
total_root_dispersion = (src_accrued_dispersion + total_root_dispersion = (src_accrued_dispersion +
sources[selected_source_index]->sel_info.root_dispersion); sources[selected_source_index]->sel_info.root_dispersion);
/* Accept leap second status if more than half of selectable sources agree */
for (i=j1=j2=0; i<n_sel_sources; i++) {
index = sel_sources[i];
if (sources[index]->leap_status == LEAP_InsertSecond) {
j1++;
} else if (sources[index]->leap_status == LEAP_DeleteSecond) {
j2++;
}
}
if (j1 > n_sel_sources / 2) {
leap_status = LEAP_InsertSecond;
} else if (j2 > n_sel_sources / 2) {
leap_status = LEAP_DeleteSecond;
}
if ((match_addr == 0) || if ((match_addr == 0) ||
(match_addr == sources[selected_source_index]->ref_id)) { (match_addr == sources[selected_source_index]->ref_id)) {

View file

@ -55,10 +55,17 @@ typedef enum {
SRC_REFCLOCK /* Rerefence clock */ SRC_REFCLOCK /* Rerefence clock */
} SRC_Type; } SRC_Type;
/* Options used when selecting sources */
typedef enum {
SRC_SelectNormal,
SRC_SelectNoselect,
SRC_SelectPrefer
} SRC_SelectOption;
/* Function to create a new instance. This would be called by one of /* Function to create a new instance. This would be called by one of
the individual source-type instance creation routines. */ the individual source-type instance creation routines. */
extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *addr); extern SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, SRC_SelectOption sel_option, IPAddr *addr);
/* Function to get rid of a source when it is being unconfigured. /* Function to get rid of a source when it is being unconfigured.
This may cause the current reference source to be reselected, if this This may cause the current reference source to be reselected, if this

View file

@ -31,6 +31,8 @@
#ifndef GOT_SRCPARAMS_H #ifndef GOT_SRCPARAMS_H
#define GOT_SRCPARAMS_H #define GOT_SRCPARAMS_H
#include "sources.h"
typedef struct { typedef struct {
int minpoll; int minpoll;
int maxpoll; int maxpoll;
@ -42,6 +44,7 @@ typedef struct {
unsigned long authkey; unsigned long authkey;
double max_delay; double max_delay;
double max_delay_ratio; double max_delay_ratio;
SRC_SelectOption sel_option;
} SourceParameters; } SourceParameters;
#define INACTIVE_AUTHKEY 0UL #define INACTIVE_AUTHKEY 0UL