chiark / gitweb /
95416f3e746263c63be03b49dac7fab8bb1f0209
[elogind.git] / src / core / timer.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23
24 #include "unit.h"
25 #include "unit-name.h"
26 #include "timer.h"
27 #include "dbus-timer.h"
28 #include "special.h"
29 #include "bus-util.h"
30 #include "bus-error.h"
31 #include "mkdir.h"
32
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
39 };
40
41 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata);
42
43 static void timer_init(Unit *u) {
44         Timer *t = TIMER(u);
45
46         assert(u);
47         assert(u->load_state == UNIT_STUB);
48
49         t->next_elapse_monotonic = (usec_t) -1;
50         t->next_elapse_realtime = (usec_t) -1;
51         t->accuracy_usec = USEC_PER_MINUTE;
52 }
53
54 void timer_free_values(Timer *t) {
55         TimerValue *v;
56
57         assert(t);
58
59         while ((v = t->values)) {
60                 LIST_REMOVE(value, t->values, v);
61
62                 if (v->calendar_spec)
63                         calendar_spec_free(v->calendar_spec);
64
65                 free(v);
66         }
67 }
68
69 static void timer_done(Unit *u) {
70         Timer *t = TIMER(u);
71
72         assert(t);
73
74         timer_free_values(t);
75
76         t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
77         t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
78
79         free(t->stamp_path);
80 }
81
82 static int timer_verify(Timer *t) {
83         assert(t);
84
85         if (UNIT(t)->load_state != UNIT_LOADED)
86                 return 0;
87
88         if (!t->values) {
89                 log_error_unit(UNIT(t)->id, "%s lacks value setting. Refusing.", UNIT(t)->id);
90                 return -EINVAL;
91         }
92
93         return 0;
94 }
95
96 static int timer_add_default_dependencies(Timer *t) {
97         int r;
98
99         assert(t);
100
101         r = unit_add_dependency_by_name(UNIT(t), UNIT_BEFORE, SPECIAL_TIMERS_TARGET, NULL, true);
102         if (r < 0)
103                 return r;
104
105         if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
106                 r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
107                 if (r < 0)
108                         return r;
109         }
110
111         return unit_add_two_dependencies_by_name(UNIT(t), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
112 }
113
114 static int timer_setup_persistent(Timer *t) {
115         int r;
116
117         assert(t);
118
119         if (!t->persistent)
120                 return 0;
121
122         if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) {
123
124                 r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
125                 if (r < 0)
126                         return r;
127
128                 t->stamp_path = strappend("/var/lib/systemd/timers/stamp-", UNIT(t)->id);
129         } else {
130                 const char *e;
131
132                 e = getenv("XDG_DATA_HOME");
133                 if (e)
134                         t->stamp_path = strjoin(e, "/systemd/timers/", UNIT(t)->id, NULL);
135                 else {
136
137                         _cleanup_free_ char *h = NULL;
138
139                         r = get_home_dir(&h);
140                         if (r < 0) {
141                                 log_error("Failed to determine home directory: %s", strerror(-r));
142                                 return r;
143                         }
144
145                         t->stamp_path = strjoin(h, "/.local/share/systemd/timers/stamp-", UNIT(t)->id, NULL);
146                 }
147         }
148
149         if (!t->stamp_path)
150                 return log_oom();
151
152         return 0;
153 }
154
155 static int timer_load(Unit *u) {
156         Timer *t = TIMER(u);
157         int r;
158
159         assert(u);
160         assert(u->load_state == UNIT_STUB);
161
162         r = unit_load_fragment_and_dropin(u);
163         if (r < 0)
164                 return r;
165
166         if (u->load_state == UNIT_LOADED) {
167
168                 if (set_isempty(u->dependencies[UNIT_TRIGGERS])) {
169                         Unit *x;
170
171                         r = unit_load_related_unit(u, ".service", &x);
172                         if (r < 0)
173                                 return r;
174
175                         r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
176                         if (r < 0)
177                                 return r;
178                 }
179
180                 r = timer_setup_persistent(t);
181                 if (r < 0)
182                         return r;
183
184                 if (u->default_dependencies) {
185                         r = timer_add_default_dependencies(t);
186                         if (r < 0)
187                                 return r;
188                 }
189         }
190
191         return timer_verify(t);
192 }
193
194 static void timer_dump(Unit *u, FILE *f, const char *prefix) {
195         char buf[FORMAT_TIMESPAN_MAX];
196         Timer *t = TIMER(u);
197         Unit *trigger;
198         TimerValue *v;
199
200         trigger = UNIT_TRIGGER(u);
201
202         fprintf(f,
203                 "%sTimer State: %s\n"
204                 "%sResult: %s\n"
205                 "%sUnit: %s\n"
206                 "%sAccuracy: %s\n",
207                 prefix, timer_state_to_string(t->state),
208                 prefix, timer_result_to_string(t->result),
209                 prefix, trigger ? trigger->id : "n/a",
210                 prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1));
211
212         LIST_FOREACH(value, v, t->values) {
213
214                 if (v->base == TIMER_CALENDAR) {
215                         _cleanup_free_ char *p = NULL;
216
217                         calendar_spec_to_string(v->calendar_spec, &p);
218
219                         fprintf(f,
220                                 "%s%s: %s\n",
221                                 prefix,
222                                 timer_base_to_string(v->base),
223                                 strna(p));
224                 } else  {
225                         char timespan1[FORMAT_TIMESPAN_MAX];
226
227                         fprintf(f,
228                                 "%s%s: %s\n",
229                                 prefix,
230                                 timer_base_to_string(v->base),
231                                 strna(format_timespan(timespan1, sizeof(timespan1), v->value, 0)));
232                 }
233         }
234 }
235
236 static void timer_set_state(Timer *t, TimerState state) {
237         TimerState old_state;
238         assert(t);
239
240         old_state = t->state;
241         t->state = state;
242
243         if (state != TIMER_WAITING) {
244                 t->monotonic_event_source = sd_event_source_unref(t->monotonic_event_source);
245                 t->realtime_event_source = sd_event_source_unref(t->realtime_event_source);
246         }
247
248         if (state != old_state)
249                 log_debug_unit(UNIT(t)->id,
250                                "%s changed %s -> %s", UNIT(t)->id,
251                                timer_state_to_string(old_state),
252                                timer_state_to_string(state));
253
254         unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
255 }
256
257 static void timer_enter_waiting(Timer *t, bool initial);
258
259 static int timer_coldplug(Unit *u) {
260         Timer *t = TIMER(u);
261
262         assert(t);
263         assert(t->state == TIMER_DEAD);
264
265         if (t->deserialized_state != t->state) {
266
267                 if (t->deserialized_state == TIMER_WAITING)
268                         timer_enter_waiting(t, false);
269                 else
270                         timer_set_state(t, t->deserialized_state);
271         }
272
273         return 0;
274 }
275
276 static void timer_enter_dead(Timer *t, TimerResult f) {
277         assert(t);
278
279         if (f != TIMER_SUCCESS)
280                 t->result = f;
281
282         timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
283 }
284
285 static void timer_enter_waiting(Timer *t, bool initial) {
286         TimerValue *v;
287         usec_t base = 0;
288         dual_timestamp ts;
289         bool found_monotonic = false, found_realtime = false;
290         int r;
291
292         dual_timestamp_get(&ts);
293         t->next_elapse_monotonic = t->next_elapse_realtime = 0;
294
295         LIST_FOREACH(value, v, t->values) {
296
297                 if (v->disabled)
298                         continue;
299
300                 if (v->base == TIMER_CALENDAR) {
301                         usec_t b;
302
303                         /* If we know the last time this was
304                          * triggered, schedule the job based relative
305                          * to that. If we don't just start from
306                          * now. */
307
308                         b = t->last_trigger.realtime > 0 ? t->last_trigger.realtime : ts.realtime;
309
310                         r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse);
311                         if (r < 0)
312                                 continue;
313
314                         if (!found_realtime)
315                                 t->next_elapse_realtime = v->next_elapse;
316                         else
317                                 t->next_elapse_realtime = MIN(t->next_elapse_realtime, v->next_elapse);
318
319                         found_realtime = true;
320
321                 } else  {
322                         switch (v->base) {
323
324                         case TIMER_ACTIVE:
325                                 if (state_translation_table[t->state] == UNIT_ACTIVE)
326                                         base = UNIT(t)->inactive_exit_timestamp.monotonic;
327                                 else
328                                         base = ts.monotonic;
329                                 break;
330
331                         case TIMER_BOOT:
332                                 /* CLOCK_MONOTONIC equals the uptime on Linux */
333                                 base = 0;
334                                 break;
335
336                         case TIMER_STARTUP:
337                                 base = UNIT(t)->manager->userspace_timestamp.monotonic;
338                                 break;
339
340                         case TIMER_UNIT_ACTIVE:
341
342                                 base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
343
344                                 if (base <= 0)
345                                         base = t->last_trigger.monotonic;
346
347                                 if (base <= 0)
348                                         continue;
349
350                                 break;
351
352                         case TIMER_UNIT_INACTIVE:
353
354                                 base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
355
356                                 if (base <= 0)
357                                         base = t->last_trigger.monotonic;
358
359                                 if (base <= 0)
360                                         continue;
361
362                                 break;
363
364                         default:
365                                 assert_not_reached("Unknown timer base");
366                         }
367
368                         v->next_elapse = base + v->value;
369
370                         if (!initial && v->next_elapse < ts.monotonic && IN_SET(v->base, TIMER_ACTIVE, TIMER_BOOT, TIMER_STARTUP)) {
371                                 /* This is a one time trigger, disable it now */
372                                 v->disabled = true;
373                                 continue;
374                         }
375
376                         if (!found_monotonic)
377                                 t->next_elapse_monotonic = v->next_elapse;
378                         else
379                                 t->next_elapse_monotonic = MIN(t->next_elapse_monotonic, v->next_elapse);
380
381                         found_monotonic = true;
382                 }
383         }
384
385         if (!found_monotonic && !found_realtime) {
386                 log_debug_unit(UNIT(t)->id, "%s: Timer is elapsed.", UNIT(t)->id);
387                 timer_set_state(t, TIMER_ELAPSED);
388                 return;
389         }
390
391         if (found_monotonic) {
392                 char buf[FORMAT_TIMESPAN_MAX];
393                 log_debug_unit(UNIT(t)->id, "%s: Monotonic timer elapses in %s.", UNIT(t)->id, format_timespan(buf, sizeof(buf), t->next_elapse_monotonic > ts.monotonic ? t->next_elapse_monotonic - ts.monotonic : 0, 0));
394
395                 if (t->monotonic_event_source) {
396                         r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic);
397                         if (r < 0)
398                                 goto fail;
399
400                         r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_ONESHOT);
401                 } else
402                         r = sd_event_add_time(
403                                         UNIT(t)->manager->event,
404                                         &t->monotonic_event_source,
405                                         CLOCK_MONOTONIC,
406                                         t->next_elapse_monotonic, t->accuracy_usec,
407                                         timer_dispatch, t);
408                 if (r < 0)
409                         goto fail;
410
411         } else if (t->monotonic_event_source) {
412
413                 r = sd_event_source_set_enabled(t->monotonic_event_source, SD_EVENT_OFF);
414                 if (r < 0)
415                         goto fail;
416         }
417
418         if (found_realtime) {
419                 char buf[FORMAT_TIMESTAMP_MAX];
420                 log_debug_unit(UNIT(t)->id, "%s: Realtime timer elapses at %s.", UNIT(t)->id, format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
421
422                 if (t->realtime_event_source) {
423                         r = sd_event_source_set_time(t->realtime_event_source, t->next_elapse_realtime);
424                         if (r < 0)
425                                 goto fail;
426
427                         r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_ONESHOT);
428                 } else
429                         r = sd_event_add_time(
430                                         UNIT(t)->manager->event,
431                                         &t->realtime_event_source,
432                                         CLOCK_REALTIME,
433                                         t->next_elapse_realtime, t->accuracy_usec,
434                                         timer_dispatch, t);
435                 if (r < 0)
436                         goto fail;
437
438         } else if (t->realtime_event_source) {
439
440                 r = sd_event_source_set_enabled(t->realtime_event_source, SD_EVENT_OFF);
441                 if (r < 0)
442                         goto fail;
443         }
444
445         timer_set_state(t, TIMER_WAITING);
446         return;
447
448 fail:
449         log_warning_unit(UNIT(t)->id, "%s failed to enter waiting state: %s", UNIT(t)->id, strerror(-r));
450         timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
451 }
452
453 static void timer_enter_running(Timer *t) {
454         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
455         int r;
456
457         assert(t);
458
459         /* Don't start job if we are supposed to go down */
460         if (unit_stop_pending(UNIT(t)))
461                 return;
462
463         r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_TRIGGER(UNIT(t)),
464                             JOB_REPLACE, true, &error, NULL);
465         if (r < 0)
466                 goto fail;
467
468         dual_timestamp_get(&t->last_trigger);
469
470         if (t->stamp_path) {
471                 _cleanup_close_ int fd = -1;
472
473                 mkdir_parents_label(t->stamp_path, 0755);
474
475                 /* Update the file atime + mtime, if we can */
476                 fd = open(t->stamp_path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
477                 if (fd >= 0) {
478                         struct timespec ts[2];
479
480                         timespec_store(&ts[0], t->last_trigger.realtime);
481                         ts[1] = ts[0];
482
483                         futimens(fd, ts);
484                 }
485         }
486
487         timer_set_state(t, TIMER_RUNNING);
488         return;
489
490 fail:
491         log_warning_unit(UNIT(t)->id,
492                          "%s failed to queue unit startup job: %s",
493                          UNIT(t)->id, bus_error_message(&error, r));
494         timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
495 }
496
497 static int timer_start(Unit *u) {
498         Timer *t = TIMER(u);
499
500         assert(t);
501         assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
502
503         if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
504                 return -ENOENT;
505
506         t->last_trigger = DUAL_TIMESTAMP_NULL;
507
508         if (t->stamp_path) {
509                 struct stat st;
510
511                 if (stat(t->stamp_path, &st) >= 0)
512                         t->last_trigger.realtime = timespec_load(&st.st_atim);
513         }
514
515         t->result = TIMER_SUCCESS;
516         timer_enter_waiting(t, true);
517         return 0;
518 }
519
520 static int timer_stop(Unit *u) {
521         Timer *t = TIMER(u);
522
523         assert(t);
524         assert(t->state == TIMER_WAITING || t->state == TIMER_RUNNING || t->state == TIMER_ELAPSED);
525
526         timer_enter_dead(t, TIMER_SUCCESS);
527         return 0;
528 }
529
530 static int timer_serialize(Unit *u, FILE *f, FDSet *fds) {
531         Timer *t = TIMER(u);
532
533         assert(u);
534         assert(f);
535         assert(fds);
536
537         unit_serialize_item(u, f, "state", timer_state_to_string(t->state));
538         unit_serialize_item(u, f, "result", timer_result_to_string(t->result));
539
540         if (t->last_trigger.realtime > 0)
541                 unit_serialize_item_format(u, f, "last-trigger-realtime", "%" PRIu64, t->last_trigger.realtime);
542
543         if (t->last_trigger.monotonic > 0)
544                 unit_serialize_item_format(u, f, "last-trigger-monotonic", "%" PRIu64, t->last_trigger.monotonic);
545
546         return 0;
547 }
548
549 static int timer_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
550         Timer *t = TIMER(u);
551         int r;
552
553         assert(u);
554         assert(key);
555         assert(value);
556         assert(fds);
557
558         if (streq(key, "state")) {
559                 TimerState state;
560
561                 state = timer_state_from_string(value);
562                 if (state < 0)
563                         log_debug_unit(u->id, "Failed to parse state value %s", value);
564                 else
565                         t->deserialized_state = state;
566         } else if (streq(key, "result")) {
567                 TimerResult f;
568
569                 f = timer_result_from_string(value);
570                 if (f < 0)
571                         log_debug_unit(u->id, "Failed to parse result value %s", value);
572                 else if (f != TIMER_SUCCESS)
573                         t->result = f;
574         } else if (streq(key, "last-trigger-realtime")) {
575
576                 r = safe_atou64(value, &t->last_trigger.realtime);
577                 if (r < 0)
578                         log_debug_unit(u->id, "Failed to parse last-trigger-realtime value %s", value);
579
580         } else if (streq(key, "last-trigger-monotonic")) {
581
582                 r = safe_atou64(value, &t->last_trigger.monotonic);
583                 if (r < 0)
584                         log_debug_unit(u->id, "Failed to parse last-trigger-monotonic value %s", value);
585
586         } else
587                 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
588
589         return 0;
590 }
591
592 _pure_ static UnitActiveState timer_active_state(Unit *u) {
593         assert(u);
594
595         return state_translation_table[TIMER(u)->state];
596 }
597
598 _pure_ static const char *timer_sub_state_to_string(Unit *u) {
599         assert(u);
600
601         return timer_state_to_string(TIMER(u)->state);
602 }
603
604 static int timer_dispatch(sd_event_source *s, uint64_t usec, void *userdata) {
605         Timer *t = TIMER(userdata);
606
607         assert(t);
608
609         if (t->state != TIMER_WAITING)
610                 return 0;
611
612         log_debug_unit(UNIT(t)->id, "Timer elapsed on %s", UNIT(t)->id);
613         timer_enter_running(t);
614         return 0;
615 }
616
617 static void timer_trigger_notify(Unit *u, Unit *other) {
618         Timer *t = TIMER(u);
619         TimerValue *v;
620
621         assert(u);
622         assert(other);
623
624         if (other->load_state != UNIT_LOADED)
625                 return;
626
627         /* Reenable all timers that depend on unit state */
628         LIST_FOREACH(value, v, t->values)
629                 if (v->base == TIMER_UNIT_ACTIVE ||
630                     v->base == TIMER_UNIT_INACTIVE)
631                         v->disabled = false;
632
633         switch (t->state) {
634
635         case TIMER_WAITING:
636         case TIMER_ELAPSED:
637
638                 /* Recalculate sleep time */
639                 timer_enter_waiting(t, false);
640                 break;
641
642         case TIMER_RUNNING:
643
644                 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) {
645                         log_debug_unit(UNIT(t)->id, "%s got notified about unit deactivation.", UNIT(t)->id);
646                         timer_enter_waiting(t, false);
647                 }
648                 break;
649
650         case TIMER_DEAD:
651         case TIMER_FAILED:
652                 break;
653
654         default:
655                 assert_not_reached("Unknown timer state");
656         }
657 }
658
659 static void timer_reset_failed(Unit *u) {
660         Timer *t = TIMER(u);
661
662         assert(t);
663
664         if (t->state == TIMER_FAILED)
665                 timer_set_state(t, TIMER_DEAD);
666
667         t->result = TIMER_SUCCESS;
668 }
669
670 static void timer_time_change(Unit *u) {
671         Timer *t = TIMER(u);
672
673         assert(u);
674
675         if (t->state != TIMER_WAITING)
676                 return;
677
678         log_debug_unit(u->id, "%s: time change, recalculating next elapse.", u->id);
679         timer_enter_waiting(t, false);
680 }
681
682 static const char* const timer_state_table[_TIMER_STATE_MAX] = {
683         [TIMER_DEAD] = "dead",
684         [TIMER_WAITING] = "waiting",
685         [TIMER_RUNNING] = "running",
686         [TIMER_ELAPSED] = "elapsed",
687         [TIMER_FAILED] = "failed"
688 };
689
690 DEFINE_STRING_TABLE_LOOKUP(timer_state, TimerState);
691
692 static const char* const timer_base_table[_TIMER_BASE_MAX] = {
693         [TIMER_ACTIVE] = "OnActiveSec",
694         [TIMER_BOOT] = "OnBootSec",
695         [TIMER_STARTUP] = "OnStartupSec",
696         [TIMER_UNIT_ACTIVE] = "OnUnitActiveSec",
697         [TIMER_UNIT_INACTIVE] = "OnUnitInactiveSec",
698         [TIMER_CALENDAR] = "OnCalendar"
699 };
700
701 DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
702
703 static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
704         [TIMER_SUCCESS] = "success",
705         [TIMER_FAILURE_RESOURCES] = "resources"
706 };
707
708 DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);
709
710 const UnitVTable timer_vtable = {
711         .object_size = sizeof(Timer),
712
713         .sections =
714                 "Unit\0"
715                 "Timer\0"
716                 "Install\0",
717
718         .init = timer_init,
719         .done = timer_done,
720         .load = timer_load,
721
722         .coldplug = timer_coldplug,
723
724         .dump = timer_dump,
725
726         .start = timer_start,
727         .stop = timer_stop,
728
729         .serialize = timer_serialize,
730         .deserialize_item = timer_deserialize_item,
731
732         .active_state = timer_active_state,
733         .sub_state_to_string = timer_sub_state_to_string,
734
735         .trigger_notify = timer_trigger_notify,
736
737         .reset_failed = timer_reset_failed,
738         .time_change = timer_time_change,
739
740         .bus_interface = "org.freedesktop.systemd1.Timer",
741         .bus_vtable = bus_timer_vtable,
742 };