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
);
61 calendar_spec_free(v
->calendar_spec
);
67 static void timer_done(Unit
*u
) {
74 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
75 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
80 static int timer_verify(Timer
*t
) {
83 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
87 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
94 static int timer_add_default_dependencies(Timer
*t
) {
100 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
104 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
105 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
109 LIST_FOREACH(value
, v
, t
->values
) {
110 if (v
->base
== TIMER_CALENDAR
) {
111 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
119 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
122 static int timer_setup_persistent(Timer
*t
) {
130 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
132 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
136 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
140 e
= getenv("XDG_DATA_HOME");
142 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
145 _cleanup_free_
char *h
= NULL
;
147 r
= get_home_dir(&h
);
149 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
151 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
161 static int timer_load(Unit
*u
) {
166 assert(u
->load_state
== UNIT_STUB
);
168 r
= unit_load_fragment_and_dropin(u
);
172 if (u
->load_state
== UNIT_LOADED
) {
174 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
177 r
= unit_load_related_unit(u
, ".service", &x
);
181 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
186 r
= timer_setup_persistent(t
);
190 if (u
->default_dependencies
) {
191 r
= timer_add_default_dependencies(t
);
197 return timer_verify(t
);
200 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
201 char buf
[FORMAT_TIMESPAN_MAX
];
206 trigger
= UNIT_TRIGGER(u
);
209 "%sTimer State: %s\n"
215 prefix
, timer_state_to_string(t
->state
),
216 prefix
, timer_result_to_string(t
->result
),
217 prefix
, trigger
? trigger
->id
: "n/a",
218 prefix
, yes_no(t
->persistent
),
219 prefix
, yes_no(t
->wake_system
),
220 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
222 LIST_FOREACH(value
, v
, t
->values
) {
224 if (v
->base
== TIMER_CALENDAR
) {
225 _cleanup_free_
char *p
= NULL
;
227 calendar_spec_to_string(v
->calendar_spec
, &p
);
232 timer_base_to_string(v
->base
),
235 char timespan1
[FORMAT_TIMESPAN_MAX
];
240 timer_base_to_string(v
->base
),
241 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
246 static void timer_set_state(Timer
*t
, TimerState state
) {
247 TimerState old_state
;
250 old_state
= t
->state
;
253 if (state
!= TIMER_WAITING
) {
254 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
255 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
258 if (state
!= old_state
)
259 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
261 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
264 static void timer_enter_waiting(Timer
*t
, bool initial
);
266 static int timer_coldplug(Unit
*u
) {
270 assert(t
->state
== TIMER_DEAD
);
272 if (t
->deserialized_state
!= t
->state
) {
274 if (t
->deserialized_state
== TIMER_WAITING
)
275 timer_enter_waiting(t
, false);
277 timer_set_state(t
, t
->deserialized_state
);
283 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
286 if (f
!= TIMER_SUCCESS
)
289 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
292 static usec_t
monotonic_to_boottime(usec_t t
) {
298 a
= now(CLOCK_BOOTTIME
);
299 b
= now(CLOCK_MONOTONIC
);
307 static void timer_enter_waiting(Timer
*t
, bool initial
) {
308 bool found_monotonic
= false, found_realtime
= false;
309 usec_t ts_realtime
, ts_monotonic
;
314 /* If we shall wake the system we use the boottime clock
315 * rather than the monotonic clock. */
317 ts_realtime
= now(CLOCK_REALTIME
);
318 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
319 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
321 LIST_FOREACH(value
, v
, t
->values
) {
326 if (v
->base
== TIMER_CALENDAR
) {
329 /* If we know the last time this was
330 * triggered, schedule the job based relative
331 * to that. If we don't just start from
334 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
336 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
341 t
->next_elapse_realtime
= v
->next_elapse
;
343 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
345 found_realtime
= true;
351 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
352 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
358 /* CLOCK_MONOTONIC equals the uptime on Linux */
363 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
366 case TIMER_UNIT_ACTIVE
:
368 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
371 base
= t
->last_trigger
.monotonic
;
378 case TIMER_UNIT_INACTIVE
:
380 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
383 base
= t
->last_trigger
.monotonic
;
391 assert_not_reached("Unknown timer base");
395 base
= monotonic_to_boottime(base
);
397 v
->next_elapse
= base
+ v
->value
;
399 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
400 /* This is a one time trigger, disable it now */
405 if (!found_monotonic
)
406 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
408 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
410 found_monotonic
= true;
414 if (!found_monotonic
&& !found_realtime
) {
415 log_unit_debug(UNIT(t
), "Timer is elapsed.");
416 timer_set_state(t
, TIMER_ELAPSED
);
420 if (found_monotonic
) {
421 char buf
[FORMAT_TIMESPAN_MAX
];
423 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));
425 if (t
->monotonic_event_source
) {
426 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
430 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
435 r
= sd_event_add_time(
436 UNIT(t
)->manager
->event
,
437 &t
->monotonic_event_source
,
438 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
439 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
444 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
447 } else if (t
->monotonic_event_source
) {
449 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
454 if (found_realtime
) {
455 char buf
[FORMAT_TIMESTAMP_MAX
];
456 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
458 if (t
->realtime_event_source
) {
459 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
463 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
467 r
= sd_event_add_time(
468 UNIT(t
)->manager
->event
,
469 &t
->realtime_event_source
,
470 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
471 t
->next_elapse_realtime
, t
->accuracy_usec
,
476 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
479 } else if (t
->realtime_event_source
) {
481 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
486 timer_set_state(t
, TIMER_WAITING
);
490 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
491 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
494 static void timer_enter_running(Timer
*t
) {
495 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
500 /* Don't start job if we are supposed to go down */
501 if (unit_stop_pending(UNIT(t
)))
504 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
505 JOB_REPLACE
, true, &error
, NULL
);
509 dual_timestamp_get(&t
->last_trigger
);
512 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
514 timer_set_state(t
, TIMER_RUNNING
);
518 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
519 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
522 static int timer_start(Unit
*u
) {
527 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
529 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
532 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
534 /* Reenable all timers that depend on unit activation time */
535 LIST_FOREACH(value
, v
, t
->values
)
536 if (v
->base
== TIMER_ACTIVE
)
542 if (stat(t
->stamp_path
, &st
) >= 0)
543 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
544 else if (errno
== ENOENT
)
545 /* The timer has never run before,
546 * make sure a stamp file exists.
548 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
551 t
->result
= TIMER_SUCCESS
;
552 timer_enter_waiting(t
, true);
556 static int timer_stop(Unit
*u
) {
560 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
562 timer_enter_dead(t
, TIMER_SUCCESS
);
566 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
573 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
574 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
576 if (t
->last_trigger
.realtime
> 0)
577 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
579 if (t
->last_trigger
.monotonic
> 0)
580 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
585 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
594 if (streq(key
, "state")) {
597 state
= timer_state_from_string(value
);
599 log_unit_debug(u
, "Failed to parse state value: %s", value
);
601 t
->deserialized_state
= state
;
602 } else if (streq(key
, "result")) {
605 f
= timer_result_from_string(value
);
607 log_unit_debug(u
, "Failed to parse result value: %s", value
);
608 else if (f
!= TIMER_SUCCESS
)
610 } else if (streq(key
, "last-trigger-realtime")) {
612 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
614 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
616 } else if (streq(key
, "last-trigger-monotonic")) {
618 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
620 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
623 log_unit_debug(u
, "Unknown serialization key: %s", key
);
628 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
631 return state_translation_table
[TIMER(u
)->state
];
634 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
637 return timer_state_to_string(TIMER(u
)->state
);
640 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
641 Timer
*t
= TIMER(userdata
);
645 if (t
->state
!= TIMER_WAITING
)
648 log_unit_debug(UNIT(t
), "Timer elapsed.");
649 timer_enter_running(t
);
653 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
660 if (other
->load_state
!= UNIT_LOADED
)
663 /* Reenable all timers that depend on unit state */
664 LIST_FOREACH(value
, v
, t
->values
)
665 if (v
->base
== TIMER_UNIT_ACTIVE
||
666 v
->base
== TIMER_UNIT_INACTIVE
)
674 /* Recalculate sleep time */
675 timer_enter_waiting(t
, false);
680 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
681 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
682 timer_enter_waiting(t
, false);
691 assert_not_reached("Unknown timer state");
695 static void timer_reset_failed(Unit
*u
) {
700 if (t
->state
== TIMER_FAILED
)
701 timer_set_state(t
, TIMER_DEAD
);
703 t
->result
= TIMER_SUCCESS
;
706 static void timer_time_change(Unit
*u
) {
711 if (t
->state
!= TIMER_WAITING
)
714 log_unit_debug(u
, "Time change, recalculating next elapse.");
715 timer_enter_waiting(t
, false);
718 static const char* const timer_state_table
[_TIMER_STATE_MAX
] = {
719 [TIMER_DEAD
] = "dead",
720 [TIMER_WAITING
] = "waiting",
721 [TIMER_RUNNING
] = "running",
722 [TIMER_ELAPSED
] = "elapsed",
723 [TIMER_FAILED
] = "failed"
726 DEFINE_STRING_TABLE_LOOKUP(timer_state
, TimerState
);
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_interface
= "org.freedesktop.systemd1.Timer",
778 .bus_vtable
= bus_timer_vtable
,
779 .bus_set_property
= bus_timer_set_property
,
781 .can_transient
= true,