2 chronyd/chronyc - Programs for keeping computer clocks accurate.
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2003
6 * Copyright (C) John G. Hasler 2009
7 * Copyright (C) Miroslav Lichvar 2009-2012, 2014-2018
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 **********************************************************************
24 =======================================================================
26 This is the module specific to the Linux operating system.
34 #include <sys/utsname.h>
36 #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
37 #include <linux/ptp_clock.h>
41 #include <sys/prctl.h>
45 #include <linux/pps.h>
48 #include <linux/rtc.h>
50 #ifdef HAVE_LINUX_TIMESTAMPING
51 #include <linux/sockios.h>
56 #include <sys/prctl.h>
57 #include <sys/capability.h>
60 #include "sys_linux.h"
61 #include "sys_timex.h"
68 /* Frequency scale to convert from ppm to the timex freq */
69 #define FREQ_SCALE (double)(1 << 16)
71 /* Definitions used if missed in the system headers */
73 #define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
76 #define ADJ_NANO 0x2000 /* select nanosecond resolution */
79 /* This is the uncompensated system tick value */
80 static int nominal_tick
;
82 /* Current tick value */
83 static int current_delta_tick
;
85 /* The maximum amount by which 'tick' can be biased away from 'nominal_tick'
86 (sys_adjtimex() in the kernel bounds this to 10%) */
87 static int max_tick_bias
;
89 /* The kernel USER_HZ constant */
91 static double dhz
; /* And dbl prec version of same for arithmetic */
93 /* Flag indicating whether adjtimex() can step the clock */
94 static int have_setoffset
;
96 /* The assumed rate at which the effective frequency and tick values are
97 updated in the kernel */
98 static int tick_update_hz
;
100 /* ================================================== */
115 /* ================================================== */
116 /* Positive means currently fast of true time, i.e. jump backwards */
119 apply_step_offset(double offset
)
123 txc
.modes
= ADJ_SETOFFSET
| ADJ_NANO
;
124 txc
.time
.tv_sec
= -offset
;
125 txc
.time
.tv_usec
= 1.0e9
* (-offset
- txc
.time
.tv_sec
);
126 if (txc
.time
.tv_usec
< 0) {
128 txc
.time
.tv_usec
+= 1000000000;
131 if (SYS_Timex_Adjust(&txc
, 1) < 0)
137 /* ================================================== */
138 /* This call sets the Linux kernel frequency to a given value in parts
139 per million relative to the nominal running frequency. Nominal is taken to
140 be tick=10000, freq=0 (for a USER_HZ==100 system, other values otherwise).
141 The convention is that this is called with a positive argument if the local
142 clock runs fast when uncompensated. */
145 set_frequency(double freq_ppm
)
149 double required_freq
;
150 int required_delta_tick
;
152 required_delta_tick
= our_round(freq_ppm
/ dhz
);
154 /* Older kernels (pre-2.6.18) don't apply the frequency offset exactly as
155 set by adjtimex() and a scaling constant (that depends on the internal
156 kernel HZ constant) would be needed to compensate for the error. Because
157 chronyd is closed loop it doesn't matter much if we don't scale the
158 required frequency, but we want to prevent thrashing between two states
159 when the system's frequency error is close to a multiple of USER_HZ. With
160 USER_HZ <= 250, the maximum frequency adjustment of 500 ppm overlaps at
161 least two ticks and we can stick to the current tick if it's next to the
163 if (hz
<= 250 && (required_delta_tick
+ 1 == current_delta_tick
||
164 required_delta_tick
- 1 == current_delta_tick
)) {
165 required_delta_tick
= current_delta_tick
;
168 required_freq
= -(freq_ppm
- dhz
* required_delta_tick
);
169 required_tick
= nominal_tick
- required_delta_tick
;
171 txc
.modes
= ADJ_TICK
| ADJ_FREQUENCY
;
172 txc
.freq
= required_freq
* FREQ_SCALE
;
173 txc
.tick
= required_tick
;
175 SYS_Timex_Adjust(&txc
, 0);
177 current_delta_tick
= required_delta_tick
;
179 return dhz
* current_delta_tick
- txc
.freq
/ FREQ_SCALE
;
182 /* ================================================== */
183 /* Read the ppm frequency from the kernel */
192 SYS_Timex_Adjust(&txc
, 0);
194 current_delta_tick
= nominal_tick
- txc
.tick
;
196 return dhz
* current_delta_tick
- txc
.freq
/ FREQ_SCALE
;
199 /* ================================================== */
201 /* Estimate the value of USER_HZ given the value of txc.tick that chronyd finds when
202 * it starts. The only credible values are 100 (Linux/x86) or powers of 2.
203 * Also, the bounds checking inside the kernel's adjtimex system call enforces
204 * a +/- 10% movement of tick away from the nominal value 1e6/USER_HZ. */
210 int i
, tick
, tick_lo
, tick_hi
, ihz
;
214 SYS_Timex_Adjust(&txc
, 0);
217 /* Pick off the hz=100 case first */
218 if (tick
>= 9000 && tick
<= 11000) {
222 for (i
=4; i
<16; i
++) { /* surely 16 .. 32768 is a wide enough range? */
224 tick_nominal
= 1.0e6
/ (double) ihz
;
225 tick_lo
= (int)(0.5 + tick_nominal
*2.0/3.0);
226 tick_hi
= (int)(0.5 + tick_nominal
*4.0/3.0);
228 if (tick_lo
< tick
&& tick
<= tick_hi
) {
233 /* oh dear. doomed. */
234 LOG_FATAL("Can't determine hz from tick %d", tick
);
239 /* ================================================== */
247 if ((hz
= sysconf(_SC_CLK_TCK
)) < 1)
256 /* ================================================== */
259 kernelvercmp(int major1
, int minor1
, int patch1
,
260 int major2
, int minor2
, int patch2
)
262 if (major1
!= major2
)
263 return major1
- major2
;
264 if (minor1
!= minor2
)
265 return minor1
- minor2
;
266 return patch1
- patch2
;
269 /* ================================================== */
272 get_kernel_version(int *major
, int *minor
, int *patch
)
277 LOG_FATAL("uname() failed");
280 if (sscanf(uts
.release
, "%d.%d.%d", major
, minor
, patch
) < 2)
281 LOG_FATAL("Could not parse kernel version");
284 /* ================================================== */
286 /* Compute the scaling to use on any frequency we set, according to
287 the vintage of the Linux kernel being used. */
290 get_version_specific_details(void)
292 int major
, minor
, patch
;
300 nominal_tick
= (1000000L + (hz
/2))/hz
; /* Mirror declaration in kernel */
301 max_tick_bias
= nominal_tick
/ 10;
303 /* In modern kernels the frequency of the clock is updated immediately in the
304 adjtimex() system call. Assume a maximum delay of 10 microseconds. */
305 tick_update_hz
= 100000;
307 get_kernel_version(&major
, &minor
, &patch
);
308 DEBUG_LOG("Linux kernel major=%d minor=%d patch=%d", major
, minor
, patch
);
310 if (kernelvercmp(major
, minor
, patch
, 2, 2, 0) < 0) {
311 LOG_FATAL("Kernel version not supported, sorry.");
314 if (kernelvercmp(major
, minor
, patch
, 2, 6, 27) >= 0 &&
315 kernelvercmp(major
, minor
, patch
, 2, 6, 33) < 0) {
316 /* In tickless kernels before 2.6.33 the frequency is updated in
317 a half-second interval */
319 } else if (kernelvercmp(major
, minor
, patch
, 4, 19, 0) < 0) {
320 /* In kernels before 4.19 the frequency is updated only on internal ticks
321 (CONFIG_HZ). As their rate cannot be reliably detected from the user
322 space, and it may not even be constant (CONFIG_NO_HZ - aka tickless),
323 assume the lowest commonly used constant rate */
324 tick_update_hz
= 100;
327 /* ADJ_SETOFFSET support */
328 if (kernelvercmp(major
, minor
, patch
, 2, 6, 39) < 0) {
334 DEBUG_LOG("hz=%d nominal_tick=%d max_tick_bias=%d tick_update_hz=%d",
335 hz
, nominal_tick
, max_tick_bias
, tick_update_hz
);
338 /* ================================================== */
341 reset_adjtime_offset(void)
345 /* Reset adjtime() offset */
346 txc
.modes
= ADJ_OFFSET_SINGLESHOT
;
349 SYS_Timex_Adjust(&txc
, 0);
352 /* ================================================== */
355 test_step_offset(void)
359 /* Zero maxerror and check it's reset to a maximum after ADJ_SETOFFSET.
360 This seems to be the only way how to verify that the kernel really
361 supports the ADJ_SETOFFSET mode as it doesn't return an error on unknown
364 txc
.modes
= MOD_MAXERROR
;
367 if (SYS_Timex_Adjust(&txc
, 1) < 0 || txc
.maxerror
!= 0)
370 txc
.modes
= ADJ_SETOFFSET
| ADJ_NANO
;
372 txc
.time
.tv_usec
= 0;
374 if (SYS_Timex_Adjust(&txc
, 1) < 0 || txc
.maxerror
< 100000)
380 /* ================================================== */
383 report_time_adjust_blockers(void)
385 #if defined(FEAT_PRIVDROP) && defined(CAP_IS_SUPPORTED)
386 if (CAP_IS_SUPPORTED(CAP_SYS_TIME
) && cap_get_bound(CAP_SYS_TIME
))
388 LOG(LOGS_WARN
, "CAP_SYS_TIME not present");
392 /* ================================================== */
393 /* Initialisation code for this module */
396 SYS_Linux_Initialise(void)
398 get_version_specific_details();
400 report_time_adjust_blockers();
402 reset_adjtime_offset();
404 if (have_setoffset
&& !test_step_offset()) {
405 LOG(LOGS_INFO
, "adjtimex() doesn't support ADJ_SETOFFSET");
409 SYS_Timex_InitialiseWithFunctions(1.0e6
* max_tick_bias
/ nominal_tick
,
410 1.0 / tick_update_hz
,
411 read_frequency
, set_frequency
,
412 have_setoffset
? apply_step_offset
: NULL
,
413 0.0, 0.0, NULL
, NULL
);
416 /* ================================================== */
417 /* Finalisation code for this module */
420 SYS_Linux_Finalise(void)
422 SYS_Timex_Finalise();
425 /* ================================================== */
429 SYS_Linux_DropRoot(uid_t uid
, gid_t gid
, SYS_ProcessContext context
, int clock_control
)
434 if (prctl(PR_SET_KEEPCAPS
, 1)) {
435 LOG_FATAL("prctl() failed");
438 UTI_DropRoot(uid
, gid
);
440 /* Keep CAP_NET_BIND_SERVICE if the NTP server sockets may need to be bound
441 to a privileged port.
442 Keep CAP_NET_RAW if an NTP socket may need to be bound to a device on
444 Keep CAP_SYS_TIME if the clock control is enabled. */
445 if (snprintf(cap_text
, sizeof (cap_text
), "%s %s %s",
446 (CNF_GetNTPPort() > 0 && CNF_GetNTPPort() < 1024) ?
447 "cap_net_bind_service=ep" : "",
448 (CNF_GetBindNtpInterface() || CNF_GetBindAcquisitionInterface()) &&
449 !SYS_Linux_CheckKernelVersion(5, 7) ? "cap_net_raw=ep" : "",
450 clock_control
? "cap_sys_time=ep" : "") >= sizeof (cap_text
))
453 /* Helpers don't need any capabilities */
454 if (context
!= SYS_MAIN_PROCESS
)
457 if ((cap
= cap_from_text(cap_text
)) == NULL
) {
458 LOG_FATAL("cap_from_text() failed");
461 if (cap_set_proc(cap
)) {
462 LOG_FATAL("cap_set_proc() failed");
469 /* ================================================== */
473 void check_seccomp_applicability(void)
476 double mail_threshold
;
479 CNF_GetMailOnChange(&mail_enabled
, &mail_threshold
, &mail_user
);
481 LOG_FATAL("mailonchange directive cannot be used with -F enabled");
484 /* ================================================== */
487 SYS_Linux_EnableSystemCallFilter(int level
, SYS_ProcessContext context
)
489 const int allowed
[] = {
492 SCMP_SYS(clock_adjtime
),
493 #ifdef __NR_clock_adjtime64
494 SCMP_SYS(clock_adjtime64
),
496 SCMP_SYS(clock_gettime
),
497 #ifdef __NR_clock_gettime64
498 SCMP_SYS(clock_gettime64
),
500 SCMP_SYS(gettimeofday
),
501 SCMP_SYS(settimeofday
),
510 SCMP_SYS(exit_group
),
515 SCMP_SYS(rt_sigaction
),
516 SCMP_SYS(rt_sigreturn
),
517 SCMP_SYS(rt_sigprocmask
),
518 SCMP_SYS(set_tid_address
),
546 SCMP_SYS(getdents64
),
550 SCMP_SYS(newfstatat
),
552 SCMP_SYS(readlinkat
),
555 #ifdef __NR_renameat2
572 SCMP_SYS(getsockname
),
573 SCMP_SYS(getsockopt
),
577 #ifdef __NR_recvmmsg_time64
578 SCMP_SYS(recvmmsg_time64
),
586 /* TODO: check socketcall arguments */
587 SCMP_SYS(socketcall
),
590 SCMP_SYS(_newselect
),
598 #ifdef __NR_ppoll_time64
599 SCMP_SYS(ppoll_time64
),
603 #ifdef __NR_pselect6_time64
604 SCMP_SYS(pselect6_time64
),
608 #ifdef __NR_futex_time64
609 SCMP_SYS(futex_time64
),
612 SCMP_SYS(set_robust_list
),
621 const int denied_any
[] = {
631 const int denied_ntske
[] = {
633 SCMP_SYS(setsockopt
),
637 const int socket_domains
[] = {
638 AF_NETLINK
, AF_UNIX
, AF_INET
,
644 const static int socket_options
[][2] = {
645 { SOL_IP
, IP_PKTINFO
}, { SOL_IP
, IP_FREEBIND
}, { SOL_IP
, IP_TOS
},
647 { SOL_IPV6
, IPV6_V6ONLY
}, { SOL_IPV6
, IPV6_RECVPKTINFO
},
649 #ifdef SO_BINDTODEVICE
650 { SOL_SOCKET
, SO_BINDTODEVICE
},
652 { SOL_SOCKET
, SO_BROADCAST
}, { SOL_SOCKET
, SO_REUSEADDR
},
654 { SOL_SOCKET
, SO_REUSEPORT
},
656 { SOL_SOCKET
, SO_TIMESTAMP
}, { SOL_SOCKET
, SO_TIMESTAMPNS
},
657 #ifdef HAVE_LINUX_TIMESTAMPING
658 { SOL_SOCKET
, SO_SELECT_ERR_QUEUE
}, { SOL_SOCKET
, SO_TIMESTAMPING
},
662 const static int fcntls
[] = { F_GETFD
, F_SETFD
, F_GETFL
, F_SETFL
};
664 const static unsigned long ioctls
[] = {
666 #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
667 PTP_EXTTS_REQUEST
, PTP_SYS_OFFSET
,
668 #ifdef PTP_PIN_SETFUNC
671 #ifdef PTP_SYS_OFFSET_EXTENDED
672 PTP_SYS_OFFSET_EXTENDED
,
674 #ifdef PTP_SYS_OFFSET_PRECISE
675 PTP_SYS_OFFSET_PRECISE
,
682 RTC_RD_TIME
, RTC_SET_TIME
, RTC_UIE_ON
, RTC_UIE_OFF
,
684 #ifdef HAVE_LINUX_TIMESTAMPING
689 unsigned int default_action
, deny_action
;
690 scmp_filter_ctx
*ctx
;
693 /* Sign of the level determines the deny action (kill or SIGSYS).
694 At level 1, selected syscalls are allowed, others are denied.
695 At level 2, selected syscalls are denied, others are allowed. */
697 deny_action
= level
> 0 ? SCMP_ACT_KILL
: SCMP_ACT_TRAP
;
703 default_action
= deny_action
;
706 default_action
= SCMP_ACT_ALLOW
;
709 LOG_FATAL("Unsupported filter level");
712 if (context
== SYS_MAIN_PROCESS
) {
713 /* Check if the chronyd configuration is supported */
714 check_seccomp_applicability();
716 /* At level 1, start a helper process which will not have a seccomp filter.
717 It will be used for getaddrinfo(), for which it is difficult to maintain
718 a list of required system calls (with glibc it depends on what NSS
719 modules are installed and enabled on the system). */
720 if (default_action
!= SCMP_ACT_ALLOW
)
724 ctx
= seccomp_init(default_action
);
726 LOG_FATAL("Failed to initialize seccomp");
728 if (default_action
!= SCMP_ACT_ALLOW
) {
729 for (i
= 0; i
< sizeof (allowed
) / sizeof (*allowed
); i
++) {
730 if (seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, allowed
[i
], 0) < 0)
734 for (i
= 0; i
< sizeof (denied_any
) / sizeof (*denied_any
); i
++) {
735 if (seccomp_rule_add(ctx
, deny_action
, denied_any
[i
], 0) < 0)
739 if (context
== SYS_NTSKE_HELPER
) {
740 for (i
= 0; i
< sizeof (denied_ntske
) / sizeof (*denied_ntske
); i
++) {
741 if (seccomp_rule_add(ctx
, deny_action
, denied_ntske
[i
], 0) < 0)
747 if (default_action
!= SCMP_ACT_ALLOW
&& context
== SYS_MAIN_PROCESS
) {
748 /* Allow opening sockets in selected domains */
749 for (i
= 0; i
< sizeof (socket_domains
) / sizeof (*socket_domains
); i
++) {
750 if (seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(socket
), 1,
751 SCMP_A0(SCMP_CMP_EQ
, socket_domains
[i
])) < 0)
755 /* Allow selected socket options */
756 for (i
= 0; i
< sizeof (socket_options
) / sizeof (*socket_options
); i
++) {
757 if (seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(setsockopt
), 3,
758 SCMP_A1(SCMP_CMP_EQ
, socket_options
[i
][0]),
759 SCMP_A2(SCMP_CMP_EQ
, socket_options
[i
][1]),
760 SCMP_A4(SCMP_CMP_LE
, sizeof (int))) < 0)
764 /* Allow selected fcntl calls */
765 for (i
= 0; i
< sizeof (fcntls
) / sizeof (*fcntls
); i
++) {
766 if (seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl
), 1,
767 SCMP_A1(SCMP_CMP_EQ
, fcntls
[i
])) < 0 ||
768 seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(fcntl64
), 1,
769 SCMP_A1(SCMP_CMP_EQ
, fcntls
[i
])) < 0)
773 /* Allow selected ioctls */
774 for (i
= 0; i
< sizeof (ioctls
) / sizeof (*ioctls
); i
++) {
775 if (seccomp_rule_add(ctx
, SCMP_ACT_ALLOW
, SCMP_SYS(ioctl
), 1,
776 SCMP_A1(SCMP_CMP_EQ
, ioctls
[i
])) < 0)
781 if (seccomp_load(ctx
) < 0)
782 LOG_FATAL("Failed to load seccomp rules");
784 LOG(context
== SYS_MAIN_PROCESS
? LOGS_INFO
: LOGS_DEBUG
,
785 "Loaded seccomp filter (level %d)", level
);
786 seccomp_release(ctx
);
790 LOG_FATAL("Failed to add seccomp rules");
794 /* ================================================== */
797 SYS_Linux_CheckKernelVersion(int req_major
, int req_minor
)
799 int major
, minor
, patch
;
801 get_kernel_version(&major
, &minor
, &patch
);
803 return kernelvercmp(req_major
, req_minor
, 0, major
, minor
, patch
) <= 0;
806 /* ================================================== */
808 #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
810 #define PHC_READINGS 10
813 process_phc_readings(struct timespec ts
[][3], int n
, double precision
,
814 struct timespec
*phc_ts
, struct timespec
*sys_ts
, double *err
)
816 double min_delay
= 0.0, delays
[PTP_MAX_SAMPLES
], phc_sum
, sys_sum
, sys_prec
;
819 if (n
> PTP_MAX_SAMPLES
)
822 for (i
= 0; i
< n
; i
++) {
823 delays
[i
] = UTI_DiffTimespecsToDouble(&ts
[i
][2], &ts
[i
][0]);
825 if (delays
[i
] < 0.0) {
826 /* Step in the middle of a PHC reading? */
827 DEBUG_LOG("Bad PTP_SYS_OFFSET sample delay=%e", delays
[i
]);
831 if (!i
|| delays
[i
] < min_delay
)
832 min_delay
= delays
[i
];
835 sys_prec
= LCL_GetSysPrecisionAsQuantum();
837 /* Combine best readings */
838 for (i
= combined
= 0, phc_sum
= sys_sum
= 0.0; i
< n
; i
++) {
839 if (delays
[i
] > min_delay
+ MAX(sys_prec
, precision
))
842 phc_sum
+= UTI_DiffTimespecsToDouble(&ts
[i
][1], &ts
[0][1]);
843 sys_sum
+= UTI_DiffTimespecsToDouble(&ts
[i
][0], &ts
[0][0]) + delays
[i
] / 2.0;
849 UTI_AddDoubleToTimespec(&ts
[0][1], phc_sum
/ combined
, phc_ts
);
850 UTI_AddDoubleToTimespec(&ts
[0][0], sys_sum
/ combined
, sys_ts
);
851 *err
= MAX(min_delay
/ 2.0, precision
);
856 /* ================================================== */
859 get_phc_sample(int phc_fd
, double precision
, struct timespec
*phc_ts
,
860 struct timespec
*sys_ts
, double *err
)
862 struct timespec ts
[PHC_READINGS
][3];
863 struct ptp_sys_offset sys_off
;
866 /* Silence valgrind */
867 memset(&sys_off
, 0, sizeof (sys_off
));
869 sys_off
.n_samples
= PHC_READINGS
;
871 if (ioctl(phc_fd
, PTP_SYS_OFFSET
, &sys_off
)) {
872 DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno
));
876 for (i
= 0; i
< PHC_READINGS
; i
++) {
877 ts
[i
][0].tv_sec
= sys_off
.ts
[i
* 2].sec
;
878 ts
[i
][0].tv_nsec
= sys_off
.ts
[i
* 2].nsec
;
879 ts
[i
][1].tv_sec
= sys_off
.ts
[i
* 2 + 1].sec
;
880 ts
[i
][1].tv_nsec
= sys_off
.ts
[i
* 2 + 1].nsec
;
881 ts
[i
][2].tv_sec
= sys_off
.ts
[i
* 2 + 2].sec
;
882 ts
[i
][2].tv_nsec
= sys_off
.ts
[i
* 2 + 2].nsec
;
885 return process_phc_readings(ts
, PHC_READINGS
, precision
, phc_ts
, sys_ts
, err
);
888 /* ================================================== */
891 get_extended_phc_sample(int phc_fd
, double precision
, struct timespec
*phc_ts
,
892 struct timespec
*sys_ts
, double *err
)
894 #ifdef PTP_SYS_OFFSET_EXTENDED
895 struct timespec ts
[PHC_READINGS
][3];
896 struct ptp_sys_offset_extended sys_off
;
899 /* Silence valgrind */
900 memset(&sys_off
, 0, sizeof (sys_off
));
902 sys_off
.n_samples
= PHC_READINGS
;
904 if (ioctl(phc_fd
, PTP_SYS_OFFSET_EXTENDED
, &sys_off
)) {
905 DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_EXTENDED", strerror(errno
));
909 for (i
= 0; i
< PHC_READINGS
; i
++) {
910 ts
[i
][0].tv_sec
= sys_off
.ts
[i
][0].sec
;
911 ts
[i
][0].tv_nsec
= sys_off
.ts
[i
][0].nsec
;
912 ts
[i
][1].tv_sec
= sys_off
.ts
[i
][1].sec
;
913 ts
[i
][1].tv_nsec
= sys_off
.ts
[i
][1].nsec
;
914 ts
[i
][2].tv_sec
= sys_off
.ts
[i
][2].sec
;
915 ts
[i
][2].tv_nsec
= sys_off
.ts
[i
][2].nsec
;
918 return process_phc_readings(ts
, PHC_READINGS
, precision
, phc_ts
, sys_ts
, err
);
924 /* ================================================== */
927 get_precise_phc_sample(int phc_fd
, double precision
, struct timespec
*phc_ts
,
928 struct timespec
*sys_ts
, double *err
)
930 #ifdef PTP_SYS_OFFSET_PRECISE
931 struct ptp_sys_offset_precise sys_off
;
933 /* Silence valgrind */
934 memset(&sys_off
, 0, sizeof (sys_off
));
936 if (ioctl(phc_fd
, PTP_SYS_OFFSET_PRECISE
, &sys_off
)) {
937 DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_PRECISE",
942 phc_ts
->tv_sec
= sys_off
.device
.sec
;
943 phc_ts
->tv_nsec
= sys_off
.device
.nsec
;
944 sys_ts
->tv_sec
= sys_off
.sys_realtime
.sec
;
945 sys_ts
->tv_nsec
= sys_off
.sys_realtime
.nsec
;
946 *err
= MAX(LCL_GetSysPrecisionAsQuantum(), precision
);
954 /* ================================================== */
957 SYS_Linux_OpenPHC(const char *path
, int phc_index
)
959 struct ptp_clock_caps caps
;
964 if (snprintf(phc_path
, sizeof (phc_path
), "/dev/ptp%d", phc_index
) >= sizeof (phc_path
))
969 phc_fd
= open(path
, O_RDONLY
);
971 LOG(LOGS_ERR
, "Could not open %s : %s", path
, strerror(errno
));
975 /* Make sure it is a PHC */
976 if (ioctl(phc_fd
, PTP_CLOCK_GETCAPS
, &caps
)) {
977 LOG(LOGS_ERR
, "ioctl(%s) failed : %s", "PTP_CLOCK_GETCAPS", strerror(errno
));
982 UTI_FdSetCloexec(phc_fd
);
987 /* ================================================== */
990 SYS_Linux_GetPHCSample(int fd
, int nocrossts
, double precision
, int *reading_mode
,
991 struct timespec
*phc_ts
, struct timespec
*sys_ts
, double *err
)
993 if ((*reading_mode
== 2 || !*reading_mode
) && !nocrossts
&&
994 get_precise_phc_sample(fd
, precision
, phc_ts
, sys_ts
, err
)) {
997 } else if ((*reading_mode
== 3 || !*reading_mode
) &&
998 get_extended_phc_sample(fd
, precision
, phc_ts
, sys_ts
, err
)) {
1001 } else if ((*reading_mode
== 1 || !*reading_mode
) &&
1002 get_phc_sample(fd
, precision
, phc_ts
, sys_ts
, err
)) {
1009 /* ================================================== */
1012 SYS_Linux_SetPHCExtTimestamping(int fd
, int pin
, int channel
,
1013 int rising
, int falling
, int enable
)
1015 struct ptp_extts_request extts_req
;
1016 #ifdef PTP_PIN_SETFUNC
1017 struct ptp_pin_desc pin_desc
;
1019 memset(&pin_desc
, 0, sizeof (pin_desc
));
1020 pin_desc
.index
= pin
;
1021 pin_desc
.func
= enable
? PTP_PF_EXTTS
: PTP_PF_NONE
;
1022 pin_desc
.chan
= channel
;
1024 if (ioctl(fd
, PTP_PIN_SETFUNC
, &pin_desc
)) {
1025 DEBUG_LOG("ioctl(%s) failed : %s", "PTP_PIN_SETFUNC", strerror(errno
));
1029 DEBUG_LOG("Missing PTP_PIN_SETFUNC");
1033 memset(&extts_req
, 0, sizeof (extts_req
));
1034 extts_req
.index
= channel
;
1035 extts_req
.flags
= (enable
? PTP_ENABLE_FEATURE
: 0) |
1036 (rising
? PTP_RISING_EDGE
: 0) |
1037 (falling
? PTP_FALLING_EDGE
: 0);
1039 if (ioctl(fd
, PTP_EXTTS_REQUEST
, &extts_req
)) {
1040 DEBUG_LOG("ioctl(%s) failed : %s", "PTP_EXTTS_REQUEST", strerror(errno
));
1047 /* ================================================== */
1050 SYS_Linux_ReadPHCExtTimestamp(int fd
, struct timespec
*phc_ts
, int *channel
)
1052 struct ptp_extts_event extts_event
;
1054 if (read(fd
, &extts_event
, sizeof (extts_event
)) != sizeof (extts_event
)) {
1055 DEBUG_LOG("Could not read PHC extts event");
1059 phc_ts
->tv_sec
= extts_event
.t
.sec
;
1060 phc_ts
->tv_nsec
= extts_event
.t
.nsec
;
1061 *channel
= extts_event
.index
;