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"
31 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
32 [TIMER_DEAD
] = UNIT_INACTIVE
,
33 [TIMER_WAITING
] = UNIT_ACTIVE
,
34 [TIMER_RUNNING
] = UNIT_ACTIVE
,
35 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
36 [TIMER_FAILED
] = UNIT_FAILED
39 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
41 static void timer_init(Unit
*u
) {
45 assert(u
->load_state
== UNIT_STUB
);
47 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
48 t
->next_elapse_realtime
= USEC_INFINITY
;
49 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
52 void timer_free_values(Timer
*t
) {
57 while ((v
= t
->values
)) {
58 LIST_REMOVE(value
, t
->values
, v
);
59 calendar_spec_free(v
->calendar_spec
);
64 static void timer_done(Unit
*u
) {
71 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
72 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
77 static int timer_verify(Timer
*t
) {
80 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
84 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
91 static int timer_add_default_dependencies(Timer
*t
) {
97 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
101 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
102 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
106 LIST_FOREACH(value
, v
, t
->values
) {
107 if (v
->base
== TIMER_CALENDAR
) {
108 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
116 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
119 static int timer_setup_persistent(Timer
*t
) {
127 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
129 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
133 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
137 e
= getenv("XDG_DATA_HOME");
139 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
142 _cleanup_free_
char *h
= NULL
;
144 r
= get_home_dir(&h
);
146 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
148 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
158 static int timer_load(Unit
*u
) {
163 assert(u
->load_state
== UNIT_STUB
);
165 r
= unit_load_fragment_and_dropin(u
);
169 if (u
->load_state
== UNIT_LOADED
) {
171 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
174 r
= unit_load_related_unit(u
, ".service", &x
);
178 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
183 r
= timer_setup_persistent(t
);
187 if (u
->default_dependencies
) {
188 r
= timer_add_default_dependencies(t
);
194 return timer_verify(t
);
197 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
198 char buf
[FORMAT_TIMESPAN_MAX
];
203 trigger
= UNIT_TRIGGER(u
);
206 "%sTimer State: %s\n"
212 prefix
, timer_state_to_string(t
->state
),
213 prefix
, timer_result_to_string(t
->result
),
214 prefix
, trigger
? trigger
->id
: "n/a",
215 prefix
, yes_no(t
->persistent
),
216 prefix
, yes_no(t
->wake_system
),
217 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
219 LIST_FOREACH(value
, v
, t
->values
) {
221 if (v
->base
== TIMER_CALENDAR
) {
222 _cleanup_free_
char *p
= NULL
;
224 calendar_spec_to_string(v
->calendar_spec
, &p
);
229 timer_base_to_string(v
->base
),
232 char timespan1
[FORMAT_TIMESPAN_MAX
];
237 timer_base_to_string(v
->base
),
238 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
243 static void timer_set_state(Timer
*t
, TimerState state
) {
244 TimerState old_state
;
247 old_state
= t
->state
;
250 if (state
!= TIMER_WAITING
) {
251 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
252 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
255 if (state
!= old_state
)
256 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
258 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
261 static void timer_enter_waiting(Timer
*t
, bool initial
);
263 static int timer_coldplug(Unit
*u
) {
267 assert(t
->state
== TIMER_DEAD
);
269 if (t
->deserialized_state
!= t
->state
) {
271 if (t
->deserialized_state
== TIMER_WAITING
)
272 timer_enter_waiting(t
, false);
274 timer_set_state(t
, t
->deserialized_state
);
280 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
283 if (f
!= TIMER_SUCCESS
)
286 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
289 static usec_t
monotonic_to_boottime(usec_t t
) {
295 a
= now(CLOCK_BOOTTIME
);
296 b
= now(CLOCK_MONOTONIC
);
304 static void timer_enter_waiting(Timer
*t
, bool initial
) {
305 bool found_monotonic
= false, found_realtime
= false;
306 usec_t ts_realtime
, ts_monotonic
;
311 /* If we shall wake the system we use the boottime clock
312 * rather than the monotonic clock. */
314 ts_realtime
= now(CLOCK_REALTIME
);
315 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
316 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
318 LIST_FOREACH(value
, v
, t
->values
) {
323 if (v
->base
== TIMER_CALENDAR
) {
326 /* If we know the last time this was
327 * triggered, schedule the job based relative
328 * to that. If we don't just start from
331 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
333 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
338 t
->next_elapse_realtime
= v
->next_elapse
;
340 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
342 found_realtime
= true;
348 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
349 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
355 /* CLOCK_MONOTONIC equals the uptime on Linux */
360 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
363 case TIMER_UNIT_ACTIVE
:
365 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
368 base
= t
->last_trigger
.monotonic
;
375 case TIMER_UNIT_INACTIVE
:
377 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
380 base
= t
->last_trigger
.monotonic
;
388 assert_not_reached("Unknown timer base");
392 base
= monotonic_to_boottime(base
);
394 v
->next_elapse
= base
+ v
->value
;
396 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
397 /* This is a one time trigger, disable it now */
402 if (!found_monotonic
)
403 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
405 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
407 found_monotonic
= true;
411 if (!found_monotonic
&& !found_realtime
) {
412 log_unit_debug(UNIT(t
), "Timer is elapsed.");
413 timer_set_state(t
, TIMER_ELAPSED
);
417 if (found_monotonic
) {
418 char buf
[FORMAT_TIMESPAN_MAX
];
420 log_unit_debug(UNIT(t
), "Monotonic timer elapses in %s.", format_timespan(buf
, sizeof(buf
), t
->next_elapse_monotonic_or_boottime
> ts_monotonic
? t
->next_elapse_monotonic_or_boottime
- ts_monotonic
: 0, 0));
422 if (t
->monotonic_event_source
) {
423 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
427 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
432 r
= sd_event_add_time(
433 UNIT(t
)->manager
->event
,
434 &t
->monotonic_event_source
,
435 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
436 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
441 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
444 } else if (t
->monotonic_event_source
) {
446 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
451 if (found_realtime
) {
452 char buf
[FORMAT_TIMESTAMP_MAX
];
453 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
455 if (t
->realtime_event_source
) {
456 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
460 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
464 r
= sd_event_add_time(
465 UNIT(t
)->manager
->event
,
466 &t
->realtime_event_source
,
467 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
468 t
->next_elapse_realtime
, t
->accuracy_usec
,
473 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
476 } else if (t
->realtime_event_source
) {
478 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
483 timer_set_state(t
, TIMER_WAITING
);
487 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
488 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
491 static void timer_enter_running(Timer
*t
) {
492 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
497 /* Don't start job if we are supposed to go down */
498 if (unit_stop_pending(UNIT(t
)))
501 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
502 JOB_REPLACE
, true, &error
, NULL
);
506 dual_timestamp_get(&t
->last_trigger
);
509 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
511 timer_set_state(t
, TIMER_RUNNING
);
515 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
516 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
519 static int timer_start(Unit
*u
) {
524 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
526 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
529 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
531 /* Reenable all timers that depend on unit activation time */
532 LIST_FOREACH(value
, v
, t
->values
)
533 if (v
->base
== TIMER_ACTIVE
)
539 if (stat(t
->stamp_path
, &st
) >= 0)
540 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
541 else if (errno
== ENOENT
)
542 /* The timer has never run before,
543 * make sure a stamp file exists.
545 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
548 t
->result
= TIMER_SUCCESS
;
549 timer_enter_waiting(t
, true);
553 static int timer_stop(Unit
*u
) {
557 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
559 timer_enter_dead(t
, TIMER_SUCCESS
);
563 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
570 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
571 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
573 if (t
->last_trigger
.realtime
> 0)
574 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
576 if (t
->last_trigger
.monotonic
> 0)
577 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
582 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
591 if (streq(key
, "state")) {
594 state
= timer_state_from_string(value
);
596 log_unit_debug(u
, "Failed to parse state value: %s", value
);
598 t
->deserialized_state
= state
;
599 } else if (streq(key
, "result")) {
602 f
= timer_result_from_string(value
);
604 log_unit_debug(u
, "Failed to parse result value: %s", value
);
605 else if (f
!= TIMER_SUCCESS
)
607 } else if (streq(key
, "last-trigger-realtime")) {
609 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
611 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
613 } else if (streq(key
, "last-trigger-monotonic")) {
615 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
617 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
620 log_unit_debug(u
, "Unknown serialization key: %s", key
);
625 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
628 return state_translation_table
[TIMER(u
)->state
];
631 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
634 return timer_state_to_string(TIMER(u
)->state
);
637 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
638 Timer
*t
= TIMER(userdata
);
642 if (t
->state
!= TIMER_WAITING
)
645 log_unit_debug(UNIT(t
), "Timer elapsed.");
646 timer_enter_running(t
);
650 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
657 if (other
->load_state
!= UNIT_LOADED
)
660 /* Reenable all timers that depend on unit state */
661 LIST_FOREACH(value
, v
, t
->values
)
662 if (v
->base
== TIMER_UNIT_ACTIVE
||
663 v
->base
== TIMER_UNIT_INACTIVE
)
671 /* Recalculate sleep time */
672 timer_enter_waiting(t
, false);
677 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
678 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
679 timer_enter_waiting(t
, false);
688 assert_not_reached("Unknown timer state");
692 static void timer_reset_failed(Unit
*u
) {
697 if (t
->state
== TIMER_FAILED
)
698 timer_set_state(t
, TIMER_DEAD
);
700 t
->result
= TIMER_SUCCESS
;
703 static void timer_time_change(Unit
*u
) {
708 if (t
->state
!= TIMER_WAITING
)
711 log_unit_debug(u
, "Time change, recalculating next elapse.");
712 timer_enter_waiting(t
, false);
715 static const char* const timer_state_table
[_TIMER_STATE_MAX
] = {
716 [TIMER_DEAD
] = "dead",
717 [TIMER_WAITING
] = "waiting",
718 [TIMER_RUNNING
] = "running",
719 [TIMER_ELAPSED
] = "elapsed",
720 [TIMER_FAILED
] = "failed"
723 DEFINE_STRING_TABLE_LOOKUP(timer_state
, TimerState
);
725 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
726 [TIMER_ACTIVE
] = "OnActiveSec",
727 [TIMER_BOOT
] = "OnBootSec",
728 [TIMER_STARTUP
] = "OnStartupSec",
729 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
730 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
731 [TIMER_CALENDAR
] = "OnCalendar"
734 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
736 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
737 [TIMER_SUCCESS
] = "success",
738 [TIMER_FAILURE_RESOURCES
] = "resources"
741 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
743 const UnitVTable timer_vtable
= {
744 .object_size
= sizeof(Timer
),
750 .private_section
= "Timer",
756 .coldplug
= timer_coldplug
,
760 .start
= timer_start
,
763 .serialize
= timer_serialize
,
764 .deserialize_item
= timer_deserialize_item
,
766 .active_state
= timer_active_state
,
767 .sub_state_to_string
= timer_sub_state_to_string
,
769 .trigger_notify
= timer_trigger_notify
,
771 .reset_failed
= timer_reset_failed
,
772 .time_change
= timer_time_change
,
774 .bus_interface
= "org.freedesktop.systemd1.Timer",
775 .bus_vtable
= bus_timer_vtable
,
776 .bus_set_property
= bus_timer_set_property
,
778 .can_transient
= true,