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
Refclock precision (in seconds). The default is 1e-6 (1 microsecond)
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
@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
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
@c }}}
@c {{{ tempcomp

View file

@ -934,6 +934,9 @@ process_cmd_add_server_or_peer(CMD_Request *msg, char *line)
if (data.params.min_stratum) {
fprintf(stderr, "Option minstratum not supported\n");
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);

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.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.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);
switch (status) {
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.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.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);
switch (status) {
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.iburst = 0;
src->params.min_stratum = 0;
src->params.sel_option = SRC_SelectNormal;
result = CPS_Success;
@ -163,6 +164,12 @@ CPS_ParseNTPSourceAdd(const char *line, CPS_NTP_Source *src)
} else {
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 {
result = CPS_BadOption;

9
conf.c
View file

@ -448,6 +448,7 @@ parse_refclock(const char *line)
const char *tmp;
char name[5], cmd[10 + 1], *param;
unsigned char ref[5];
SRC_SelectOption sel_option;
i = n_refclock_sources;
if (i >= MAX_RCL_SOURCES)
@ -462,6 +463,7 @@ parse_refclock(const char *line)
precision = 0.0;
ref_id = 0;
lock_ref_id = 0;
sel_option = SRC_SelectNormal;
if (sscanf(line, "%4s%n", name, &n) != 1) {
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)) {
if (sscanf(line, "%lf%n", &precision, &n) != 1)
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 {
LOG(LOGS_WARN, LOGF_Configure, "Unknown refclock parameter %s at line %d", cmd, line_number);
break;
@ -534,6 +542,7 @@ parse_refclock(const char *line)
refclock_sources[i].offset = offset;
refclock_sources[i].delay = delay;
refclock_sources[i].precision = precision;
refclock_sources[i].sel_option = sel_option;
refclock_sources[i].ref_id = 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;
/* 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_usec = 0;

View file

@ -236,7 +236,7 @@ RCL_AddRefclock(RefclockParameters *params)
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
LOG(LOGS_INFO, LOGF_Refclock, "refclock added poll=%d dpoll=%d filter=%d",

View file

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

View file

@ -100,6 +100,9 @@ struct SRC_Instance_Record {
/* Type of the source */
SRC_Type type;
/* Options used when selecting sources */
SRC_SelectOption sel_option;
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
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;
@ -196,6 +199,7 @@ SRC_Instance SRC_CreateNewInstance(unsigned long ref_id, SRC_Type type, IPAddr *
result->reachable = 0;
result->status = SRC_BAD_STATS;
result->type = type;
result->sel_option = sel_option;
n_sources++;
@ -414,7 +418,7 @@ SRC_SelectSource(unsigned long match_addr)
n_reachable_sources = 0;
for (i=0; i<n_sources; i++) {
if (sources[i]->reachable) {
if (sources[i]->reachable && sources[i]->sel_option != SRC_SelectNoselect) {
++n_reachable_sources;
@ -638,11 +642,39 @@ SRC_SelectSource(unsigned long match_addr)
}
n_sel_sources = j;
/* Now find minimum stratum. If none are left now,
tough. RFC1305 is not so harsh on pruning sources due to
excess variance, which prevents this from happening */
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,
tough. RFC1305 is not so harsh on pruning sources due to
excess variance, which prevents this from happening */
index = sel_sources[0];
min_stratum = sources[index]->sel_info.stratum;
for (i=1; i<n_sel_sources; i++) {
@ -709,23 +741,6 @@ SRC_SelectSource(unsigned long match_addr)
total_root_dispersion = (src_accrued_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) ||
(match_addr == sources[selected_source_index]->ref_id)) {

View file

@ -55,10 +55,17 @@ typedef enum {
SRC_REFCLOCK /* Rerefence clock */
} 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
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.
This may cause the current reference source to be reselected, if this

View file

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