core: Detect initial timer state from serialized data

System Internals / systemd - Michal Koutný [suse.com] - 21 November 2018 10:28 EST

We keep a mark whether a single-shot timer was triggered in the caller's
variable initial. When such a timer elapses while we are serializing/deserializing the inner state, we consider the timer incorrectly as elapsed and don't trigger it later.

This patch exploits last_trigger timestamp that we already serialize, hence we can eliminate the argument initial completely.

A reproducer for OnBootSec= timers: cat >repro.c <- Compile: gcc repro.c -o repro
- Run: ./repro
*/ #include #include #include #include #include #include #include #include

int main(int argc, char *argv[]) { char command[1024]; int pause;

struct timespec now;

while (1) { usleep(rand() % 200000); // prevent periodic repeats clock_gettime(CLOCK_MONOTONIC, &now); printf("%i\n", now.tv_sec);

system("rm -f $PWD/mark"); snprintf(command, 1024, "systemd-run --user --on-boot=%i --timer-property=AccuracySec=100ms " "touch $PWD/mark", now.tv_sec + 1); system(command); system("systemctl --user list-timers"); pause = (1000000000 - now.tv_nsec)/1000 - 70000; // fiddle to hit the middle of reloading usleep(pause > 0 ? pause : 0); system("systemctl --user daemon-reload"); sync(); sleep(2); if (open("./mark", 0) < 0) if (errno == ENOENT) { printf("mark file does not exist\n"); break; } }

return 0; } EOD

aa1f95d26 core: Detect initial timer state from serialized data
src/core/timer.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

Upstream: github.com


  • Share