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"
30 #include "random-util.h"
32 #include "string-table.h"
33 #include "string-util.h"
35 #include "unit-name.h"
37 #include "user-util.h"
40 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
41 [TIMER_DEAD
] = UNIT_INACTIVE
,
42 [TIMER_WAITING
] = UNIT_ACTIVE
,
43 [TIMER_RUNNING
] = UNIT_ACTIVE
,
44 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
45 [TIMER_FAILED
] = UNIT_FAILED
48 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
50 static void timer_init(Unit
*u
) {
54 assert(u
->load_state
== UNIT_STUB
);
56 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
57 t
->next_elapse_realtime
= USEC_INFINITY
;
58 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
59 t
->remain_after_elapse
= true;
62 void timer_free_values(Timer
*t
) {
67 while ((v
= t
->values
)) {
68 LIST_REMOVE(value
, t
->values
, v
);
69 calendar_spec_free(v
->calendar_spec
);
74 static void timer_done(Unit
*u
) {
81 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
82 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
87 static int timer_verify(Timer
*t
) {
90 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
94 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
101 static int timer_add_default_dependencies(Timer
*t
) {
107 if (!UNIT(t
)->default_dependencies
)
110 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
114 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
115 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
119 LIST_FOREACH(value
, v
, t
->values
) {
120 if (v
->base
== TIMER_CALENDAR
) {
121 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
129 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
132 static int timer_setup_persistent(Timer
*t
) {
140 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
142 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
146 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
150 e
= getenv("XDG_DATA_HOME");
152 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
155 _cleanup_free_
char *h
= NULL
;
157 r
= get_home_dir(&h
);
159 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
161 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
171 static int timer_load(Unit
*u
) {
176 assert(u
->load_state
== UNIT_STUB
);
178 r
= unit_load_fragment_and_dropin(u
);
182 if (u
->load_state
== UNIT_LOADED
) {
184 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
187 r
= unit_load_related_unit(u
, ".service", &x
);
191 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
196 r
= timer_setup_persistent(t
);
200 r
= timer_add_default_dependencies(t
);
205 return timer_verify(t
);
208 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
209 char buf
[FORMAT_TIMESPAN_MAX
];
214 trigger
= UNIT_TRIGGER(u
);
217 "%sTimer State: %s\n"
223 "%sRemainAfterElapse: %s\n",
224 prefix
, timer_state_to_string(t
->state
),
225 prefix
, timer_result_to_string(t
->result
),
226 prefix
, trigger
? trigger
->id
: "n/a",
227 prefix
, yes_no(t
->persistent
),
228 prefix
, yes_no(t
->wake_system
),
229 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1),
230 prefix
, yes_no(t
->remain_after_elapse
));
232 LIST_FOREACH(value
, v
, t
->values
) {
234 if (v
->base
== TIMER_CALENDAR
) {
235 _cleanup_free_
char *p
= NULL
;
237 calendar_spec_to_string(v
->calendar_spec
, &p
);
242 timer_base_to_string(v
->base
),
245 char timespan1
[FORMAT_TIMESPAN_MAX
];
250 timer_base_to_string(v
->base
),
251 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
256 static void timer_set_state(Timer
*t
, TimerState state
) {
257 TimerState old_state
;
260 old_state
= t
->state
;
263 if (state
!= TIMER_WAITING
) {
264 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
265 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
268 if (state
!= old_state
)
269 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
271 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
274 static void timer_enter_waiting(Timer
*t
, bool initial
);
276 static int timer_coldplug(Unit
*u
) {
280 assert(t
->state
== TIMER_DEAD
);
282 if (t
->deserialized_state
== t
->state
)
285 if (t
->deserialized_state
== TIMER_WAITING
)
286 timer_enter_waiting(t
, false);
288 timer_set_state(t
, t
->deserialized_state
);
293 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
296 if (f
!= TIMER_SUCCESS
)
299 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
302 static void timer_enter_elapsed(Timer
*t
, bool leave_around
) {
305 /* If a unit is marked with RemainAfterElapse=yes we leave it
306 * around even after it elapsed once, so that starting it
307 * later again does not necessarily mean immediate
308 * retriggering. We unconditionally leave units with
309 * TIMER_UNIT_ACTIVE or TIMER_UNIT_INACTIVE triggers around,
310 * since they might be restarted automatically at any time
313 if (t
->remain_after_elapse
|| leave_around
)
314 timer_set_state(t
, TIMER_ELAPSED
);
316 timer_enter_dead(t
, TIMER_SUCCESS
);
319 static usec_t
monotonic_to_boottime(usec_t t
) {
325 a
= now(CLOCK_BOOTTIME
);
326 b
= now(CLOCK_MONOTONIC
);
334 static void add_random(Timer
*t
, usec_t
*v
) {
335 char s
[FORMAT_TIMESPAN_MAX
];
341 if (t
->random_usec
== 0)
343 if (*v
== USEC_INFINITY
)
346 add
= random_u64() % t
->random_usec
;
348 if (*v
+ add
< *v
) /* overflow */
349 *v
= (usec_t
) -2; /* Highest possible value, that is not USEC_INFINITY */
353 log_unit_info(UNIT(t
), "Adding %s random time.", format_timespan(s
, sizeof(s
), add
, 0));
356 static void timer_enter_waiting(Timer
*t
, bool initial
) {
357 bool found_monotonic
= false, found_realtime
= false;
358 usec_t ts_realtime
, ts_monotonic
;
360 bool leave_around
= false;
364 /* If we shall wake the system we use the boottime clock
365 * rather than the monotonic clock. */
367 ts_realtime
= now(CLOCK_REALTIME
);
368 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
369 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
371 LIST_FOREACH(value
, v
, t
->values
) {
376 if (v
->base
== TIMER_CALENDAR
) {
379 /* If we know the last time this was
380 * triggered, schedule the job based relative
381 * to that. If we don't just start from
384 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
386 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
391 t
->next_elapse_realtime
= v
->next_elapse
;
393 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
395 found_realtime
= true;
401 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
402 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
408 if (detect_container() <= 0) {
409 /* CLOCK_MONOTONIC equals the uptime on Linux */
413 /* In a container we don't want to include the time the host
414 * was already up when the container started, so count from
415 * our own startup. Fall through. */
417 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
420 case TIMER_UNIT_ACTIVE
:
422 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
425 base
= t
->last_trigger
.monotonic
;
432 case TIMER_UNIT_INACTIVE
:
434 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
437 base
= t
->last_trigger
.monotonic
;
445 assert_not_reached("Unknown timer base");
449 base
= monotonic_to_boottime(base
);
451 v
->next_elapse
= base
+ v
->value
;
453 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
454 /* This is a one time trigger, disable it now */
459 if (!found_monotonic
)
460 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
462 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
464 found_monotonic
= true;
468 if (!found_monotonic
&& !found_realtime
) {
469 log_unit_debug(UNIT(t
), "Timer is elapsed.");
470 timer_enter_elapsed(t
, leave_around
);
474 if (found_monotonic
) {
475 char buf
[FORMAT_TIMESPAN_MAX
];
478 add_random(t
, &t
->next_elapse_monotonic_or_boottime
);
480 left
= t
->next_elapse_monotonic_or_boottime
> ts_monotonic
? t
->next_elapse_monotonic_or_boottime
- ts_monotonic
: 0;
481 log_unit_debug(UNIT(t
), "Monotonic timer elapses in %s.", format_timespan(buf
, sizeof(buf
), left
, 0));
483 if (t
->monotonic_event_source
) {
484 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
488 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
493 r
= sd_event_add_time(
494 UNIT(t
)->manager
->event
,
495 &t
->monotonic_event_source
,
496 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
497 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
502 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
505 } else if (t
->monotonic_event_source
) {
507 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
512 if (found_realtime
) {
513 char buf
[FORMAT_TIMESTAMP_MAX
];
515 add_random(t
, &t
->next_elapse_realtime
);
517 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
519 if (t
->realtime_event_source
) {
520 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
524 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
528 r
= sd_event_add_time(
529 UNIT(t
)->manager
->event
,
530 &t
->realtime_event_source
,
531 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
532 t
->next_elapse_realtime
, t
->accuracy_usec
,
537 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
540 } else if (t
->realtime_event_source
) {
542 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
547 timer_set_state(t
, TIMER_WAITING
);
551 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
552 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
555 static void timer_enter_running(Timer
*t
) {
556 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
561 /* Don't start job if we are supposed to go down */
562 if (unit_stop_pending(UNIT(t
)))
565 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)), JOB_REPLACE
, &error
, NULL
);
569 dual_timestamp_get(&t
->last_trigger
);
572 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
574 timer_set_state(t
, TIMER_RUNNING
);
578 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
579 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
582 static int timer_start(Unit
*u
) {
587 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
589 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
592 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
594 /* Reenable all timers that depend on unit activation time */
595 LIST_FOREACH(value
, v
, t
->values
)
596 if (v
->base
== TIMER_ACTIVE
)
602 if (stat(t
->stamp_path
, &st
) >= 0)
603 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
604 else if (errno
== ENOENT
)
605 /* The timer has never run before,
606 * make sure a stamp file exists.
608 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
611 t
->result
= TIMER_SUCCESS
;
612 timer_enter_waiting(t
, true);
616 static int timer_stop(Unit
*u
) {
620 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
622 timer_enter_dead(t
, TIMER_SUCCESS
);
626 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
633 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
634 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
636 if (t
->last_trigger
.realtime
> 0)
637 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
639 if (t
->last_trigger
.monotonic
> 0)
640 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
645 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
654 if (streq(key
, "state")) {
657 state
= timer_state_from_string(value
);
659 log_unit_debug(u
, "Failed to parse state value: %s", value
);
661 t
->deserialized_state
= state
;
662 } else if (streq(key
, "result")) {
665 f
= timer_result_from_string(value
);
667 log_unit_debug(u
, "Failed to parse result value: %s", value
);
668 else if (f
!= TIMER_SUCCESS
)
670 } else if (streq(key
, "last-trigger-realtime")) {
672 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
674 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
676 } else if (streq(key
, "last-trigger-monotonic")) {
678 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
680 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
683 log_unit_debug(u
, "Unknown serialization key: %s", key
);
688 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
691 return state_translation_table
[TIMER(u
)->state
];
694 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
697 return timer_state_to_string(TIMER(u
)->state
);
700 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
701 Timer
*t
= TIMER(userdata
);
705 if (t
->state
!= TIMER_WAITING
)
708 log_unit_debug(UNIT(t
), "Timer elapsed.");
709 timer_enter_running(t
);
713 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
720 if (other
->load_state
!= UNIT_LOADED
)
723 /* Reenable all timers that depend on unit state */
724 LIST_FOREACH(value
, v
, t
->values
)
725 if (v
->base
== TIMER_UNIT_ACTIVE
||
726 v
->base
== TIMER_UNIT_INACTIVE
)
734 /* Recalculate sleep time */
735 timer_enter_waiting(t
, false);
740 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
741 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
742 timer_enter_waiting(t
, false);
751 assert_not_reached("Unknown timer state");
755 static void timer_reset_failed(Unit
*u
) {
760 if (t
->state
== TIMER_FAILED
)
761 timer_set_state(t
, TIMER_DEAD
);
763 t
->result
= TIMER_SUCCESS
;
766 static void timer_time_change(Unit
*u
) {
771 if (t
->state
!= TIMER_WAITING
)
774 log_unit_debug(u
, "Time change, recalculating next elapse.");
775 timer_enter_waiting(t
, false);
778 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
779 [TIMER_ACTIVE
] = "OnActiveSec",
780 [TIMER_BOOT
] = "OnBootSec",
781 [TIMER_STARTUP
] = "OnStartupSec",
782 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
783 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
784 [TIMER_CALENDAR
] = "OnCalendar"
787 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
789 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
790 [TIMER_SUCCESS
] = "success",
791 [TIMER_FAILURE_RESOURCES
] = "resources"
794 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
796 const UnitVTable timer_vtable
= {
797 .object_size
= sizeof(Timer
),
803 .private_section
= "Timer",
809 .coldplug
= timer_coldplug
,
813 .start
= timer_start
,
816 .serialize
= timer_serialize
,
817 .deserialize_item
= timer_deserialize_item
,
819 .active_state
= timer_active_state
,
820 .sub_state_to_string
= timer_sub_state_to_string
,
822 .trigger_notify
= timer_trigger_notify
,
824 .reset_failed
= timer_reset_failed
,
825 .time_change
= timer_time_change
,
827 .bus_vtable
= bus_timer_vtable
,
828 .bus_set_property
= bus_timer_set_property
,
830 .can_transient
= true,