timer.c revision 82a2b6bb5e4e5d294f09af778c48974a7857afb6
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/***
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen***/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <errno.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "unit-name.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "timer.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "dbus-timer.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "special.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "bus-util.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "bus-error.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include "mkdir.h"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_DEAD] = UNIT_INACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_WAITING] = UNIT_ACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_RUNNING] = UNIT_ACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_ELAPSED] = UNIT_ACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_FAILED] = UNIT_FAILED
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_init(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u->load_state == UNIT_STUB);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_monotonic_or_boottime = USEC_INFINITY;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_realtime = USEC_INFINITY;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->accuracy_usec = u->manager->default_timer_accuracy_usec;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poetteringvoid timer_free_values(Timer *t) {
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering TimerValue *v;
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering assert(t);
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while ((v = t->values)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_REMOVE(value, t->values, v);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->calendar_spec)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen calendar_spec_free(v->calendar_spec);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(v);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_done(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_free_values(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen free(t->stamp_path);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_verify(Timer *t) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(t)->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!t->values) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_error(UNIT(t)->id, "%s lacks value setting. Refusing.", UNIT(t)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -EINVAL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_add_default_dependencies(Timer *t) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerValue *v;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_FOREACH(value, v, t->values) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->base == TIMER_CALENDAR) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_dependency_by_name(UNIT(t), UNIT_AFTER, SPECIAL_TIME_SYNC_TARGET, NULL, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return r;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl break;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl }
b7e7184634d573fb73143210962acce205f37f61Michael Biebl }
b7e7184634d573fb73143210962acce205f37f61Michael Biebl }
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl}
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Bieblstatic int timer_setup_persistent(Timer *t) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl int r;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl assert(t);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (!t->persistent)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return 0;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->stamp_path = strappend("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
91e7bad45dced1cb2dfaac79337bb08d6e2b74a9Andreas Henriksson } else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen const char *e;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen e = getenv("XDG_DATA_HOME");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (e)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->stamp_path = strjoin(e, "/systemd/timers/stamp-", UNIT(t)->id, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *h = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = get_home_dir(&h);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_error_errno(r, "Failed to determine home directory: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id, NULL);
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen }
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen }
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen if (!t->stamp_path)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return log_oom();
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_load(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt assert(u);
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt assert(u->load_state == UNIT_STUB);
9993ef2e9817b35b1d467707bef12b2a140b62dcLennart Poettering
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt r = unit_load_fragment_and_dropin(u);
9993ef2e9817b35b1d467707bef12b2a140b62dcLennart Poettering if (r < 0)
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt return r;
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u->load_state == UNIT_LOADED) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *x;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_load_related_unit(u, ".service", &x);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
aad0a2c80097926757d4385e5f5492082d47f006Zbigniew Jędrzejewski-Szmek return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = timer_setup_persistent(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen return r;
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u->default_dependencies) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = timer_add_default_dependencies(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return timer_verify(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_dump(Unit *u, FILE *f, const char *prefix) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char buf[FORMAT_TIMESPAN_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Unit *trigger;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerValue *v;
d171ed1c50ba64928b7fb30ee2ae729fdfe0826bThomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen trigger = UNIT_TRIGGER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sTimer State: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sResult: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sUnit: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sPersistent: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sWakeSystem: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sAccuracy: %s\n",
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen prefix, timer_state_to_string(t->state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, timer_result_to_string(t->result),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, trigger ? trigger->id : "n/a",
31938a8560a664c32a9d72f1fc2d4347b232e6e9Michal Schmidt prefix, yes_no(t->persistent),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, yes_no(t->wake_system),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_FOREACH(value, v, t->values) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->base == TIMER_CALENDAR) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *p = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen calendar_spec_to_string(v->calendar_spec, &p);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s%s: %s\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_base_to_string(v->base),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen strna(p));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char timespan1[FORMAT_TIMESPAN_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen fprintf(f,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s%s: %s\n",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_base_to_string(v->base),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen format_timespan(timespan1, sizeof(timespan1), v->value, 0));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_set_state(Timer *t, TimerState state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerState old_state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen old_state = t->state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->state = state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state != TIMER_WAITING) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state != old_state)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s changed %s -> %s", UNIT(t)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_state_to_string(old_state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_state_to_string(state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_enter_waiting(Timer *t, bool initial);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poetteringstatic int timer_coldplug(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t->state == TIMER_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->deserialized_state != t->state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->deserialized_state == TIMER_WAITING)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_waiting(t, false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, t->deserialized_state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_enter_dead(Timer *t, TimerResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f != TIMER_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt}
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering
40780877c19ef408da8ab21f4156cfc153f94b5cMartin Pittstatic usec_t monotonic_to_boottime(usec_t t) {
3315f085178f46155fda345d9526c09083b45946Lennart Poettering usec_t a, b;
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering
3315f085178f46155fda345d9526c09083b45946Lennart Poettering if (t <= 0)
3315f085178f46155fda345d9526c09083b45946Lennart Poettering return 0;
29e0e6d8c1f7f648b7c998880d034eaa3e58c53aMartin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a = now(CLOCK_BOOTTIME);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = now(CLOCK_MONOTONIC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t + a > b)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return t + a - b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
3315f085178f46155fda345d9526c09083b45946Lennart Poetteringstatic void timer_enter_waiting(Timer *t, bool initial) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen bool found_monotonic = false, found_realtime = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t ts_realtime, ts_monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t base = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerValue *v;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* If we shall wake the system we use the boottime clock
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * rather than the monotonic clock. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ts_realtime = now(CLOCK_REALTIME);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ts_monotonic = now(t->wake_system ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_FOREACH(value, v, t->values) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->disabled)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->base == TIMER_CALENDAR) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen usec_t b;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* If we know the last time this was
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * triggered, schedule the job based relative
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * to that. If we don't just start from
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * now. */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts_realtime;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!found_realtime)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_realtime = v->next_elapse;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt t->next_elapse_realtime = MIN(t->next_elapse_realtime, v->next_elapse);
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen found_realtime = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (v->base) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_ACTIVE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state_translation_table[t->state] == UNIT_ACTIVE)
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering base = UNIT(t)->inactive_exit_timestamp.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = ts_monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_BOOT:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* CLOCK_MONOTONIC equals the uptime on Linux */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_STARTUP:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = UNIT(t)->manager->userspace_timestamp.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_UNIT_ACTIVE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (base <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = t->last_trigger.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (base <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_UNIT_INACTIVE:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (base <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = t->last_trigger.monotonic;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (base <= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen default:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_not_reached("Unknown timer base");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->wake_system)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen base = monotonic_to_boottime(base);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen v->next_elapse = base + v->value;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!initial && v->next_elapse < ts_monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* This is a one time trigger, disable it now */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen v->disabled = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen continue;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!found_monotonic)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_monotonic_or_boottime = v->next_elapse;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_monotonic_or_boottime = MIN(t->next_elapse_monotonic_or_boottime, v->next_elapse);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen found_monotonic = true;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!found_monotonic && !found_realtime) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id, "%s: Timer is elapsed.", UNIT(t)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, TIMER_ELAPSED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (found_monotonic) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char buf[FORMAT_TIMESPAN_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id, "%s: Monotonic timer elapses in %s.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(t)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen format_timespan(buf, sizeof(buf), t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0, 0));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (t->monotonic_event_source) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic_or_boottime);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_add_time(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(t)->manager->event,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &t->monotonic_event_source,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->wake_system ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_monotonic_or_boottime, t->accuracy_usec,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_dispatch, t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (t->monotonic_event_source) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_OFF);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (found_realtime) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen char buf[FORMAT_TIMESTAMP_MAX];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id, "%s: Realtime timer elapses at %s.", UNIT(t)->id, format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->realtime_event_source) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_time(t->realtime_event_source, t->next_elapse_realtime);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_add_time(
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(t)->manager->event,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen &t->realtime_event_source,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->wake_system ? CLOCK_REALTIME_ALARM : CLOCK_REALTIME,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->next_elapse_realtime, t->accuracy_usec,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_dispatch, t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (t->realtime_event_source) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_OFF);
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, TIMER_WAITING);
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek log_unit_warning_errno(UNIT(t)->id, r, "%s failed to enter waiting state: %m", UNIT(t)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_enter_running(Timer *t) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
b7e7184634d573fb73143210962acce205f37f61Michael Biebl /* Don't start job if we are supposed to go down */
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt if (unit_stop_pending(UNIT(t)))
b7e7184634d573fb73143210962acce205f37f61Michael Biebl return;
b7e7184634d573fb73143210962acce205f37f61Michael Biebl
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_TRIGGER(UNIT(t)),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JOB_REPLACE, true, &error, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen goto fail;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen dual_timestamp_get(&t->last_trigger);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->stamp_path)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen touch_file(t->stamp_path, true, t->last_trigger.realtime, UID_INVALID, GID_INVALID, 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, TIMER_RUNNING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenfail:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_warning(UNIT(t)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to queue unit startup job: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(t)->id, bus_error_message(&error, r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
805b573fad06b845502e76f3db3a0efa7583149dLukas Nykryn
805b573fad06b845502e76f3db3a0efa7583149dLukas Nykrynstatic int timer_start(Unit *u) {
805b573fad06b845502e76f3db3a0efa7583149dLukas Nykryn Timer *t = TIMER(u);
805b573fad06b845502e76f3db3a0efa7583149dLukas Nykryn TimerValue *v;
805b573fad06b845502e76f3db3a0efa7583149dLukas Nykryn
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return -ENOENT;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->last_trigger = DUAL_TIMESTAMP_NULL;
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering /* Reenable all timers that depend on unit activation time */
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek LIST_FOREACH(value, v, t->values)
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek if (v->base == TIMER_ACTIVE)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen v->disabled = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->stamp_path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen struct stat st;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek if (stat(t->stamp_path, &st) >= 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->last_trigger.realtime = timespec_load(&st.st_atim);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (errno == ENOENT)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* The timer has never run before,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * make sure a stamp file exists.
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen touch_file(t->stamp_path, true, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a2a5291b3f5ab6ed4c92f51d0fd10a03047380d8Zbigniew Jędrzejewski-Szmek t->result = TIMER_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_waiting(t, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_stop(Unit *u) {
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_dead(t, TIMER_SUCCESS);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(f);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(fds);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->last_trigger.realtime > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "last-trigger-realtime", "%" PRIu64, t->last_trigger.realtime);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->last_trigger.monotonic > 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "last-trigger-monotonic", "%" PRIu64, t->last_trigger.monotonic);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen int r;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(key);
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering assert(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(fds);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (streq(key, "state")) {
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek TimerState state;
79008bddf679a5e0900369950eb346c9fa687107Lennart Poettering
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek state = timer_state_from_string(value);
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek if (state < 0)
b2fadec6048adb3596f2633cb7fe7a49f5937a18Zbigniew Jędrzejewski-Szmek log_unit_debug(u->id, "Failed to parse state value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->deserialized_state = state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "result")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerResult f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f = timer_result_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (f < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(u->id, "Failed to parse result value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (f != TIMER_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->result = f;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "last-trigger-realtime")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = safe_atou64(value, &t->last_trigger.realtime);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(u->id, "Failed to parse last-trigger-realtime value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "last-trigger-monotonic")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = safe_atou64(value, &t->last_trigger.monotonic);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (r < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(u->id, "Failed to parse last-trigger-monotonic value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(u->id, "Unknown serialization key '%s'", key);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static UnitActiveState timer_active_state(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return state_translation_table[TIMER(u)->state];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen_pure_ static const char *timer_sub_state_to_string(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return timer_state_to_string(TIMER(u)->state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->state != TIMER_WAITING)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id, "Timer elapsed on %s", UNIT(t)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_running(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return 0;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_trigger_notify(Unit *u, Unit *other) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen TimerValue *v;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(other);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (other->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Reenable all timers that depend on unit state */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen LIST_FOREACH(value, v, t->values)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (v->base == TIMER_UNIT_ACTIVE ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen v->base == TIMER_UNIT_INACTIVE)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen v->disabled = false;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen switch (t->state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_WAITING:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_ELAPSED:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Recalculate sleep time */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_waiting(t, false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_RUNNING:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(UNIT(t)->id, "%s got notified about unit deactivation.", UNIT(t)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_waiting(t, false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_DEAD:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen case TIMER_FAILED:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen break;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen default:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert_not_reached("Unknown timer state");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen }
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_reset_failed(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(t);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->state == TIMER_FAILED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_set_state(t, TIMER_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen t->result = TIMER_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void timer_time_change(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Timer *t = TIMER(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (t->state != TIMER_WAITING)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_unit_debug(u->id, "%s: time change, recalculating next elapse.", u->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen timer_enter_waiting(t, false);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen}
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const char* const timer_state_table[_TIMER_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_DEAD] = "dead",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_WAITING] = "waiting",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_RUNNING] = "running",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_ELAPSED] = "elapsed",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_FAILED] = "failed"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const char* const timer_base_table[_TIMER_BASE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_ACTIVE] = "OnActiveSec",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_BOOT] = "OnBootSec",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_STARTUP] = "OnStartupSec",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_CALENDAR] = "OnCalendar"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const char* const timer_result_table[_TIMER_RESULT_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_SUCCESS] = "success",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [TIMER_FAILURE_RESOURCES] = "resources"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenconst UnitVTable timer_vtable = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .object_size = sizeof(Timer),
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering .sections =
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Unit\0"
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering "Timer\0"
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering "Install\0",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .private_section = "Timer",
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .init = timer_init,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .done = timer_done,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .load = timer_load,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering .coldplug = timer_coldplug,
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering .dump = timer_dump,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .start = timer_start,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .stop = timer_stop,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering .serialize = timer_serialize,
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering .deserialize_item = timer_deserialize_item,
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering .active_state = timer_active_state,
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering .sub_state_to_string = timer_sub_state_to_string,
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering .trigger_notify = timer_trigger_notify,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt .reset_failed = timer_reset_failed,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt .time_change = timer_time_change,
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt .bus_interface = "org.freedesktop.systemd1.Timer",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .bus_vtable = bus_timer_vtable,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .bus_set_property = bus_timer_set_property,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .can_transient = true,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen};
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen