]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: optionally, trigger .timer units on timezone and clock changes
authorLennart Poettering <lennart@poettering.net>
Thu, 14 Mar 2019 20:36:47 +0000 (21:36 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Apr 2019 06:20:10 +0000 (08:20 +0200)
Fixes: #6228
docs/TRANSIENT-SETTINGS.md
src/core/dbus-timer.c
src/core/load-fragment-gperf.gperf.m4
src/core/timer.c
src/core/timer.h
src/run/run.c
src/shared/bus-unit-util.c

index ac89fb174ff96c5e4d1b4f402d3412801d0b60cf..343df6675418839324b1070a217134781e66fa3d 100644 (file)
@@ -335,10 +335,12 @@ All automount unit setting is available to transient units:
 Most timer unit settings are available to transient units.
 
 ```
-✓ OnCalendar=
 ✓ OnActiveSec=
 ✓ OnBootSec=
+✓ OnCalendar=
+✓ OnClockChange=
 ✓ OnStartupSec=
+✓ OnTimezoneChange
 ✓ OnUnitActiveSec=
 ✓ OnUnitInactiveSec=
 ✓ Persistent=
index faed632e908f8974891b97c97bdae98dc3bdd929..807ca8022a7a601bfcbd791c8b2a01fc6e2bf974 100644 (file)
@@ -123,6 +123,8 @@ const sd_bus_vtable bus_timer_vtable[] = {
         SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("TimersMonotonic", "a(stt)", property_get_monotonic_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         SD_BUS_PROPERTY("TimersCalendar", "a(sst)", property_get_calendar_timers, 0, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
+        SD_BUS_PROPERTY("OnClockChange", "b", bus_property_get_bool, offsetof(Timer, on_clock_change), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("OnTimezoneChange", "b", bus_property_get_bool, offsetof(Timer, on_timezone_change), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("NextElapseUSecRealtime", "t", bus_property_get_usec, offsetof(Timer, next_elapse_realtime), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("NextElapseUSecMonotonic", "t", property_get_next_elapse_monotonic, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -171,6 +173,12 @@ static int bus_timer_set_transient_property(
         if (streq(name, "RemainAfterElapse"))
                 return bus_set_transient_bool(u, name, &t->remain_after_elapse, message, flags, error);
 
+        if (streq(name, "OnTimezoneChange"))
+                return bus_set_transient_bool(u, name, &t->on_timezone_change, message, flags, error);
+
+        if (streq(name, "OnClockChange"))
+                return bus_set_transient_bool(u, name, &t->on_clock_change, message, flags, error);
+
         if (streq(name, "TimersMonotonic")) {
                 const char *base_name;
                 usec_t usec = 0;
index ca0cf5894dca2ff12e62ae4c09f32bd28a7bc2a5..a2ed7f2abe3f546bb830728fa8079ddf05e512ff 100644 (file)
@@ -433,6 +433,8 @@ Timer.OnBootSec,                 config_parse_timer,                 TIMER_BOOT,
 Timer.OnStartupSec,              config_parse_timer,                 TIMER_STARTUP,                 0
 Timer.OnUnitActiveSec,           config_parse_timer,                 TIMER_UNIT_ACTIVE,             0
 Timer.OnUnitInactiveSec,         config_parse_timer,                 TIMER_UNIT_INACTIVE,           0
+Timer.OnClockChange,             config_parse_bool,                  0,                             offsetof(Timer, on_clock_change)
+Timer.OnTimezoneChange,          config_parse_bool,                  0,                             offsetof(Timer, on_timezone_change)
 Timer.Persistent,                config_parse_bool,                  0,                             offsetof(Timer, persistent)
 Timer.WakeSystem,                config_parse_bool,                  0,                             offsetof(Timer, wake_system)
 Timer.RemainAfterElapse,         config_parse_bool,                  0,                             offsetof(Timer, remain_after_elapse)
index 0e5214afe837a320f3e2aa8ad907d20e9e56eb1a..8440bb27ba88dc90df120069ab37d2a51619ebd2 100644 (file)
@@ -77,7 +77,7 @@ static int timer_verify(Timer *t) {
         if (UNIT(t)->load_state != UNIT_LOADED)
                 return 0;
 
-        if (!t->values) {
+        if (!t->values && !t->on_clock_change && !t->on_timezone_change) {
                 log_unit_error(UNIT(t), "Timer unit lacks value setting. Refusing.");
                 return -ENOEXEC;
         }
@@ -215,14 +215,18 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
                 "%sPersistent: %s\n"
                 "%sWakeSystem: %s\n"
                 "%sAccuracy: %s\n"
-                "%sRemainAfterElapse: %s\n",
+                "%sRemainAfterElapse: %s\n"
+                "%sOnClockChange: %s\n"
+                "%sOnTimeZoneChange %s\n",
                 prefix, timer_state_to_string(t->state),
                 prefix, timer_result_to_string(t->result),
                 prefix, trigger ? trigger->id : "n/a",
                 prefix, yes_no(t->persistent),
                 prefix, yes_no(t->wake_system),
                 prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1),
-                prefix, yes_no(t->remain_after_elapse));
+                prefix, yes_no(t->remain_after_elapse),
+                prefix, yes_no(t->on_clock_change),
+                prefix, yes_no(t->on_timezone_change));
 
         LIST_FOREACH(value, v, t->values) {
 
@@ -474,7 +478,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) {
                 }
         }
 
-        if (!found_monotonic && !found_realtime) {
+        if (!found_monotonic && !found_realtime && !t->on_timezone_change && !t->on_clock_change) {
                 log_unit_debug(UNIT(t), "Timer is elapsed.");
                 timer_enter_elapsed(t, leave_around);
                 return;
@@ -815,8 +819,13 @@ static void timer_time_change(Unit *u) {
         if (t->last_trigger.realtime > ts)
                 t->last_trigger.realtime = ts;
 
-        log_unit_debug(u, "Time change, recalculating next elapse.");
-        timer_enter_waiting(t, true);
+        if (t->on_clock_change) {
+                log_unit_debug(u, "Time change, triggering activation.");
+                timer_enter_running(t);
+        } else {
+                log_unit_debug(u, "Time change, recalculating next elapse.");
+                timer_enter_waiting(t, true);
+        }
 }
 
 static void timer_timezone_change(Unit *u) {
@@ -827,8 +836,13 @@ static void timer_timezone_change(Unit *u) {
         if (t->state != TIMER_WAITING)
                 return;
 
-        log_unit_debug(u, "Timezone change, recalculating next elapse.");
-        timer_enter_waiting(t, false);
+        if (t->on_timezone_change) {
+                log_unit_debug(u, "Timezone change, triggering activation.");
+                timer_enter_running(t);
+        } else {
+                log_unit_debug(u, "Timezone change, recalculating next elapse.");
+                timer_enter_waiting(t, false);
+        }
 }
 
 static const char* const timer_base_table[_TIMER_BASE_MAX] = {
index 833aadb0b8c5edb804a5a18aebf91a1bca7c6854..ab66a201adc23c6b48028bbea4ebfb09e22c4d26 100644 (file)
@@ -57,6 +57,8 @@ struct Timer {
         bool persistent;
         bool wake_system;
         bool remain_after_elapse;
+        bool on_clock_change;
+        bool on_timezone_change;
 
         char *stamp_path;
 };
index ba49e0daa2b5cb49f82db15d1f8f54404d37f409..56aa9aaee64d54f8e43ddb29ff211b77ad5f6aa9 100644 (file)
@@ -124,6 +124,8 @@ static int help(void) {
                "     --on-unit-active=SECONDS     Run SECONDS after the last activation\n"
                "     --on-unit-inactive=SECONDS   Run SECONDS after the last deactivation\n"
                "     --on-calendar=SPEC           Realtime timer\n"
+               "     --on-timezone-change         Run when the timezone changes\n"
+               "     --on-clock-change            Run when the realtime clock jumps\n"
                "     --timer-property=NAME=VALUE  Set timer unit property\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
@@ -170,6 +172,8 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_ON_UNIT_ACTIVE,
                 ARG_ON_UNIT_INACTIVE,
                 ARG_ON_CALENDAR,
+                ARG_ON_TIMEZONE_CHANGE,
+                ARG_ON_CLOCK_CHANGE,
                 ARG_TIMER_PROPERTY,
                 ARG_PATH_PROPERTY,
                 ARG_SOCKET_PROPERTY,
@@ -210,6 +214,8 @@ static int parse_argv(int argc, char *argv[]) {
                 { "on-unit-active",    required_argument, NULL, ARG_ON_UNIT_ACTIVE    },
                 { "on-unit-inactive",  required_argument, NULL, ARG_ON_UNIT_INACTIVE  },
                 { "on-calendar",       required_argument, NULL, ARG_ON_CALENDAR       },
+                { "on-timezone-change",no_argument,       NULL, ARG_ON_TIMEZONE_CHANGE},
+                { "on-clock-change",   no_argument,       NULL, ARG_ON_CLOCK_CHANGE   },
                 { "timer-property",    required_argument, NULL, ARG_TIMER_PROPERTY    },
                 { "path-property",     required_argument, NULL, ARG_PATH_PROPERTY     },
                 { "socket-property",   required_argument, NULL, ARG_SOCKET_PROPERTY   },
@@ -382,6 +388,22 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_with_timer = true;
                         break;
 
+                case ARG_ON_TIMEZONE_CHANGE:
+                        r = add_timer_property("OnTimezoneChange", "yes");
+                        if (r < 0)
+                                return r;
+
+                        arg_with_timer = true;
+                        break;
+
+                case ARG_ON_CLOCK_CHANGE:
+                        r = add_timer_property("OnClockChange", "yes");
+                        if (r < 0)
+                                return r;
+
+                        arg_with_timer = true;
+                        break;
+
                 case ARG_TIMER_PROPERTY:
 
                         if (strv_extend(&arg_timer_property, optarg) < 0)
index 968f91b28c3f496e79ba0682a0fd3faf0e412952..b27227aeb6cc81bea17e48debf27f4e19c8e2286 100644 (file)
@@ -1499,7 +1499,8 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
 static int bus_append_timer_property(sd_bus_message *m, const char *field, const char *eq) {
         int r;
 
-        if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent"))
+        if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent",
+                       "OnTimezoneChange", "OnClockChange"))
 
                 return bus_append_parse_boolean(m, field, eq);