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 */