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"
32 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
33 [TIMER_DEAD
] = UNIT_INACTIVE
,
34 [TIMER_WAITING
] = UNIT_ACTIVE
,
35 [TIMER_RUNNING
] = UNIT_ACTIVE
,
36 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
37 [TIMER_FAILED
] = UNIT_FAILED
40 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
42 static void timer_init(Unit
*u
) {
46 assert(u
->load_state
== UNIT_STUB
);
48 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
49 t
->next_elapse_realtime
= USEC_INFINITY
;
50 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
53 void timer_free_values(Timer
*t
) {
58 while ((v
= t
->values
)) {
59 LIST_REMOVE(value
, t
->values
, v
);
60 calendar_spec_free(v
->calendar_spec
);
65 static void timer_done(Unit
*u
) {
72 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
73 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
78 static int timer_verify(Timer
*t
) {
81 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
85 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
92 static int timer_add_default_dependencies(Timer
*t
) {
98 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
102 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
103 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
107 LIST_FOREACH(value
, v
, t
->values
) {
108 if (v
->base
== TIMER_CALENDAR
) {
109 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
117 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
120 static int timer_setup_persistent(Timer
*t
) {
128 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
130 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
134 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
138 e
= getenv("XDG_DATA_HOME");
140 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
143 _cleanup_free_
char *h
= NULL
;
145 r
= get_home_dir(&h
);
147 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
149 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
159 static int timer_load(Unit
*u
) {
164 assert(u
->load_state
== UNIT_STUB
);
166 r
= unit_load_fragment_and_dropin(u
);
170 if (u
->load_state
== UNIT_LOADED
) {
172 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
175 r
= unit_load_related_unit(u
, ".service", &x
);
179 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
184 r
= timer_setup_persistent(t
);
188 if (u
->default_dependencies
) {
189 r
= timer_add_default_dependencies(t
);
195 return timer_verify(t
);
198 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
199 char buf
[FORMAT_TIMESPAN_MAX
];
204 trigger
= UNIT_TRIGGER(u
);
207 "%sTimer State: %s\n"
213 prefix
, timer_state_to_string(t
->state
),
214 prefix
, timer_result_to_string(t
->result
),
215 prefix
, trigger
? trigger
->id
: "n/a",
216 prefix
, yes_no(t
->persistent
),
217 prefix
, yes_no(t
->wake_system
),
218 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
220 LIST_FOREACH(value
, v
, t
->values
) {
222 if (v
->base
== TIMER_CALENDAR
) {
223 _cleanup_free_
char *p
= NULL
;
225 calendar_spec_to_string(v
->calendar_spec
, &p
);
230 timer_base_to_string(v
->base
),
233 char timespan1
[FORMAT_TIMESPAN_MAX
];
238 timer_base_to_string(v
->base
),
239 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
244 static void timer_set_state(Timer
*t
, TimerState state
) {
245 TimerState old_state
;
248 old_state
= t
->state
;
251 if (state
!= TIMER_WAITING
) {
252 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
253 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
256 if (state
!= old_state
)
257 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
259 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
262 static void timer_enter_waiting(Timer
*t
, bool initial
);
264 static int timer_coldplug(Unit
*u
) {
268 assert(t
->state
== TIMER_DEAD
);
270 if (t
->deserialized_state
!= t
->state
) {
272 if (t
->deserialized_state
== TIMER_WAITING
)
273 timer_enter_waiting(t
, false);
275 timer_set_state(t
, t
->deserialized_state
);
281 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
284 if (f
!= TIMER_SUCCESS
)
287 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
290 static usec_t
monotonic_to_boottime(usec_t t
) {
296 a
= now(CLOCK_BOOTTIME
);
297 b
= now(CLOCK_MONOTONIC
);
305 static void timer_enter_waiting(Timer
*t
, bool initial
) {
306 bool found_monotonic
= false, found_realtime
= false;
307 usec_t ts_realtime
, ts_monotonic
;
312 /* If we shall wake the system we use the boottime clock
313 * rather than the monotonic clock. */
315 ts_realtime
= now(CLOCK_REALTIME
);
316 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
317 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
319 LIST_FOREACH(value
, v
, t
->values
) {
324 if (v
->base
== TIMER_CALENDAR
) {
327 /* If we know the last time this was
328 * triggered, schedule the job based relative
329 * to that. If we don't just start from
332 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
334 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
339 t
->next_elapse_realtime
= v
->next_elapse
;
341 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
343 found_realtime
= true;
349 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
350 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
356 /* CLOCK_MONOTONIC equals the uptime on Linux */
361 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
364 case TIMER_UNIT_ACTIVE
:
366 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
369 base
= t
->last_trigger
.monotonic
;
376 case TIMER_UNIT_INACTIVE
:
378 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
381 base
= t
->last_trigger
.monotonic
;
389 assert_not_reached("Unknown timer base");
393 base
= monotonic_to_boottime(base
);
395 v
->next_elapse
= base
+ v
->value
;
397 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
398 /* This is a one time trigger, disable it now */
403 if (!found_monotonic
)
404 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
406 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
408 found_monotonic
= true;
412 if (!found_monotonic
&& !found_realtime
) {
413 log_unit_debug(UNIT(t
), "Timer is elapsed.");
414 timer_set_state(t
, TIMER_ELAPSED
);
418 if (found_monotonic
) {
419 char buf
[FORMAT_TIMESPAN_MAX
];
421 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));
423 if (t
->monotonic_event_source
) {
424 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
428 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
433 r
= sd_event_add_time(
434 UNIT(t
)->manager
->event
,
435 &t
->monotonic_event_source
,
436 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
437 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
442 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
445 } else if (t
->monotonic_event_source
) {
447 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
452 if (found_realtime
) {
453 char buf
[FORMAT_TIMESTAMP_MAX
];
454 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
456 if (t
->realtime_event_source
) {
457 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
461 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
465 r
= sd_event_add_time(
466 UNIT(t
)->manager
->event
,
467 &t
->realtime_event_source
,
468 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
469 t
->next_elapse_realtime
, t
->accuracy_usec
,
474 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
477 } else if (t
->realtime_event_source
) {
479 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
484 timer_set_state(t
, TIMER_WAITING
);
488 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
489 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
492 static void timer_enter_running(Timer
*t
) {
493 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
498 /* Don't start job if we are supposed to go down */
499 if (unit_stop_pending(UNIT(t
)))
502 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
503 JOB_REPLACE
, true, &error
, NULL
);
507 dual_timestamp_get(&t
->last_trigger
);
510 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
512 timer_set_state(t
, TIMER_RUNNING
);
516 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
517 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
520 static int timer_start(Unit
*u
) {
525 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
527 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
530 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
532 /* Reenable all timers that depend on unit activation time */
533 LIST_FOREACH(value
, v
, t
->values
)
534 if (v
->base
== TIMER_ACTIVE
)
540 if (stat(t
->stamp_path
, &st
) >= 0)
541 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
542 else if (errno
== ENOENT
)
543 /* The timer has never run before,
544 * make sure a stamp file exists.
546 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
549 t
->result
= TIMER_SUCCESS
;
550 timer_enter_waiting(t
, true);
554 static int timer_stop(Unit
*u
) {
558 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
560 timer_enter_dead(t
, TIMER_SUCCESS
);
564 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
571 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
572 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
574 if (t
->last_trigger
.realtime
> 0)
575 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
577 if (t
->last_trigger
.monotonic
> 0)
578 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
583 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
592 if (streq(key
, "state")) {
595 state
= timer_state_from_string(value
);
597 log_unit_debug(u
, "Failed to parse state value: %s", value
);
599 t
->deserialized_state
= state
;
600 } else if (streq(key
, "result")) {
603 f
= timer_result_from_string(value
);
605 log_unit_debug(u
, "Failed to parse result value: %s", value
);
606 else if (f
!= TIMER_SUCCESS
)
608 } else if (streq(key
, "last-trigger-realtime")) {
610 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
612 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
614 } else if (streq(key
, "last-trigger-monotonic")) {
616 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
618 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
621 log_unit_debug(u
, "Unknown serialization key: %s", key
);
626 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
629 return state_translation_table
[TIMER(u
)->state
];
632 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
635 return timer_state_to_string(TIMER(u
)->state
);
638 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
639 Timer
*t
= TIMER(userdata
);
643 if (t
->state
!= TIMER_WAITING
)
646 log_unit_debug(UNIT(t
), "Timer elapsed.");
647 timer_enter_running(t
);
651 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
658 if (other
->load_state
!= UNIT_LOADED
)
661 /* Reenable all timers that depend on unit state */
662 LIST_FOREACH(value
, v
, t
->values
)
663 if (v
->base
== TIMER_UNIT_ACTIVE
||
664 v
->base
== TIMER_UNIT_INACTIVE
)
672 /* Recalculate sleep time */
673 timer_enter_waiting(t
, false);
678 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
679 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
680 timer_enter_waiting(t
, false);
689 assert_not_reached("Unknown timer state");
693 static void timer_reset_failed(Unit
*u
) {
698 if (t
->state
== TIMER_FAILED
)
699 timer_set_state(t
, TIMER_DEAD
);
701 t
->result
= TIMER_SUCCESS
;
704 static void timer_time_change(Unit
*u
) {
709 if (t
->state
!= TIMER_WAITING
)
712 log_unit_debug(u
, "Time change, recalculating next elapse.");
713 timer_enter_waiting(t
, false);
716 static const char* const timer_state_table
[_TIMER_STATE_MAX
] = {
717 [TIMER_DEAD
] = "dead",
718 [TIMER_WAITING
] = "waiting",
719 [TIMER_RUNNING
] = "running",
720 [TIMER_ELAPSED
] = "elapsed",
721 [TIMER_FAILED
] = "failed"
724 DEFINE_STRING_TABLE_LOOKUP(timer_state
, TimerState
);
726 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
727 [TIMER_ACTIVE
] = "OnActiveSec",
728 [TIMER_BOOT
] = "OnBootSec",
729 [TIMER_STARTUP
] = "OnStartupSec",
730 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
731 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
732 [TIMER_CALENDAR
] = "OnCalendar"
735 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
737 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
738 [TIMER_SUCCESS
] = "success",
739 [TIMER_FAILURE_RESOURCES
] = "resources"
742 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
744 const UnitVTable timer_vtable
= {
745 .object_size
= sizeof(Timer
),
751 .private_section
= "Timer",
757 .coldplug
= timer_coldplug
,
761 .start
= timer_start
,
764 .serialize
= timer_serialize
,
765 .deserialize_item
= timer_deserialize_item
,
767 .active_state
= timer_active_state
,
768 .sub_state_to_string
= timer_sub_state_to_string
,
770 .trigger_notify
= timer_trigger_notify
,
772 .reset_failed
= timer_reset_failed
,
773 .time_change
= timer_time_change
,
775 .bus_vtable
= bus_timer_vtable
,
776 .bus_set_property
= bus_timer_set_property
,
778 .can_transient
= true,