]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/timer.c
util: use SPECIAL_ROOT_SLICE macro where appropriate
[thirdparty/systemd.git] / src / core / timer.c
index a3c8ac72e833f5af66195a856c5ee1bfb412e52b..e2b43f02f8b12a0d709f52668e902a7c7cb8e3f9 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
@@ -111,7 +109,7 @@ static int timer_add_default_dependencies(Timer *t) {
         if (r < 0)
                 return r;
 
-        if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) {
+        if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
                 r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
                 if (r < 0)
                         return r;
@@ -137,7 +135,7 @@ static int timer_setup_persistent(Timer *t) {
         if (!t->persistent)
                 return 0;
 
-        if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) {
+        if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) {
 
                 r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers");
                 if (r < 0)
@@ -293,7 +291,7 @@ static int timer_coldplug(Unit *u) {
 static void timer_enter_dead(Timer *t, TimerResult f) {
         assert(t);
 
-        if (f != TIMER_SUCCESS)
+        if (t->result == TIMER_SUCCESS)
                 t->result = f;
 
         timer_set_state(t, t->result != TIMER_SUCCESS ? TIMER_FAILED : TIMER_DEAD);
@@ -322,7 +320,7 @@ static usec_t monotonic_to_boottime(usec_t t) {
         if (t <= 0)
                 return 0;
 
-        a = now(CLOCK_BOOTTIME);
+        a = now(clock_boottime_or_monotonic());
         b = now(CLOCK_MONOTONIC);
 
         if (t + a > b)
@@ -336,7 +334,7 @@ static void add_random(Timer *t, usec_t *v) {
         usec_t add;
 
         assert(t);
-        assert(*v);
+        assert(v);
 
         if (t->random_usec == 0)
                 return;
@@ -359,13 +357,23 @@ static void timer_enter_waiting(Timer *t, bool initial) {
         usec_t base = 0;
         bool leave_around = false;
         TimerValue *v;
+        Unit *trigger;
         int r;
 
+        assert(t);
+
+        trigger = UNIT_TRIGGER(UNIT(t));
+        if (!trigger) {
+                log_unit_error(UNIT(t), "Unit to trigger vanished.");
+                timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
+                return;
+        }
+
         /* If we shall wake the system we use the boottime clock
          * rather than the monotonic clock. */
 
         ts_realtime = now(CLOCK_REALTIME);
-        ts_monotonic = now(t->wake_system ? CLOCK_BOOTTIME : CLOCK_MONOTONIC);
+        ts_monotonic = now(t->wake_system ? clock_boottime_or_monotonic() : CLOCK_MONOTONIC);
         t->next_elapse_monotonic_or_boottime = t->next_elapse_realtime = 0;
 
         LIST_FOREACH(value, v, t->values) {
@@ -419,7 +427,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
 
                         case TIMER_UNIT_ACTIVE:
                                 leave_around = true;
-                                base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic;
+                                base = trigger->inactive_exit_timestamp.monotonic;
 
                                 if (base <= 0)
                                         base = t->last_trigger.monotonic;
@@ -431,7 +439,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
 
                         case TIMER_UNIT_INACTIVE:
                                 leave_around = true;
-                                base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic;
+                                base = trigger->inactive_enter_timestamp.monotonic;
 
                                 if (base <= 0)
                                         base = t->last_trigger.monotonic;
@@ -554,6 +562,7 @@ fail:
 
 static void timer_enter_running(Timer *t) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        Unit *trigger;
         int r;
 
         assert(t);
@@ -562,7 +571,14 @@ static void timer_enter_running(Timer *t) {
         if (unit_stop_pending(UNIT(t)))
                 return;
 
-        r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_TRIGGER(UNIT(t)), JOB_REPLACE, &error, NULL);
+        trigger = UNIT_TRIGGER(UNIT(t));
+        if (!trigger) {
+                log_unit_error(UNIT(t), "Unit to trigger vanished.");
+                timer_enter_dead(t, TIMER_FAILURE_RESOURCES);
+                return;
+        }
+
+        r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL);
         if (r < 0)
                 goto fail;
 
@@ -582,12 +598,23 @@ fail:
 static int timer_start(Unit *u) {
         Timer *t = TIMER(u);
         TimerValue *v;
+        Unit *trigger;
+        int r;
 
         assert(t);
         assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED);
 
-        if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
+        trigger = UNIT_TRIGGER(u);
+        if (!trigger || trigger->load_state != UNIT_LOADED) {
+                log_unit_error(u, "Refusing to start, unit to trigger not loaded.");
                 return -ENOENT;
+        }
+
+        r = unit_start_limit_test(u);
+        if (r < 0) {
+                timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT);
+                return r;
+        }
 
         t->last_trigger = DUAL_TIMESTAMP_NULL;
 
@@ -788,7 +815,8 @@ DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase);
 
 static const char* const timer_result_table[_TIMER_RESULT_MAX] = {
         [TIMER_SUCCESS] = "success",
-        [TIMER_FAILURE_RESOURCES] = "resources"
+        [TIMER_FAILURE_RESOURCES] = "resources",
+        [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult);