diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-23 17:40:40 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2014-10-24 19:24:32 +0200 |
commit | b54030de222ff5d1cf5c6643cda38a8d1552dabf (patch) | |
tree | 529c2954cf039b1f7aeaf72e5affe15f4c6a8bf4 | |
parent | e9bfd0e29c164b79205c23617b199573b78abd5b (diff) | |
download | NetworkManager-b54030de222ff5d1cf5c6643cda38a8d1552dabf.tar.gz |
core: Fall back to CLOCK_MONOTONIC if CLOCK_BOOTTIME unsupported
It was added fairly recently (2.6.39), this breaks run (and test run in mock)
on RHEL-6 with 2.6.32.
-rw-r--r-- | src/NetworkManagerUtils.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 66da861daf..1d80c3a58b 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -1740,15 +1740,36 @@ static gint64 monotonic_timestamp_offset_sec; static void monotonic_timestamp_get (struct timespec *tp) { - static gboolean initialized = FALSE; - int err; - - err = clock_gettime (CLOCK_BOOTTIME, tp); + static int clock_mode = 0; + gboolean first_time = FALSE; + int err = 0; + + switch (clock_mode) { + case 0: + /* the clock is not yet initialized (first run) */ + err = clock_gettime (CLOCK_BOOTTIME, tp); + if (err == -1 && errno == EINVAL) { + clock_mode = 2; + err = clock_gettime (CLOCK_MONOTONIC, tp); + } else + clock_mode = 1; + first_time = TRUE; + break; + case 1: + /* default, return CLOCK_BOOTTIME */ + err = clock_gettime (CLOCK_BOOTTIME, tp); + break; + case 2: + /* fallback, return CLOCK_MONOTONIC. Kernels prior to 2.6.39 + * don't support CLOCK_BOOTTIME. */ + err = clock_gettime (CLOCK_MONOTONIC, tp); + break; + } g_assert (err == 0); (void)err; g_assert (tp->tv_nsec >= 0 && tp->tv_nsec < NM_UTILS_NS_PER_SECOND); - if (G_LIKELY (initialized)) + if (G_LIKELY (!first_time)) return; /* Calculate an offset for the time stamp. @@ -1765,7 +1786,6 @@ monotonic_timestamp_get (struct timespec *tp) * wraps (~68 years). **/ monotonic_timestamp_offset_sec = (- ((gint64) tp->tv_sec)) + 1; - initialized = TRUE; if (nm_logging_enabled (LOGL_DEBUG, LOGD_CORE)) { time_t now = time (NULL); @@ -1774,8 +1794,9 @@ monotonic_timestamp_get (struct timespec *tp) strftime (s, sizeof (s), "%Y-%m-%d %H:%M:%S", localtime_r (&now, &tm)); nm_log_dbg (LOGD_CORE, "monotonic timestamp started counting 1.%09ld seconds ago with " - "an offset of %lld.0 seconds to CLOCK_BOOTTIME (local time is %s)", - tp->tv_nsec, (long long) -monotonic_timestamp_offset_sec, s); + "an offset of %lld.0 seconds to %s (local time is %s)", + tp->tv_nsec, (long long) -monotonic_timestamp_offset_sec, + clock_mode == 1 ? "CLOCK_BOOTTIME" : "CLOCK_MONOTONIC", s); } } |