|
|
df98bb |
From 73bf41a783edbff1b367e645956ed602de1889e2 Mon Sep 17 00:00:00 2001
|
|
|
df98bb |
From: Insun <iplayinsun@gmail.com>
|
|
|
df98bb |
Date: Sun, 28 Oct 2018 21:26:13 +0900
|
|
|
df98bb |
Subject: [PATCH] core: don't drop timer expired but not yet processed when
|
|
|
df98bb |
system date is changed
|
|
|
df98bb |
|
|
|
df98bb |
There is difference between time set by the user and real elapsed time because of accuracy feature.
|
|
|
df98bb |
If you change the system date(or time) between these times, the timer drops.
|
|
|
df98bb |
|
|
|
df98bb |
You can easily reproduce it with the following command.
|
|
|
df98bb |
-----------------------------------------------------------
|
|
|
df98bb |
$ systemd-run --on-active=3s ls; sleep 3; date -s "`date`"
|
|
|
df98bb |
-----------------------------------------------------------
|
|
|
df98bb |
|
|
|
df98bb |
In the following command, the problem is rarely reproduced. But it exists.
|
|
|
df98bb |
---------------------------------------------------------------------------------------------
|
|
|
df98bb |
$ systemd-run --on-active=3s --timer-property=AccuracySec=1us ls ; sleep 1; date -s "`date`"
|
|
|
df98bb |
---------------------------------------------------------------------------------------------
|
|
|
df98bb |
|
|
|
df98bb |
Note : Global AccuracySec value.
|
|
|
df98bb |
----------------------------------------------------------------------
|
|
|
df98bb |
$ cat /etc/systemd/system.conf
|
|
|
df98bb |
DefaultTimerAccuracySec=1min
|
|
|
df98bb |
----------------------------------------------------------------------
|
|
|
df98bb |
|
|
|
df98bb |
(cherry picked from commit fee04d7f3ab810e99b97535ca5fda2f9517acda9)
|
|
|
df98bb |
|
|
|
df98bb |
Related: #1899402
|
|
|
df98bb |
---
|
|
|
df98bb |
src/core/timer.c | 18 +++++++++---------
|
|
|
df98bb |
1 file changed, 9 insertions(+), 9 deletions(-)
|
|
|
df98bb |
|
|
|
df98bb |
diff --git a/src/core/timer.c b/src/core/timer.c
|
|
|
df98bb |
index 281ac7f97f..ef240a6f19 100644
|
|
|
df98bb |
--- a/src/core/timer.c
|
|
|
df98bb |
+++ b/src/core/timer.c
|
|
|
df98bb |
@@ -262,7 +262,7 @@ static void timer_set_state(Timer *t, TimerState state) {
|
|
|
df98bb |
unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], 0);
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
-static void timer_enter_waiting(Timer *t, bool initial);
|
|
|
df98bb |
+static void timer_enter_waiting(Timer *t, bool initial, bool time_change);
|
|
|
df98bb |
|
|
|
df98bb |
static int timer_coldplug(Unit *u) {
|
|
|
df98bb |
Timer *t = TIMER(u);
|
|
|
df98bb |
@@ -274,7 +274,7 @@ static int timer_coldplug(Unit *u) {
|
|
|
df98bb |
return 0;
|
|
|
df98bb |
|
|
|
df98bb |
if (t->deserialized_state == TIMER_WAITING)
|
|
|
df98bb |
- timer_enter_waiting(t, false);
|
|
|
df98bb |
+ timer_enter_waiting(t, false, false);
|
|
|
df98bb |
else
|
|
|
df98bb |
timer_set_state(t, t->deserialized_state);
|
|
|
df98bb |
|
|
|
df98bb |
@@ -334,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) {
|
|
|
df98bb |
log_unit_debug(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
-static void timer_enter_waiting(Timer *t, bool initial) {
|
|
|
df98bb |
+static void timer_enter_waiting(Timer *t, bool initial, bool time_change) {
|
|
|
df98bb |
bool found_monotonic = false, found_realtime = false;
|
|
|
df98bb |
bool leave_around = false;
|
|
|
df98bb |
triple_timestamp ts;
|
|
|
df98bb |
@@ -444,7 +444,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
|
|
df98bb |
|
|
|
df98bb |
v->next_elapse = usec_add(usec_shift_clock(base, CLOCK_MONOTONIC, TIMER_MONOTONIC_CLOCK(t)), v->value);
|
|
|
df98bb |
|
|
|
df98bb |
- if (!initial &&
|
|
|
df98bb |
+ if (!initial && !time_change &&
|
|
|
df98bb |
v->next_elapse < triple_timestamp_by_clock(&ts, TIMER_MONOTONIC_CLOCK(t)) &&
|
|
|
df98bb |
IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
|
|
|
df98bb |
/* This is a one time trigger, disable it now */
|
|
|
df98bb |
@@ -642,7 +642,7 @@ static int timer_start(Unit *u) {
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
t->result = TIMER_SUCCESS;
|
|
|
df98bb |
- timer_enter_waiting(t, true);
|
|
|
df98bb |
+ timer_enter_waiting(t, true, false);
|
|
|
df98bb |
return 1;
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
@@ -764,14 +764,14 @@ static void timer_trigger_notify(Unit *u, Unit *other) {
|
|
|
df98bb |
case TIMER_ELAPSED:
|
|
|
df98bb |
|
|
|
df98bb |
/* Recalculate sleep time */
|
|
|
df98bb |
- timer_enter_waiting(t, false);
|
|
|
df98bb |
+ timer_enter_waiting(t, false, false);
|
|
|
df98bb |
break;
|
|
|
df98bb |
|
|
|
df98bb |
case TIMER_RUNNING:
|
|
|
df98bb |
|
|
|
df98bb |
if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
|
|
|
df98bb |
log_unit_debug(UNIT(t), "Got notified about unit deactivation.");
|
|
|
df98bb |
- timer_enter_waiting(t, false);
|
|
|
df98bb |
+ timer_enter_waiting(t, false, false);
|
|
|
df98bb |
}
|
|
|
df98bb |
break;
|
|
|
df98bb |
|
|
|
df98bb |
@@ -813,7 +813,7 @@ static void timer_time_change(Unit *u) {
|
|
|
df98bb |
t->last_trigger.realtime = ts;
|
|
|
df98bb |
|
|
|
df98bb |
log_unit_debug(u, "Time change, recalculating next elapse.");
|
|
|
df98bb |
- timer_enter_waiting(t, false);
|
|
|
df98bb |
+ timer_enter_waiting(t, false, true);
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
static void timer_timezone_change(Unit *u) {
|
|
|
df98bb |
@@ -825,7 +825,7 @@ static void timer_timezone_change(Unit *u) {
|
|
|
df98bb |
return;
|
|
|
df98bb |
|
|
|
df98bb |
log_unit_debug(u, "Timezone change, recalculating next elapse.");
|
|
|
df98bb |
- timer_enter_waiting(t, false);
|
|
|
df98bb |
+ timer_enter_waiting(t, false, false);
|
|
|
df98bb |
}
|
|
|
df98bb |
|
|
|
df98bb |
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
|