commit 4e8dbd84925d36f1193a7339a542677d884d3ba1
Author: Richard Cochran <richardcochran@gmail.com>
Date: Tue Dec 6 19:40:36 2016 +0100
ptp4l: Accept any configuration option as a command line argument.
This patch provides a way to use the entire table of configuration options
as "long" command line switches.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
diff --git a/config.c b/config.c
index 5da5ecc..384b437 100644
--- a/config.c
+++ b/config.c
@@ -329,6 +329,7 @@ static enum parser_result parse_section_line(char *s, enum config_section *secti
}
static enum parser_result parse_item(struct config *cfg,
+ int commandline,
const char *section,
const char *option,
const char *value)
@@ -387,7 +388,7 @@ static enum parser_result parse_item(struct config *cfg,
return NOT_PARSED;
}
}
- } else if (cgi->flags & CFG_ITEM_LOCKED) {
+ } else if (!commandline && cgi->flags & CFG_ITEM_LOCKED) {
/* This global option was set on the command line. */
return PARSED_OK;
} else {
@@ -415,6 +416,10 @@ static enum parser_result parse_item(struct config *cfg,
dst->flags |= CFG_ITEM_DYNSTR;
break;
}
+
+ if (commandline) {
+ dst->flags &= CFG_ITEM_LOCKED;
+ }
return PARSED_OK;
}
@@ -490,6 +495,25 @@ static void check_deprecated_options(const char **option)
}
}
+static struct option *config_alloc_longopts(struct config *cfg)
+{
+ struct config_item *ci;
+ struct option *opts;
+ int i;
+
+ opts = calloc(1, (1 + N_CONFIG_ITEMS) * sizeof(*opts));
+ if (!opts) {
+ return NULL;
+ }
+ for (i = 0; i < N_CONFIG_ITEMS; i++) {
+ ci = &config_tab[i];
+ opts[i].name = ci->label;
+ opts[i].has_arg = required_argument;
+ }
+
+ return opts;
+}
+
int config_read(char *name, struct config *cfg)
{
enum config_section current_section = UNKNOWN_SECTION;
@@ -554,7 +578,7 @@ int config_read(char *name, struct config *cfg)
check_deprecated_options(&option);
- parser_res = parse_item(cfg, current_section == GLOBAL_SECTION ?
+ parser_res = parse_item(cfg, 0, current_section == GLOBAL_SECTION ?
NULL : current_port->name, option, value);
switch (parser_res) {
@@ -627,8 +651,15 @@ struct config *config_create(void)
}
STAILQ_INIT(&cfg->interfaces);
+ cfg->opts = config_alloc_longopts(cfg);
+ if (!cfg->opts) {
+ free(cfg);
+ return NULL;
+ }
+
cfg->htab = hash_create();
if (!cfg->htab) {
+ free(cfg->opts);
free(cfg);
return NULL;
}
@@ -657,6 +688,7 @@ struct config *config_create(void)
return cfg;
fail:
hash_destroy(cfg->htab, NULL);
+ free(cfg->opts);
free(cfg);
return NULL;
}
@@ -670,6 +702,7 @@ void config_destroy(struct config *cfg)
free(iface);
}
hash_destroy(cfg->htab, config_item_free);
+ free(cfg->opts);
free(cfg);
}
@@ -720,6 +753,33 @@ char *config_get_string(struct config *cfg, const char *section,
return ci->val.s;
}
+int config_parse_option(struct config *cfg, const char *opt, const char *val)
+{
+ enum parser_result result;
+
+ result = parse_item(cfg, 1, NULL, opt, val);
+
+ switch (result) {
+ case PARSED_OK:
+ return 0;
+ case NOT_PARSED:
+ fprintf(stderr, "unknown option %s\n", opt);
+ break;
+ case BAD_VALUE:
+ fprintf(stderr, "%s is a bad value for option %s\n", val, opt);
+ break;
+ case MALFORMED:
+ fprintf(stderr, "%s is a malformed value for option %s\n",
+ val, opt);
+ break;
+ case OUT_OF_RANGE:
+ fprintf(stderr, "%s is an out of range value for option %s\n",
+ val, opt);
+ break;
+ }
+ return -1;
+}
+
int config_set_double(struct config *cfg, const char *option, double val)
{
struct config_item *ci = config_find_item(cfg, NULL, option);
diff --git a/config.h b/config.h
index b02bde6..1cc7051 100644
--- a/config.h
+++ b/config.h
@@ -20,6 +20,7 @@
#ifndef HAVE_CONFIG_H
#define HAVE_CONFIG_H
+#include <getopt.h>
#include <sys/queue.h>
#include "ds.h"
@@ -43,6 +44,9 @@ struct config {
STAILQ_HEAD(interfaces_head, interface) interfaces;
int n_interfaces;
+ /* for parsing command line options */
+ struct option *opts;
+
/* hash of all non-legacy items */
struct hash *htab;
};
@@ -64,6 +68,13 @@ int config_get_int(struct config *cfg, const char *section,
char *config_get_string(struct config *cfg, const char *section,
const char *option);
+static inline struct option *config_long_options(struct config *cfg)
+{
+ return cfg->opts;
+}
+
+int config_parse_option(struct config *cfg, const char *opt, const char *val);
+
int config_set_double(struct config *cfg, const char *option, double val);
int config_set_section_int(struct config *cfg, const char *section,
diff --git a/ptp4l.c b/ptp4l.c
index a87e7e6..e90fcb2 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -73,8 +73,9 @@ static void usage(char *progname)
int main(int argc, char *argv[])
{
char *config = NULL, *req_phc = NULL, *progname;
- int c, err = -1, print_level;
+ int c, err = -1, index, print_level;
struct clock *clock = NULL;
+ struct option *opts;
struct config *cfg;
if (handle_term_signals())
@@ -84,12 +85,18 @@ int main(int argc, char *argv[])
if (!cfg) {
return -1;
}
+ opts = config_long_options(cfg);
/* Process the command line arguments. */
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
- while (EOF != (c = getopt(argc, argv, "AEP246HSLf:i:p:sl:mqvh"))) {
+ while (EOF != (c = getopt_long(argc, argv, "AEP246HSLf:i:p:sl:mqvh",
+ opts, &index))) {
switch (c) {
+ case 0:
+ if (config_parse_option(cfg, opts[index].name, optarg))
+ goto out;
+ break;
case 'A':
if (config_set_int(cfg, "delay_mechanism", DM_AUTO))
goto out;
commit e658982624bfd5cd998066fdf35b93cdcf8797ca
Author: Richard Cochran <rcochran@linutronix.de>
Date: Tue Dec 13 19:55:39 2016 +0100
config: Fix bitwise copy-and-pasto for command line items.
The recent change allowing every configuration option to appear on the
command line wrongly used bitwise AND to set a flag. This patch fixes
the bug by using the proper bitwise OR idiom.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
Reported-by: Miroslav Lichvar <mlichvar@redhat.com>
Fixes: 4e8dbd8 ("ptp4l: Accept any configuration option as a command line argument.")
diff --git a/config.c b/config.c
index 384b437..b19f3ad 100644
--- a/config.c
+++ b/config.c
@@ -418,7 +418,7 @@ static enum parser_result parse_item(struct config *cfg,
}
if (commandline) {
- dst->flags &= CFG_ITEM_LOCKED;
+ dst->flags |= CFG_ITEM_LOCKED;
}
return PARSED_OK;
}
commit 4e966536c6253d73e1a3202e8b562ab0f518e33b
Author: Richard Cochran <rcochran@linutronix.de>
Date: Tue Dec 13 20:49:22 2016 +0100
ptp4l: Document the "long" command line options in the man page.
Signed-off-by: Richard Cochran <rcochran@linutronix.de>
diff --git a/ptp4l.8 b/ptp4l.8
index 63e9abd..f53fc6e 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -1,4 +1,4 @@
-.TH PTP4l 8 "July 2016" "linuxptp"
+.TH PTP4l 8 "December 2016" "linuxptp"
.SH NAME
ptp4l - PTP Boundary/Ordinary Clock
@@ -15,6 +15,8 @@ ptp4l - PTP Boundary/Ordinary Clock
]
[
.BI \-i " interface"
+] [
+.I long-options
]
.I .\|.\|.
@@ -94,6 +96,19 @@ Prints the software version and exits.
.BI \-h
Display a help message.
+.SH LONG OPTIONS
+
+Each and every configuration file option (see below) may also appear
+as a "long" style command line argument. For example, the slaveOnly
+option may be set using either of these two forms.
+
+.RS
+\f(CW\-\-slaveOnly 1 \-\-slaveOnly=1\fP
+.RE
+
+Option values given on the command line override values in the global
+section of the configuration file.
+
.SH CONFIGURATION FILE
The configuration file is divided into sections. Each section starts with a
commit 0f6c6972c791813e0b9618e9158da3951a099737
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Jan 17 14:17:39 2017 +0100
Add options to tag ptp4l and phc2sys log messages.
When running multiple instances of ptp4l or phc2sys, it's difficult to
tell which log message belongs to which instance. Add new options to
ptp4l and phc2sys which can specify a tag for all messages printed to
the standard output or system log, so messages from different instances
can have different tags.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/config.c b/config.c
index 7bb949d..e6fe676 100644
--- a/config.c
+++ b/config.c
@@ -199,6 +199,7 @@ struct config_item config_tab[] = {
PORT_ITEM_INT("logMinPdelayReqInterval", 0, INT8_MIN, INT8_MAX),
PORT_ITEM_INT("logSyncInterval", 0, INT8_MIN, INT8_MAX),
GLOB_ITEM_INT("logging_level", LOG_INFO, PRINT_LEVEL_MIN, PRINT_LEVEL_MAX),
+ GLOB_ITEM_STR("message_tag", NULL),
GLOB_ITEM_STR("manufacturerIdentity", "00:00:00"),
GLOB_ITEM_INT("max_frequency", 900000000, 0, INT_MAX),
PORT_ITEM_INT("min_neighbor_prop_delay", -20000000, INT_MIN, -1),
diff --git a/phc2sys.8 b/phc2sys.8
index 22d02c2..2559c74 100644
--- a/phc2sys.8
+++ b/phc2sys.8
@@ -206,6 +206,10 @@ The default is /var/run/ptp4l.
Set the maximum syslog level of messages which should be printed or sent to
the system logger. The default is 6 (LOG_INFO).
.TP
+.BI \-t " message-tag"
+Specify the tag which is added to all messages printed to the standard output
+or system log. The default is an empty string.
+.TP
.B \-m
Print messages to the standard output.
.TP
diff --git a/phc2sys.c b/phc2sys.c
index 35cf6fa..aa4186b 100644
--- a/phc2sys.c
+++ b/phc2sys.c
@@ -1209,6 +1209,7 @@ static void usage(char *progname)
" -x apply leap seconds by servo instead of kernel\n"
" -z [path] server address for UDS (/var/run/ptp4l)\n"
" -l [num] set the logging level to 'num' (6)\n"
+ " -t [tag] add tag to log messages\n"
" -m print messages to stdout\n"
" -q do not print messages to the syslog\n"
" -v prints the software version and exits\n"
@@ -1219,7 +1220,7 @@ static void usage(char *progname)
int main(int argc, char *argv[])
{
- char *progname;
+ char *progname, *message_tag = NULL;
char *src_name = NULL, *dst_name = NULL;
struct clock *src, *dst;
struct config *cfg;
@@ -1251,7 +1252,7 @@ int main(int argc, char *argv[])
progname = strrchr(argv[0], '/');
progname = progname ? 1+progname : argv[0];
while (EOF != (c = getopt(argc, argv,
- "arc:d:s:E:P:I:S:F:R:N:O:L:M:i:u:wn:xz:l:mqvh"))) {
+ "arc:d:s:E:P:I:S:F:R:N:O:L:M:i:u:wn:xz:l:t:mqvh"))) {
switch (c) {
case 'a':
autocfg = 1;
@@ -1363,6 +1364,9 @@ int main(int argc, char *argv[])
PRINT_LEVEL_MIN, PRINT_LEVEL_MAX))
goto end;
break;
+ case 't':
+ message_tag = optarg;
+ break;
case 'm':
verbose = 1;
break;
@@ -1405,6 +1409,7 @@ int main(int argc, char *argv[])
}
print_set_progname(progname);
+ print_set_tag(message_tag);
print_set_verbose(verbose);
print_set_syslog(use_syslog);
print_set_level(print_level);
diff --git a/print.c b/print.c
index a82d0e7..6c48e1e 100644
--- a/print.c
+++ b/print.c
@@ -28,12 +28,18 @@ static int verbose = 0;
static int print_level = LOG_INFO;
static int use_syslog = 1;
static const char *progname;
+static const char *message_tag;
void print_set_progname(const char *name)
{
progname = name;
}
+void print_set_tag(const char *tag)
+{
+ message_tag = tag;
+}
+
void print_set_syslog(int value)
{
use_syslog = value ? 1 : 0;
@@ -67,13 +73,17 @@ void print(int level, char const *format, ...)
if (verbose) {
f = level >= LOG_NOTICE ? stdout : stderr;
- fprintf(f, "%s[%ld.%03ld]: %s\n",
+ fprintf(f, "%s[%ld.%03ld]: %s%s%s\n",
progname ? progname : "",
- ts.tv_sec, ts.tv_nsec / 1000000, buf);
+ ts.tv_sec, ts.tv_nsec / 1000000,
+ message_tag ? message_tag : "", message_tag ? " " : "",
+ buf);
fflush(f);
}
if (use_syslog) {
- syslog(level, "[%ld.%03ld] %s",
- ts.tv_sec, ts.tv_nsec / 1000000, buf);
+ syslog(level, "[%ld.%03ld] %s%s%s",
+ ts.tv_sec, ts.tv_nsec / 1000000,
+ message_tag ? message_tag : "", message_tag ? " " : "",
+ buf);
}
}
diff --git a/print.h b/print.h
index e8f2c8e..1723d8a 100644
--- a/print.h
+++ b/print.h
@@ -33,6 +33,7 @@ __attribute__ ((format (printf, 2, 3)))
void print(int level, char const *format, ...);
void print_set_progname(const char *name);
+void print_set_tag(const char *tag);
void print_set_syslog(int value);
void print_set_level(int level);
void print_set_verbose(int value);
diff --git a/ptp4l.8 b/ptp4l.8
index 53d5f28..a724151 100644
--- a/ptp4l.8
+++ b/ptp4l.8
@@ -485,6 +485,12 @@ is 0.
The maximum logging level of messages which should be printed.
The default is 6 (LOG_INFO).
.TP
+.B message_tag
+The tag which is added to all messages printed to the standard output or system
+log.
+The default is an empty string (which cannot be set in the configuration file
+as the option requires an argument).
+.TP
.B verbose
Print messages to the standard output if enabled.
The default is 0 (disabled).
diff --git a/ptp4l.c b/ptp4l.c
index e90fcb2..f01ff6f 100644
--- a/ptp4l.c
+++ b/ptp4l.c
@@ -183,6 +183,7 @@ int main(int argc, char *argv[])
}
print_set_progname(progname);
+ print_set_tag(config_get_string(cfg, NULL, "message_tag"));
print_set_verbose(config_get_int(cfg, NULL, "verbose"));
print_set_syslog(config_get_int(cfg, NULL, "use_syslog"));
print_set_level(config_get_int(cfg, NULL, "logging_level"));
commit e54158195b1eadfdb6275646bc3dfb7611dba5b6
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Jan 17 14:17:40 2017 +0100
timemaster: tag ptp4l and phc2sys messages.
Use the new options of ptp4l and phc2sys to tag their log messages with
the PTP domain number and name(s) of interface(s) in the domain.
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
diff --git a/timemaster.c b/timemaster.c
index 66ac521..880b2ab 100644
--- a/timemaster.c
+++ b/timemaster.c
@@ -599,7 +599,8 @@ static char **get_ptp4l_command(struct program_config *config,
}
static char **get_phc2sys_command(struct program_config *config, int domain,
- int poll, int shm_segment, char *uds_path)
+ int poll, int shm_segment, char *uds_path,
+ char *message_tag)
{
char **command = (char **)parray_new();
@@ -610,6 +611,7 @@ static char **get_phc2sys_command(struct program_config *config, int domain,
xstrdup("-R"), string_newf("%.2f", poll > 0 ?
1.0 / (1 << poll) : 1 << -poll),
xstrdup("-z"), xstrdup(uds_path),
+ xstrdup("-t"), xstrdup(message_tag),
xstrdup("-n"), string_newf("%d", domain),
xstrdup("-E"), xstrdup("ntpshm"),
xstrdup("-M"), string_newf("%d", shm_segment), NULL);
@@ -671,7 +673,7 @@ static int add_ptp_source(struct ptp_domain *source,
struct script *script)
{
struct config_file *config_file;
- char **command, *uds_path, **interfaces;
+ char **command, *uds_path, **interfaces, *message_tag;
int i, j, num_interfaces, *phc, *phcs, hw_ts;
struct sk_ts_info ts_info;
@@ -749,6 +751,12 @@ static int add_ptp_source(struct ptp_domain *source,
uds_path = string_newf("%s/ptp4l.%d.socket",
config->rundir, *shm_segment);
+ message_tag = string_newf("[%d", source->domain);
+ for (j = 0; interfaces[j]; j++)
+ string_appendf(&message_tag, "%s%s", j ? "+" : ":",
+ interfaces[j]);
+ string_appendf(&message_tag, "]");
+
config_file = xmalloc(sizeof(*config_file));
config_file->path = string_newf("%s/ptp4l.%d.conf",
config->rundir, *shm_segment);
@@ -760,8 +768,9 @@ static int add_ptp_source(struct ptp_domain *source,
string_appendf(&config_file->content,
"slaveOnly 1\n"
"domainNumber %d\n"
- "uds_address %s\n",
- source->domain, uds_path);
+ "uds_address %s\n"
+ "message_tag %s\n",
+ source->domain, uds_path, message_tag);
if (phcs[i] >= 0) {
/* HW time stamping */
@@ -772,7 +781,8 @@ static int add_ptp_source(struct ptp_domain *source,
command = get_phc2sys_command(&config->phc2sys,
source->domain,
source->phc2sys_poll,
- *shm_segment, uds_path);
+ *shm_segment, uds_path,
+ message_tag);
parray_append((void ***)&script->commands, command);
} else {
/* SW time stamping */
@@ -793,6 +803,7 @@ static int add_ptp_source(struct ptp_domain *source,
(*shm_segment)++;
+ free(message_tag);
free(uds_path);
free(interfaces);
}