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
;
58 t
->remain_after_elapse
= true;
61 void timer_free_values(Timer
*t
) {
66 while ((v
= t
->values
)) {
67 LIST_REMOVE(value
, t
->values
, v
);
68 calendar_spec_free(v
->calendar_spec
);
73 static void timer_done(Unit
*u
) {
80 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
81 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
86 static int timer_verify(Timer
*t
) {
89 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
93 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
100 static int timer_add_default_dependencies(Timer
*t
) {
106 if (!UNIT(t
)->default_dependencies
)
109 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
113 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
114 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
118 LIST_FOREACH(value
, v
, t
->values
) {
119 if (v
->base
== TIMER_CALENDAR
) {
120 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
128 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
131 static int timer_setup_persistent(Timer
*t
) {
139 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
141 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
145 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
149 e
= getenv("XDG_DATA_HOME");
151 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
154 _cleanup_free_
char *h
= NULL
;
156 r
= get_home_dir(&h
);
158 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
160 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
170 static int timer_load(Unit
*u
) {
175 assert(u
->load_state
== UNIT_STUB
);
177 r
= unit_load_fragment_and_dropin(u
);
181 if (u
->load_state
== UNIT_LOADED
) {
183 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
186 r
= unit_load_related_unit(u
, ".service", &x
);
190 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
195 r
= timer_setup_persistent(t
);
199 r
= timer_add_default_dependencies(t
);
204 return timer_verify(t
);
207 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
208 char buf
[FORMAT_TIMESPAN_MAX
];
213 trigger
= UNIT_TRIGGER(u
);
216 "%sTimer State: %s\n"
222 "%sRemainAfterElapse: %s\n",
223 prefix
, timer_state_to_string(t
->state
),
224 prefix
, timer_result_to_string(t
->result
),
225 prefix
, trigger
? trigger
->id
: "n/a",
226 prefix
, yes_no(t
->persistent
),
227 prefix
, yes_no(t
->wake_system
),
228 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1),
229 prefix
, yes_no(t
->remain_after_elapse
));
231 LIST_FOREACH(value
, v
, t
->values
) {
233 if (v
->base
== TIMER_CALENDAR
) {
234 _cleanup_free_
char *p
= NULL
;
236 calendar_spec_to_string(v
->calendar_spec
, &p
);
241 timer_base_to_string(v
->base
),
244 char timespan1
[FORMAT_TIMESPAN_MAX
];
249 timer_base_to_string(v
->base
),
250 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
255 static void timer_set_state(Timer
*t
, TimerState state
) {
256 TimerState old_state
;
259 old_state
= t
->state
;
262 if (state
!= TIMER_WAITING
) {
263 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
264 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
267 if (state
!= old_state
)
268 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
270 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
273 static void timer_enter_waiting(Timer
*t
, bool initial
);
275 static int timer_coldplug(Unit
*u
) {
279 assert(t
->state
== TIMER_DEAD
);
281 if (t
->deserialized_state
== t
->state
)
284 if (t
->deserialized_state
== TIMER_WAITING
)
285 timer_enter_waiting(t
, false);
287 timer_set_state(t
, t
->deserialized_state
);
292 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
295 if (f
!= TIMER_SUCCESS
)
298 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
301 static void timer_enter_elapsed(Timer
*t
, bool leave_around
) {
304 /* If a unit is marked with RemainAfterElapse=yes we leave it
305 * around even after it elapsed once, so that starting it
306 * later again does not necessarily mean immediate
307 * retriggering. We unconditionally leave units with
308 * TIMER_UNIT_ACTIVE or TIMER_UNIT_INACTIVE triggers around,
309 * since they might be restarted automatically at any time
312 if (t
->remain_after_elapse
|| leave_around
)
313 timer_set_state(t
, TIMER_ELAPSED
);
315 timer_enter_dead(t
, TIMER_SUCCESS
);
318 static usec_t
monotonic_to_boottime(usec_t t
) {
324 a
= now(CLOCK_BOOTTIME
);
325 b
= now(CLOCK_MONOTONIC
);
333 static void timer_enter_waiting(Timer
*t
, bool initial
) {
334 bool found_monotonic
= false, found_realtime
= false;
335 usec_t ts_realtime
, ts_monotonic
;
337 bool leave_around
= false;
341 /* If we shall wake the system we use the boottime clock
342 * rather than the monotonic clock. */
344 ts_realtime
= now(CLOCK_REALTIME
);
345 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
346 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
348 LIST_FOREACH(value
, v
, t
->values
) {
353 if (v
->base
== TIMER_CALENDAR
) {
356 /* If we know the last time this was
357 * triggered, schedule the job based relative
358 * to that. If we don't just start from
361 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
363 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
368 t
->next_elapse_realtime
= v
->next_elapse
;
370 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
372 found_realtime
= true;
378 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
379 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
385 if (detect_container() <= 0) {
386 /* CLOCK_MONOTONIC equals the uptime on Linux */
390 /* In a container we don't want to include the time the host
391 * was already up when the container started, so count from
392 * our own startup. Fall through. */
394 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
397 case TIMER_UNIT_ACTIVE
:
399 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
402 base
= t
->last_trigger
.monotonic
;
409 case TIMER_UNIT_INACTIVE
:
411 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
414 base
= t
->last_trigger
.monotonic
;
422 assert_not_reached("Unknown timer base");
426 base
= monotonic_to_boottime(base
);
428 v
->next_elapse
= base
+ v
->value
;
430 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
431 /* This is a one time trigger, disable it now */
436 if (!found_monotonic
)
437 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
439 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
441 found_monotonic
= true;
445 if (!found_monotonic
&& !found_realtime
) {
446 log_unit_debug(UNIT(t
), "Timer is elapsed.");
447 timer_enter_elapsed(t
, leave_around
);
451 if (found_monotonic
) {
452 char buf
[FORMAT_TIMESPAN_MAX
];
455 left
= t
->next_elapse_monotonic_or_boottime
> ts_monotonic
? t
->next_elapse_monotonic_or_boottime
- ts_monotonic
: 0;
456 log_unit_debug(UNIT(t
), "Monotonic timer elapses in %s.", format_timespan(buf
, sizeof(buf
), left
, 0));
458 if (t
->monotonic_event_source
) {
459 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
463 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
468 r
= sd_event_add_time(
469 UNIT(t
)->manager
->event
,
470 &t
->monotonic_event_source
,
471 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
472 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
477 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
480 } else if (t
->monotonic_event_source
) {
482 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
487 if (found_realtime
) {
488 char buf
[FORMAT_TIMESTAMP_MAX
];
489 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
491 if (t
->realtime_event_source
) {
492 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
496 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
500 r
= sd_event_add_time(
501 UNIT(t
)->manager
->event
,
502 &t
->realtime_event_source
,
503 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
504 t
->next_elapse_realtime
, t
->accuracy_usec
,
509 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
512 } else if (t
->realtime_event_source
) {
514 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
519 timer_set_state(t
, TIMER_WAITING
);
523 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
524 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
527 static void timer_enter_running(Timer
*t
) {
528 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
533 /* Don't start job if we are supposed to go down */
534 if (unit_stop_pending(UNIT(t
)))
537 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)), JOB_REPLACE
, &error
, NULL
);
541 dual_timestamp_get(&t
->last_trigger
);
544 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
546 timer_set_state(t
, TIMER_RUNNING
);
550 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
551 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
554 static int timer_start(Unit
*u
) {
559 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
561 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
564 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
566 /* Reenable all timers that depend on unit activation time */
567 LIST_FOREACH(value
, v
, t
->values
)
568 if (v
->base
== TIMER_ACTIVE
)
574 if (stat(t
->stamp_path
, &st
) >= 0)
575 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
576 else if (errno
== ENOENT
)
577 /* The timer has never run before,
578 * make sure a stamp file exists.
580 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
583 t
->result
= TIMER_SUCCESS
;
584 timer_enter_waiting(t
, true);
588 static int timer_stop(Unit
*u
) {
592 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
594 timer_enter_dead(t
, TIMER_SUCCESS
);
598 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
605 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
606 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
608 if (t
->last_trigger
.realtime
> 0)
609 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
611 if (t
->last_trigger
.monotonic
> 0)
612 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
617 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
626 if (streq(key
, "state")) {
629 state
= timer_state_from_string(value
);
631 log_unit_debug(u
, "Failed to parse state value: %s", value
);
633 t
->deserialized_state
= state
;
634 } else if (streq(key
, "result")) {
637 f
= timer_result_from_string(value
);
639 log_unit_debug(u
, "Failed to parse result value: %s", value
);
640 else if (f
!= TIMER_SUCCESS
)
642 } else if (streq(key
, "last-trigger-realtime")) {
644 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
646 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
648 } else if (streq(key
, "last-trigger-monotonic")) {
650 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
652 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
655 log_unit_debug(u
, "Unknown serialization key: %s", key
);
660 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
663 return state_translation_table
[TIMER(u
)->state
];
666 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
669 return timer_state_to_string(TIMER(u
)->state
);
672 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
673 Timer
*t
= TIMER(userdata
);
677 if (t
->state
!= TIMER_WAITING
)
680 log_unit_debug(UNIT(t
), "Timer elapsed.");
681 timer_enter_running(t
);
685 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
692 if (other
->load_state
!= UNIT_LOADED
)
695 /* Reenable all timers that depend on unit state */
696 LIST_FOREACH(value
, v
, t
->values
)
697 if (v
->base
== TIMER_UNIT_ACTIVE
||
698 v
->base
== TIMER_UNIT_INACTIVE
)
706 /* Recalculate sleep time */
707 timer_enter_waiting(t
, false);
712 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
713 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
714 timer_enter_waiting(t
, false);
723 assert_not_reached("Unknown timer state");
727 static void timer_reset_failed(Unit
*u
) {
732 if (t
->state
== TIMER_FAILED
)
733 timer_set_state(t
, TIMER_DEAD
);
735 t
->result
= TIMER_SUCCESS
;
738 static void timer_time_change(Unit
*u
) {
743 if (t
->state
!= TIMER_WAITING
)
746 log_unit_debug(u
, "Time change, recalculating next elapse.");
747 timer_enter_waiting(t
, false);
750 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
751 [TIMER_ACTIVE
] = "OnActiveSec",
752 [TIMER_BOOT
] = "OnBootSec",
753 [TIMER_STARTUP
] = "OnStartupSec",
754 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
755 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
756 [TIMER_CALENDAR
] = "OnCalendar"
759 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
761 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
762 [TIMER_SUCCESS
] = "success",
763 [TIMER_FAILURE_RESOURCES
] = "resources"
766 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
768 const UnitVTable timer_vtable
= {
769 .object_size
= sizeof(Timer
),
775 .private_section
= "Timer",
781 .coldplug
= timer_coldplug
,
785 .start
= timer_start
,
788 .serialize
= timer_serialize
,
789 .deserialize_item
= timer_deserialize_item
,
791 .active_state
= timer_active_state
,
792 .sub_state_to_string
= timer_sub_state_to_string
,
794 .trigger_notify
= timer_trigger_notify
,
796 .reset_failed
= timer_reset_failed
,
797 .time_change
= timer_time_change
,
799 .bus_vtable
= bus_timer_vtable
,
800 .bus_set_property
= bus_timer_set_property
,
802 .can_transient
= true,