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
);
62 calendar_spec_free(v
->calendar_spec
);
68 static void timer_done(Unit
*u
) {
75 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
76 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
81 static int timer_verify(Timer
*t
) {
84 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
88 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
95 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
== MANAGER_SYSTEM
) {
106 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
110 LIST_FOREACH(value
, v
, t
->values
) {
111 if (v
->base
== TIMER_CALENDAR
) {
112 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
120 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
123 static int timer_setup_persistent(Timer
*t
) {
131 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
133 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
137 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
141 e
= getenv("XDG_DATA_HOME");
143 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
146 _cleanup_free_
char *h
= NULL
;
148 r
= get_home_dir(&h
);
150 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
152 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
162 static int timer_load(Unit
*u
) {
167 assert(u
->load_state
== UNIT_STUB
);
169 r
= unit_load_fragment_and_dropin(u
);
173 if (u
->load_state
== UNIT_LOADED
) {
175 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
178 r
= unit_load_related_unit(u
, ".service", &x
);
182 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
187 r
= timer_setup_persistent(t
);
191 if (u
->default_dependencies
) {
192 r
= timer_add_default_dependencies(t
);
198 return timer_verify(t
);
201 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
202 char buf
[FORMAT_TIMESPAN_MAX
];
207 trigger
= UNIT_TRIGGER(u
);
210 "%sTimer State: %s\n"
216 prefix
, timer_state_to_string(t
->state
),
217 prefix
, timer_result_to_string(t
->result
),
218 prefix
, trigger
? trigger
->id
: "n/a",
219 prefix
, yes_no(t
->persistent
),
220 prefix
, yes_no(t
->wake_system
),
221 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
223 LIST_FOREACH(value
, v
, t
->values
) {
225 if (v
->base
== TIMER_CALENDAR
) {
226 _cleanup_free_
char *p
= NULL
;
228 calendar_spec_to_string(v
->calendar_spec
, &p
);
233 timer_base_to_string(v
->base
),
236 char timespan1
[FORMAT_TIMESPAN_MAX
];
241 timer_base_to_string(v
->base
),
242 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
247 static void timer_set_state(Timer
*t
, TimerState state
) {
248 TimerState old_state
;
251 old_state
= t
->state
;
254 if (state
!= TIMER_WAITING
) {
255 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
256 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
259 if (state
!= old_state
)
260 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
262 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
265 static void timer_enter_waiting(Timer
*t
, bool initial
);
267 static int timer_coldplug(Unit
*u
) {
271 assert(t
->state
== TIMER_DEAD
);
273 if (t
->deserialized_state
!= t
->state
) {
275 if (t
->deserialized_state
== TIMER_WAITING
)
276 timer_enter_waiting(t
, false);
278 timer_set_state(t
, t
->deserialized_state
);
284 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
287 if (f
!= TIMER_SUCCESS
)
290 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
293 static usec_t
monotonic_to_boottime(usec_t t
) {
299 a
= now(CLOCK_BOOTTIME
);
300 b
= now(CLOCK_MONOTONIC
);
308 static void timer_enter_waiting(Timer
*t
, bool initial
) {
309 bool found_monotonic
= false, found_realtime
= false;
310 usec_t ts_realtime
, ts_monotonic
;
315 /* If we shall wake the system we use the boottime clock
316 * rather than the monotonic clock. */
318 ts_realtime
= now(CLOCK_REALTIME
);
319 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
320 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
322 LIST_FOREACH(value
, v
, t
->values
) {
327 if (v
->base
== TIMER_CALENDAR
) {
330 /* If we know the last time this was
331 * triggered, schedule the job based relative
332 * to that. If we don't just start from
335 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
337 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
342 t
->next_elapse_realtime
= v
->next_elapse
;
344 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
346 found_realtime
= true;
352 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
353 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
359 /* CLOCK_MONOTONIC equals the uptime on Linux */
364 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
367 case TIMER_UNIT_ACTIVE
:
369 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
372 base
= t
->last_trigger
.monotonic
;
379 case TIMER_UNIT_INACTIVE
:
381 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
384 base
= t
->last_trigger
.monotonic
;
392 assert_not_reached("Unknown timer base");
396 base
= monotonic_to_boottime(base
);
398 v
->next_elapse
= base
+ v
->value
;
400 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
401 /* This is a one time trigger, disable it now */
406 if (!found_monotonic
)
407 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
409 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
411 found_monotonic
= true;
415 if (!found_monotonic
&& !found_realtime
) {
416 log_unit_debug(UNIT(t
), "Timer is elapsed.");
417 timer_set_state(t
, TIMER_ELAPSED
);
421 if (found_monotonic
) {
422 char buf
[FORMAT_TIMESPAN_MAX
];
424 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));
426 if (t
->monotonic_event_source
) {
427 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
431 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");
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
);
462 r
= sd_event_add_time(
463 UNIT(t
)->manager
->event
,
464 &t
->realtime_event_source
,
465 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
466 t
->next_elapse_realtime
, t
->accuracy_usec
,
471 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
473 } else if (t
->realtime_event_source
) {
475 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
480 timer_set_state(t
, TIMER_WAITING
);
484 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
485 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
488 static void timer_enter_running(Timer
*t
) {
489 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
494 /* Don't start job if we are supposed to go down */
495 if (unit_stop_pending(UNIT(t
)))
498 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
499 JOB_REPLACE
, true, &error
, NULL
);
503 dual_timestamp_get(&t
->last_trigger
);
506 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
508 timer_set_state(t
, TIMER_RUNNING
);
512 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
513 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
516 static int timer_start(Unit
*u
) {
521 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
523 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
526 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
528 /* Reenable all timers that depend on unit activation time */
529 LIST_FOREACH(value
, v
, t
->values
)
530 if (v
->base
== TIMER_ACTIVE
)
536 if (stat(t
->stamp_path
, &st
) >= 0)
537 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
538 else if (errno
== ENOENT
)
539 /* The timer has never run before,
540 * make sure a stamp file exists.
542 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
545 t
->result
= TIMER_SUCCESS
;
546 timer_enter_waiting(t
, true);
550 static int timer_stop(Unit
*u
) {
554 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
556 timer_enter_dead(t
, TIMER_SUCCESS
);
560 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
567 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
568 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
570 if (t
->last_trigger
.realtime
> 0)
571 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
573 if (t
->last_trigger
.monotonic
> 0)
574 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
579 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
588 if (streq(key
, "state")) {
591 state
= timer_state_from_string(value
);
593 log_unit_debug(u
, "Failed to parse state value: %s", value
);
595 t
->deserialized_state
= state
;
596 } else if (streq(key
, "result")) {
599 f
= timer_result_from_string(value
);
601 log_unit_debug(u
, "Failed to parse result value: %s", value
);
602 else if (f
!= TIMER_SUCCESS
)
604 } else if (streq(key
, "last-trigger-realtime")) {
606 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
608 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
610 } else if (streq(key
, "last-trigger-monotonic")) {
612 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
614 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
617 log_unit_debug(u
, "Unknown serialization key: %s", key
);
622 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
625 return state_translation_table
[TIMER(u
)->state
];
628 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
631 return timer_state_to_string(TIMER(u
)->state
);
634 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
635 Timer
*t
= TIMER(userdata
);
639 if (t
->state
!= TIMER_WAITING
)
642 log_unit_debug(UNIT(t
), "Timer elapsed.");
643 timer_enter_running(t
);
647 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
654 if (other
->load_state
!= UNIT_LOADED
)
657 /* Reenable all timers that depend on unit state */
658 LIST_FOREACH(value
, v
, t
->values
)
659 if (v
->base
== TIMER_UNIT_ACTIVE
||
660 v
->base
== TIMER_UNIT_INACTIVE
)
668 /* Recalculate sleep time */
669 timer_enter_waiting(t
, false);
674 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
675 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
676 timer_enter_waiting(t
, false);
685 assert_not_reached("Unknown timer state");
689 static void timer_reset_failed(Unit
*u
) {
694 if (t
->state
== TIMER_FAILED
)
695 timer_set_state(t
, TIMER_DEAD
);
697 t
->result
= TIMER_SUCCESS
;
700 static void timer_time_change(Unit
*u
) {
705 if (t
->state
!= TIMER_WAITING
)
708 log_unit_debug(u
, "Time change, recalculating next elapse.");
709 timer_enter_waiting(t
, false);
712 static const char* const timer_state_table
[_TIMER_STATE_MAX
] = {
713 [TIMER_DEAD
] = "dead",
714 [TIMER_WAITING
] = "waiting",
715 [TIMER_RUNNING
] = "running",
716 [TIMER_ELAPSED
] = "elapsed",
717 [TIMER_FAILED
] = "failed"
720 DEFINE_STRING_TABLE_LOOKUP(timer_state
, TimerState
);
722 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
723 [TIMER_ACTIVE
] = "OnActiveSec",
724 [TIMER_BOOT
] = "OnBootSec",
725 [TIMER_STARTUP
] = "OnStartupSec",
726 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
727 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
728 [TIMER_CALENDAR
] = "OnCalendar"
731 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
733 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
734 [TIMER_SUCCESS
] = "success",
735 [TIMER_FAILURE_RESOURCES
] = "resources"
738 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
740 const UnitVTable timer_vtable
= {
741 .object_size
= sizeof(Timer
),
747 .private_section
= "Timer",
753 .coldplug
= timer_coldplug
,
757 .start
= timer_start
,
760 .serialize
= timer_serialize
,
761 .deserialize_item
= timer_deserialize_item
,
763 .active_state
= timer_active_state
,
764 .sub_state_to_string
= timer_sub_state_to_string
,
766 .trigger_notify
= timer_trigger_notify
,
768 .reset_failed
= timer_reset_failed
,
769 .time_change
= timer_time_change
,
771 .bus_interface
= "org.freedesktop.systemd1.Timer",
772 .bus_vtable
= bus_timer_vtable
,
773 .bus_set_property
= bus_timer_set_property
,
775 .can_transient
= true,