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 "parse-util.h"
30 #include "string-table.h"
31 #include "string-util.h"
33 #include "unit-name.h"
35 #include "user-util.h"
37 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
38 [TIMER_DEAD
] = UNIT_INACTIVE
,
39 [TIMER_WAITING
] = UNIT_ACTIVE
,
40 [TIMER_RUNNING
] = UNIT_ACTIVE
,
41 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
42 [TIMER_FAILED
] = UNIT_FAILED
45 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
47 static void timer_init(Unit
*u
) {
51 assert(u
->load_state
== UNIT_STUB
);
53 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
54 t
->next_elapse_realtime
= USEC_INFINITY
;
55 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
58 void timer_free_values(Timer
*t
) {
63 while ((v
= t
->values
)) {
64 LIST_REMOVE(value
, t
->values
, v
);
65 calendar_spec_free(v
->calendar_spec
);
70 static void timer_done(Unit
*u
) {
77 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
78 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
83 static int timer_verify(Timer
*t
) {
86 if (UNIT(t
)->load_state
!= UNIT_LOADED
)
90 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
97 static int timer_add_default_dependencies(Timer
*t
) {
103 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, NULL
, true);
107 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
108 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, NULL
, true);
112 LIST_FOREACH(value
, v
, t
->values
) {
113 if (v
->base
== TIMER_CALENDAR
) {
114 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, NULL
, true);
122 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
125 static int timer_setup_persistent(Timer
*t
) {
133 if (UNIT(t
)->manager
->running_as
== MANAGER_SYSTEM
) {
135 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers");
139 t
->stamp_path
= strappend("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
143 e
= getenv("XDG_DATA_HOME");
145 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
148 _cleanup_free_
char *h
= NULL
;
150 r
= get_home_dir(&h
);
152 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
154 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
, NULL
);
164 static int timer_load(Unit
*u
) {
169 assert(u
->load_state
== UNIT_STUB
);
171 r
= unit_load_fragment_and_dropin(u
);
175 if (u
->load_state
== UNIT_LOADED
) {
177 if (set_isempty(u
->dependencies
[UNIT_TRIGGERS
])) {
180 r
= unit_load_related_unit(u
, ".service", &x
);
184 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
189 r
= timer_setup_persistent(t
);
193 if (u
->default_dependencies
) {
194 r
= timer_add_default_dependencies(t
);
200 return timer_verify(t
);
203 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
204 char buf
[FORMAT_TIMESPAN_MAX
];
209 trigger
= UNIT_TRIGGER(u
);
212 "%sTimer State: %s\n"
218 prefix
, timer_state_to_string(t
->state
),
219 prefix
, timer_result_to_string(t
->result
),
220 prefix
, trigger
? trigger
->id
: "n/a",
221 prefix
, yes_no(t
->persistent
),
222 prefix
, yes_no(t
->wake_system
),
223 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1));
225 LIST_FOREACH(value
, v
, t
->values
) {
227 if (v
->base
== TIMER_CALENDAR
) {
228 _cleanup_free_
char *p
= NULL
;
230 calendar_spec_to_string(v
->calendar_spec
, &p
);
235 timer_base_to_string(v
->base
),
238 char timespan1
[FORMAT_TIMESPAN_MAX
];
243 timer_base_to_string(v
->base
),
244 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
249 static void timer_set_state(Timer
*t
, TimerState state
) {
250 TimerState old_state
;
253 old_state
= t
->state
;
256 if (state
!= TIMER_WAITING
) {
257 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
258 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
261 if (state
!= old_state
)
262 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
264 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], true);
267 static void timer_enter_waiting(Timer
*t
, bool initial
);
269 static int timer_coldplug(Unit
*u
) {
273 assert(t
->state
== TIMER_DEAD
);
275 if (t
->deserialized_state
!= t
->state
) {
277 if (t
->deserialized_state
== TIMER_WAITING
)
278 timer_enter_waiting(t
, false);
280 timer_set_state(t
, t
->deserialized_state
);
286 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
289 if (f
!= TIMER_SUCCESS
)
292 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
295 static usec_t
monotonic_to_boottime(usec_t t
) {
301 a
= now(CLOCK_BOOTTIME
);
302 b
= now(CLOCK_MONOTONIC
);
310 static void timer_enter_waiting(Timer
*t
, bool initial
) {
311 bool found_monotonic
= false, found_realtime
= false;
312 usec_t ts_realtime
, ts_monotonic
;
317 /* If we shall wake the system we use the boottime clock
318 * rather than the monotonic clock. */
320 ts_realtime
= now(CLOCK_REALTIME
);
321 ts_monotonic
= now(t
->wake_system
? CLOCK_BOOTTIME
: CLOCK_MONOTONIC
);
322 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
324 LIST_FOREACH(value
, v
, t
->values
) {
329 if (v
->base
== TIMER_CALENDAR
) {
332 /* If we know the last time this was
333 * triggered, schedule the job based relative
334 * to that. If we don't just start from
337 b
= t
->last_trigger
.realtime
> 0 ? t
->last_trigger
.realtime
: ts_realtime
;
339 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
344 t
->next_elapse_realtime
= v
->next_elapse
;
346 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
348 found_realtime
= true;
354 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
355 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
361 /* CLOCK_MONOTONIC equals the uptime on Linux */
366 base
= UNIT(t
)->manager
->userspace_timestamp
.monotonic
;
369 case TIMER_UNIT_ACTIVE
:
371 base
= UNIT_TRIGGER(UNIT(t
))->inactive_exit_timestamp
.monotonic
;
374 base
= t
->last_trigger
.monotonic
;
381 case TIMER_UNIT_INACTIVE
:
383 base
= UNIT_TRIGGER(UNIT(t
))->inactive_enter_timestamp
.monotonic
;
386 base
= t
->last_trigger
.monotonic
;
394 assert_not_reached("Unknown timer base");
398 base
= monotonic_to_boottime(base
);
400 v
->next_elapse
= base
+ v
->value
;
402 if (!initial
&& v
->next_elapse
< ts_monotonic
&& IN_SET(v
->base
, TIMER_ACTIVE
, TIMER_BOOT
, TIMER_STARTUP
)) {
403 /* This is a one time trigger, disable it now */
408 if (!found_monotonic
)
409 t
->next_elapse_monotonic_or_boottime
= v
->next_elapse
;
411 t
->next_elapse_monotonic_or_boottime
= MIN(t
->next_elapse_monotonic_or_boottime
, v
->next_elapse
);
413 found_monotonic
= true;
417 if (!found_monotonic
&& !found_realtime
) {
418 log_unit_debug(UNIT(t
), "Timer is elapsed.");
419 timer_set_state(t
, TIMER_ELAPSED
);
423 if (found_monotonic
) {
424 char buf
[FORMAT_TIMESPAN_MAX
];
426 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));
428 if (t
->monotonic_event_source
) {
429 r
= sd_event_source_set_time(t
->monotonic_event_source
, t
->next_elapse_monotonic_or_boottime
);
433 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_ONESHOT
);
438 r
= sd_event_add_time(
439 UNIT(t
)->manager
->event
,
440 &t
->monotonic_event_source
,
441 t
->wake_system
? CLOCK_BOOTTIME_ALARM
: CLOCK_MONOTONIC
,
442 t
->next_elapse_monotonic_or_boottime
, t
->accuracy_usec
,
447 (void) sd_event_source_set_description(t
->monotonic_event_source
, "timer-monotonic");
450 } else if (t
->monotonic_event_source
) {
452 r
= sd_event_source_set_enabled(t
->monotonic_event_source
, SD_EVENT_OFF
);
457 if (found_realtime
) {
458 char buf
[FORMAT_TIMESTAMP_MAX
];
459 log_unit_debug(UNIT(t
), "Realtime timer elapses at %s.", format_timestamp(buf
, sizeof(buf
), t
->next_elapse_realtime
));
461 if (t
->realtime_event_source
) {
462 r
= sd_event_source_set_time(t
->realtime_event_source
, t
->next_elapse_realtime
);
466 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_ONESHOT
);
470 r
= sd_event_add_time(
471 UNIT(t
)->manager
->event
,
472 &t
->realtime_event_source
,
473 t
->wake_system
? CLOCK_REALTIME_ALARM
: CLOCK_REALTIME
,
474 t
->next_elapse_realtime
, t
->accuracy_usec
,
479 (void) sd_event_source_set_description(t
->realtime_event_source
, "timer-realtime");
482 } else if (t
->realtime_event_source
) {
484 r
= sd_event_source_set_enabled(t
->realtime_event_source
, SD_EVENT_OFF
);
489 timer_set_state(t
, TIMER_WAITING
);
493 log_unit_warning_errno(UNIT(t
), r
, "Failed to enter waiting state: %m");
494 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
497 static void timer_enter_running(Timer
*t
) {
498 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
503 /* Don't start job if we are supposed to go down */
504 if (unit_stop_pending(UNIT(t
)))
507 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(t
)),
508 JOB_REPLACE
, true, &error
, NULL
);
512 dual_timestamp_get(&t
->last_trigger
);
515 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, 0);
517 timer_set_state(t
, TIMER_RUNNING
);
521 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
522 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
525 static int timer_start(Unit
*u
) {
530 assert(t
->state
== TIMER_DEAD
|| t
->state
== TIMER_FAILED
);
532 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
535 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
537 /* Reenable all timers that depend on unit activation time */
538 LIST_FOREACH(value
, v
, t
->values
)
539 if (v
->base
== TIMER_ACTIVE
)
545 if (stat(t
->stamp_path
, &st
) >= 0)
546 t
->last_trigger
.realtime
= timespec_load(&st
.st_atim
);
547 else if (errno
== ENOENT
)
548 /* The timer has never run before,
549 * make sure a stamp file exists.
551 touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
554 t
->result
= TIMER_SUCCESS
;
555 timer_enter_waiting(t
, true);
559 static int timer_stop(Unit
*u
) {
563 assert(t
->state
== TIMER_WAITING
|| t
->state
== TIMER_RUNNING
|| t
->state
== TIMER_ELAPSED
);
565 timer_enter_dead(t
, TIMER_SUCCESS
);
569 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
576 unit_serialize_item(u
, f
, "state", timer_state_to_string(t
->state
));
577 unit_serialize_item(u
, f
, "result", timer_result_to_string(t
->result
));
579 if (t
->last_trigger
.realtime
> 0)
580 unit_serialize_item_format(u
, f
, "last-trigger-realtime", "%" PRIu64
, t
->last_trigger
.realtime
);
582 if (t
->last_trigger
.monotonic
> 0)
583 unit_serialize_item_format(u
, f
, "last-trigger-monotonic", "%" PRIu64
, t
->last_trigger
.monotonic
);
588 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
597 if (streq(key
, "state")) {
600 state
= timer_state_from_string(value
);
602 log_unit_debug(u
, "Failed to parse state value: %s", value
);
604 t
->deserialized_state
= state
;
605 } else if (streq(key
, "result")) {
608 f
= timer_result_from_string(value
);
610 log_unit_debug(u
, "Failed to parse result value: %s", value
);
611 else if (f
!= TIMER_SUCCESS
)
613 } else if (streq(key
, "last-trigger-realtime")) {
615 r
= safe_atou64(value
, &t
->last_trigger
.realtime
);
617 log_unit_debug(u
, "Failed to parse last-trigger-realtime value: %s", value
);
619 } else if (streq(key
, "last-trigger-monotonic")) {
621 r
= safe_atou64(value
, &t
->last_trigger
.monotonic
);
623 log_unit_debug(u
, "Failed to parse last-trigger-monotonic value: %s", value
);
626 log_unit_debug(u
, "Unknown serialization key: %s", key
);
631 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
634 return state_translation_table
[TIMER(u
)->state
];
637 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
640 return timer_state_to_string(TIMER(u
)->state
);
643 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
644 Timer
*t
= TIMER(userdata
);
648 if (t
->state
!= TIMER_WAITING
)
651 log_unit_debug(UNIT(t
), "Timer elapsed.");
652 timer_enter_running(t
);
656 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
663 if (other
->load_state
!= UNIT_LOADED
)
666 /* Reenable all timers that depend on unit state */
667 LIST_FOREACH(value
, v
, t
->values
)
668 if (v
->base
== TIMER_UNIT_ACTIVE
||
669 v
->base
== TIMER_UNIT_INACTIVE
)
677 /* Recalculate sleep time */
678 timer_enter_waiting(t
, false);
683 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
684 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
685 timer_enter_waiting(t
, false);
694 assert_not_reached("Unknown timer state");
698 static void timer_reset_failed(Unit
*u
) {
703 if (t
->state
== TIMER_FAILED
)
704 timer_set_state(t
, TIMER_DEAD
);
706 t
->result
= TIMER_SUCCESS
;
709 static void timer_time_change(Unit
*u
) {
714 if (t
->state
!= TIMER_WAITING
)
717 log_unit_debug(u
, "Time change, recalculating next elapse.");
718 timer_enter_waiting(t
, false);
721 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
722 [TIMER_ACTIVE
] = "OnActiveSec",
723 [TIMER_BOOT
] = "OnBootSec",
724 [TIMER_STARTUP
] = "OnStartupSec",
725 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
726 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
727 [TIMER_CALENDAR
] = "OnCalendar"
730 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
732 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
733 [TIMER_SUCCESS
] = "success",
734 [TIMER_FAILURE_RESOURCES
] = "resources"
737 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
739 const UnitVTable timer_vtable
= {
740 .object_size
= sizeof(Timer
),
746 .private_section
= "Timer",
752 .coldplug
= timer_coldplug
,
756 .start
= timer_start
,
759 .serialize
= timer_serialize
,
760 .deserialize_item
= timer_deserialize_item
,
762 .active_state
= timer_active_state
,
763 .sub_state_to_string
= timer_sub_state_to_string
,
765 .trigger_notify
= timer_trigger_notify
,
767 .reset_failed
= timer_reset_failed
,
768 .time_change
= timer_time_change
,
770 .bus_vtable
= bus_timer_vtable
,
771 .bus_set_property
= bus_timer_set_property
,
773 .can_transient
= true,