timemaster: allow arbitrary options in server/refclock directives.

Instead of trying to support all options of the server and refclock
directives in both NTP implementations, add an "ntp_options" option
which specifies a string that is added directly to the lines in the
chronyd/ntpd configuration file.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
master
Miroslav Lichvar 2016-07-14 13:43:46 +02:00 committed by Richard Cochran
parent 1e667ff7fb
commit ac77099493
2 changed files with 50 additions and 25 deletions

View File

@ -103,6 +103,12 @@ Enable or disable sending a burst of NTP packets on start to speed up the
initial synchronization. Possible values are 1 and 0. The default value is 0 initial synchronization. Possible values are 1 and 0. The default value is 0
(disabled). (disabled).
.TP
.B ntp_options
Specify extra options that should be added for this source to the \fBserver\fR
directive in the configuration file of the selected NTP implementation. No
extra options are added by default.
.SS [ptp_domain number] .SS [ptp_domain number]
The \fBptp_domain\fR section specifies a PTP domain that should be used as a The \fBptp_domain\fR section specifies a PTP domain that should be used as a
@ -142,6 +148,12 @@ assign weights for source combining. The default value is 1e\-4 (100
microseconds). With \fBntpd\fR, the \fBtos mindist\fR command can be used to microseconds). With \fBntpd\fR, the \fBtos mindist\fR command can be used to
set a limit with similar purpose globally for all time sources. set a limit with similar purpose globally for all time sources.
.TP
.B ntp_options
Specify extra options that should be added for this source to the
\fBrefclock\fR or \fBserver\fR directives in the configuration file of the
selected NTP implementation. No extra options are added by default.
.TP .TP
.B ptp4l_option .B ptp4l_option
Specify an extra \fBptp4l\fR option specific to this PTP domain that should be Specify an extra \fBptp4l\fR option specific to this PTP domain that should be
@ -284,12 +296,14 @@ A more complex example using all \fBtimemaster\fR options would be:
minpoll 3 minpoll 3
maxpoll 4 maxpoll 4
iburst 1 iburst 1
ntp_options key 12
[ptp_domain 0] [ptp_domain 0]
interfaces eth0 eth1 interfaces eth0 eth1
ntp_poll 0 ntp_poll 0
phc2sys_poll \-2 phc2sys_poll \-2
delay 10e\-6 delay 10e\-6
ntp_options prefer
ptp4l_option clock_servo linreg ptp4l_option clock_servo linreg
ptp4l_option delay_mechanism P2P ptp4l_option delay_mechanism P2P

View File

