RFE: Please provide option RandomSec= to systemd timer (#1303552)
Resolves: #1303552
This commit is contained in:
parent
743659b0b9
commit
66361260e2
|
@ -0,0 +1,251 @@
|
|||
From d2686a718564c0873e2ed7138e7a31471279c1ec Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 18 Nov 2015 13:37:30 +0100
|
||||
Subject: [PATCH 5/6] core: add new RandomSec= setting for time units
|
||||
|
||||
This allows configuration of a random time on top of the elapse events,
|
||||
in order to spread time events in a network evenly across a range.
|
||||
|
||||
(cherry picked from commit 744c7693751830149ae78fdaf95c6c6f99d59f07)
|
||||
|
||||
Resolves: #1303552
|
||||
---
|
||||
man/systemd.timer.xml | 43 ++++++++++++++++++++++++++++++-----
|
||||
src/core/dbus-timer.c | 17 ++++++++++++++
|
||||
src/core/load-fragment-gperf.gperf.m4 | 1 +
|
||||
src/core/timer.c | 32 +++++++++++++++++++++++++-
|
||||
src/core/timer.h | 1 +
|
||||
src/shared/bus-util.c | 31 +++++++++++++++++++++++++
|
||||
6 files changed, 118 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
|
||||
index 20890f2..bdd14d8 100644
|
||||
--- a/man/systemd.timer.xml
|
||||
+++ b/man/systemd.timer.xml
|
||||
@@ -180,13 +180,12 @@
|
||||
<varname>OnUnitInactiveSec=</varname> and ending the time
|
||||
configured with <varname>AccuracySec=</varname> later. Within
|
||||
this time window, the expiry time will be placed at a
|
||||
- host-specific, randomized but stable position that is
|
||||
+ host-specific, randomized, but stable position that is
|
||||
synchronized between all local timer units. This is done in
|
||||
- order to distribute the wake-up time in networked
|
||||
- installations, as well as optimizing power consumption to
|
||||
- suppress unnecessary CPU wake-ups. To get best accuracy, set
|
||||
- this option to 1us. Note that the timer is still subject to
|
||||
- the timer slack configured via
|
||||
+ order to optimize power consumption to suppress unnecessary
|
||||
+ CPU wake-ups. To get best accuracy, set this option to
|
||||
+ 1us. Note that the timer is still subject to the timer slack
|
||||
+ configured via
|
||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>'s
|
||||
<varname>TimerSlackNSec=</varname> setting. See
|
||||
<citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||
@@ -194,6 +193,38 @@
|
||||
this value as high as possible and as low as
|
||||
necessary.</para></listitem>
|
||||
</varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term><varname>RandomSec=</varname></term>
|
||||
+
|
||||
+ <listitem><para>Delay the timer by a randomly selected, evenly
|
||||
+ distributed amount of time between 0 and the specified time
|
||||
+ value. Defaults to 0, indicating that no randomized delay
|
||||
+ shall be applied. Each timer unit will determine this delay
|
||||
+ randomly each time it is started, and the delay will simply be
|
||||
+ added on top of the next determined elapsing time. This is
|
||||
+ useful to stretch dispatching of similarly configured timer
|
||||
+ events over a certain amount time, to avoid that they all fire
|
||||
+ at the same time, possibly resulting in resource
|
||||
+ congestion. Note the relation to
|
||||
+ <varname>AccuracySec=</varname> above: the latter allows the
|
||||
+ service manager to coalesce timer events within a specified
|
||||
+ time range in order to minimize wakeups, the former does the
|
||||
+ opposite: it stretches timer events over a time range, to make
|
||||
+ it unlikely that they fire simultaneously. If
|
||||
+ <varname>RandomSec=</varname> and
|
||||
+ <varname>AccuracySec=</varname> are used in conjunction, first
|
||||
+ the a randomized time is added, and the result is then
|
||||
+ possibly shifted further to coalesce it with other timer
|
||||
+ events possibly happening on the system. As mentioned above
|
||||
+ <varname>AccuracySec=</varname> defaults to 1min and
|
||||
+ <varname>RandomSec=</varname> to 0, thus encouraging
|
||||
+ coalescing of timer events. In order to optimally stretch
|
||||
+ timer events over a certain range of time, make sure to set
|
||||
+ <varname>RandomSec=</varname> to a higher value, and
|
||||
+ <varname>AccuracySec=1us</varname>.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<varlistentry>
|
||||
<term><varname>Unit=</varname></term>
|
||||
|
||||
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
|
||||
index 74a9914..7875bf6 100644
|
||||
--- a/src/core/dbus-timer.c
|
||||
+++ b/src/core/dbus-timer.c
|
||||
@@ -179,6 +179,7 @@ const sd_bus_vtable bus_timer_vtable[] = {
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
+ SD_BUS_PROPERTY("RandomUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_VTABLE_END
|
||||
@@ -282,6 +283,22 @@ static int bus_timer_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
+ } else if (streq(name, "RandomUSec")) {
|
||||
+ usec_t u = 0;
|
||||
+
|
||||
+ r = sd_bus_message_read(message, "t", &u);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ if (mode != UNIT_CHECK) {
|
||||
+ char time[FORMAT_TIMESPAN_MAX];
|
||||
+
|
||||
+ t->random_usec = u;
|
||||
+ unit_write_drop_in_private_format(UNIT(t), mode, name, "RandomSec=%s\n", format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+
|
||||
} else if (streq(name, "WakeSystem")) {
|
||||
|
||||
int b;
|
||||
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
||||
index aae81c8..270b069 100644
|
||||
--- a/src/core/load-fragment-gperf.gperf.m4
|
||||
+++ b/src/core/load-fragment-gperf.gperf.m4
|
||||
@@ -335,6 +335,7 @@ Timer.OnUnitInactiveSec, config_parse_timer, 0,
|
||||
Timer.Persistent, config_parse_bool, 0, offsetof(Timer, persistent)
|
||||
Timer.WakeSystem, config_parse_bool, 0, offsetof(Timer, wake_system)
|
||||
Timer.AccuracySec, config_parse_sec, 0, offsetof(Timer, accuracy_usec)
|
||||
+Timer.RandomSec, config_parse_sec, 0, offsetof(Timer, random_usec)
|
||||
Timer.Unit, config_parse_trigger_unit, 0, 0
|
||||
m4_dnl
|
||||
Path.PathExists, config_parse_path_spec, 0, 0
|
||||
diff --git a/src/core/timer.c b/src/core/timer.c
|
||||
index 7f4a2eb..cf50f03 100644
|
||||
--- a/src/core/timer.c
|
||||
+++ b/src/core/timer.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "unit-name.h"
|
||||
#include "timer.h"
|
||||
#include "dbus-timer.h"
|
||||
+#include "random-util.h"
|
||||
#include "special.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-error.h"
|
||||
@@ -305,6 +306,28 @@ static usec_t monotonic_to_boottime(usec_t t) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void add_random(Timer *t, usec_t *v) {
|
||||
+ char s[FORMAT_TIMESPAN_MAX];
|
||||
+ usec_t add;
|
||||
+
|
||||
+ assert(t);
|
||||
+ assert(*v);
|
||||
+
|
||||
+ if (t->random_usec == 0)
|
||||
+ return;
|
||||
+ if (*v == USEC_INFINITY)
|
||||
+ return;
|
||||
+
|
||||
+ add = random_u64() % t->random_usec;
|
||||
+
|
||||
+ if (*v + add < *v) /* overflow */
|
||||
+ *v = (usec_t) -2; /* Highest possible value, that is not USEC_INFINITY */
|
||||
+ else
|
||||
+ *v += add;
|
||||
+
|
||||
+ log_unit_info(UNIT(t), "Adding %s random time.", format_timespan(s, sizeof(s), add, 0));
|
||||
+}
|
||||
+
|
||||
static void timer_enter_waiting(Timer *t, bool initial) {
|
||||
bool found_monotonic = false, found_realtime = false;
|
||||
usec_t ts_realtime, ts_monotonic;
|
||||
@@ -420,8 +443,12 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
||||
|
||||
if (found_monotonic) {
|
||||
char buf[FORMAT_TIMESPAN_MAX];
|
||||
+ usec_t left;
|
||||
|
||||
- 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));
|
||||
+ add_random(t, &t->next_elapse_monotonic_or_boottime);
|
||||
+
|
||||
+ left = t->next_elapse_monotonic_or_boottime > ts_monotonic ? t->next_elapse_monotonic_or_boottime - ts_monotonic : 0;
|
||||
+ log_unit_debug(UNIT(t), "Monotonic timer elapses in %s.", format_timespan(buf, sizeof(buf), left, 0));
|
||||
|
||||
if (t->monotonic_event_source) {
|
||||
r = sd_event_source_set_time(t->monotonic_event_source, t->next_elapse_monotonic_or_boottime);
|
||||
@@ -454,6 +481,9 @@ static void timer_enter_waiting(Timer *t, bool initial) {
|
||||
|
||||
if (found_realtime) {
|
||||
char buf[FORMAT_TIMESTAMP_MAX];
|
||||
+
|
||||
+ add_random(t, &t->next_elapse_realtime);
|
||||
+
|
||||
log_unit_debug(UNIT(t), "Realtime timer elapses at %s.", format_timestamp(buf, sizeof(buf), t->next_elapse_realtime));
|
||||
|
||||
if (t->realtime_event_source) {
|
||||
diff --git a/src/core/timer.h b/src/core/timer.h
|
||||
index 9d919e4..415a71b 100644
|
||||
--- a/src/core/timer.h
|
||||
+++ b/src/core/timer.h
|
||||
@@ -68,6 +68,7 @@ struct Timer {
|
||||
Unit meta;
|
||||
|
||||
usec_t accuracy_usec;
|
||||
+ usec_t random_usec;
|
||||
|
||||
LIST_HEAD(TimerValue, values);
|
||||
usec_t next_elapse_realtime;
|
||||
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||
index 11350da..b1f598a 100644
|
||||
--- a/src/shared/bus-util.c
|
||||
+++ b/src/shared/bus-util.c
|
||||
@@ -1374,6 +1374,37 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 0;
|
||||
+
|
||||
+ } else if (streq(field, "EnvironmentFile")) {
|
||||
+
|
||||
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "EnvironmentFiles");
|
||||
+ if (r < 0)
|
||||
+ return bus_log_create_error(r);
|
||||
+
|
||||
+ r = sd_bus_message_append(m, "v", "a(sb)", 1,
|
||||
+ eq[0] == '-' ? eq + 1 : eq,
|
||||
+ eq[0] == '-');
|
||||
+ if (r < 0)
|
||||
+ return bus_log_create_error(r);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ } else if (streq(field, "RandomSec")) {
|
||||
+ usec_t t;
|
||||
+
|
||||
+ r = parse_sec(eq, &t);
|
||||
+ if (r < 0)
|
||||
+ return log_error_errno(r, "Failed to parse RandomSec= parameter: %s", eq);
|
||||
+
|
||||
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "RandomUSec");
|
||||
+ if (r < 0)
|
||||
+ return bus_log_create_error(r);
|
||||
+
|
||||
+ r = sd_bus_message_append(m, "v", "t", t);
|
||||
+ if (r < 0)
|
||||
+ return bus_log_create_error(r);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
|
||||
--
|
||||
2.5.0
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
From 631a626cee4f80368fec05f11c4e6cab637256b7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Thu, 26 Nov 2015 16:32:41 -0500
|
||||
Subject: [PATCH 6/6] core: rename Random* to RandomizedDelay*
|
||||
|
||||
The name RandomSec is too generic: "Sec" just specifies the default
|
||||
unit type, and "Random" by itself is not enough. Rename to something
|
||||
that should give the user general idea what the setting does without
|
||||
looking at documentation.
|
||||
|
||||
(cherry picked from commit 6f5d79986a9c98b9cacc83f865fed957e4e6e4e6)
|
||||
|
||||
Related: #1303552
|
||||
---
|
||||
man/systemd.timer.xml | 8 ++++----
|
||||
src/core/dbus-timer.c | 6 +++---
|
||||
src/core/load-fragment-gperf.gperf.m4 | 2 +-
|
||||
src/shared/bus-util.c | 6 +++---
|
||||
4 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
|
||||
index bdd14d8..ab83b2c 100644
|
||||
--- a/man/systemd.timer.xml
|
||||
+++ b/man/systemd.timer.xml
|
||||
@@ -195,7 +195,7 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
- <term><varname>RandomSec=</varname></term>
|
||||
+ <term><varname>RandomizedDelaySec=</varname></term>
|
||||
|
||||
<listitem><para>Delay the timer by a randomly selected, evenly
|
||||
distributed amount of time between 0 and the specified time
|
||||
@@ -212,16 +212,16 @@
|
||||
time range in order to minimize wakeups, the former does the
|
||||
opposite: it stretches timer events over a time range, to make
|
||||
it unlikely that they fire simultaneously. If
|
||||
- <varname>RandomSec=</varname> and
|
||||
+ <varname>RandomizedDelaySec=</varname> and
|
||||
<varname>AccuracySec=</varname> are used in conjunction, first
|
||||
the a randomized time is added, and the result is then
|
||||
possibly shifted further to coalesce it with other timer
|
||||
events possibly happening on the system. As mentioned above
|
||||
<varname>AccuracySec=</varname> defaults to 1min and
|
||||
- <varname>RandomSec=</varname> to 0, thus encouraging
|
||||
+ <varname>RandomizedDelaySec=</varname> to 0, thus encouraging
|
||||
coalescing of timer events. In order to optimally stretch
|
||||
timer events over a certain range of time, make sure to set
|
||||
- <varname>RandomSec=</varname> to a higher value, and
|
||||
+ <varname>RandomizedDelaySec=</varname> to a higher value, and
|
||||
<varname>AccuracySec=1us</varname>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c
|
||||
index 7875bf6..270cd27 100644
|
||||
--- a/src/core/dbus-timer.c
|
||||
+++ b/src/core/dbus-timer.c
|
||||
@@ -179,7 +179,7 @@ const sd_bus_vtable bus_timer_vtable[] = {
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("LastTriggerUSec", offsetof(Timer, last_trigger), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
- SD_BUS_PROPERTY("RandomUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
+ SD_BUS_PROPERTY("RandomizedDelayUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Persistent", "b", bus_property_get_bool, offsetof(Timer, persistent), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_VTABLE_END
|
||||
@@ -283,7 +283,7 @@ static int bus_timer_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
- } else if (streq(name, "RandomUSec")) {
|
||||
+ } else if (streq(name, "RandomizedDelayUSec")) {
|
||||
usec_t u = 0;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u);
|
||||
@@ -294,7 +294,7 @@ static int bus_timer_set_transient_property(
|
||||
char time[FORMAT_TIMESPAN_MAX];
|
||||
|
||||
t->random_usec = u;
|
||||
- unit_write_drop_in_private_format(UNIT(t), mode, name, "RandomSec=%s\n", format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
|
||||
+ unit_write_drop_in_private_format(UNIT(t), mode, name, "RandomizedDelaySec=%s\n", format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
|
||||
}
|
||||
|
||||
return 1;
|
||||
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
||||
index 270b069..2b37641 100644
|
||||
--- a/src/core/load-fragment-gperf.gperf.m4
|
||||
+++ b/src/core/load-fragment-gperf.gperf.m4
|
||||
@@ -335,7 +335,7 @@ Timer.OnUnitInactiveSec, config_parse_timer, 0,
|
||||
Timer.Persistent, config_parse_bool, 0, offsetof(Timer, persistent)
|
||||
Timer.WakeSystem, config_parse_bool, 0, offsetof(Timer, wake_system)
|
||||
Timer.AccuracySec, config_parse_sec, 0, offsetof(Timer, accuracy_usec)
|
||||
-Timer.RandomSec, config_parse_sec, 0, offsetof(Timer, random_usec)
|
||||
+Timer.RandomizedDelaySec, config_parse_sec, 0, offsetof(Timer, random_usec)
|
||||
Timer.Unit, config_parse_trigger_unit, 0, 0
|
||||
m4_dnl
|
||||
Path.PathExists, config_parse_path_spec, 0, 0
|
||||
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||
index b1f598a..f19633a 100644
|
||||
--- a/src/shared/bus-util.c
|
||||
+++ b/src/shared/bus-util.c
|
||||
@@ -1389,14 +1389,14 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
|
||||
return 0;
|
||||
|
||||
- } else if (streq(field, "RandomSec")) {
|
||||
+ } else if (streq(field, "RandomizedDelaySec")) {
|
||||
usec_t t;
|
||||
|
||||
r = parse_sec(eq, &t);
|
||||
if (r < 0)
|
||||
- return log_error_errno(r, "Failed to parse RandomSec= parameter: %s", eq);
|
||||
+ return log_error_errno(r, "Failed to parse RandomizedDelaySec= parameter: %s", eq);
|
||||
|
||||
- r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "RandomUSec");
|
||||
+ r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "RandomizedDelayUSec");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
|
@ -116,6 +116,8 @@ Patch0080: 0080-tests-don-t-abbreviate-function-names-needlessly.patch
|
|||
Patch0081: 0081-basic-don-t-append-suffixes-to-unit-name-glob-expres.patch
|
||||
Patch0082: 0082-man-document-that-unit-file-globbing-only-operates-o.patch
|
||||
Patch0083: 0083-ask-password-api-only-emit-a-star-on-valid-unicode-c.patch
|
||||
Patch0084: 0084-core-add-new-RandomSec-setting-for-time-units.patch
|
||||
Patch0085: 0085-core-rename-Random-to-RandomizedDelay.patch
|
||||
|
||||
Patch997: 0001-Re-apply-walters-unit-patch-for-F23-systemd-v222.patch
|
||||
Patch998: 0001-Revert-core-mount-add-dependencies-to-dynamically-mo-v222.patch
|
||||
|
@ -859,6 +861,7 @@ getent passwd systemd-journal-upload >/dev/null 2>&1 || useradd -r -l -g systemd
|
|||
* Mon Feb 1 2016 Jan Synáček <jsynacek@redhat.com> - 222-14
|
||||
- Stopping services using glob patterns does not work as stated in man page (#1288851)
|
||||
- systemd asking for password on boot: ask_password_tty() prints multiple asterisks when typing special characters (#1301984)
|
||||
- RFE: Please provide option RandomSec= to systemd timer (#1303552)
|
||||
|
||||
* Mon Jan 25 2016 Jan Synáček <jsynacek@redhat.com> - 222-13
|
||||
- units: increase watchdog timeout to 3min for all our services
|
||||
|
|
Loading…
Reference in New Issue