mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
timer: rebase the next elapse timestamp only if timer didn't already run (#39296)
This commit is contained in:
@@ -392,7 +392,8 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
|
||||
continue;
|
||||
|
||||
if (v->base == TIMER_CALENDAR) {
|
||||
usec_t b, rebased, random_offset = 0;
|
||||
bool rebase_after_boot_time = false;
|
||||
usec_t b, random_offset = 0;
|
||||
|
||||
if (t->random_offset_usec != 0)
|
||||
random_offset = timer_get_fixed_delay_hash(t) % t->random_offset_usec;
|
||||
@@ -417,8 +418,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
|
||||
b = t->last_trigger.realtime;
|
||||
else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp))
|
||||
b = UNIT(t)->inactive_exit_timestamp.realtime - random_offset;
|
||||
else
|
||||
else {
|
||||
b = ts.realtime - random_offset;
|
||||
rebase_after_boot_time = true;
|
||||
}
|
||||
|
||||
r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
|
||||
if (r < 0)
|
||||
@@ -426,14 +429,16 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
|
||||
|
||||
v->next_elapse += random_offset;
|
||||
|
||||
/* To make the delay due to RandomizedDelaySec= work even at boot, if the scheduled
|
||||
* time has already passed, set the time when systemd first started as the scheduled
|
||||
* time. Note that we base this on the monotonic timestamp of the boot, not the
|
||||
* realtime one, since the wallclock might have been off during boot. */
|
||||
rebased = map_clock_usec(UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic,
|
||||
CLOCK_MONOTONIC, CLOCK_REALTIME);
|
||||
if (v->next_elapse < rebased)
|
||||
v->next_elapse = rebased;
|
||||
if (rebase_after_boot_time) {
|
||||
/* To make the delay due to RandomizedDelaySec= work even at boot, if the scheduled
|
||||
* time has already passed, set the time when systemd first started as the scheduled
|
||||
* time. Note that we base this on the monotonic timestamp of the boot, not the
|
||||
* realtime one, since the wallclock might have been off during boot. */
|
||||
usec_t rebased = map_clock_usec(UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic,
|
||||
CLOCK_MONOTONIC, CLOCK_REALTIME);
|
||||
if (v->next_elapse < rebased)
|
||||
v->next_elapse = rebased;
|
||||
}
|
||||
|
||||
if (!found_realtime)
|
||||
t->next_elapse_realtime = v->next_elapse;
|
||||
|
||||
@@ -15,11 +15,11 @@ set -o pipefail
|
||||
. "$(dirname "$0")"/util.sh
|
||||
|
||||
UNIT_NAME="timer-RandomizedDelaySec-$RANDOM"
|
||||
TARGET_TS="$(date --date="tomorrow 00:10")"
|
||||
TARGET_TS="$(date --date="tomorrow 00:10" "+%a %Y-%m-%d %H:%M:%S %Z")"
|
||||
TARGET_TS_S="$(date --date="$TARGET_TS" "+%s")"
|
||||
# Maximum possible next elapse timestamp: $TARGET_TS (OnCalendar=) + 22 hours (RandomizedDelaySec=)
|
||||
MAX_NEXT_ELAPSE_REALTIME_S="$((TARGET_TS_S + 22 * 60 * 60))"
|
||||
MAX_NEXT_ELAPSE_REALTIME="$(date --date="@$MAX_NEXT_ELAPSE_REALTIME_S")"
|
||||
MAX_NEXT_ELAPSE_REALTIME="$(date --date="@$MAX_NEXT_ELAPSE_REALTIME_S" "+%a %Y-%m-%d %H:%M:%S %Z")"
|
||||
|
||||
# Let's make sure to return the date & time back to the original state once we're done with our time
|
||||
# shenigans. One way to do this would be to use hwclock, but the RTC in VMs can be unreliable or slow to
|
||||
|
||||
Reference in New Issue
Block a user