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. to the service.
* Timer units gained a new FixedRandomDelay= boolean setting. If * Timer units gained a new FixedRandomDelay= boolean setting. If
enabled, the random delay configured with RandomizedDelaySec= is enabled the random delay configured with RandomizedDelaySec= is
selected in a way that is stable on a given system (though still hashed from the unit name, system identity, and execution context, so
different for different units). 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" * Socket units gained a new setting Timestamping= that takes "us", "ns"
or "off". This controls the SO_TIMESTAMP/SO_TIMESTAMPNS socket or "off". This controls the SO_TIMESTAMP/SO_TIMESTAMPNS socket

View File

@ -1179,60 +1179,6 @@
</varlistentry> </varlistentry>
</variablelist> </variablelist>
</refsect2> </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>
<refsect1> <refsect1>

View File

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

View File

@ -107,8 +107,3 @@
/* The root directory. */ /* The root directory. */
#define SPECIAL_ROOT_MOUNT "-.mount" #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; return 0;
} }
static bool mount_is_extrinsic(Unit *u) { static bool mount_is_extrinsic(Mount *m) {
MountParameters *p; MountParameters *p;
Mount *m = MOUNT(u);
assert(m); assert(m);
/* Returns true for all units that are "magic" and should be excluded from the usual /* 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. */ * ourselves but it's fine if the user operates on them with us. */
/* We only automatically manage mounts if we are in system mode */ /* 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; return true;
p = get_mount_parameters(m); 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 * 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, * bother with anything mounted below virtual file systems, it's also going to be virtual,
* and hence not worth the effort. */ * and hence not worth the effort. */
if (mount_is_extrinsic(UNIT(m))) if (mount_is_extrinsic(m))
return 0; return 0;
p = get_mount_parameters(m); 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, p ? strna(p->options) : "n/a",
prefix, yes_no(m->from_proc_self_mountinfo), prefix, yes_no(m->from_proc_self_mountinfo),
prefix, yes_no(m->from_fragment), 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, m->directory_mode,
prefix, yes_no(m->sloppy_options), prefix, yes_no(m->sloppy_options),
prefix, yes_no(m->lazy_unmount), prefix, yes_no(m->lazy_unmount),
@ -2159,7 +2161,6 @@ const UnitVTable mount_vtable = {
.will_restart = unit_will_restart_default, .will_restart = unit_will_restart_default,
.may_gc = mount_may_gc, .may_gc = mount_may_gc,
.is_extrinsic = mount_is_extrinsic,
.sigchld_event = mount_sigchld_event, .sigchld_event = mount_sigchld_event,

View File

@ -56,35 +56,6 @@ static bool SWAP_STATE_WITH_PROCESS(SwapState state) {
SWAP_CLEANING); 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) { static void swap_unset_proc_swaps(Swap *s) {
assert(s); assert(s);
@ -639,15 +610,13 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
"%sClean Result: %s\n" "%sClean Result: %s\n"
"%sWhat: %s\n" "%sWhat: %s\n"
"%sFrom /proc/swaps: %s\n" "%sFrom /proc/swaps: %s\n"
"%sFrom fragment: %s\n" "%sFrom fragment: %s\n",
"%sExtrinsic: %s\n",
prefix, swap_state_to_string(s->state), prefix, swap_state_to_string(s->state),
prefix, swap_result_to_string(s->result), prefix, swap_result_to_string(s->result),
prefix, swap_result_to_string(s->clean_result), prefix, swap_result_to_string(s->clean_result),
prefix, s->what, prefix, s->what,
prefix, yes_no(s->from_proc_swaps), prefix, yes_no(s->from_proc_swaps),
prefix, yes_no(s->from_fragment), prefix, yes_no(s->from_fragment));
prefix, yes_no(swap_is_extrinsic(u)));
if (s->devnode) if (s->devnode)
fprintf(f, "%sDevice Node: %s\n", prefix, 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; 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) { static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Swap *s = SWAP(u); Swap *s = SWAP(u);
SwapResult f; SwapResult f;
@ -1657,7 +1649,6 @@ const UnitVTable swap_vtable = {
.will_restart = unit_will_restart_default, .will_restart = unit_will_restart_default,
.may_gc = swap_may_gc, .may_gc = swap_may_gc,
.is_extrinsic = swap_is_extrinsic,
.sigchld_event = swap_sigchld_event, .sigchld_event = swap_sigchld_event,

View File

@ -1988,10 +1988,6 @@ int unit_stop(Unit *u) {
bool unit_can_stop(Unit *u) { bool unit_can_stop(Unit *u) {
assert(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)) if (!unit_type_supported(u->type))
return false; return false;
@ -3349,17 +3345,12 @@ int unit_set_default_slice(Unit *u) {
if (MANAGER_IS_SYSTEM(u->manager)) if (MANAGER_IS_SYSTEM(u->manager))
slice_name = strjoina("system-", escaped, ".slice"); slice_name = strjoina("system-", escaped, ".slice");
else else
slice_name = strjoina("app-", escaped, ".slice"); slice_name = strjoina(escaped, ".slice");
} else
} else if (unit_is_extrinsic(u)) slice_name =
/* Keep all extrinsic units (e.g. perpetual units and swap and mount units in user mode) in MANAGER_IS_SYSTEM(u->manager) && !unit_has_name(u, SPECIAL_INIT_SCOPE)
* the root slice. They don't really belong in one of the subslices. */ ? SPECIAL_SYSTEM_SLICE
slice_name = SPECIAL_ROOT_SLICE; : SPECIAL_ROOT_SLICE;
else if (MANAGER_IS_SYSTEM(u->manager))
slice_name = SPECIAL_SYSTEM_SLICE;
else
slice_name = SPECIAL_APP_SLICE;
r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice); r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
if (r < 0) 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. */ * even though nothing references it and it isn't active in any way. */
bool (*may_gc)(Unit *u); 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 */ /* When the unit is not running and no job for it queued we shall release its runtime resources */
void (*release_resources)(Unit *u); void (*release_resources)(Unit *u);
@ -687,11 +684,6 @@ int unit_set_description(Unit *u, const char *description);
bool unit_may_gc(Unit *u); 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_load_queue(Unit *u);
void unit_add_to_dbus_queue(Unit *u); void unit_add_to_dbus_queue(Unit *u);
void unit_add_to_cleanup_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 header : _systemd_headers + _not_installed_headers + ['../libudev/libudev.h']
foreach opt : opts foreach opt : opts
name = ''.join(['cc-', header.split('/')[-1], '_'] + opt) name = ''.join(['cc-', header.split('/')[-1], ':'] + opt)
if want_tests != 'false' if want_tests != 'false'
test(name, test(name,
check_compilation_sh, 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 # SPDX-License-Identifier: LGPL-2.1-or-later
units = [ units = [
'app.slice',
'background.slice',
'basic.target', 'basic.target',
'bluetooth.target', 'bluetooth.target',
'default.target', 'default.target',
@ -11,7 +9,6 @@ units = [
'graphical-session.target', 'graphical-session.target',
'paths.target', 'paths.target',
'printer.target', 'printer.target',
'session.slice',
'shutdown.target', 'shutdown.target',
'smartcard.target', 'smartcard.target',
'sockets.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 Requires=shutdown.target
After=shutdown.target After=shutdown.target
SuccessAction=exit-force 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 ExecStart=systemd-tmpfiles --user --clean
SuccessExitStatus=DATAERR SuccessExitStatus=DATAERR
IOSchedulingClass=idle IOSchedulingClass=idle
Slice=background.slice