1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "unit-name.h"
27 #include "dbus-timer.h"
30 #include "bus-error.h"
33 static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
34 [TIMER_DEAD] = UNIT_INACTIVE,
35 [TIMER_WAITING] = UNIT_ACTIVE,
36 [TIMER_RUNNING] = UNIT_ACTIVE,
37 [TIMER_ELAPSED] = UNIT_ACTIVE,
38 [TIMER_FAILED] = UNIT_FAILED
41 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata);
43 static void timer_init(Unit *u) {
47 assert(u->load_state == UNIT_STUB);
49 t->next_elapse_monotonic_or_boottime = (usec_t) -1;
50 t->next_elapse_realtime = (usec_t) -1;
51 t->accuracy_usec = u->manager->default_timer_accuracy_usec;
54 void timer_free_values(Timer *t) {
59 while ((v = t->values)) {
60 LIST_REMOVE(value, t->values, v);
63 calendar_spec_free(v->calendar_spec);
69 static void timer_done(Unit *u) {
76 t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
77 t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
82 static int timer_verify(Timer *t) {
85 if (UNIT(t)->load_state != UNIT_LOADED)
89 log_error_unit(UNIT(t)->id, "%s lacks value setting. Refusing.", UNIT(t)->id);
96 static int timer_add_default_dependencies(Timer *t) {
101 r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
105 if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
106 r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
111 return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
114 static void update_stampfile(Timer *t, usec_t timestamp) {
115 _cleanup_close_ int fd = -1;
117 mkdir_parents_label(t->stamp_path, 0755);
119 /* Update the file atime + mtime, if we can */
120 fd = open(t->stamp_path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
122 struct timespec ts[2];
124 timespec_store(&ts[0], timestamp);
131 static int timer_setup_persistent(Timer *t) {
139 if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
141 r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
145 t->stamp_path = strappend("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
149 e = getenv("XDG_DATA_HOME");
151 t->stamp_path = strjoin(e, "/systemd/timers/", UNIT(t)->id, NULL);
154 _cleanup_free_ char *h = NULL;
156 r = get_home_dir(&h);
158 log_error("Failed to determine home directory: %s", strerror(-r));
162 t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id, NULL);
172 static int timer_load(Unit *u) {
177 assert(u->load_state == UNIT_STUB);
179 r = unit_load_fragment_and_dropin(u);
183 if (u->load_state == UNIT_LOADED) {
185 if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
188 r = unit_load_related_unit(u, ".service", &x);
192 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
197 r = timer_setup_persistent(t);
201 if (u->default_dependencies) {
202 r = timer_add_default_dependencies(t);
208 return timer_verify(t);
211 static void timer_dump(Unit *u, FILE *f, const char *prefix) {
212 char buf[FORMAT_TIMESPAN_MAX];
217 trigger = UNIT_TRIGGER(u);
220 "%sTimer State: %s\n"
226 prefix, timer_state_to_string(t->state),
227 prefix, timer_result_to_string(t->result),
228 prefix, trigger ? trigger->id : "n/a",
229 prefix, yes_no(t->persistent),
230 prefix, yes_no(t->wake_system),
231 prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1));
233 LIST_FOREACH(value, v, t->values) {
235 if (v->base == TIMER_CALENDAR) {
236 _cleanup_free_ char *p = NULL;
238 calendar_spec_to_string(v->calendar_spec, &p);
243 timer_base_to_string(v->base),
246 char timespan1[FORMAT_TIMESPAN_MAX];
251 timer_base_to_string(v->base),
252 strna(format_timespan(timespan1, sizeof(timespan1), v->value, 0)));
257 static void timer_set_state(Timer *t, TimerState state) {
258 TimerState old_state;
261 old_state = t->state;
264 if (state != TIMER_WAITING) {
265 t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
266 t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
269 if (state != old_state)
270 log_debug_unit(UNIT(t)->id,
271 "%s changed %s -> %s", UNIT(t)->id,
272 timer_state_to_string(old_state),
273 timer_state_to_string(state));
275 unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
278 static void timer_enter_waiting(Timer *t, bool initial);
280 static int timer_coldplug(Unit *u) {
284 assert(t->state == TIMER_DEAD);
286 if (t->deserialized_state != t->state) {
288 if (t->deserialized_state == TIMER_WAITING)
289 timer_enter_waiting(t, false);
291 timer_set_state(t, t->deserialized_state);
297 static void timer_enter_dead(Timer *t, TimerResult f) {
300 if (f != TIMER_SUCCESS)
303 timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
306 static usec_t monotonic_to_boottime(usec_t t) {
312 a = now(CLOCK_BOOTTIME);
313 b = now(CLOCK_MONOTONIC);
321 static void timer_enter_waiting(Timer *t, bool initial) {
322 bool found_monotonic = false, found_realtime = false;
323 usec_t ts_realtime, ts_monotonic;
328 /* If we shall wake the system we use the boottime clock
329 * rather than the monotonic clock. */
331 ts_realtime = now(CLOCK_REALTIME);
332 ts_monotonic = now(t->wake_system ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
333 t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
335 LIST_FOREACH(value, v, t->values) {
340 if (v->base == TIMER_CALENDAR) {
343 /* If we know the last time this was
344 * triggered, schedule the job based relative
345 * to that. If we don't just start from
348 b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts_realtime;
350 r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
355 t->next_elapse_realtime = v->next_elapse;
357 t->next_elapse_realtime = MIN(t->next_elapse_realtime, v->next_elapse);
359 found_realtime = true;
365 if (state_translation_table[t->state] == UNIT_ACTIVE)
366 base = UNIT(t)->inactive_exit_timestamp.monotonic;
372 /* CLOCK_MONOTONIC equals the uptime on Linux */
377 base = UNIT(t)->manager->userspace_timestamp.monotonic;
380 case TIMER_UNIT_ACTIVE:
382 base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
385 base = t->last_trigger.monotonic;
392 case TIMER_UNIT_INACTIVE:
394 base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
397 base = t->last_trigger.monotonic;
405 assert_not_reached("Unknown timer base");
409 base = monotonic_to_boottime(base);
411 v->next_elapse = base + v->value;
413 if (!initial && v->next_elapse < ts_monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
414 /* This is a one time trigger, disable it now */
419 if (!found_monotonic)
420 t->next_elapse_monotonic_or_boottime = v->next_elapse;
422 t->next_elapse_monotonic_or_boottime = MIN(t->next_elapse_monotonic_or_boottime, v->next_elapse);
424 found_monotonic = true;
428 if (!found_monotonic && !found_realtime) {
429 log_debug_unit(UNIT(t)->id, "%s: Timer is elapsed.", UNIT(t)->id);
430 timer_set_state(t, TIMER_ELAPSED);
434 if (found_monotonic) {
435 char buf[FORMAT_TIMESPAN_MAX];
437 log_debug_unit(UNIT(t)->id, "%s: Monotonic timer elapses in %s.",
439 format_timespan(buf, sizeof(buf), t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0, 0));
441 if (t->monotonic_event_source) {
442 r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic_or_boottime);
446 r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
448 r = sd_event_add_time(
449 UNIT(t)->manager->event,
450 &t->monotonic_event_source,
451 t->wake_system ? CLOCK_BOOTTIME_ALARM : CLOCK_MONOTONIC,
452 t->next_elapse_monotonic_or_boottime, t->accuracy_usec,
457 } else if (t->monotonic_event_source) {
459 r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_OFF);
464 if (found_realtime) {
465 char buf[FORMAT_TIMESTAMP_MAX];
466 log_debug_unit(UNIT(t)->id, "%s: Realtime timer elapses at %s.", UNIT(t)->id, format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
468 if (t->realtime_event_source) {
469 r = sd_event_source_set_time(t->realtime_event_source, t->next_elapse_realtime);
473 r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
475 r = sd_event_add_time(
476 UNIT(t)->manager->event,
477 &t->realtime_event_source,
478 t->wake_system ? CLOCK_REALTIME_ALARM : CLOCK_REALTIME,
479 t->next_elapse_realtime, t->accuracy_usec,
484 } else if (t->realtime_event_source) {
486 r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_OFF);
491 timer_set_state(t, TIMER_WAITING);
495 log_warning_unit(UNIT(t)->id, "%s failed to enter waiting state: %s", UNIT(t)->id, strerror(-r));
496 timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
499 static void timer_enter_running(Timer *t) {
500 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
505 /* Don't start job if we are supposed to go down */
506 if (unit_stop_pending(UNIT(t)))
509 r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_TRIGGER(UNIT(t)),
510 JOB_REPLACE, true, &error, NULL);
514 dual_timestamp_get(&t->last_trigger);
517 update_stampfile(t, t->last_trigger.realtime);
519 timer_set_state(t, TIMER_RUNNING);
523 log_warning_unit(UNIT(t)->id,
524 "%s failed to queue unit startup job: %s",
525 UNIT(t)->id, bus_error_message(&error, r));
526 timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
529 static int timer_start(Unit *u) {
533 assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
535 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
538 t->last_trigger = DUAL_TIMESTAMP_NULL;
543 if (stat(t->stamp_path, &st) >= 0)
544 t->last_trigger.realtime = timespec_load(&st.st_atim);
545 else if (errno == ENOENT)
546 /* The timer has never run before,
547 * make sure a stamp file exists.
549 update_stampfile(t, now(CLOCK_REALTIME));
552 t->result = TIMER_SUCCESS;
553 timer_enter_waiting(t, true);
557 static int timer_stop(Unit *u) {
561 assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED);
563 timer_enter_dead(t, TIMER_SUCCESS);
567 static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
574 unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
575 unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
577 if (t->last_trigger.realtime > 0)
578 unit_serialize_item_format(u, f, "last-trigger-realtime", "%" PRIu64, t->last_trigger.realtime);
580 if (t->last_trigger.monotonic > 0)
581 unit_serialize_item_format(u, f, "last-trigger-monotonic", "%" PRIu64, t->last_trigger.monotonic);
586 static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
595 if (streq(key, "state")) {
598 state = timer_state_from_string(value);
600 log_debug_unit(u->id, "Failed to parse state value %s", value);
602 t->deserialized_state = state;
603 } else if (streq(key, "result")) {
606 f = timer_result_from_string(value);
608 log_debug_unit(u->id, "Failed to parse result value %s", value);
609 else if (f != TIMER_SUCCESS)
611 } else if (streq(key, "last-trigger-realtime")) {
613 r = safe_atou64(value, &t->last_trigger.realtime);
615 log_debug_unit(u->id, "Failed to parse last-trigger-realtime value %s", value);
617 } else if (streq(key, "last-trigger-monotonic")) {
619 r = safe_atou64(value, &t->last_trigger.monotonic);
621 log_debug_unit(u->id, "Failed to parse last-trigger-monotonic value %s", value);
624 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
629 _pure_ static UnitActiveState timer_active_state(Unit *u) {
632 return state_translation_table[TIMER(u)->state];
635 _pure_ static const char *timer_sub_state_to_string(Unit *u) {
638 return timer_state_to_string(TIMER(u)->state);
641 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata) {
642 Timer *t = TIMER(userdata);
646 if (t->state != TIMER_WAITING)
649 log_debug_unit(UNIT(t)->id, "Timer elapsed on %s", UNIT(t)->id);
650 timer_enter_running(t);
654 static void timer_trigger_notify(Unit *u, Unit *other) {
661 if (other->load_state != UNIT_LOADED)
664 /* Reenable all timers that depend on unit state */
665 LIST_FOREACH(value, v, t->values)
666 if (v->base == TIMER_UNIT_ACTIVE ||
667 v->base == TIMER_UNIT_INACTIVE)
675 /* Recalculate sleep time */
676 timer_enter_waiting(t, false);
681 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
682 log_debug_unit(UNIT(t)->id, "%s got notified about unit deactivation.", UNIT(t)->id);
683 timer_enter_waiting(t, false);
692 assert_not_reached("Unknown timer state");
696 static void timer_reset_failed(Unit *u) {
701 if (t->state == TIMER_FAILED)
702 timer_set_state(t, TIMER_DEAD);
704 t->result = TIMER_SUCCESS;
707 static void timer_time_change(Unit *u) {
712 if (t->state != TIMER_WAITING)
715 log_debug_unit(u->id, "%s: time change, recalculating next elapse.", u->id);
716 timer_enter_waiting(t, false);
719 static const char* const timer_state_table[_TIMER_STATE_MAX] = {
720 [TIMER_DEAD] = "dead",
721 [TIMER_WAITING] = "waiting",
722 [TIMER_RUNNING] = "running",
723 [TIMER_ELAPSED] = "elapsed",
724 [TIMER_FAILED] = "failed"
727 DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
729 static const char* const timer_base_table[_TIMER_BASE_MAX] = {
730 [TIMER_ACTIVE] = "OnActiveSec",
731 [TIMER_BOOT] = "OnBootSec",
732 [TIMER_STARTUP] = "OnStartupSec",
733 [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
734 [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec",
735 [TIMER_CALENDAR] = "OnCalendar"
738 DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
740 static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
741 [TIMER_SUCCESS] = "success",
742 [TIMER_FAILURE_RESOURCES] = "resources"
745 DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);
747 const UnitVTable timer_vtable = {
748 .object_size = sizeof(Timer),
759 .coldplug = timer_coldplug,
763 .start = timer_start,
766 .serialize = timer_serialize,
767 .deserialize_item = timer_deserialize_item,
769 .active_state = timer_active_state,
770 .sub_state_to_string = timer_sub_state_to_string,
772 .trigger_notify = timer_trigger_notify,
774 .reset_failed = timer_reset_failed,
775 .time_change = timer_time_change,
777 .bus_interface = "org.freedesktop.systemd1.Timer",
778 .bus_vtable = bus_timer_vtable,