@cryptotaxi247 / netdata-1 / commits / e0d6a2f5f

When running a binary with CLOCK_BOOTTIME defined on a system with a linux (#5415)

kernel older than Linux 2.6.39 the clock_gettime(2) system call fails with EINVAL. In that case it must fall-back to CLOCK_MONOTONIC.

Markos Fountoulakis committed Feb 18, 2019 at 18:29 UTC e0d6a2f5fac251479c99463d70e65d9674a50796
3 files changed +18 -3
daemon/main.c
+1
@@ -955,6 +955,7 @@ int main(int argc, char **argv) {
955 if(i > 0)
956 mallopt(M_ARENA_MAX, 1);
957 #endif
958 + test_clock_boottime();
959
960 // prepare configuration environment variables for the plugins
961
libnetdata/clocks/clocks.c
+11 -3
@@ -2,6 +2,8 @@
2
3 #include "../libnetdata.h"
4
5 +static int clock_boottime_valid = 1;
6 +
7 #ifndef HAVE_CLOCK_GETTIME
8 inline int clock_gettime(clockid_t clk_id, struct timespec *ts) {
9 struct timeval tv;
@@ -15,6 +17,12 @@ inline int clock_gettime(clockid_t clk_id, struct timespec *ts) {
17 }
18 #endif
19
20 +void test_clock_boottime(void) {
21 + struct timespec ts;
22 + if(clock_gettime(CLOCK_BOOTTIME, &ts) == -1 && errno == EINVAL)
23 + clock_boottime_valid = 0;
24 +}
25 +
26 static inline time_t now_sec(clockid_t clk_id) {
27 struct timespec ts;
28 if(unlikely(clock_gettime(clk_id, &ts) == -1)) {
@@ -73,15 +81,15 @@ inline int now_monotonic_timeval(struct timeval *tv) {
81 }
82
83 inline time_t now_boottime_sec(void) {
76 - return now_sec(CLOCK_BOOTTIME);
84 + return now_sec(likely(clock_boottime_valid) ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
85 }
86
87 inline usec_t now_boottime_usec(void) {
80 - return now_usec(CLOCK_BOOTTIME);
88 + return now_usec(likely(clock_boottime_valid) ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
89 }
90
91 inline int now_boottime_timeval(struct timeval *tv) {
84 - return now_timeval(CLOCK_BOOTTIME, tv);
92 + return now_timeval(likely(clock_boottime_valid) ? CLOCK_BOOTTIME : CLOCK_MONOTONIC, tv);
93 }
94
95 inline usec_t timeval_usec(struct timeval *tv) {
libnetdata/clocks/clocks.h
+6
@@ -130,4 +130,10 @@ extern usec_t heartbeat_monotonic_dt_to_now_usec(heartbeat_t *hb);
130
131 extern int sleep_usec(usec_t usec);
132
133 +/*
134 + * When running a binary with CLOCK_BOOTTIME defined on a system with a linux kernel older than Linux 2.6.39 the
135 + * clock_gettime(2) system call fails with EINVAL. In that case it must fall-back to CLOCK_MONOTONIC.
136 + */
137 +void test_clock_boottime(void);
138 +
139 #endif /* NETDATA_CLOCKS_H */