mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
timer: add new feature FixedRandomDelay=
FixedRandomDelay=yes will use `siphash24(sd_id128_get_machine() || MANAGER_IS_SYSTEM(m) || getuid() || u->id)`, where || is concatenation, instead of a random number to choose a value between 0 and RandomizedDelaySec= as the timer delay. This essentially sets up a fixed, but seemingly random, offset for each timer iteration rather than having a random offset recalculated each time it fires. Closes #10355 Co-author: Anita Zhang <the.anitazha@gmail.com>
This commit is contained in:
parent
5cecbae158
commit
acf24a1a84
|
@ -374,6 +374,7 @@ Most timer unit settings are available to transient units.
|
||||||
✓ RemainAfterElapse=
|
✓ RemainAfterElapse=
|
||||||
✓ AccuracySec=
|
✓ AccuracySec=
|
||||||
✓ RandomizedDelaySec=
|
✓ RandomizedDelaySec=
|
||||||
|
✓ FixedRandomDelay=
|
||||||
Unit=
|
Unit=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -7211,6 +7211,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly t RandomizedDelayUSec = ...;
|
readonly t RandomizedDelayUSec = ...;
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
|
readonly b FixedRandomDelay = ...;
|
||||||
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly b Persistent = ...;
|
readonly b Persistent = ...;
|
||||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||||
readonly b WakeSystem = ...;
|
readonly b WakeSystem = ...;
|
||||||
|
@ -7236,6 +7238,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
|
||||||
|
|
||||||
<!--property RandomizedDelayUSec is not documented!-->
|
<!--property RandomizedDelayUSec is not documented!-->
|
||||||
|
|
||||||
|
<!--property FixedRandomDelay is not documented!-->
|
||||||
|
|
||||||
<!--property Persistent is not documented!-->
|
<!--property Persistent is not documented!-->
|
||||||
|
|
||||||
<!--property WakeSystem is not documented!-->
|
<!--property WakeSystem is not documented!-->
|
||||||
|
@ -7276,6 +7280,8 @@ node /org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer {
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="RandomizedDelayUSec"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="RandomizedDelayUSec"/>
|
||||||
|
|
||||||
|
<variablelist class="dbus-property" generated="True" extra-ref="FixedRandomDelay"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="Persistent"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="Persistent"/>
|
||||||
|
|
||||||
<variablelist class="dbus-property" generated="True" extra-ref="WakeSystem"/>
|
<variablelist class="dbus-property" generated="True" extra-ref="WakeSystem"/>
|
||||||
|
|
|
@ -268,6 +268,18 @@
|
||||||
<varname>AccuracySec=1us</varname>.</para></listitem>
|
<varname>AccuracySec=1us</varname>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>FixedRandomDelay=</varname></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes a boolean argument. If true, some amount of time between 0 and
|
||||||
|
<varname>RandomizedDelaySec=</varname> is chosen and added as the delay for each timer iteration. As this
|
||||||
|
delay will not be recalculated on each run, this effectively creates a fixed offset for each iteration.
|
||||||
|
The distribution between 0 and <varname>RandomizedDelaySec=</varname> is deterministic and based on
|
||||||
|
a combination of the machine ID, whether the timer is run by the user/system manager, the service manager's
|
||||||
|
user ID, and the timer's unit name. Has no effect if
|
||||||
|
<varname>RandomizedDelaySec=</varname> is set to 0. Defaults to <option>false</option>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>OnClockChange=</varname></term>
|
<term><varname>OnClockChange=</varname></term>
|
||||||
<term><varname>OnTimezoneChange=</varname></term>
|
<term><varname>OnTimezoneChange=</varname></term>
|
||||||
|
|
|
@ -131,6 +131,7 @@ const sd_bus_vtable bus_timer_vtable[] = {
|
||||||
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Timer, result), 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("AccuracyUSec", "t", bus_property_get_usec, offsetof(Timer, accuracy_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("RandomizedDelayUSec", "t", bus_property_get_usec, offsetof(Timer, random_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("FixedRandomDelay", "b", bus_property_get_bool, offsetof(Timer, fixed_random_delay), 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("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_PROPERTY("WakeSystem", "b", bus_property_get_bool, offsetof(Timer, wake_system), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RemainAfterElapse", "b", bus_property_get_bool, offsetof(Timer, remain_after_elapse), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RemainAfterElapse", "b", bus_property_get_bool, offsetof(Timer, remain_after_elapse), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@ -232,6 +233,9 @@ static int bus_timer_set_transient_property(
|
||||||
if (streq(name, "RandomizedDelayUSec"))
|
if (streq(name, "RandomizedDelayUSec"))
|
||||||
return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error);
|
return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "FixedRandomDelay"))
|
||||||
|
return bus_set_transient_bool(u, name, &t->fixed_random_delay, message, flags, error);
|
||||||
|
|
||||||
if (streq(name, "WakeSystem"))
|
if (streq(name, "WakeSystem"))
|
||||||
return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
|
return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
|
||||||
|
|
||||||
|
|
|
@ -481,6 +481,7 @@ Timer.OnTimezoneChange, config_parse_bool,
|
||||||
Timer.Persistent, config_parse_bool, 0, offsetof(Timer, persistent)
|
Timer.Persistent, config_parse_bool, 0, offsetof(Timer, persistent)
|
||||||
Timer.WakeSystem, config_parse_bool, 0, offsetof(Timer, wake_system)
|
Timer.WakeSystem, config_parse_bool, 0, offsetof(Timer, wake_system)
|
||||||
Timer.RemainAfterElapse, config_parse_bool, 0, offsetof(Timer, remain_after_elapse)
|
Timer.RemainAfterElapse, config_parse_bool, 0, offsetof(Timer, remain_after_elapse)
|
||||||
|
Timer.FixedRandomDelay, config_parse_bool, 0, offsetof(Timer, fixed_random_delay)
|
||||||
Timer.AccuracySec, config_parse_sec, 0, offsetof(Timer, accuracy_usec)
|
Timer.AccuracySec, config_parse_sec, 0, offsetof(Timer, accuracy_usec)
|
||||||
Timer.RandomizedDelaySec, 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
|
Timer.Unit, config_parse_trigger_unit, 0, 0
|
||||||
|
|
|
@ -169,6 +169,36 @@ static int timer_setup_persistent(Timer *t) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t timer_get_fixed_delay_hash(Timer *t) {
|
||||||
|
static const uint8_t hash_key[] = {
|
||||||
|
0x51, 0x0a, 0xdb, 0x76, 0x29, 0x51, 0x42, 0xc2,
|
||||||
|
0x80, 0x35, 0xea, 0xe6, 0x8e, 0x3a, 0x37, 0xbd
|
||||||
|
};
|
||||||
|
|
||||||
|
struct siphash state;
|
||||||
|
sd_id128_t machine_id;
|
||||||
|
uid_t uid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(t);
|
||||||
|
|
||||||
|
uid = getuid();
|
||||||
|
r = sd_id128_get_machine(&machine_id);
|
||||||
|
if (r < 0) {
|
||||||
|
log_unit_debug_errno(UNIT(t), r,
|
||||||
|
"Failed to get machine ID for the fixed delay calculation, proceeding with 0: %m");
|
||||||
|
machine_id = SD_ID128_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
siphash24_init(&state, hash_key);
|
||||||
|
siphash24_compress(&machine_id, sizeof(sd_id128_t), &state);
|
||||||
|
siphash24_compress_boolean(MANAGER_IS_SYSTEM(UNIT(t)->manager), &state);
|
||||||
|
siphash24_compress(&uid, sizeof(uid_t), &state);
|
||||||
|
siphash24_compress_string(UNIT(t)->id, &state);
|
||||||
|
|
||||||
|
return siphash24_finalize(&state);
|
||||||
|
}
|
||||||
|
|
||||||
static int timer_load(Unit *u) {
|
static int timer_load(Unit *u) {
|
||||||
Timer *t = TIMER(u);
|
Timer *t = TIMER(u);
|
||||||
int r;
|
int r;
|
||||||
|
@ -215,6 +245,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
"%sWakeSystem: %s\n"
|
"%sWakeSystem: %s\n"
|
||||||
"%sAccuracy: %s\n"
|
"%sAccuracy: %s\n"
|
||||||
"%sRemainAfterElapse: %s\n"
|
"%sRemainAfterElapse: %s\n"
|
||||||
|
"%sFixedRandomDelay: %s\n"
|
||||||
"%sOnClockChange: %s\n"
|
"%sOnClockChange: %s\n"
|
||||||
"%sOnTimeZoneChange: %s\n",
|
"%sOnTimeZoneChange: %s\n",
|
||||||
prefix, timer_state_to_string(t->state),
|
prefix, timer_state_to_string(t->state),
|
||||||
|
@ -224,6 +255,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
prefix, yes_no(t->wake_system),
|
prefix, yes_no(t->wake_system),
|
||||||
prefix, format_timespan(buf, sizeof(buf), t->accuracy_usec, 1),
|
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->fixed_random_delay),
|
||||||
prefix, yes_no(t->on_clock_change),
|
prefix, yes_no(t->on_clock_change),
|
||||||
prefix, yes_no(t->on_timezone_change));
|
prefix, yes_no(t->on_timezone_change));
|
||||||
|
|
||||||
|
@ -332,7 +364,7 @@ static void add_random(Timer *t, usec_t *v) {
|
||||||
if (*v == USEC_INFINITY)
|
if (*v == USEC_INFINITY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
add = random_u64() % t->random_usec;
|
add = (t->fixed_random_delay ? timer_get_fixed_delay_hash(t) : random_u64()) % t->random_usec;
|
||||||
|
|
||||||
if (*v + add < *v) /* overflow */
|
if (*v + add < *v) /* overflow */
|
||||||
*v = (usec_t) -2; /* Highest possible value, that is not USEC_INFINITY */
|
*v = (usec_t) -2; /* Highest possible value, that is not USEC_INFINITY */
|
||||||
|
|
|
@ -59,6 +59,7 @@ struct Timer {
|
||||||
bool remain_after_elapse;
|
bool remain_after_elapse;
|
||||||
bool on_clock_change;
|
bool on_clock_change;
|
||||||
bool on_timezone_change;
|
bool on_timezone_change;
|
||||||
|
bool fixed_random_delay;
|
||||||
|
|
||||||
char *stamp_path;
|
char *stamp_path;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2074,7 +2074,8 @@ static int bus_append_timer_property(sd_bus_message *m, const char *field, const
|
||||||
"RemainAfterElapse",
|
"RemainAfterElapse",
|
||||||
"Persistent",
|
"Persistent",
|
||||||
"OnTimezoneChange",
|
"OnTimezoneChange",
|
||||||
"OnClockChange"))
|
"OnClockChange",
|
||||||
|
"FixedRandomDelay"))
|
||||||
return bus_append_parse_boolean(m, field, eq);
|
return bus_append_parse_boolean(m, field, eq);
|
||||||
|
|
||||||
if (STR_IN_SET(field, "AccuracySec",
|
if (STR_IN_SET(field, "AccuracySec",
|
||||||
|
|
|
@ -175,6 +175,7 @@ PipeSize=
|
||||||
Priority=
|
Priority=
|
||||||
PropagatesReloadTo=
|
PropagatesReloadTo=
|
||||||
RandomizedDelaySec=
|
RandomizedDelaySec=
|
||||||
|
FixedRandomDelay=
|
||||||
RebootArgument=
|
RebootArgument=
|
||||||
ReceiveBuffer=
|
ReceiveBuffer=
|
||||||
RefuseManualStart=
|
RefuseManualStart=
|
||||||
|
|
|
@ -32,6 +32,7 @@ OnCalendar=Fri 2012-11-23 11:12:13
|
||||||
Persistent=true
|
Persistent=true
|
||||||
AccuracySec=24h
|
AccuracySec=24h
|
||||||
RandomizedDelaySec=234234234
|
RandomizedDelaySec=234234234
|
||||||
|
FixedRandomDelay=true
|
||||||
|
|
||||||
Persistent=no
|
Persistent=no
|
||||||
Unit=foo.service
|
Unit=foo.service
|
||||||
|
|
Loading…
Reference in a new issue