@ -72,6 +72,7 @@ struct ntp_server {
int minpoll; int minpoll;
int maxpoll; int maxpoll;
int iburst; int iburst;
char *ntp_options;
}; };
struct ptp_domain { struct ptp_domain {
@ -81,6 +82,7 @@ struct ptp_domain {
double delay; double delay;
char **interfaces; char **interfaces;
char **ptp4l_settings; char **ptp4l_settings;
char *ntp_options;
}; };
struct source { struct source {
@ -223,10 +225,12 @@ static void source_destroy(struct source *source)
switch (source->type) { switch (source->type) {
case NTP_SERVER: case NTP_SERVER:
free(source->ntp.address); free(source->ntp.address);
free(source->ntp.ntp_options);
break; break;
case PTP_DOMAIN: case PTP_DOMAIN:
free_parray((void **)source->ptp.interfaces); free_parray((void **)source->ptp.interfaces);
free_parray((void **)source->ptp.ptp4l_settings); free_parray((void **)source->ptp.ptp4l_settings);
free(source->ptp.ntp_options);
break; break;
} }
free(source); free(source);
@ -235,7 +239,6 @@ static void source_destroy(struct source *source)
static struct source *source_ntp_parse(char *parameter, char **settings) static struct source *source_ntp_parse(char *parameter, char **settings)
{ {
char *name, *value; char *name, *value;
struct ntp_server ntp_server;
struct source *source; struct source *source;
int r = 0; int r = 0;
@ -244,35 +247,38 @@ static struct source *source_ntp_parse(char *parameter, char **settings)
return NULL; return NULL;
} }
ntp_server.address = parameter; source = xmalloc(sizeof(*source));
ntp_server.minpoll = DEFAULT_NTP_MINPOLL; source->type = NTP_SERVER;
ntp_server.maxpoll = DEFAULT_NTP_MAXPOLL; source->ntp.address = xstrdup(parameter);
ntp_server.iburst = 0; source->ntp.minpoll = DEFAULT_NTP_MINPOLL;
source->ntp.maxpoll = DEFAULT_NTP_MAXPOLL;
source->ntp.iburst = 0;
source->ntp.ntp_options = xstrdup("");
for (; *settings; settings++) { for (; *settings; settings++) {
parse_setting(*settings, &name, &value); parse_setting(*settings, &name, &value);
if (!strcasecmp(name, "minpoll")) { if (!strcasecmp(name, "minpoll")) {
r = parse_int(value, &ntp_server.minpoll); r = parse_int(value, &source->ntp.minpoll);
} else if (!strcasecmp(name, "maxpoll")) { } else if (!strcasecmp(name, "maxpoll")) {
r = parse_int(value, &ntp_server.maxpoll); r = parse_int(value, &source->ntp.maxpoll);
} else if (!strcasecmp(name, "iburst")) { } else if (!strcasecmp(name, "iburst")) {
r = parse_bool(value, &ntp_server.iburst); r = parse_bool(value, &source->ntp.iburst);
} else if (!strcasecmp(name, "ntp_options")) {
replace_string(value, &source->ntp.ntp_options);
} else { } else {
pr_err("unknown ntp_server setting %s", name); pr_err("unknown ntp_server setting %s", name);
return NULL; goto failed;
} }
if (r) { if (r) {
pr_err("invalid value %s for %s", value, name); pr_err("invalid value %s for %s", value, name);
return NULL; goto failed;
} }
} }
source = xmalloc(sizeof(*source));
source->type = NTP_SERVER;
source->ntp = ntp_server;
source->ntp.address = xstrdup(source->ntp.address);
return source; return source;
failed:
source_destroy(source);
return NULL;
} }
static struct source *source_ptp_parse(char *parameter, char **settings) static struct source *source_ptp_parse(char *parameter, char **settings)
@ -288,6 +294,7 @@ static struct source *source_ptp_parse(char *parameter, char **settings)
source->ptp.phc2sys_poll = DEFAULT_PTP_PHC2SYS_POLL; source->ptp.phc2sys_poll = DEFAULT_PTP_PHC2SYS_POLL;
source->ptp.interfaces = (char **)parray_new(); source->ptp.interfaces = (char **)parray_new();
source->ptp.ptp4l_settings = (char **)parray_new(); source->ptp.ptp4l_settings = (char **)parray_new();
source->ptp.ntp_options = xstrdup("");
if (parse_int(parameter, &source->ptp.domain)) { if (parse_int(parameter, &source->ptp.domain)) {
pr_err("invalid ptp_domain number %s", parameter); pr_err("invalid ptp_domain number %s", parameter);
@ -305,6 +312,8 @@ static struct source *source_ptp_parse(char *parameter, char **settings)
} else if (!strcasecmp(name, "ptp4l_option")) { } else if (!strcasecmp(name, "ptp4l_option")) {
parray_append((void ***)&source->ptp.ptp4l_settings, parray_append((void ***)&source->ptp.ptp4l_settings,
xstrdup(value)); xstrdup(value));
} else if (!strcasecmp(name, "ntp_options")) {
replace_string(value, &source->ptp.ntp_options);
} else if (!strcasecmp(name, "interfaces")) { } else if (!strcasecmp(name, "interfaces")) {
parse_words(value, &source->ptp.interfaces); parse_words(value, &source->ptp.interfaces);
} else { } else {
@ -609,8 +618,8 @@ static char *get_refid(char *prefix, unsigned int number)
}; };
static void add_shm_source(int shm_segment, int poll, int dpoll, double delay, static void add_shm_source(int shm_segment, int poll, int dpoll, double delay,
char *prefix, struct timemaster_config *config, char *ntp_options, char *prefix,
char **ntp_config) struct timemaster_config *config, char **ntp_config)
{ {
char *refid = get_refid(prefix, shm_segment); char *refid = get_refid(prefix, shm_segment);
@ -618,15 +627,17 @@ static void add_shm_source(int shm_segment, int poll, int dpoll, double delay,
case CHRONYD: case CHRONYD:
string_appendf(ntp_config, string_appendf(ntp_config,
"refclock SHM %d poll %d dpoll %d " "refclock SHM %d poll %d dpoll %d "
"refid %s precision 1.0e-9 delay %.1e\n", "refid %s precision 1.0e-9 delay %.1e %s\n",
shm_segment, poll, dpoll, refid, delay); shm_segment, poll, dpoll, refid, delay,
ntp_options);
break; break;
case NTPD: case NTPD:
string_appendf(ntp_config, string_appendf(ntp_config,
"server 127.127.28.%d minpoll %d maxpoll %d " "server 127.127.28.%d minpoll %d maxpoll %d "
"mode 1\n" "mode 1 %s\n"
"fudge 127.127.28.%d refid %s\n", "fudge 127.127.28.%d refid %s\n",
shm_segment, poll, poll, shm_segment, refid); shm_segment, poll, poll, ntp_options,
shm_segment, refid);
break; break;
} }
@ -637,9 +648,9 @@ static int add_ntp_source(struct ntp_server *source, char **ntp_config)
{ {
pr_debug("adding NTP server %s", source->address); pr_debug("adding NTP server %s", source->address);
string_appendf(ntp_config, "server %s minpoll %d maxpoll %d%s\n", string_appendf(ntp_config, "server %s minpoll %d maxpoll %d %s %s\n",
source->address, source->minpoll, source->maxpoll, source->address, source->minpoll, source->maxpoll,
source->iburst ? " iburst" : ""); source->iburst ? "iburst" : "", source->ntp_options);
return 0; return 0;
} }
@ -766,8 +777,8 @@ static int add_ptp_source(struct ptp_domain *source,
parray_append((void ***)&script->configs, config_file); parray_append((void ***)&script->configs, config_file);
add_shm_source(*shm_segment, source->ntp_poll, add_shm_source(*shm_segment, source->ntp_poll,
source->phc2sys_poll, source->delay, "PTP", source->phc2sys_poll, source->delay,
config, ntp_config); source->ntp_options, "PTP", config, ntp_config);
(*shm_segment)++; (*shm_segment)++;