2b61bbee11
- Resolves: upstream #3154 - sssd exits if clock is adjusted backwards after boot - Resolves: upstream #3163 - resolving IPA nested user group is broken in 1.14
98 lines
3.1 KiB
Diff
98 lines
3.1 KiB
Diff
From 2263fb23bdbbf313535edf54440fe20627b57d7f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
|
Date: Mon, 22 Aug 2016 13:15:04 +0200
|
|
Subject: [PATCH 08/39] watchdog: cope with time shift
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
When a time is changed into the past during sssd runtime
|
|
(e.g. on boot during time correction), it is possible that
|
|
we never hit watchdog tevent timer since it is based on
|
|
system time.
|
|
|
|
This patch adds a past-time shift detection mechanism. If a time
|
|
shift is detected we restart watchdog.
|
|
|
|
Resolves:
|
|
https://fedorahosted.org/sssd/ticket/3154
|
|
|
|
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
|
(cherry picked from commit b8ceaeb80cffb00c26390913ea959b77f7e848b9)
|
|
---
|
|
src/util/util_watchdog.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 41 insertions(+)
|
|
|
|
diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
|
|
index 5032fddba1b94b3fc7e560162c392dfa57d699cf..1c27d73f13b3042ecb549a2184e1368e8339d199 100644
|
|
--- a/src/util/util_watchdog.c
|
|
+++ b/src/util/util_watchdog.c
|
|
@@ -29,8 +29,39 @@ struct watchdog_ctx {
|
|
struct timeval interval;
|
|
struct tevent_timer *te;
|
|
volatile int ticks;
|
|
+
|
|
+ /* To detect time shift. */
|
|
+ struct tevent_context *ev;
|
|
+ int input_interval;
|
|
+ time_t timestamp;
|
|
} watchdog_ctx;
|
|
|
|
+static bool watchdog_detect_timeshift(void)
|
|
+{
|
|
+ time_t prev_time;
|
|
+ time_t cur_time;
|
|
+ errno_t ret;
|
|
+
|
|
+ prev_time = watchdog_ctx.timestamp;
|
|
+ cur_time = watchdog_ctx.timestamp = time(NULL);
|
|
+ if (cur_time < prev_time) {
|
|
+ /* Time shift detected. We need to restart watchdog. */
|
|
+ DEBUG(SSSDBG_IMPORTANT_INFO, "Time shift detected, "
|
|
+ "restarting watchdog!\n");
|
|
+ teardown_watchdog();
|
|
+ ret = setup_watchdog(watchdog_ctx.ev, watchdog_ctx.input_interval);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to restart watchdog "
|
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
|
+ orderly_shutdown(1);
|
|
+ }
|
|
+
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
/* the watchdog is purposefully *not* handled by the tevent
|
|
* signal handler as it is meant to check if the daemon is
|
|
* still processing the event queue itself. A stuck process
|
|
@@ -38,6 +69,12 @@ struct watchdog_ctx {
|
|
* signals either */
|
|
static void watchdog_handler(int sig)
|
|
{
|
|
+ /* Do not count ticks if time shift was detected
|
|
+ * since watchdog was restarted. */
|
|
+ if (watchdog_detect_timeshift()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
/* if 3 ticks passed by kills itself */
|
|
|
|
if (__sync_add_and_fetch(&watchdog_ctx.ticks, 1) > 3) {
|
|
@@ -101,6 +138,10 @@ int setup_watchdog(struct tevent_context *ev, int interval)
|
|
watchdog_ctx.interval.tv_sec = interval;
|
|
watchdog_ctx.interval.tv_usec = 0;
|
|
|
|
+ watchdog_ctx.ev = ev;
|
|
+ watchdog_ctx.input_interval = interval;
|
|
+ watchdog_ctx.timestamp = time(NULL);
|
|
+
|
|
/* Start the timer */
|
|
/* we give 1 second head start to the watchdog event */
|
|
its.it_value.tv_sec = interval + 1;
|
|
--
|
|
2.9.3
|
|
|