summaryrefslogtreecommitdiff
path: root/sys_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys_linux.c')
-rw-r--r--sys_linux.c127
1 files changed, 95 insertions, 32 deletions
diff --git a/sys_linux.c b/sys_linux.c
index 9e8ed65..190b54f 100644
--- a/sys_linux.c
+++ b/sys_linux.c
@@ -4,7 +4,7 @@
**********************************************************************
* Copyright (C) Richard P. Curnow 1997-2003
* Copyright (C) John G. Hasler 2009
- * Copyright (C) Miroslav Lichvar 2009-2012, 2014-2016
+ * Copyright (C) Miroslav Lichvar 2009-2012, 2014-2017
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -240,7 +240,7 @@ guess_hz(void)
}
/* oh dear. doomed. */
- LOG_FATAL(LOGF_SysLinux, "Can't determine hz from tick %d", tick);
+ LOG_FATAL("Can't determine hz from tick %d", tick);
return 0;
}
@@ -283,11 +283,11 @@ get_kernel_version(int *major, int *minor, int *patch)
struct utsname uts;
if (uname(&uts) < 0)
- LOG_FATAL(LOGF_SysLinux, "uname() failed");
+ LOG_FATAL("uname() failed");
*patch = 0;
if (sscanf(uts.release, "%d.%d.%d", major, minor, patch) < 2)
- LOG_FATAL(LOGF_SysLinux, "Could not parse kernel version");
+ LOG_FATAL("Could not parse kernel version");
}
/* ================================================== */
@@ -314,10 +314,10 @@ get_version_specific_details(void)
tick_update_hz = 100;
get_kernel_version(&major, &minor, &patch);
- DEBUG_LOG(LOGF_SysLinux, "Linux kernel major=%d minor=%d patch=%d", major, minor, patch);
+ DEBUG_LOG("Linux kernel major=%d minor=%d patch=%d", major, minor, patch);
if (kernelvercmp(major, minor, patch, 2, 2, 0) < 0) {
- LOG_FATAL(LOGF_SysLinux, "Kernel version not supported, sorry.");
+ LOG_FATAL("Kernel version not supported, sorry.");
}
if (kernelvercmp(major, minor, patch, 2, 6, 27) >= 0 &&
@@ -334,7 +334,7 @@ get_version_specific_details(void)
have_setoffset = 1;
}
- DEBUG_LOG(LOGF_SysLinux, "hz=%d nominal_tick=%d max_tick_bias=%d",
+ DEBUG_LOG("hz=%d nominal_tick=%d max_tick_bias=%d",
hz, nominal_tick, max_tick_bias);
}
@@ -391,7 +391,7 @@ SYS_Linux_Initialise(void)
reset_adjtime_offset();
if (have_setoffset && !test_step_offset()) {
- LOG(LOGS_INFO, LOGF_SysLinux, "adjtimex() doesn't support ADJ_SETOFFSET");
+ LOG(LOGS_INFO, "adjtimex() doesn't support ADJ_SETOFFSET");
have_setoffset = 0;
}
@@ -421,7 +421,7 @@ SYS_Linux_DropRoot(uid_t uid, gid_t gid)
cap_t cap;
if (prctl(PR_SET_KEEPCAPS, 1)) {
- LOG_FATAL(LOGF_SysLinux, "prctl() failed");
+ LOG_FATAL("prctl() failed");
}
UTI_DropRoot(uid, gid);
@@ -431,11 +431,11 @@ SYS_Linux_DropRoot(uid_t uid, gid_t gid)
"cap_net_bind_service,cap_sys_time=ep" : "cap_sys_time=ep";
if ((cap = cap_from_text(cap_text)) == NULL) {
- LOG_FATAL(LOGF_SysLinux, "cap_from_text() failed");
+ LOG_FATAL("cap_from_text() failed");
}
if (cap_set_proc(cap)) {
- LOG_FATAL(LOGF_SysLinux, "cap_set_proc() failed");
+ LOG_FATAL("cap_set_proc() failed");
}
cap_free(cap);
@@ -454,7 +454,7 @@ void check_seccomp_applicability(void)
CNF_GetMailOnChange(&mail_enabled, &mail_threshold, &mail_user);
if (mail_enabled)
- LOG_FATAL(LOGF_SysLinux, "mailonchange directive cannot be used with -F enabled");
+ LOG_FATAL("mailonchange directive cannot be used with -F enabled");
}
/* ================================================== */
@@ -467,9 +467,10 @@ SYS_Linux_EnableSystemCallFilter(int level)
SCMP_SYS(adjtimex), SCMP_SYS(clock_gettime), SCMP_SYS(gettimeofday),
SCMP_SYS(settimeofday), SCMP_SYS(time),
/* Process */
- SCMP_SYS(clone), SCMP_SYS(exit), SCMP_SYS(exit_group), SCMP_SYS(getrlimit),
- SCMP_SYS(rt_sigaction), SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask),
- SCMP_SYS(set_tid_address), SCMP_SYS(sigreturn), SCMP_SYS(wait4),
+ SCMP_SYS(clone), SCMP_SYS(exit), SCMP_SYS(exit_group), SCMP_SYS(getpid),
+ SCMP_SYS(getrlimit), SCMP_SYS(rt_sigaction), SCMP_SYS(rt_sigreturn),
+ SCMP_SYS(rt_sigprocmask), SCMP_SYS(set_tid_address), SCMP_SYS(sigreturn),
+ SCMP_SYS(wait4),
/* Memory */
SCMP_SYS(brk), SCMP_SYS(madvise), SCMP_SYS(mmap), SCMP_SYS(mmap2),
SCMP_SYS(mprotect), SCMP_SYS(mremap), SCMP_SYS(munmap), SCMP_SYS(shmdt),
@@ -489,7 +490,7 @@ SYS_Linux_EnableSystemCallFilter(int level)
SCMP_SYS(poll), SCMP_SYS(read), SCMP_SYS(futex), SCMP_SYS(select),
SCMP_SYS(set_robust_list), SCMP_SYS(write),
/* Miscellaneous */
- SCMP_SYS(uname),
+ SCMP_SYS(getrandom), SCMP_SYS(sysinfo), SCMP_SYS(uname),
};
const int socket_domains[] = {
@@ -516,7 +517,10 @@ SYS_Linux_EnableSystemCallFilter(int level)
const static unsigned long ioctls[] = {
FIONREAD, TCGETS,
#if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING)
- PTP_SYS_OFFSET,
+ PTP_EXTTS_REQUEST, PTP_SYS_OFFSET,
+#ifdef PTP_PIN_SETFUNC
+ PTP_PIN_SETFUNC,
+#endif
#ifdef PTP_SYS_OFFSET_PRECISE
PTP_SYS_OFFSET_PRECISE,
#endif
@@ -546,7 +550,7 @@ SYS_Linux_EnableSystemCallFilter(int level)
ctx = seccomp_init(level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP);
if (ctx == NULL)
- LOG_FATAL(LOGF_SysLinux, "Failed to initialize seccomp");
+ LOG_FATAL("Failed to initialize seccomp");
/* Add system calls that are always allowed */
for (i = 0; i < (sizeof (syscalls) / sizeof (*syscalls)); i++) {
@@ -587,14 +591,14 @@ SYS_Linux_EnableSystemCallFilter(int level)
}
if (seccomp_load(ctx) < 0)
- LOG_FATAL(LOGF_SysLinux, "Failed to load seccomp rules");
+ LOG_FATAL("Failed to load seccomp rules");
- LOG(LOGS_INFO, LOGF_SysLinux, "Loaded seccomp filter");
+ LOG(LOGS_INFO, "Loaded seccomp filter");
seccomp_release(ctx);
return;
add_failed:
- LOG_FATAL(LOGF_SysLinux, "Failed to add seccomp rules");
+ LOG_FATAL("Failed to add seccomp rules");
}
#endif
@@ -608,7 +612,7 @@ void SYS_Linux_SetScheduler(int SchedPriority)
struct sched_param sched;
if (SchedPriority < 1 || SchedPriority > 99) {
- LOG_FATAL(LOGF_SysLinux, "Bad scheduler priority: %d", SchedPriority);
+ LOG_FATAL("Bad scheduler priority: %d", SchedPriority);
} else {
sched.sched_priority = SchedPriority;
pmax = sched_get_priority_max(SCHED_FIFO);
@@ -620,10 +624,10 @@ void SYS_Linux_SetScheduler(int SchedPriority)
sched.sched_priority = pmin;
}
if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) {
- LOG(LOGS_ERR, LOGF_SysLinux, "sched_setscheduler() failed");
+ LOG(LOGS_ERR, "sched_setscheduler() failed");
}
else {
- DEBUG_LOG(LOGF_SysLinux, "Enabled SCHED_FIFO with priority %d",
+ DEBUG_LOG("Enabled SCHED_FIFO with priority %d",
sched.sched_priority);
}
}
@@ -641,14 +645,14 @@ void SYS_Linux_MemLockAll(int LockAll)
rlim.rlim_max = RLIM_INFINITY;
rlim.rlim_cur = RLIM_INFINITY;
if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) {
- LOG(LOGS_ERR, LOGF_SysLinux, "setrlimit() failed: not locking into RAM");
+ LOG(LOGS_ERR, "setrlimit() failed: not locking into RAM");
}
else {
if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) {
- LOG(LOGS_ERR, LOGF_SysLinux, "mlockall() failed");
+ LOG(LOGS_ERR, "mlockall() failed");
}
else {
- DEBUG_LOG(LOGF_SysLinux, "Successfully locked into RAM");
+ DEBUG_LOG("Successfully locked into RAM");
}
}
}
@@ -688,7 +692,7 @@ get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
sys_off.n_samples = PHC_READINGS;
if (ioctl(phc_fd, PTP_SYS_OFFSET, &sys_off)) {
- DEBUG_LOG(LOGF_SysLinux, "ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno));
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno));
return 0;
}
@@ -704,9 +708,11 @@ get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
phc_tss[i] = ts2;
delays[i] = UTI_DiffTimespecsToDouble(&ts3, &ts1);
- if (delays[i] <= 0.0)
+ if (delays[i] < 0.0) {
/* Step in the middle of a PHC reading? */
+ DEBUG_LOG("Bad PTP_SYS_OFFSET sample delay=%e", delays[i]);
return 0;
+ }
if (!i || delays[i] < min_delay)
min_delay = delays[i];
@@ -745,7 +751,7 @@ get_precise_phc_sample(int phc_fd, double precision, struct timespec *phc_ts,
memset(&sys_off, 0, sizeof (sys_off));
if (ioctl(phc_fd, PTP_SYS_OFFSET_PRECISE, &sys_off)) {
- DEBUG_LOG(LOGF_SysLinux, "ioctl(%s) failed : %s", "PTP_SYS_OFFSET_PRECISE",
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_PRECISE",
strerror(errno));
return 0;
}
@@ -779,13 +785,13 @@ SYS_Linux_OpenPHC(const char *path, int phc_index)
phc_fd = open(path, O_RDONLY);
if (phc_fd < 0) {
- LOG(LOGS_ERR, LOGF_SysLinux, "Could not open %s : %s", path, strerror(errno));
+ LOG(LOGS_ERR, "Could not open %s : %s", path, strerror(errno));
return -1;
}
/* Make sure it is a PHC */
if (ioctl(phc_fd, PTP_CLOCK_GETCAPS, &caps)) {
- LOG(LOGS_ERR, LOGF_SysLinux, "ioctl(%s) failed : %s", "PTP_CLOCK_GETCAPS", strerror(errno));
+ LOG(LOGS_ERR, "ioctl(%s) failed : %s", "PTP_CLOCK_GETCAPS", strerror(errno));
close(phc_fd);
return -1;
}
@@ -813,4 +819,61 @@ SYS_Linux_GetPHCSample(int fd, int nocrossts, double precision, int *reading_mod
return 0;
}
+/* ================================================== */
+
+int
+SYS_Linux_SetPHCExtTimestamping(int fd, int pin, int channel,
+ int rising, int falling, int enable)
+{
+ struct ptp_extts_request extts_req;
+#ifdef PTP_PIN_SETFUNC
+ struct ptp_pin_desc pin_desc;
+
+ memset(&pin_desc, 0, sizeof (pin_desc));
+ pin_desc.index = pin;
+ pin_desc.func = enable ? PTP_PF_EXTTS : PTP_PF_NONE;
+ pin_desc.chan = channel;
+
+ if (ioctl(fd, PTP_PIN_SETFUNC, &pin_desc)) {
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_PIN_SETFUNC", strerror(errno));
+ return 0;
+ }
+#else
+ DEBUG_LOG("Missing PTP_PIN_SETFUNC");
+ return 0;
+#endif
+
+ memset(&extts_req, 0, sizeof (extts_req));
+ extts_req.index = channel;
+ extts_req.flags = (enable ? PTP_ENABLE_FEATURE : 0) |
+ (rising ? PTP_RISING_EDGE : 0) |
+ (falling ? PTP_FALLING_EDGE : 0);
+
+ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_req)) {
+ DEBUG_LOG("ioctl(%s) failed : %s", "PTP_EXTTS_REQUEST", strerror(errno));
+ return 0;
+ }
+
+ return 1;
+}
+
+/* ================================================== */
+
+int
+SYS_Linux_ReadPHCExtTimestamp(int fd, struct timespec *phc_ts, int *channel)
+{
+ struct ptp_extts_event extts_event;
+
+ if (read(fd, &extts_event, sizeof (extts_event)) != sizeof (extts_event)) {
+ DEBUG_LOG("Could not read PHC extts event");
+ return 0;
+ }
+
+ phc_ts->tv_sec = extts_event.t.sec;
+ phc_ts->tv_nsec = extts_event.t.nsec;
+ *channel = extts_event.index;
+
+ return 1;
+}
+
#endif