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/>.
24 #include "alloc-util.h"
25 #include "bus-error.h"
27 #include "dbus-timer.h"
29 #include "parse-util.h"
31 #include "string-table.h"
32 #include "string-util.h"
34 #include "unit-name.h"
36 #include "user-util.h"
39 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
40 [TIMER_DEAD
] = UNIT_INACTIVE
,
41 [TIMER_WAITING
] = UNIT_ACTIVE
,
42 [TIMER_RUNNING
] = UNIT_ACTIVE
,
43 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
44 [TIMER_FAILED
] = UNIT_FAILED
47 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
49 static void timer_init(Unit
*u
) {
53 assert(u
->load_state
== UNIT_STUB
);
55 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
56 t
->next_elapse_realtime
= USEC_INFINITY
;
57 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
60 void timer_free_values(Timer
*t
) {
65 while ((v
= t
->values
)) {
66 LIST_REMOVE(value
, t
->values
, v
);
67 calendar_spec_free(v
->calendar_spec
);
72 static void timer_done(Unit
*u
) {
79 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
80 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
85 static int timer_verify(Timer
*t
) {
88 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
92 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
99 static int timer_add_default_dependencies(Timer
*t
) {
105 if (!UNIT(t
)->default_dependencies
)
108 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
112 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
113 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
117 LIST_FOREACH(value
, v
, t
->values
) {
118 if (v
->base
== TIMER_CALENDAR
) {
119 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
127 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
130 static int timer_setup_persistent(Timer
*t
) {
138 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
140 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
144 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
148 e
= getenv("XDG_DATA_HOME");
150 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
153 _cleanup_free_
char *h
= NULL
;
155 r
= get_home_dir(&h
);
157 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
159 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
169 static int timer_load(Unit
*u
) {
174 assert(u
->load_state
== UNIT_STUB
);
176 r
= unit_load_fragment_and_dropin(u
);
180 if (u
->load_state
== UNIT_LOADED
) {
182 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
185 r
= unit_load_related_unit(u
, ".service", &x
);
189 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
194 r
= timer_setup_persistent(t
);
198 r
= timer_add_default_dependencies(t
);
203 return timer_verify(t
);
206 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
207 char buf
[FORMAT_TIMESPAN_MAX
];
212 trigger
= UNIT_TRIGGER(u
);
215 "%sTimer State: %s\n"
221 prefix
, timer_state_to_string(t
->state
),
222 prefix
, timer_result_to_string(t
->result
),
223 prefix
, trigger
? trigger
->id
: "n/a",
224 prefix
, yes_no(t
->persistent
),
225 prefix
, yes_no(t
->wake_system
),
226 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
228 LIST_FOREACH(value
, v
, t
->values
) {
230 if (v
->base
== TIMER_CALENDAR
) {
231 _cleanup_free_
char *p
= NULL
;
233 calendar_spec_to_string(v
->calendar_spec
, &p
);
238 timer_base_to_string(v
->base
),
241 char timespan1
[FORMAT_TIMESPAN_MAX
];
246 timer_base_to_string(v
->base
),
247 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
252 static void timer_set_state(Timer
*t
, TimerState state
) {
253 TimerState old_state
;
256 old_state
= t
->state
;
259 if (state
!= TIMER_WAITING
) {
260 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
261 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
264 if (state
!= old_state
)
265 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
267 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
270 static void timer_enter_waiting(Timer
*t
, bool initial
);
272 static int timer_coldplug(Unit
*u
) {
276 assert(t
->state
== TIMER_DEAD
);
278 if (t
->deserialized_state
!= t
->state
) {
280 if (t
->deserialized_state
== TIMER_WAITING
)
281 timer_enter_waiting(t
, false);
283 timer_set_state(t
, t
->deserialized_state
);
289 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
292 if (f
!= TIMER_SUCCESS
)
295 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
298 static usec_t
monotonic_to_boottime(usec_t t
) {
304 a
= now(CLOCK_BOOTTIME
);
305 b
= now(CLOCK_MONOTONIC
);
313 static void timer_enter_waiting(Timer
*t
, bool initial
) {
314 bool found_monotonic
= false, found_realtime
= false;
315 usec_t ts_realtime
, ts_monotonic
;
320 /* If we shall wake the system we use the boottime clock
321 * rather than the monotonic clock. */
323 ts_realtime
= now(CLOCK_REALTIME
);
324 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
325 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
327 LIST_FOREACH(value
, v
, t
->values
) {
332 if (v
->base
== TIMER_CALENDAR
) {
335 /* If we know the last time this was
336 * triggered, schedule the job based relative
337 * to that. If we don't just start from
340 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
342 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
347 t
->next_elapse_realtime
= v
->next_elapse
;
349 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
351 found_realtime
= true;
357 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
358 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
364 if (detect_container() <= 0) {
365 /* CLOCK_MONOTONIC equals the uptime on Linux */
369 /* In a container we don't want to include the time the host
370 * was already up when the container started, so count from
371 * our own startup. Fall through. */
373 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
376 case TIMER_UNIT_ACTIVE
:
378 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
381 base
= t
->last_trigger
.monotonic
;
388 case TIMER_UNIT_INACTIVE
:
390 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
393 base
= t
->last_trigger
.monotonic
;
401 assert_not_reached("Unknown timer base");
405 base
= monotonic_to_boottime(base
);
407 v
->next_elapse
= base
+ v
->value
;
409 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
410 /* This is a one time trigger, disable it now */
415 if (!found_monotonic
)
416 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
418 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
420 found_monotonic
= true;
424 if (!found_monotonic
&& !found_realtime
) {
425 log_unit_debug(UNIT(t
), "Timer is elapsed.");
426 timer_set_state(t
, TIMER_ELAPSED
);
430 if (found_monotonic
) {
431 char buf
[FORMAT_TIMESPAN_MAX
];
433 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));
435 if (t
->monotonic_event_source
) {
436 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
440 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
445 r
= sd_event_add_time(
446 UNIT(t
)->manager
->event
,
447 &t
->monotonic_event_source
,
448 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
449 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
454 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
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_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", 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
);
477 r
= sd_event_add_time(
478 UNIT(t
)->manager
->event
,
479 &t
->realtime_event_source
,
480 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
481 t
->next_elapse_realtime
, t
->accuracy_usec
,
486 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
489 } else if (t
->realtime_event_source
) {
491 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
496 timer_set_state(t
, TIMER_WAITING
);
500 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
501 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
504 static void timer_enter_running(Timer
*t
) {
505 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
510 /* Don't start job if we are supposed to go down */
511 if (unit_stop_pending(UNIT(t
)))
514 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
515 JOB_REPLACE
, true, &error
, NULL
);
519 dual_timestamp_get(&t
->last_trigger
);
522 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
524 timer_set_state(t
, TIMER_RUNNING
);
528 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
529 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
532 static int timer_start(Unit
*u
) {
537 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
539 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
542 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
544 /* Reenable all timers that depend on unit activation time */
545 LIST_FOREACH(value
, v
, t
->values
)
546 if (v
->base
== TIMER_ACTIVE
)
552 if (stat(t
->stamp_path
, &st
) >= 0)
553 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
554 else if (errno
== ENOENT
)
555 /* The timer has never run before,
556 * make sure a stamp file exists.
558 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
561 t
->result
= TIMER_SUCCESS
;
562 timer_enter_waiting(t
, true);
566 static int timer_stop(Unit
*u
) {
570 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
572 timer_enter_dead(t
, TIMER_SUCCESS
);
576 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
583 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
584 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
586 if (t
->last_trigger
.realtime
> 0)
587 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
589 if (t
->last_trigger
.monotonic
> 0)
590 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
595 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
604 if (streq(key
, "state")) {
607 state
= timer_state_from_string(value
);
609 log_unit_debug(u
, "Failed to parse state value: %s", value
);
611 t
->deserialized_state
= state
;
612 } else if (streq(key
, "result")) {
615 f
= timer_result_from_string(value
);
617 log_unit_debug(u
, "Failed to parse result value: %s", value
);
618 else if (f
!= TIMER_SUCCESS
)
620 } else if (streq(key
, "last-trigger-realtime")) {
622 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
624 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
626 } else if (streq(key
, "last-trigger-monotonic")) {
628 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
630 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
633 log_unit_debug(u
, "Unknown serialization key: %s", key
);
638 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
641 return state_translation_table
[TIMER(u
)->state
];
644 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
647 return timer_state_to_string(TIMER(u
)->state
);
650 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
651 Timer
*t
= TIMER(userdata
);
655 if (t
->state
!= TIMER_WAITING
)
658 log_unit_debug(UNIT(t
), "Timer elapsed.");
659 timer_enter_running(t
);
663 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
670 if (other
->load_state
!= UNIT_LOADED
)
673 /* Reenable all timers that depend on unit state */
674 LIST_FOREACH(value
, v
, t
->values
)
675 if (v
->base
== TIMER_UNIT_ACTIVE
||
676 v
->base
== TIMER_UNIT_INACTIVE
)
684 /* Recalculate sleep time */
685 timer_enter_waiting(t
, false);
690 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
691 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
692 timer_enter_waiting(t
, false);
701 assert_not_reached("Unknown timer state");
705 static void timer_reset_failed(Unit
*u
) {
710 if (t
->state
== TIMER_FAILED
)
711 timer_set_state(t
, TIMER_DEAD
);
713 t
->result
= TIMER_SUCCESS
;
716 static void timer_time_change(Unit
*u
) {
721 if (t
->state
!= TIMER_WAITING
)
724 log_unit_debug(u
, "Time change, recalculating next elapse.");
725 timer_enter_waiting(t
, false);
728 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
729 [TIMER_ACTIVE
] = "OnActiveSec",
730 [TIMER_BOOT
] = "OnBootSec",
731 [TIMER_STARTUP
] = "OnStartupSec",
732 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
733 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
734 [TIMER_CALENDAR
] = "OnCalendar"
737 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
739 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
740 [TIMER_SUCCESS
] = "success",
741 [TIMER_FAILURE_RESOURCES
] = "resources"
744 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
746 const UnitVTable timer_vtable
= {
747 .object_size
= sizeof(Timer
),
753 .private_section
= "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_vtable
= bus_timer_vtable
,
778 .bus_set_property
= bus_timer_set_property
,
780 .can_transient
= true,