Compare commits

..

No commits in common. "ca121e20c42219e3bc4e5cb63dcc96cc5eae2879" and "a54bcb901677b297a8073b0cb92992a6fff8c954" have entirely different histories.

15 changed files with 77 additions and 200 deletions

8
NEWS
View File

@ -159,9 +159,11 @@ CHANGES WITH 247 in spe:
to the service.
* Timer units gained a new FixedRandomDelay= boolean setting. If
enabled, the random delay configured with RandomizedDelaySec= is
selected in a way that is stable on a given system (though still
different for different units).
enabled the random delay configured with RandomizedDelaySec= is
hashed from the unit name, system identity, and execution context, so
that always the same offset is used for the same unit on the same
system run in the same context, in a way that is stable across system
reboots.
* Socket units gained a new setting Timestamping= that takes "us", "ns"
or "off". This controls the SO_TIMESTAMP/SO_TIMESTAMPNS socket

View File

@ -1179,60 +1179,6 @@
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Special User Slice Units</title>
<para>There are four <literal>.slice</literal> units which form the basis of the user hierarchy for
assignment of resources for user applications and services. See
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>7</manvolnum></citerefentry>
for details about slice units and the documentation about
<ulink url="https://systemd.io/DESKTOP_ENVIRONMENTS">Desktop Environments</ulink>
for further information.</para>
<variablelist>
<varlistentry>
<term><filename>-.slice</filename></term>
<listitem>
<para>The root slice is the root of the user's slice hierarchy.
It usually does not contain units directly, but may be used to set defaults for the whole tree.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>app.slice</filename></term>
<listitem>
<para>By default, all user services and applications managed by
<command>systemd</command> are found in this slice.
All interactively launched applications like web browsers and text editors
as well as non-critical services should be placed into this slice.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>session.slice</filename></term>
<listitem>
<para>All essential services and applications required for the
session should use this slice.
These are services that either cannot be restarted easily
or where latency issues may affect the interactivity of the system and applications.
This includes the display server, screen readers and other services such as DBus or XDG portals.
Such services should be configured to be part of this slice by
adding <varname>Slice=session.slice</varname> to their unit files.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>background.slice</filename></term>
<listitem>
<para>All services running low-priority background tasks should use this slice.
This permits resources to be preferentially assigned to the other slices.
Examples include non-interactive tasks like file indexing or backup operations
where latency is not important.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>

View File

@ -240,41 +240,44 @@
<varlistentry>
<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 value. Defaults to 0, indicating that no randomized delay shall be applied.
Each timer unit will determine this delay randomly before each iteration, and the delay will simply
be added on top of the next determined elapsing time, unless modified with
<varname>FixedRandomDelay=</varname>, see below.</para>
<para>This setting is useful to stretch dispatching of similarly configured timer events over a
certain time interval, to prevent them from firing all at the same time, possibly resulting in
resource congestion.</para>
<para>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, while
this setting does the opposite: it stretches timer events over an interval, to make it unlikely that
they fire simultaneously. If <varname>RandomizedDelaySec=</varname> and
<varname>AccuracySec=</varname> are used in conjunction, first the randomized delay is added, and
then the result is possibly further shifted to coalesce it with other timer events happening on the
system. As mentioned above <varname>AccuracySec=</varname> defaults to 1 minute and
<varname>RandomizedDelaySec=</varname> to 0, thus encouraging coalescing of timer events. In order to
optimally stretch timer events over a certain range of time, set
<varname>AccuracySec=1us</varname> and <varname>RandomizedDelaySec=</varname> to some higher value.
</para></listitem>
<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 before each iteration, 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>RandomizedDelaySec=</varname> and
<varname>AccuracySec=</varname> are used in conjunction, first
the randomized delay is added, and then the result is
possibly further shifted to coalesce it with other timer
events happening on the system. As mentioned above
<varname>AccuracySec=</varname> defaults to 1min and
<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>RandomizedDelaySec=</varname> to a higher value, and
<varname>AccuracySec=1us</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>FixedRandomDelay=</varname></term>
<listitem><para>Takes a boolean argument. When enabled, the randomized offset specified by
<varname>RandomizedDelaySec=</varname> is reused for all firings of the same timer. For a given timer
unit, the offset depends on the machine ID, user identifier and timer name, which means that it is
stable between restarts of the manager. This effectively creates a fixed offset for an individual
timer, reducing the jitter in firings of this timer, while still avoiding firing at the same time as
other similarly configured timers.</para>
<para>This setting has no effect if <varname>RandomizedDelaySec=</varname> is set to 0. Defaults to
<option>false</option>.</para></listitem>
<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>

