diff options
Diffstat (limited to 'sys_linux.c')
-rw-r--r-- | sys_linux.c | 206 |
1 files changed, 100 insertions, 106 deletions
diff --git a/sys_linux.c b/sys_linux.c index 00bc239..898dc7a 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -33,15 +33,6 @@ #include <sys/utsname.h> -#if defined(HAVE_SCHED_SETSCHEDULER) -# include <sched.h> -#endif - -#if defined(HAVE_MLOCKALL) -# include <sys/mman.h> -#include <sys/resource.h> -#endif - #if defined(FEAT_PHC) || defined(HAVE_LINUX_TIMESTAMPING) #include <linux/ptp_clock.h> #endif @@ -493,25 +484,27 @@ SYS_Linux_EnableSystemCallFilter(int level) 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), + SCMP_SYS(wait4), SCMP_SYS(waitpid), /* 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), /* Filesystem */ - SCMP_SYS(access), SCMP_SYS(chmod), SCMP_SYS(chown), SCMP_SYS(chown32), + SCMP_SYS(_llseek), SCMP_SYS(access), SCMP_SYS(chmod), SCMP_SYS(chown), + SCMP_SYS(chown32), SCMP_SYS(faccessat), SCMP_SYS(fchmodat), SCMP_SYS(fchownat), SCMP_SYS(fstat), SCMP_SYS(fstat64), SCMP_SYS(getdents), SCMP_SYS(getdents64), - SCMP_SYS(lseek), SCMP_SYS(rename), SCMP_SYS(stat), SCMP_SYS(stat64), - SCMP_SYS(statfs), SCMP_SYS(statfs64), SCMP_SYS(unlink), + SCMP_SYS(lseek), SCMP_SYS(newfstatat), SCMP_SYS(rename), SCMP_SYS(renameat), + SCMP_SYS(stat), SCMP_SYS(stat64), SCMP_SYS(statfs), SCMP_SYS(statfs64), + SCMP_SYS(unlink), SCMP_SYS(unlinkat), /* Socket */ SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname), SCMP_SYS(getsockopt), - SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg), - SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto), + SCMP_SYS(recv), SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg), + SCMP_SYS(send), SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto), /* TODO: check socketcall arguments */ SCMP_SYS(socketcall), /* General I/O */ SCMP_SYS(_newselect), SCMP_SYS(close), SCMP_SYS(open), SCMP_SYS(openat), SCMP_SYS(pipe), - SCMP_SYS(poll), SCMP_SYS(read), SCMP_SYS(futex), SCMP_SYS(select), - SCMP_SYS(set_robust_list), SCMP_SYS(write), + SCMP_SYS(pipe2), SCMP_SYS(poll), SCMP_SYS(ppoll), SCMP_SYS(pselect6), SCMP_SYS(read), + SCMP_SYS(futex), SCMP_SYS(select), SCMP_SYS(set_robust_list), SCMP_SYS(write), /* Miscellaneous */ SCMP_SYS(getrandom), SCMP_SYS(sysinfo), SCMP_SYS(uname), }; @@ -544,6 +537,9 @@ SYS_Linux_EnableSystemCallFilter(int level) #ifdef PTP_PIN_SETFUNC PTP_PIN_SETFUNC, #endif +#ifdef PTP_SYS_OFFSET_EXTENDED + PTP_SYS_OFFSET_EXTENDED, +#endif #ifdef PTP_SYS_OFFSET_PRECISE PTP_SYS_OFFSET_PRECISE, #endif @@ -627,63 +623,6 @@ add_failed: /* ================================================== */ -#if defined(HAVE_SCHED_SETSCHEDULER) - /* Install SCHED_FIFO real-time scheduler with specified priority */ -void SYS_Linux_SetScheduler(int SchedPriority) -{ - int pmax, pmin; - struct sched_param sched; - - if (SchedPriority < 1 || SchedPriority > 99) { - LOG_FATAL("Bad scheduler priority: %d", SchedPriority); - } else { - sched.sched_priority = SchedPriority; - pmax = sched_get_priority_max(SCHED_FIFO); - pmin = sched_get_priority_min(SCHED_FIFO); - if ( SchedPriority > pmax ) { - sched.sched_priority = pmax; - } - else if ( SchedPriority < pmin ) { - sched.sched_priority = pmin; - } - if ( sched_setscheduler(0, SCHED_FIFO, &sched) == -1 ) { - LOG(LOGS_ERR, "sched_setscheduler() failed"); - } - else { - DEBUG_LOG("Enabled SCHED_FIFO with priority %d", - sched.sched_priority); - } - } -} -#endif /* HAVE_SCHED_SETSCHEDULER */ - -#if defined(HAVE_MLOCKALL) -/* Lock the process into RAM so that it will never be swapped out */ -void SYS_Linux_MemLockAll(int LockAll) -{ - struct rlimit rlim; - if (LockAll == 1 ) { - /* Make sure that we will be able to lock all the memory we need */ - /* even after dropping privileges. This does not actually reaerve any memory */ - rlim.rlim_max = RLIM_INFINITY; - rlim.rlim_cur = RLIM_INFINITY; - if (setrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { - LOG(LOGS_ERR, "setrlimit() failed: not locking into RAM"); - } - else { - if (mlockall(MCL_CURRENT|MCL_FUTURE) < 0) { - LOG(LOGS_ERR, "mlockall() failed"); - } - else { - DEBUG_LOG("Successfully locked into RAM"); - } - } - } -} -#endif /* HAVE_MLOCKALL */ - -/* ================================================== */ - int SYS_Linux_CheckKernelVersion(int req_major, int req_minor) { @@ -701,35 +640,17 @@ SYS_Linux_CheckKernelVersion(int req_major, int req_minor) #define PHC_READINGS 10 static int -get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, - struct timespec *sys_ts, double *err) +process_phc_readings(struct timespec ts[][3], int n, double precision, + struct timespec *phc_ts, struct timespec *sys_ts, double *err) { - struct ptp_sys_offset sys_off; - struct timespec ts1, ts2, ts3, phc_tss[PHC_READINGS], sys_tss[PHC_READINGS]; - double min_delay = 0.0, delays[PHC_READINGS], phc_sum, sys_sum, sys_prec; - int i, n; + double min_delay = 0.0, delays[PTP_MAX_SAMPLES], phc_sum, sys_sum, sys_prec; + int i, combined; - /* Silence valgrind */ - memset(&sys_off, 0, sizeof (sys_off)); - - sys_off.n_samples = PHC_READINGS; - - if (ioctl(phc_fd, PTP_SYS_OFFSET, &sys_off)) { - DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno)); + if (n > PTP_MAX_SAMPLES) return 0; - } - for (i = 0; i < PHC_READINGS; i++) { - ts1.tv_sec = sys_off.ts[i * 2].sec; - ts1.tv_nsec = sys_off.ts[i * 2].nsec; - ts2.tv_sec = sys_off.ts[i * 2 + 1].sec; - ts2.tv_nsec = sys_off.ts[i * 2 + 1].nsec; - ts3.tv_sec = sys_off.ts[i * 2 + 2].sec; - ts3.tv_nsec = sys_off.ts[i * 2 + 2].nsec; - - sys_tss[i] = ts1; - phc_tss[i] = ts2; - delays[i] = UTI_DiffTimespecsToDouble(&ts3, &ts1); + for (i = 0; i < n; i++) { + delays[i] = UTI_DiffTimespecsToDouble(&ts[i][2], &ts[i][0]); if (delays[i] < 0.0) { /* Step in the middle of a PHC reading? */ @@ -744,23 +665,92 @@ get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, sys_prec = LCL_GetSysPrecisionAsQuantum(); /* Combine best readings */ - for (i = n = 0, phc_sum = sys_sum = 0.0; i < PHC_READINGS; i++) { + for (i = combined = 0, phc_sum = sys_sum = 0.0; i < n; i++) { if (delays[i] > min_delay + MAX(sys_prec, precision)) continue; - phc_sum += UTI_DiffTimespecsToDouble(&phc_tss[i], &phc_tss[0]); - sys_sum += UTI_DiffTimespecsToDouble(&sys_tss[i], &sys_tss[0]) + delays[i] / 2.0; - n++; + phc_sum += UTI_DiffTimespecsToDouble(&ts[i][1], &ts[0][1]); + sys_sum += UTI_DiffTimespecsToDouble(&ts[i][0], &ts[0][0]) + delays[i] / 2.0; + combined++; } - assert(n); + assert(combined); - UTI_AddDoubleToTimespec(&phc_tss[0], phc_sum / n, phc_ts); - UTI_AddDoubleToTimespec(&sys_tss[0], sys_sum / n, sys_ts); + UTI_AddDoubleToTimespec(&ts[0][1], phc_sum / combined, phc_ts); + UTI_AddDoubleToTimespec(&ts[0][0], sys_sum / combined, sys_ts); *err = MAX(min_delay / 2.0, precision); return 1; } + +/* ================================================== */ + +static int +get_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, + struct timespec *sys_ts, double *err) +{ + struct timespec ts[PHC_READINGS][3]; + struct ptp_sys_offset sys_off; + int i; + + /* Silence valgrind */ + memset(&sys_off, 0, sizeof (sys_off)); + + sys_off.n_samples = PHC_READINGS; + + if (ioctl(phc_fd, PTP_SYS_OFFSET, &sys_off)) { + DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET", strerror(errno)); + return 0; + } + + for (i = 0; i < PHC_READINGS; i++) { + ts[i][0].tv_sec = sys_off.ts[i * 2].sec; + ts[i][0].tv_nsec = sys_off.ts[i * 2].nsec; + ts[i][1].tv_sec = sys_off.ts[i * 2 + 1].sec; + ts[i][1].tv_nsec = sys_off.ts[i * 2 + 1].nsec; + ts[i][2].tv_sec = sys_off.ts[i * 2 + 2].sec; + ts[i][2].tv_nsec = sys_off.ts[i * 2 + 2].nsec; + } + + return process_phc_readings(ts, PHC_READINGS, precision, phc_ts, sys_ts, err); +} + +/* ================================================== */ + +static int +get_extended_phc_sample(int phc_fd, double precision, struct timespec *phc_ts, + struct timespec *sys_ts, double *err) +{ +#ifdef PTP_SYS_OFFSET_EXTENDED + struct timespec ts[PHC_READINGS][3]; + struct ptp_sys_offset_extended sys_off; + int i; + + /* Silence valgrind */ + memset(&sys_off, 0, sizeof (sys_off)); + + sys_off.n_samples = PHC_READINGS; + + if (ioctl(phc_fd, PTP_SYS_OFFSET_EXTENDED, &sys_off)) { + DEBUG_LOG("ioctl(%s) failed : %s", "PTP_SYS_OFFSET_EXTENDED", strerror(errno)); + return 0; + } + + for (i = 0; i < PHC_READINGS; i++) { + ts[i][0].tv_sec = sys_off.ts[i][0].sec; + ts[i][0].tv_nsec = sys_off.ts[i][0].nsec; + ts[i][1].tv_sec = sys_off.ts[i][1].sec; + ts[i][1].tv_nsec = sys_off.ts[i][1].nsec; + ts[i][2].tv_sec = sys_off.ts[i][2].sec; + ts[i][2].tv_nsec = sys_off.ts[i][2].nsec; + } + + return process_phc_readings(ts, PHC_READINGS, precision, phc_ts, sys_ts, err); +#else + return 0; +#endif +} + /* ================================================== */ static int @@ -834,6 +824,10 @@ SYS_Linux_GetPHCSample(int fd, int nocrossts, double precision, int *reading_mod get_precise_phc_sample(fd, precision, phc_ts, sys_ts, err)) { *reading_mode = 2; return 1; + } else if ((*reading_mode == 3 || !*reading_mode) && + get_extended_phc_sample(fd, precision, phc_ts, sys_ts, err)) { + *reading_mode = 3; + return 1; } else if ((*reading_mode == 1 || !*reading_mode) && get_phc_sample(fd, precision, phc_ts, sys_ts, err)) { *reading_mode = 1; |