1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #include "alloc-util.h"
10 #include "bus-error.h"
12 #include "dbus-timer.h"
13 #include "dbus-unit.h"
15 #include "parse-util.h"
16 #include "random-util.h"
17 #include "serialize.h"
19 #include "string-table.h"
20 #include "string-util.h"
22 #include "unit-name.h"
24 #include "user-util.h"
27 static const UnitActiveState state_translation_table
[_TIMER_STATE_MAX
] = {
28 [TIMER_DEAD
] = UNIT_INACTIVE
,
29 [TIMER_WAITING
] = UNIT_ACTIVE
,
30 [TIMER_RUNNING
] = UNIT_ACTIVE
,
31 [TIMER_ELAPSED
] = UNIT_ACTIVE
,
32 [TIMER_FAILED
] = UNIT_FAILED
35 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
);
37 static void timer_init(Unit
*u
) {
41 assert(u
->load_state
== UNIT_STUB
);
43 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
44 t
->next_elapse_realtime
= USEC_INFINITY
;
45 t
->accuracy_usec
= u
->manager
->default_timer_accuracy_usec
;
46 t
->remain_after_elapse
= true;
49 void timer_free_values(Timer
*t
) {
54 while ((v
= t
->values
)) {
55 LIST_REMOVE(value
, t
->values
, v
);
56 calendar_spec_free(v
->calendar_spec
);
61 static void timer_done(Unit
*u
) {
68 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
69 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
74 static int timer_verify(Timer
*t
) {
76 assert(UNIT(t
)->load_state
== UNIT_LOADED
);
78 if (!t
->values
&& !t
->on_clock_change
&& !t
->on_timezone_change
) {
79 log_unit_error(UNIT(t
), "Timer unit lacks value setting. Refusing.");
86 static int timer_add_default_dependencies(Timer
*t
) {
92 if (!UNIT(t
)->default_dependencies
)
95 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_BEFORE
, SPECIAL_TIMERS_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
99 if (MANAGER_IS_SYSTEM(UNIT(t
)->manager
)) {
100 r
= unit_add_two_dependencies_by_name(UNIT(t
), UNIT_AFTER
, UNIT_REQUIRES
, SPECIAL_SYSINIT_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
104 LIST_FOREACH(value
, v
, t
->values
) {
105 if (v
->base
== TIMER_CALENDAR
) {
106 r
= unit_add_dependency_by_name(UNIT(t
), UNIT_AFTER
, SPECIAL_TIME_SYNC_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
114 return unit_add_two_dependencies_by_name(UNIT(t
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_SHUTDOWN_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
117 static int timer_add_trigger_dependencies(Timer
*t
) {
123 if (!hashmap_isempty(UNIT(t
)->dependencies
[UNIT_TRIGGERS
]))
126 r
= unit_load_related_unit(UNIT(t
), ".service", &x
);
130 return unit_add_two_dependencies(UNIT(t
), UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true, UNIT_DEPENDENCY_IMPLICIT
);
133 static int timer_setup_persistent(Timer
*t
) {
141 if (MANAGER_IS_SYSTEM(UNIT(t
)->manager
)) {
143 r
= unit_require_mounts_for(UNIT(t
), "/var/lib/systemd/timers", UNIT_DEPENDENCY_FILE
);
147 t
->stamp_path
= strjoin("/var/lib/systemd/timers/stamp-", UNIT(t
)->id
);
151 e
= getenv("XDG_DATA_HOME");
153 t
->stamp_path
= strjoin(e
, "/systemd/timers/stamp-", UNIT(t
)->id
);
156 _cleanup_free_
char *h
= NULL
;
158 r
= get_home_dir(&h
);
160 return log_unit_error_errno(UNIT(t
), r
, "Failed to determine home directory: %m");
162 t
->stamp_path
= strjoin(h
, "/.local/share/systemd/timers/stamp-", UNIT(t
)->id
);
172 static int timer_load(Unit
*u
) {
177 assert(u
->load_state
== UNIT_STUB
);
179 r
= unit_load_fragment_and_dropin(u
, true);
183 if (u
->load_state
!= UNIT_LOADED
)
186 /* This is a new unit? Then let's add in some extras */
187 r
= timer_add_trigger_dependencies(t
);
191 r
= timer_setup_persistent(t
);
195 r
= timer_add_default_dependencies(t
);
199 return timer_verify(t
);
202 static void timer_dump(Unit
*u
, FILE *f
, const char *prefix
) {
203 char buf
[FORMAT_TIMESPAN_MAX
];
208 trigger
= UNIT_TRIGGER(u
);
211 "%sTimer State: %s\n"
217 "%sRemainAfterElapse: %s\n"
218 "%sOnClockChange: %s\n"
219 "%sOnTimeZoneChange: %s\n",
220 prefix
, timer_state_to_string(t
->state
),
221 prefix
, timer_result_to_string(t
->result
),
222 prefix
, trigger
? trigger
->id
: "n/a",
223 prefix
, yes_no(t
->persistent
),
224 prefix
, yes_no(t
->wake_system
),
225 prefix
, format_timespan(buf
, sizeof(buf
), t
->accuracy_usec
, 1),
226 prefix
, yes_no(t
->remain_after_elapse
),
227 prefix
, yes_no(t
->on_clock_change
),
228 prefix
, yes_no(t
->on_timezone_change
));
230 LIST_FOREACH(value
, v
, t
->values
) {
232 if (v
->base
== TIMER_CALENDAR
) {
233 _cleanup_free_
char *p
= NULL
;
235 (void) calendar_spec_to_string(v
->calendar_spec
, &p
);
240 timer_base_to_string(v
->base
),
243 char timespan1
[FORMAT_TIMESPAN_MAX
];
248 timer_base_to_string(v
->base
),
249 format_timespan(timespan1
, sizeof(timespan1
), v
->value
, 0));
254 static void timer_set_state(Timer
*t
, TimerState state
) {
255 TimerState old_state
;
258 if (t
->state
!= state
)
259 bus_unit_send_pending_change_signal(UNIT(t
), false);
261 old_state
= t
->state
;
264 if (state
!= TIMER_WAITING
) {
265 t
->monotonic_event_source
= sd_event_source_unref(t
->monotonic_event_source
);
266 t
->realtime_event_source
= sd_event_source_unref(t
->realtime_event_source
);
267 t
->next_elapse_monotonic_or_boottime
= USEC_INFINITY
;
268 t
->next_elapse_realtime
= USEC_INFINITY
;
271 if (state
!= old_state
)
272 log_unit_debug(UNIT(t
), "Changed %s -> %s", timer_state_to_string(old_state
), timer_state_to_string(state
));
274 unit_notify(UNIT(t
), state_translation_table
[old_state
], state_translation_table
[state
], 0);
277 static void timer_enter_waiting(Timer
*t
, bool time_change
);
279 static int timer_coldplug(Unit
*u
) {
283 assert(t
->state
== TIMER_DEAD
);
285 if (t
->deserialized_state
== t
->state
)
288 if (t
->deserialized_state
== TIMER_WAITING
)
289 timer_enter_waiting(t
, false);
291 timer_set_state(t
, t
->deserialized_state
);
296 static void timer_enter_dead(Timer
*t
, TimerResult f
) {
299 if (t
->result
== TIMER_SUCCESS
)
302 unit_log_result(UNIT(t
), t
->result
== TIMER_SUCCESS
, timer_result_to_string(t
->result
));
303 timer_set_state(t
, t
->result
!= TIMER_SUCCESS
? TIMER_FAILED
: TIMER_DEAD
);
306 static void timer_enter_elapsed(Timer
*t
, bool leave_around
) {
309 /* If a unit is marked with RemainAfterElapse=yes we leave it
310 * around even after it elapsed once, so that starting it
311 * later again does not necessarily mean immediate
312 * retriggering. We unconditionally leave units with
313 * TIMER_UNIT_ACTIVE or TIMER_UNIT_INACTIVE triggers around,
314 * since they might be restarted automatically at any time
317 if (t
->remain_after_elapse
|| leave_around
)
318 timer_set_state(t
, TIMER_ELAPSED
);
320 timer_enter_dead(t
, TIMER_SUCCESS
);
323 static void add_random(Timer
*t
, usec_t
*v
) {
324 char s
[FORMAT_TIMESPAN_MAX
];
330 if (t
->random_usec
== 0)
332 if (*v
== USEC_INFINITY
)
335 add
= random_u64() % t
->random_usec
;
337 if (*v
+ add
< *v
) /* overflow */
338 *v
= (usec_t
) -2; /* Highest possible value, that is not USEC_INFINITY */
342 log_unit_debug(UNIT(t
), "Adding %s random time.", format_timespan(s
, sizeof(s
), add
, 0));
345 static void timer_enter_waiting(Timer
*t
, bool time_change
) {
346 bool found_monotonic
= false, found_realtime
= false;
347 bool leave_around
= false;
355 trigger
= UNIT_TRIGGER(UNIT(t
));
357 log_unit_error(UNIT(t
), "Unit to trigger vanished.");
358 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
362 triple_timestamp_get(&ts
);
363 t
->next_elapse_monotonic_or_boottime
= t
->next_elapse_realtime
= 0;
365 LIST_FOREACH(value
, v
, t
->values
) {
369 if (v
->base
== TIMER_CALENDAR
) {
372 /* If we know the last time this was
373 * triggered, schedule the job based relative
374 * to that. If we don't, just start from
375 * the activation time. */
377 if (t
->last_trigger
.realtime
> 0)
378 b
= t
->last_trigger
.realtime
;
380 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
381 b
= UNIT(t
)->inactive_exit_timestamp
.realtime
;
386 r
= calendar_spec_next_usec(v
->calendar_spec
, b
, &v
->next_elapse
);
390 /* To make the delay due to RandomizedDelaySec= work even at boot,
391 * if the scheduled time has already passed, set the time when systemd
392 * first started as the scheduled time.
393 * Also, we don't have to check t->persistent since the logic implicitly express true. */
394 if (v
->next_elapse
< UNIT(t
)->manager
->timestamps
[MANAGER_TIMESTAMP_USERSPACE
].realtime
)
395 v
->next_elapse
= UNIT(t
)->manager
->timestamps
[MANAGER_TIMESTAMP_USERSPACE
].realtime
;
398 t
->next_elapse_realtime
= v
->next_elapse
;
400 t
->next_elapse_realtime
= MIN(t
->next_elapse_realtime
, v
->next_elapse
);
402 found_realtime
= true;
410 if (state_translation_table
[t
->state
] == UNIT_ACTIVE
)
411 base
= UNIT(t
)->inactive_exit_timestamp
.monotonic
;
417 if (detect_container() <= 0) {
418 /* CLOCK_MONOTONIC equals the uptime on Linux */
422 /* In a container we don't want to include the time the host
423 * was already up when the container started, so count from
424 * our own startup. */
427 base
= UNIT(t
)->manager
->timestamps
[MANAGER_TIMESTAMP_USERSPACE
].monotonic
;
430 case TIMER_UNIT_ACTIVE
:
432 base
= MAX(trigger
->inactive_exit_timestamp
.monotonic
, t
->last_trigger
.monotonic
);
437 case TIMER_UNIT_INACTIVE
:
439 base
= MAX(trigger
->inactive_enter_timestamp
.monotonic
, t
->last_trigger
.monotonic
);
445 assert_not_reached("Unknown timer base");
448 v
->next_elapse
= usec_add(usec_shift_clock(base
, CLOCK_MONOTONIC
, TIMER_MONOTONIC_CLOCK(t
)), v
->value
);
450 if (dual_timestamp_is_set(&t
->last_trigger
) &&
452 v
->next_elapse
< triple_timestamp_by_clock(&ts
, TIMER_MONOTONIC_CLOCK(t
)) &&
453 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
&& !t
->on_timezone_change
&& !t
->on_clock_change
) {
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
= usec_sub_unsigned(t
->next_elapse_monotonic_or_boottime
, triple_timestamp_by_clock(&ts
, TIMER_MONOTONIC_CLOCK(t
)));
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_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
562 /* Don't start job if we are supposed to go down */
563 if (unit_stop_pending(UNIT(t
)))
566 trigger
= UNIT_TRIGGER(UNIT(t
));
568 log_unit_error(UNIT(t
), "Unit to trigger vanished.");
569 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
573 r
= manager_add_job(UNIT(t
)->manager
, JOB_START
, trigger
, JOB_REPLACE
, NULL
, &error
, NULL
);
577 dual_timestamp_get(&t
->last_trigger
);
580 touch_file(t
->stamp_path
, true, t
->last_trigger
.realtime
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
582 timer_set_state(t
, TIMER_RUNNING
);
586 log_unit_warning(UNIT(t
), "Failed to queue unit startup job: %s", bus_error_message(&error
, r
));
587 timer_enter_dead(t
, TIMER_FAILURE_RESOURCES
);
590 static int timer_start(Unit
*u
) {
596 assert(IN_SET(t
->state
, TIMER_DEAD
, TIMER_FAILED
));
598 r
= unit_test_trigger_loaded(u
);
602 r
= unit_test_start_limit(u
);
604 timer_enter_dead(t
, TIMER_FAILURE_START_LIMIT_HIT
);
608 r
= unit_acquire_invocation_id(u
);
612 t
->last_trigger
= DUAL_TIMESTAMP_NULL
;
614 /* Reenable all timers that depend on unit activation time */
615 LIST_FOREACH(value
, v
, t
->values
)
616 if (v
->base
== TIMER_ACTIVE
)
622 if (stat(t
->stamp_path
, &st
) >= 0) {
625 /* Load the file timestamp, but only if it is actually in the past. If it is in the future,
626 * something is wrong with the system clock. */
628 ft
= timespec_load(&st
.st_mtim
);
629 if (ft
< now(CLOCK_REALTIME
))
630 t
->last_trigger
.realtime
= ft
;
632 char z
[FORMAT_TIMESTAMP_MAX
];
634 log_unit_warning(u
, "Not using persistent file timestamp %s as it is in the future.",
635 format_timestamp(z
, sizeof(z
), ft
));
638 } else if (errno
== ENOENT
)
639 /* The timer has never run before,
640 * make sure a stamp file exists.
642 (void) touch_file(t
->stamp_path
, true, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
645 t
->result
= TIMER_SUCCESS
;
646 timer_enter_waiting(t
, false);
650 static int timer_stop(Unit
*u
) {
654 assert(IN_SET(t
->state
, TIMER_WAITING
, TIMER_RUNNING
, TIMER_ELAPSED
));
656 timer_enter_dead(t
, TIMER_SUCCESS
);
660 static int timer_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
667 (void) serialize_item(f
, "state", timer_state_to_string(t
->state
));
668 (void) serialize_item(f
, "result", timer_result_to_string(t
->result
));
670 if (t
->last_trigger
.realtime
> 0)
671 (void) serialize_usec(f
, "last-trigger-realtime", t
->last_trigger
.realtime
);
673 if (t
->last_trigger
.monotonic
> 0)
674 (void) serialize_usec(f
, "last-trigger-monotonic", t
->last_trigger
.monotonic
);
679 static int timer_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
687 if (streq(key
, "state")) {
690 state
= timer_state_from_string(value
);
692 log_unit_debug(u
, "Failed to parse state value: %s", value
);
694 t
->deserialized_state
= state
;
696 } else if (streq(key
, "result")) {
699 f
= timer_result_from_string(value
);
701 log_unit_debug(u
, "Failed to parse result value: %s", value
);
702 else if (f
!= TIMER_SUCCESS
)
705 } else if (streq(key
, "last-trigger-realtime"))
706 (void) deserialize_usec(value
, &t
->last_trigger
.realtime
);
707 else if (streq(key
, "last-trigger-monotonic"))
708 (void) deserialize_usec(value
, &t
->last_trigger
.monotonic
);
710 log_unit_debug(u
, "Unknown serialization key: %s", key
);
715 _pure_
static UnitActiveState
timer_active_state(Unit
*u
) {
718 return state_translation_table
[TIMER(u
)->state
];
721 _pure_
static const char *timer_sub_state_to_string(Unit
*u
) {
724 return timer_state_to_string(TIMER(u
)->state
);
727 static int timer_dispatch(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
728 Timer
*t
= TIMER(userdata
);
732 if (t
->state
!= TIMER_WAITING
)
735 log_unit_debug(UNIT(t
), "Timer elapsed.");
736 timer_enter_running(t
);
740 static void timer_trigger_notify(Unit
*u
, Unit
*other
) {
747 if (other
->load_state
!= UNIT_LOADED
)
750 /* Reenable all timers that depend on unit state */
751 LIST_FOREACH(value
, v
, t
->values
)
752 if (IN_SET(v
->base
, TIMER_UNIT_ACTIVE
, TIMER_UNIT_INACTIVE
))
760 /* Recalculate sleep time */
761 timer_enter_waiting(t
, false);
766 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
))) {
767 log_unit_debug(UNIT(t
), "Got notified about unit deactivation.");
768 timer_enter_waiting(t
, false);
777 assert_not_reached("Unknown timer state");
781 static void timer_reset_failed(Unit
*u
) {
786 if (t
->state
== TIMER_FAILED
)
787 timer_set_state(t
, TIMER_DEAD
);
789 t
->result
= TIMER_SUCCESS
;
792 static void timer_time_change(Unit
*u
) {
798 if (t
->state
!= TIMER_WAITING
)
801 /* If we appear to have triggered in the future, the system clock must
802 * have been set backwards. So let's rewind our own clock and allow
803 * the future trigger(s) to happen again :). Exactly the same as when
804 * you start a timer unit with Persistent=yes. */
805 ts
= now(CLOCK_REALTIME
);
806 if (t
->last_trigger
.realtime
> ts
)
807 t
->last_trigger
.realtime
= ts
;
809 if (t
->on_clock_change
) {
810 log_unit_debug(u
, "Time change, triggering activation.");
811 timer_enter_running(t
);
813 log_unit_debug(u
, "Time change, recalculating next elapse.");
814 timer_enter_waiting(t
, true);
818 static void timer_timezone_change(Unit
*u
) {
823 if (t
->state
!= TIMER_WAITING
)
826 if (t
->on_timezone_change
) {
827 log_unit_debug(u
, "Timezone change, triggering activation.");
828 timer_enter_running(t
);
830 log_unit_debug(u
, "Timezone change, recalculating next elapse.");
831 timer_enter_waiting(t
, false);
835 static int timer_clean(Unit
*u
, ExecCleanMask mask
) {
842 if (t
->state
!= TIMER_DEAD
)
845 if (!IN_SET(mask
, EXEC_CLEAN_STATE
))
848 r
= timer_setup_persistent(t
);
855 if (unlink(t
->stamp_path
) && errno
!= ENOENT
)
856 return log_unit_error_errno(u
, errno
, "Failed to clean stamp file of timer: %m");
861 static int timer_can_clean(Unit
*u
, ExecCleanMask
*ret
) {
866 *ret
= t
->persistent
? EXEC_CLEAN_STATE
: 0;
870 static const char* const timer_base_table
[_TIMER_BASE_MAX
] = {
871 [TIMER_ACTIVE
] = "OnActiveSec",
872 [TIMER_BOOT
] = "OnBootSec",
873 [TIMER_STARTUP
] = "OnStartupSec",
874 [TIMER_UNIT_ACTIVE
] = "OnUnitActiveSec",
875 [TIMER_UNIT_INACTIVE
] = "OnUnitInactiveSec",
876 [TIMER_CALENDAR
] = "OnCalendar"
879 DEFINE_STRING_TABLE_LOOKUP(timer_base
, TimerBase
);
881 static const char* const timer_result_table
[_TIMER_RESULT_MAX
] = {
882 [TIMER_SUCCESS
] = "success",
883 [TIMER_FAILURE_RESOURCES
] = "resources",
884 [TIMER_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
887 DEFINE_STRING_TABLE_LOOKUP(timer_result
, TimerResult
);
889 const UnitVTable timer_vtable
= {
890 .object_size
= sizeof(Timer
),
896 .private_section
= "Timer",
902 .coldplug
= timer_coldplug
,
906 .start
= timer_start
,
909 .clean
= timer_clean
,
910 .can_clean
= timer_can_clean
,
912 .serialize
= timer_serialize
,
913 .deserialize_item
= timer_deserialize_item
,
915 .active_state
= timer_active_state
,
916 .sub_state_to_string
= timer_sub_state_to_string
,
918 .trigger_notify
= timer_trigger_notify
,
920 .reset_failed
= timer_reset_failed
,
921 .time_change
= timer_time_change
,
922 .timezone_change
= timer_timezone_change
,
924 .bus_vtable
= bus_timer_vtable
,
925 .bus_set_property
= bus_timer_set_property
,
927 .can_transient
= true,