Add prefer and noselect options
This commit is contained in:
parent
061d497df0
commit
f924862e89
11 changed files with 91 additions and 28 deletions
10
chrony.texi
10
chrony.texi
|
@ -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
|
||||
|
|
3
client.c
3
client.c
|
@ -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);
|
||||
|
|
12
cmdmon.c
12
cmdmon.c
|
@ -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, ¶ms);
|
||||
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, ¶ms);
|
||||
switch (status) {
|
||||
case NSR_Success:
|
||||
|
|
|
@ -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
9
conf.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef struct {
|
|||
double offset;
|
||||
double delay;
|
||||
double precision;
|
||||
SRC_SelectOption sel_option;
|
||||
} RefclockParameters;
|
||||
|
||||
typedef struct RCL_Instance_Record *RCL_Instance;
|
||||
|
|
61
sources.c
61
sources.c
|
@ -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)) {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue