From ba12da671fc3161a8b6a4b769ce4e66947ab0e3c Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Sep 2013 15:24:28 +0200 Subject: [PATCH 1/6] Make the CFLAGS more robust. This patch introduces a shell script to figure out the proper definitions for the HAVE_CLOCK_ADJTIME and HAVE_ONESTEP_SYNC macros, as well as the include path. The intent is to "do the right thing" for three different user scenarios, namely cross compiling, compiling against a custom kernel, and using a plain old disto kernel. Signed-off-by: Richard Cochran --- incdefs.sh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ makefile | 14 +++-------- 2 files changed, 74 insertions(+), 11 deletions(-) create mode 100755 incdefs.sh diff --git a/incdefs.sh b/incdefs.sh new file mode 100755 index 0000000..cf00eaf --- /dev/null +++ b/incdefs.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Discover the CFLAGS to use during compilation. +# +# Copyright (C) 2013 Richard Cochran +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# +# Look for the clock_adjtime functional prototype in the C library. +# +user_flags() +{ + dirs=$(echo "" | ${CROSS_COMPILE}cpp -Wp,-v 2>&1 >/dev/null | grep ^" /") + for d in $dirs; do + files=$(find $d -type f -name time.h) + for f in $files; do + if grep -q clock_adjtime $f; then + printf " -D_GNU_SOURCE -DHAVE_CLOCK_ADJTIME" + return + fi + done + done +} + +# +# Find the most appropriate kernel header for the SIOCSHWTSTAMP ioctl. +# +# 1. custom kernel or cross build using KBUILD_OUTPUT +# 2. sanitized headers installed under /lib/modules/`uname -r`/build +# 3. normal build using standard system headers +# +kernel_flags() +{ + prefix="" + tstamp=/usr/include/linux/net_tstamp.h + + if [ "x$KBUILD_OUTPUT" != "x" ]; then + # With KBUILD_OUTPUT set, we are building against + # either a custom kernel or a cross compiled kernel. + build=${KBUILD_OUTPUT} + else + # If the currently running kernel is a custom build + # with the headers installed, then we should use them. + build=/lib/modules/`uname -r`/build + fi + + if [ -f ${build}${tstamp} ]; then + prefix=${build} + printf " -I%s/usr/include" $prefix + fi + + if grep -q HWTSTAMP_TX_ONESTEP_SYNC ${prefix}${tstamp}; then + printf " -DHAVE_ONESTEP_SYNC" + fi +} + +flags="$(user_flags)$(kernel_flags)" +echo "$flags" diff --git a/makefile b/makefile index d79a1df..2eaeca5 100644 --- a/makefile +++ b/makefile @@ -15,21 +15,12 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -KBUILD_OUTPUT ?= /lib/modules/$(shell uname -r)/build - -FEAT_CFLAGS := -ifneq ($(shell grep --no-messages clock_adjtime /usr/include/bits/time.h),) -FEAT_CFLAGS += -D_GNU_SOURCE -DHAVE_CLOCK_ADJTIME -endif -ifneq ($(shell grep --no-messages HWTSTAMP_TX_ONESTEP_SYNC $(KBUILD_OUTPUT)/usr/include/linux/net_tstamp.h),) -FEAT_CFLAGS += -DHAVE_ONESTEP_SYNC -endif +KBUILD_OUTPUT = DEBUG = CC = $(CROSS_COMPILE)gcc -INC = -I$(KBUILD_OUTPUT)/usr/include VER = -DVER=$(version) -CFLAGS = -Wall $(VER) $(INC) $(DEBUG) $(FEAT_CFLAGS) $(EXTRA_CFLAGS) +CFLAGS = -Wall $(VER) $(incdefs) $(DEBUG) $(EXTRA_CFLAGS) LDLIBS = -lm -lrt $(EXTRA_LDFLAGS) PRG = ptp4l pmc phc2sys hwstamp_ctl OBJ = bmc.o clock.o clockadj.o config.o fault.o fsm.o ptp4l.o mave.o \ @@ -40,6 +31,7 @@ OBJECTS = $(OBJ) hwstamp_ctl.o phc2sys.o pmc.o pmc_common.o sysoff.o SRC = $(OBJECTS:.o=.c) DEPEND = $(OBJECTS:.o=.d) srcdir := $(dir $(lastword $(MAKEFILE_LIST))) +incdefs := $(shell $(srcdir)/incdefs.sh) version := $(shell $(srcdir)/version.sh $(srcdir)) VPATH = $(srcdir) From e5ddfd491e6a444cfd5404ddfe251b17ce676230 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Sep 2013 20:15:45 +0200 Subject: [PATCH 2/6] Convert the hard coded UDS server path into a variable. This patch changes the macro for the server socket address into a global variable so that a subsequent patch can provide a way to set the variable. Signed-off-by: Richard Cochran --- clock.c | 2 +- uds.c | 6 ++++-- uds.h | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clock.c b/clock.c index cf65fff..419a6b7 100644 --- a/clock.c +++ b/clock.c @@ -576,7 +576,7 @@ struct clock *clock_create(int phc_index, struct interface *iface, int count, struct interface udsif; memset(&udsif, 0, sizeof(udsif)); - snprintf(udsif.name, sizeof(udsif.name), UDS_PATH); + snprintf(udsif.name, sizeof(udsif.name), "%s", uds_path); udsif.transport = TRANS_UDS; srandom(time(NULL)); diff --git a/uds.c b/uds.c index 0d114c3..1dbfd6c 100644 --- a/uds.c +++ b/uds.c @@ -30,6 +30,8 @@ #include "transport_private.h" #include "uds.h" +char uds_path[MAX_IFNAME_SIZE + 1] = "/var/run/ptp4l"; + #define UDS_FILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) /*0660*/ struct uds { @@ -58,7 +60,7 @@ static int uds_open(struct transport *t, char *name, struct fdarray *fda, } memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_LOCAL; - strcpy(sa.sun_path, name); + strncpy(sa.sun_path, name, sizeof(sa.sun_path) - 1); unlink(name); @@ -72,7 +74,7 @@ static int uds_open(struct transport *t, char *name, struct fdarray *fda, /* For client use, pre load the server path. */ memset(&sa, 0, sizeof(sa)); sa.sun_family = AF_LOCAL; - strcpy(sa.sun_path, UDS_PATH); + strncpy(sa.sun_path, uds_path, sizeof(sa.sun_path) - 1); uds->sa = sa; uds->len = sizeof(sa); diff --git a/uds.h b/uds.h index 24effa8..d7f6626 100644 --- a/uds.h +++ b/uds.h @@ -20,13 +20,14 @@ #ifndef HAVE_UDS_H #define HAVE_UDS_H +#include "config.h" #include "fd.h" #include "transport.h" /** * Address of the server. */ -#define UDS_PATH "/var/run/ptp4l" +extern char uds_path[MAX_IFNAME_SIZE + 1]; /** * Allocate an instance of a UDS transport. From 9fe2ffd2efbbc35dcb185af6a0f21be9261da0e4 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Sep 2013 20:57:00 +0200 Subject: [PATCH 3/6] Introduce a configuration file option for the server's UDS address. Signed-off-by: Richard Cochran --- config.c | 5 +++++ config.h | 1 + default.cfg | 1 + gPTP.cfg | 1 + ptp4l.8 | 6 +++++- ptp4l.c | 2 ++ 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/config.c b/config.c index 8cae57f..fe4c0f3 100644 --- a/config.c +++ b/config.c @@ -393,6 +393,11 @@ static enum parser_result parse_global_setting(const char *option, return r; *cfg->udp6_scope = uval; + } else if (!strcmp(option, "uds_address")) { + if (strlen(value) > MAX_IFNAME_SIZE) + return OUT_OF_RANGE; + strncpy(cfg->uds_address, value, MAX_IFNAME_SIZE); + } else if (!strcmp(option, "logging_level")) { r = get_ranged_int(value, &val, PRINT_LEVEL_MIN, PRINT_LEVEL_MAX); diff --git a/config.h b/config.h index 94704a4..4a2cbaa 100644 --- a/config.h +++ b/config.h @@ -89,6 +89,7 @@ struct config { unsigned char *ptp_dst_mac; unsigned char *p2p_dst_mac; unsigned char *udp6_scope; + char *uds_address; int print_level; int use_syslog; diff --git a/default.cfg b/default.cfg index 72665a6..0a42a92 100644 --- a/default.cfg +++ b/default.cfg @@ -59,6 +59,7 @@ transportSpecific 0x0 ptp_dst_mac 01:1B:19:00:00:00 p2p_dst_mac 01:80:C2:00:00:0E udp6_scope 0x0E +uds_address /var/run/ptp4l # # Default interface options # diff --git a/gPTP.cfg b/gPTP.cfg index 30719b6..9c26ec5 100644 --- a/gPTP.cfg +++ b/gPTP.cfg @@ -57,6 +57,7 @@ clock_servo pi transportSpecific 0x1 ptp_dst_mac 01:80:C2:00:00:0E p2p_dst_mac 01:80:C2:00:00:0E +uds_address /var/run/ptp4l # # Default interface options # diff --git a/ptp4l.8 b/ptp4l.8 index 493626d..221d7d1 100644 --- a/ptp4l.8 +++ b/ptp4l.8 @@ -1,4 +1,4 @@ -.TH PTP4l 8 "July 2013" "linuxptp" +.TH PTP4l 8 "October 2013" "linuxptp" .SH NAME ptp4l \- PTP Boundary/Ordinary Clock @@ -354,6 +354,10 @@ will be used as the second byte of the primary address. This option is only relevant with IPv6 transport. See RFC 4291. The default is 0x0E for the global scope. .TP +.B uds_address +Specifies the address of the UNIX domain socket for receiving local +management messages. The default is /var/run/ptp4l. +.TP .B logging_level The maximum logging level of messages which should be printed. The default is 6 (LOG_INFO). diff --git a/ptp4l.c b/ptp4l.c index b0d1c9c..dac303a 100644 --- a/ptp4l.c +++ b/ptp4l.c @@ -32,6 +32,7 @@ #include "sk.h" #include "transport.h" #include "udp6.h" +#include "uds.h" #include "util.h" #include "version.h" @@ -111,6 +112,7 @@ static struct config cfg_settings = { .ptp_dst_mac = ptp_dst_mac, .p2p_dst_mac = p2p_dst_mac, .udp6_scope = &udp6_scope, + .uds_address = uds_path, .print_level = LOG_INFO, .use_syslog = 1, From 4f6f1e1cbafa3b42cec3a70eda8af4dce0ecec68 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 29 Sep 2013 20:58:17 +0200 Subject: [PATCH 4/6] pmc: add a command line option to select the server's UDS address. Signed-off-by: Richard Cochran --- pmc.8 | 8 +++++++- pmc.c | 12 +++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pmc.8 b/pmc.8 index d91c657..759ed84 100644 --- a/pmc.8 +++ b/pmc.8 @@ -1,4 +1,4 @@ -.TH PMC 8 "July 2013" "linuxptp" +.TH PMC 8 "October 2013" "linuxptp" .SH NAME pmc \- PTP management client @@ -19,6 +19,8 @@ pmc \- PTP management client ] [ .BI \-i " interface" ] [ +.BI \-s " uds-address" +] [ .BI \-t " transport-specific-field" ] [ .B \-v @@ -69,6 +71,10 @@ Specify the domain number in sent messages. The default is 0. Specify the network interface. The default is /var/run/pmc for the Unix Domain Socket transport and eth0 for the other transports. .TP +.BI \-s " uds-address" +Specifies the address of the server's UNIX domain socket. +The default is /var/run/ptp4l. +.TP .BI \-t " transport-specific-field" Specify the transport specific field in sent messages as a hexadecimal number. The default is 0x0. diff --git a/pmc.c b/pmc.c index 3a6d697..c9851cd 100644 --- a/pmc.c +++ b/pmc.c @@ -31,6 +31,7 @@ #include "pmc_common.h" #include "print.h" #include "tlv.h" +#include "uds.h" #include "util.h" #include "version.h" @@ -676,6 +677,7 @@ static void usage(char *progname) " -h prints this message and exits\n" " -i [dev] interface device to use, default 'eth0'\n" " for network and '/var/run/pmc' for UDS.\n" + " -s [path] server address for UDS, default '/var/run/ptp4l'.\n" " -t [hex] transport specific field, default 0x0\n" " -v prints the software version and exits\n" " -z send zero length TLV values with the GET actions\n" @@ -697,7 +699,7 @@ int main(int argc, char *argv[]) /* Process the command line arguments. */ progname = strrchr(argv[0], '/'); progname = progname ? 1+progname : argv[0]; - while (EOF != (c = getopt(argc, argv, "246u""b:d:hi:t:vz"))) { + while (EOF != (c = getopt(argc, argv, "246u""b:d:hi:s:t:vz"))) { switch (c) { case '2': transport_type = TRANS_IEEE_802_3; @@ -720,6 +722,14 @@ int main(int argc, char *argv[]) case 'i': iface_name = optarg; break; + case 's': + if (strlen(optarg) > MAX_IFNAME_SIZE) { + fprintf(stderr, "path %s too long, max is %d\n", + optarg, MAX_IFNAME_SIZE); + return -1; + } + strncpy(uds_path, optarg, MAX_IFNAME_SIZE); + break; case 't': if (1 == sscanf(optarg, "%x", &c)) transport_specific = c << 4; From 67b03860425bfb89d9182da6cf6e39af863dd6ae Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Sun, 6 Oct 2013 19:20:56 +0200 Subject: [PATCH 5/6] Extend the interface name length to allow any UDS address. This patch increases the maximum length of an interface name to accommodate a UNIX domain socket address of 108 bytes. (This value is hard coded in the glibc headers, and so we cannot use the Linux kernel header macro, UNIX_PATH_MAX.) Signed-off-by: Richard Cochran --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index 4a2cbaa..40d8978 100644 --- a/config.h +++ b/config.h @@ -27,7 +27,7 @@ #include "sk.h" #define MAX_PORTS 8 -#define MAX_IFNAME_SIZE 16 +#define MAX_IFNAME_SIZE 108 /* = UNIX_PATH_MAX */ /** Defines a network interface, with PTP options. */ struct interface { From 289699e3c9eeac98b9961fb0bda2d243214cf577 Mon Sep 17 00:00:00 2001 From: Richard Cochran Date: Tue, 8 Oct 2013 20:08:05 +0200 Subject: [PATCH 6/6] pmc: bring the man page more up to date. Signed-off-by: Richard Cochran --- pmc.8 | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/pmc.8 b/pmc.8 index 759ed84..988581f 100644 --- a/pmc.8 +++ b/pmc.8 @@ -43,6 +43,11 @@ updates the specified information and .BR COMMAND ) initiates the specified event. +By default the management commands are addressed to all ports. The +.B TARGET +command can be used to select a particular clock and port for the +subsequent messages. + Command .B help can be used to get a list of supported actions and management IDs. @@ -94,12 +99,52 @@ length TLV values instead. .SH MANAGEMENT IDS +.TP +.B ANNOUNCE_RECEIPT_TIMEOUT +.TP +.B CLOCK_ACCURACY +.TP +.B CLOCK_DESCRIPTION .TP .B CURRENT_DATA_SET .TP +.B DEFAULT_DATA_SET +.TP +.B DELAY_MECHANISM +.TP +.B DOMAIN +.TP +.B GRANDMASTER_SETTINGS_NP +.TP +.B LOG_ANNOUNCE_INTERVAL +.TP +.B LOG_MIN_PDELAY_REQ_INTERVAL +.TP +.B LOG_SYNC_INTERVAL +.TP +.B NULL_MANAGEMENT +.TP +.B PARENT_DATA_SET +.TP +.B PORT_DATA_SET +.TP +.B PRIORITY1 +.TP +.B PRIORITY2 +.TP +.B SLAVE_ONLY +.TP +.B TIMESCALE_PROPERTIES +.TP +.B TIME_PROPERTIES_DATA_SET +.TP .B TIME_STATUS_NP .TP -.B NULL_MANAGEMENT +.B TRACEABILITY_PROPERTIES +.TP +.B USER_DESCRIPTION +.TP +.B VERSION_NUMBER .SH SEE ALSO .BR ptp4l (8)