View File

@ -107,8 +107,3 @@
/* The root directory. */
#define SPECIAL_ROOT_MOUNT "-.mount"
/* Special slices valid for the user instance */
#define SPECIAL_SESSION_SLICE "session.slice"
#define SPECIAL_APP_SLICE "app.slice"
#define SPECIAL_BACKGROUND_SLICE "background.slice"

View File

@ -412,9 +412,8 @@ static int mount_add_quota_dependencies(Mount *m) {
return 0;
}
static bool mount_is_extrinsic(Unit *u) {
static bool mount_is_extrinsic(Mount *m) {
MountParameters *p;
Mount *m = MOUNT(u);
assert(m);
/* Returns true for all units that are "magic" and should be excluded from the usual
@ -423,7 +422,10 @@ static bool mount_is_extrinsic(Unit *u) {
* ourselves but it's fine if the user operates on them with us. */
/* We only automatically manage mounts if we are in system mode */
if (MANAGER_IS_USER(u->manager))
if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
return true;
if (UNIT(m)->perpetual) /* All perpetual units never change state */
return true;
p = get_mount_parameters(m);
@ -491,7 +493,7 @@ static int mount_add_default_dependencies(Mount *m) {
* guaranteed to stay mounted the whole time, since our system is on it. Also, don't
* bother with anything mounted below virtual file systems, it's also going to be virtual,
* and hence not worth the effort. */
if (mount_is_extrinsic(UNIT(m)))
if (mount_is_extrinsic(m))
return 0;
p = get_mount_parameters(m);
@ -788,7 +790,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
prefix, p ? strna(p->options) : "n/a",
prefix, yes_no(m->from_proc_self_mountinfo),
prefix, yes_no(m->from_fragment),
prefix, yes_no(mount_is_extrinsic(u)),
prefix, yes_no(mount_is_extrinsic(m)),
prefix, m->directory_mode,
prefix, yes_no(m->sloppy_options),
prefix, yes_no(m->lazy_unmount),
@ -2159,7 +2161,6 @@ const UnitVTable mount_vtable = {
.will_restart = unit_will_restart_default,
.may_gc = mount_may_gc,
.is_extrinsic = mount_is_extrinsic,
.sigchld_event = mount_sigchld_event,

View File

@ -56,35 +56,6 @@ static bool SWAP_STATE_WITH_PROCESS(SwapState state) {
SWAP_CLEANING);
}
_pure_ static UnitActiveState swap_active_state(Unit *u) {
assert(u);
return state_translation_table[SWAP(u)->state];
}
_pure_ static const char *swap_sub_state_to_string(Unit *u) {
assert(u);
return swap_state_to_string(SWAP(u)->state);
}
_pure_ static bool swap_may_gc(Unit *u) {
Swap *s = SWAP(u);
assert(s);
if (s->from_proc_swaps)
return false;
return true;
}
_pure_ static bool swap_is_extrinsic(Unit *u) {
assert(SWAP(u));
return MANAGER_IS_USER(u->manager);
}
static void swap_unset_proc_swaps(Swap *s) {
assert(s);
@ -639,15 +610,13 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
"%sClean Result: %s\n"
"%sWhat: %s\n"
"%sFrom /proc/swaps: %s\n"
"%sFrom fragment: %s\n"
"%sExtrinsic: %s\n",
"%sFrom fragment: %s\n",
prefix, swap_state_to_string(s->state),
prefix, swap_result_to_string(s->result),
prefix, swap_result_to_string(s->clean_result),
prefix, s->what,
prefix, yes_no(s->from_proc_swaps),
prefix, yes_no(s->from_fragment),
prefix, yes_no(swap_is_extrinsic(u)));
prefix, yes_no(s->from_fragment));
if (s->devnode)
fprintf(f, "%sDevice Node: %s\n", prefix, s->devnode);
@ -1059,6 +1028,29 @@ static int swap_deserialize_item(Unit *u, const char *key, const char *value, FD
return 0;
}
_pure_ static UnitActiveState swap_active_state(Unit *u) {
assert(u);
return state_translation_table[SWAP(u)->state];
}
_pure_ static const char *swap_sub_state_to_string(Unit *u) {
assert(u);
return swap_state_to_string(SWAP(u)->state);
}
_pure_ static bool swap_may_gc(Unit *u) {
Swap *s = SWAP(u);
assert(s);
if (s->from_proc_swaps)
return false;
return true;
}
static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Swap *s = SWAP(u);
SwapResult f;
@ -1657,7 +1649,6 @@ const UnitVTable swap_vtable = {
.will_restart = unit_will_restart_default,
.may_gc = swap_may_gc,
.is_extrinsic = swap_is_extrinsic,
.sigchld_event = swap_sigchld_event,

View File

@ -1988,10 +1988,6 @@ int unit_stop(Unit *u) {
bool unit_can_stop(Unit *u) {
assert(u);
/* Note: if we return true here, it does not mean that the unit may be successfully stopped.
* Extrinsic units follow external state and they may stop following external state changes
* (hence we return true here), but an attempt to do this through the manager will fail. */
if (!unit_type_supported(u->type))
return false;
@ -3349,17 +3345,12 @@ int unit_set_default_slice(Unit *u) {
if (MANAGER_IS_SYSTEM(u->manager))
slice_name = strjoina("system-", escaped, ".slice");
else
slice_name = strjoina("app-", escaped, ".slice");
} else if (unit_is_extrinsic(u))
/* Keep all extrinsic units (e.g. perpetual units and swap and mount units in user mode) in
* the root slice. They don't really belong in one of the subslices. */
slice_name = SPECIAL_ROOT_SLICE;
else if (MANAGER_IS_SYSTEM(u->manager))
slice_name = SPECIAL_SYSTEM_SLICE;
else
slice_name = SPECIAL_APP_SLICE;
slice_name = strjoina(escaped, ".slice");
} else
slice_name =
MANAGER_IS_SYSTEM(u->manager) && !unit_has_name(u, SPECIAL_INIT_SCOPE)
? SPECIAL_SYSTEM_SLICE
: SPECIAL_ROOT_SLICE;
r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
if (r < 0)

View File

@ -531,9 +531,6 @@ typedef struct UnitVTable {
* even though nothing references it and it isn't active in any way. */
bool (*may_gc)(Unit *u);
/* Return true when the unit is not controlled by the manager (e.g. extrinsic mounts). */
bool (*is_extrinsic)(Unit *u);
/* When the unit is not running and no job for it queued we shall release its runtime resources */
void (*release_resources)(Unit *u);
@ -687,11 +684,6 @@ int unit_set_description(Unit *u, const char *description);
bool unit_may_gc(Unit *u);
static inline bool unit_is_extrinsic(Unit *u) {
return u->perpetual ||
(UNIT_VTABLE(u)->is_extrinsic && UNIT_VTABLE(u)->is_extrinsic(u));
}
void unit_add_to_load_queue(Unit *u);
void unit_add_to_dbus_queue(Unit *u);
void unit_add_to_cleanup_queue(Unit *u);

View File

@ -68,7 +68,7 @@ endif
foreach header : _systemd_headers + _not_installed_headers + ['../libudev/libudev.h']
foreach opt : opts
name = ''.join(['cc-', header.split('/')[-1], '_'] + opt)
name = ''.join(['cc-', header.split('/')[-1], ':'] + opt)
if want_tests != 'false'
test(name,
check_compilation_sh,

View File

@ -1,12 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Application Slice
Documentation=man:systemd.special(7)

View File

@ -1,12 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Background Tasks Slice
Documentation=man:systemd.special(7)

View File

@ -1,8 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
units = [
'app.slice',
'background.slice',
'basic.target',
'bluetooth.target',
'default.target',
@ -11,7 +9,6 @@ units = [
'graphical-session.target',
'paths.target',
'printer.target',
'session.slice',
'shutdown.target',
'smartcard.target',
'sockets.target',

View File

@ -1,12 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=User Core Session Slice
Documentation=man:systemd.special(7)

View File

@ -14,7 +14,3 @@ DefaultDependencies=no
Requires=shutdown.target
After=shutdown.target
SuccessAction=exit-force
[Service]
# Place into the root slice to not keep another slice unit alive
Slice=-.slice

View File

@ -19,4 +19,3 @@ Type=oneshot
ExecStart=systemd-tmpfiles --user --clean
SuccessExitStatus=DATAERR
IOSchedulingClass=idle
Slice=background.slice