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 "bus-error.h"
26 #include "dbus-timer.h"
28 #include "string-util.h"
29 #include "unit-name.h"
33 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
34 [TIMER_DEAD
] = UNIT_INACTIVE
,
35 [TIMER_WAITING
] = UNIT_ACTIVE
,
36 [TIMER_RUNNING
] = UNIT_ACTIVE
,
37 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
38 [TIMER_FAILED
] = UNIT_FAILED
41 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
43 static void timer_init(Unit
*u
) {
47 assert(u
->load_state
== UNIT_STUB
);
49 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
50 t
->next_elapse_realtime
= USEC_INFINITY
;
51 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
54 void timer_free_values(Timer
*t
) {
59 while ((v
= t
->values
)) {
60 LIST_REMOVE(value
, t
->values
, v
);
61 calendar_spec_free(v
->calendar_spec
);
66 static void timer_done(Unit
*u
) {
73 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
74 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
79 static int timer_verify(Timer
*t
) {
82 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
86 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
93 static int timer_add_default_dependencies(Timer
*t
) {
99 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
103 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
104 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
108 LIST_FOREACH(value
, v
, t
->values
) {
109 if (v
->base
== TIMER_CALENDAR
) {
110 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
118 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
121 static int timer_setup_persistent(Timer
*t
) {
129 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
131 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
135 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
139 e
= getenv("XDG_DATA_HOME");
141 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
144 _cleanup_free_
char *h
= NULL
;
146 r
= get_home_dir(&h
);
148 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
150 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
160 static int timer_load(Unit
*u
) {
165 assert(u
->load_state
== UNIT_STUB
);
167 r
= unit_load_fragment_and_dropin(u
);
171 if (u
->load_state
== UNIT_LOADED
) {
173 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
176 r
= unit_load_related_unit(u
, ".service", &x
);
180 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
185 r
= timer_setup_persistent(t
);
189 if (u
->default_dependencies
) {
190 r
= timer_add_default_dependencies(t
);
196 return timer_verify(t
);
199 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
200 char buf
[FORMAT_TIMESPAN_MAX
];
205 trigger
= UNIT_TRIGGER(u
);
208 "%sTimer State: %s\n"
214 prefix
, timer_state_to_string(t
->state
),
215 prefix
, timer_result_to_string(t
->result
),
216 prefix
, trigger
? trigger
->id
: "n/a",
217 prefix
, yes_no(t
->persistent
),
218 prefix
, yes_no(t
->wake_system
),
219 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
221 LIST_FOREACH(value
, v
, t
->values
) {
223 if (v
->base
== TIMER_CALENDAR
) {
224 _cleanup_free_
char *p
= NULL
;
226 calendar_spec_to_string(v
->calendar_spec
, &p
);
231 timer_base_to_string(v
->base
),
234 char timespan1
[FORMAT_TIMESPAN_MAX
];
239 timer_base_to_string(v
->base
),
240 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
245 static void timer_set_state(Timer
*t
, TimerState state
) {
246 TimerState old_state
;
249 old_state
= t
->state
;
252 if (state
!= TIMER_WAITING
) {
253 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
254 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
257 if (state
!= old_state
)
258 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
260 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
263 static void timer_enter_waiting(Timer
*t
, bool initial
);
265 static int timer_coldplug(Unit
*u
) {
269 assert(t
->state
== TIMER_DEAD
);
271 if (t
->deserialized_state
!= t
->state
) {
273 if (t
->deserialized_state
== TIMER_WAITING
)
274 timer_enter_waiting(t
, false);
276 timer_set_state(t
, t
->deserialized_state
);
282 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
285 if (f
!= TIMER_SUCCESS
)
288 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
291 static usec_t
monotonic_to_boottime(usec_t t
) {
297 a
= now(CLOCK_BOOTTIME
);
298 b
= now(CLOCK_MONOTONIC
);
306 static void timer_enter_waiting(Timer
*t
, bool initial
) {
307 bool found_monotonic
= false, found_realtime
= false;
308 usec_t ts_realtime
, ts_monotonic
;
313 /* If we shall wake the system we use the boottime clock
314 * rather than the monotonic clock. */
316 ts_realtime
= now(CLOCK_REALTIME
);
317 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
318 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
320 LIST_FOREACH(value
, v
, t
->values
) {
325 if (v
->base
== TIMER_CALENDAR
) {
328 /* If we know the last time this was
329 * triggered, schedule the job based relative
330 * to that. If we don't just start from
333 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
335 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
340 t
->next_elapse_realtime
= v
->next_elapse
;
342 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
344 found_realtime
= true;
350 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
351 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
357 /* CLOCK_MONOTONIC equals the uptime on Linux */
362 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
365 case TIMER_UNIT_ACTIVE
:
367 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
370 base
= t
->last_trigger
.monotonic
;
377 case TIMER_UNIT_INACTIVE
:
379 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
382 base
= t
->last_trigger
.monotonic
;
390 assert_not_reached("Unknown timer base");
394 base
= monotonic_to_boottime(base
);
396 v
->next_elapse
= base
+ v
->value
;
398 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
399 /* This is a one time trigger, disable it now */
404 if (!found_monotonic
)
405 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
407 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
409 found_monotonic
= true;
413 if (!found_monotonic
&& !found_realtime
) {
414 log_unit_debug(UNIT(t
), "Timer is elapsed.");
415 timer_set_state(t
, TIMER_ELAPSED
);
419 if (found_monotonic
) {
420 char buf
[FORMAT_TIMESPAN_MAX
];
422 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));
424 if (t
->monotonic_event_source
) {
425 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
429 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
434 r
= sd_event_add_time(
435 UNIT(t
)->manager
->event
,
436 &t
->monotonic_event_source
,
437 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
438 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
443 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
446 } else if (t
->monotonic_event_source
) {
448 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
453 if (found_realtime
) {
454 char buf
[FORMAT_TIMESTAMP_MAX
];
455 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
457 if (t
->realtime_event_source
) {
458 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
462 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
466 r
= sd_event_add_time(
467 UNIT(t
)->manager
->event
,
468 &t
->realtime_event_source
,
469 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
470 t
->next_elapse_realtime
, t
->accuracy_usec
,
475 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
478 } else if (t
->realtime_event_source
) {
480 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
485 timer_set_state(t
, TIMER_WAITING
);
489 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
490 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
493 static void timer_enter_running(Timer
*t
) {
494 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
499 /* Don't start job if we are supposed to go down */
500 if (unit_stop_pending(UNIT(t
)))
503 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
504 JOB_REPLACE
, true, &error
, NULL
);
508 dual_timestamp_get(&t
->last_trigger
);
511 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
513 timer_set_state(t
, TIMER_RUNNING
);
517 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
518 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
521 static int timer_start(Unit
*u
) {
526 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
528 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
531 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
533 /* Reenable all timers that depend on unit activation time */
534 LIST_FOREACH(value
, v
, t
->values
)
535 if (v
->base
== TIMER_ACTIVE
)
541 if (stat(t
->stamp_path
, &st
) >= 0)
542 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
543 else if (errno
== ENOENT
)
544 /* The timer has never run before,
545 * make sure a stamp file exists.
547 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
550 t
->result
= TIMER_SUCCESS
;
551 timer_enter_waiting(t
, true);
555 static int timer_stop(Unit
*u
) {
559 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
561 timer_enter_dead(t
, TIMER_SUCCESS
);
565 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
572 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
573 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
575 if (t
->last_trigger
.realtime
> 0)
576 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
578 if (t
->last_trigger
.monotonic
> 0)
579 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
584 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
593 if (streq(key
, "state")) {
596 state
= timer_state_from_string(value
);
598 log_unit_debug(u
, "Failed to parse state value: %s", value
);
600 t
->deserialized_state
= state
;
601 } else if (streq(key
, "result")) {
604 f
= timer_result_from_string(value
);
606 log_unit_debug(u
, "Failed to parse result value: %s", value
);
607 else if (f
!= TIMER_SUCCESS
)
609 } else if (streq(key
, "last-trigger-realtime")) {
611 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
613 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
615 } else if (streq(key
, "last-trigger-monotonic")) {
617 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
619 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
622 log_unit_debug(u
, "Unknown serialization key: %s", key
);
627 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
630 return state_translation_table
[TIMER(u
)->state
];
633 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
636 return timer_state_to_string(TIMER(u
)->state
);
639 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
640 Timer
*t
= TIMER(userdata
);
644 if (t
->state
!= TIMER_WAITING
)
647 log_unit_debug(UNIT(t
), "Timer elapsed.");
648 timer_enter_running(t
);
652 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
659 if (other
->load_state
!= UNIT_LOADED
)
662 /* Reenable all timers that depend on unit state */
663 LIST_FOREACH(value
, v
, t
->values
)
664 if (v
->base
== TIMER_UNIT_ACTIVE
||
665 v
->base
== TIMER_UNIT_INACTIVE
)
673 /* Recalculate sleep time */
674 timer_enter_waiting(t
, false);
679 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
680 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
681 timer_enter_waiting(t
, false);
690 assert_not_reached("Unknown timer state");
694 static void timer_reset_failed(Unit
*u
) {
699 if (t
->state
== TIMER_FAILED
)
700 timer_set_state(t
, TIMER_DEAD
);
702 t
->result
= TIMER_SUCCESS
;
705 static void timer_time_change(Unit
*u
) {
710 if (t
->state
!= TIMER_WAITING
)
713 log_unit_debug(u
, "Time change, recalculating next elapse.");
714 timer_enter_waiting(t
, false);
717 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
718 [TIMER_ACTIVE
] = "OnActiveSec",
719 [TIMER_BOOT
] = "OnBootSec",
720 [TIMER_STARTUP
] = "OnStartupSec",
721 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
722 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
723 [TIMER_CALENDAR
] = "OnCalendar"
726 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
728 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
729 [TIMER_SUCCESS
] = "success",
730 [TIMER_FAILURE_RESOURCES
] = "resources"
733 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
735 const UnitVTable timer_vtable
= {
736 .object_size
= sizeof(Timer
),
742 .private_section
= "Timer",
748 .coldplug
= timer_coldplug
,
752 .start
= timer_start
,
755 .serialize
= timer_serialize
,
756 .deserialize_item
= timer_deserialize_item
,
758 .active_state
= timer_active_state
,
759 .sub_state_to_string
= timer_sub_state_to_string
,
761 .trigger_notify
= timer_trigger_notify
,
763 .reset_failed
= timer_reset_failed
,
764 .time_change
= timer_time_change
,
766 .bus_vtable
= bus_timer_vtable
,
767 .bus_set_property
= bus_timer_set_property
,
769 .can_transient
= true,