X Tutup
Skip to content

Commit 53877d0

Browse files
authored
Merge pull request systemd#22649 from keszybz/symlink-enablement-yet-again-punish-me-harder
Fixups to the unit enablement logic
2 parents f8e07c5 + b380b64 commit 53877d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2492
-1361
lines changed

docs/ENVIRONMENT.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ All tools:
4343
debugging, in order to test generators and other code against specific kernel
4444
command lines.
4545

46+
* `$SYSTEMD_OS_RELEASE` — if set, use this path instead of `/etc/os-release` or
47+
`/usr/lib/os-release`. When operating under some root (e.g. `systemctl
48+
--root=…`), the path is taken relative to the outside root. Only useful for
49+
debugging.
50+
4651
* `$SYSTEMD_FSTAB` — if set, use this path instead of `/etc/fstab`. Only useful
4752
for debugging.
4853

man/os-release.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575
from earliest boot on, and hence must be located on the root file
7676
system.</para>
7777

78+
<para><filename>os-release</filename> must not contain repeating keys. Nevertheless, readers should pick
79+
the entries later in the file in case of repeats, similarly to how a shell sourcing the file would. A
80+
reader may warn about repeating entries.</para>
81+
7882
<para>For a longer rationale for <filename>os-release</filename>
7983
please refer to the <ulink
8084
url="http://0pointer.de/blog/projects/os-release">Announcement of <filename>/etc/os-release</filename></ulink>.</para>

man/systemd.unit.xml

Lines changed: 68 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
a symlink, so when <command>systemd</command> is asked through D-Bus to load
139139
<filename>dbus-org.freedesktop.network1.service</filename>, it'll load
140140
<filename>systemd-networkd.service</filename>. As another example, <filename>default.target</filename> —
141-
the default system target started at boot — is commonly symlinked (aliased) to either
141+
the default system target started at boot — is commonly aliased to either
142142
<filename>multi-user.target</filename> or <filename>graphical.target</filename> to select what is started
143143
by default. Alias names may be used in commands like <command>disable</command>,
144144
<command>start</command>, <command>stop</command>, <command>status</command>, and similar, and in all
@@ -154,8 +154,12 @@
154154
template instance (e.g. <literal>alias@inst.service</literal>) may be a symlink to different template
155155
(e.g. <literal>template@inst.service</literal>). In that case, just this specific instance is aliased,
156156
while other instances of the template (e.g. <literal>alias@foo.service</literal>,
157-
<literal>alias@bar.service</literal>) are not aliased. Those rule preserve the requirement that the
158-
instance (if any) is always uniquely defined for a given unit and all its aliases.</para>
157+
<literal>alias@bar.service</literal>) are not aliased. Those rules preserve the requirement that the
158+
instance (if any) is always uniquely defined for a given unit and all its aliases. The target of alias
159+
symlink must point to a valid unit file location, i.e. the symlink target name must match the symlink
160+
source name as described, and the destination path must be in one of the unit search paths, see UNIT FILE
161+
LOAD PATH section below for more details. Note that the target file may not exist, i.e. the symlink may
162+
be dangling.</para>
159163

160164
<para>Unit files may specify aliases through the <varname>Alias=</varname> directive in the [Install]
161165
section. When the unit is enabled, symlinks will be created for those names, and removed when the unit is
@@ -175,11 +179,18 @@
175179
exists for <varname>Requires=</varname> type dependencies as well, the directory suffix is
176180
<filename>.requires/</filename> in this case. This functionality is useful to hook units into the
177181
start-up of other units, without having to modify their unit files. For details about the semantics of
178-
<varname>Wants=</varname>, see below. The preferred way to create symlinks in the
179-
<filename>.wants/</filename> or <filename>.requires/</filename> directory of a unit file is by embedding
180-
the dependency in [Install] section of the target unit, and creating the symlink in the file system with
181-
the <command>enable</command> or <command>preset</command> commands of
182-
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
182+
<varname>Wants=</varname> and <varname>Requires=</varname>, see below. The preferred way to create
183+
symlinks in the <filename>.wants/</filename> or <filename>.requires/</filename> directories is by
184+
specifying the dependency in [Install] section of the target unit, and creating the symlink in the file
185+
system with the <command>enable</command> or <command>preset</command> commands of
186+
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. The
187+
target can be a normal unit (either plain or a specific instance of a template unit). In case when the
188+
source unit is a template, the target can also be a template, in which case the instance will be
189+
"propagated" to the target unit to form a valid unit instance. The target of symlinks in
190+
<filename>.wants/</filename> or <filename>.requires/</filename> must thus point to a valid unit file
191+
location, i.e. the symlink target name must satisfy the described requirements, and the destination path
192+
must be in one of the unit search paths, see UNIT FILE LOAD PATH section below for more details. Note
193+
that the target file may not exist, i.e. the symlink may be dangling.</para>
183194

184195
<para>Along with a unit file <filename>foo.service</filename>, a "drop-in" directory
185196
<filename>foo.service.d/</filename> may exist. All files with the suffix
@@ -501,13 +512,30 @@
501512
<programlisting>systemd-analyze --user unit-paths</programlisting>
502513
</para>
503514

504-
<para>Moreover, additional units might be loaded into systemd from
505-
directories not on the unit load path by creating a symlink pointing to a
506-
unit file in the directories. You can use <command>systemctl link</command>
507-
for this operation. See
508-
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
509-
for its usage and precaution.
510-
</para>
515+
<para>Moreover, additional units might be loaded into systemd from directories not on the unit load path
516+
by creating a symlink pointing to a unit file in the directories. You can use <command>systemctl
517+
link</command> for this; see
518+
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. The file
519+
system where the linked unit files are located must be accessible when systemd is started (e.g. anything
520+
underneath <filename>/home/</filename> or <filename>/var/</filename> is not allowed, unless those
521+
directories are located on the root file system).</para>
522+
523+
<para>It is important to distinguish "linked unit files" from "unit file aliases": any symlink where the
524+
symlink <emphasis>target</emphasis> is within the unit load path becomes an alias: the source name and
525+
the target file name must satisfy specific constraints listed above in the discussion of aliases, but the
526+
symlink target doesn't have to exist, and in fact the symlink target path is not used, except to check
527+
whether the target is within the unit load path. In constrast, a symlink which goes outside of the unit
528+
load path signifies a linked unit file. The symlink is followed when loading the file, but the
529+
destination name is otherwise unused (and may even not be a valid unit file name). For example, symlinks
530+
<filename index='false'>/etc/systemd/system/alias1.service</filename> → <filename index='false'>service1.service</filename>,
531+
<filename index='false'>/etc/systemd/system/alias2.service</filename> → <filename index='false'>/usr/lib/systemd/service1.service</filename>,
532+
<filename index='false'>/etc/systemd/system/alias3.service</filename> → <filename index='false'>/etc/systemd/system/service1.service</filename>
533+
are all valid aliases and <filename index='false'>service1.service</filename> will have
534+
four names, even if the unit file is located at
535+
<filename index='false'>/run/systemd/system/service1.service</filename>. In contrast,
536+
a symlink <filename index='false'>/etc/systemd/system/link1.service</filename> → <filename index='false'>../link1_service_file</filename>
537+
means that <filename index='false'>link1.service</filename> is a "linked unit" and the contents of
538+
<filename index='false'>/etc/systemd/link1_service_file</filename> provide its configuration.</para>
511539
</refsect1>
512540

513541
<refsect1>
@@ -1876,34 +1904,31 @@
18761904
<term><varname>WantedBy=</varname></term>
18771905
<term><varname>RequiredBy=</varname></term>
18781906

1879-
<listitem><para>This option may be used more than once, or a
1880-
space-separated list of unit names may be given. A symbolic
1881-
link is created in the <filename>.wants/</filename> or
1882-
<filename>.requires/</filename> directory of each of the
1883-
listed units when this unit is installed by <command>systemctl
1884-
enable</command>. This has the effect that a dependency of
1885-
type <varname>Wants=</varname> or <varname>Requires=</varname>
1886-
is added from the listed unit to the current unit. The primary
1887-
result is that the current unit will be started when the
1888-
listed unit is started. See the description of
1889-
<varname>Wants=</varname> and <varname>Requires=</varname> in
1890-
the [Unit] section for details.</para>
1891-
1892-
<para><command>WantedBy=foo.service</command> in a service
1893-
<filename>bar.service</filename> is mostly equivalent to
1894-
<command>Alias=foo.service.wants/bar.service</command> in the
1895-
same file. In case of template units listing non template units,
1896-
<command>systemctl enable</command> must be called with an
1897-
instance name, and this instance will be added to the
1898-
<filename>.wants/</filename> or
1899-
<filename>.requires/</filename> list of the listed unit. E.g.
1900-
<command>WantedBy=getty.target</command> in a service
1901-
<filename>getty@.service</filename> will result in
1902-
<command>systemctl enable getty@tty2.service</command>
1903-
creating a
1904-
<filename>getty.target.wants/getty@tty2.service</filename>
1905-
link to <filename>getty@.service</filename>.
1906-
</para></listitem>
1907+
<listitem><para>This option may be used more than once, or a space-separated list of unit names may
1908+
be given. A symbolic link is created in the <filename>.wants/</filename> or
1909+
<filename>.requires/</filename> directory of each of the listed units when this unit is installed by
1910+
<command>systemctl enable</command>. This has the effect of a dependency of type
1911+
<varname>Wants=</varname> or <varname>Requires=</varname> being added from the listed unit to the
1912+
current unit. The primary result is that the current unit will be started when the listed unit is
1913+
started, see the description of <varname>Wants=</varname> and <varname>Requires=</varname> in the
1914+
[Unit] section for details.</para>
1915+
1916+
<para>In case of template units listing non template units, the listing unit must have
1917+
<varname>DefaultInstance=</varname> set, or <command>systemctl enable</command> must be called with
1918+
an instance name. The instance (default or specified) will be added to the
1919+
<filename>.wants/</filename> or <filename>.requires/</filename> list of the listed unit. For example,
1920+
<command>WantedBy=getty.target</command> in a service <filename>getty@.service</filename> will result
1921+
in <command>systemctl enable getty@tty2.service</command> creating a
1922+
<filename>getty.target.wants/getty@tty2.service</filename> link to
1923+
<filename>getty@.service</filename>. This also applies to listing specific instances of templated
1924+
units: this specific instance will gain the dependency. A template unit may also list a template
1925+
unit, in which case a generic dependency will be added where each instance of the listing unit will
1926+
have a dependency on an instance of the listed template with the same instance value. For example,
1927+
<command>WantedBy=container@.target</command> in a service <filename>monitor@.service</filename> will
1928+
result in <command>systemctl enable monitor@.service</command> creating a
1929+
<filename>container@.target.wants/monitor@.service</filename> link to
1930+
<filename>monitor@.service</filename>, which applies to all instances of
1931+
<filename>container@.target</filename>.</para></listitem>
19071932
</varlistentry>
19081933

19091934
<varlistentry>

meson.build

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@ public_programs += executable(
24502450
install_rpath : rootlibexecdir,
24512451
install : true)
24522452

2453-
public_programs += executable(
2453+
systemctl = executable(
24542454
'systemctl',
24552455
systemctl_sources,
24562456
include_directories : includes,
@@ -2464,6 +2464,7 @@ public_programs += executable(
24642464
install_rpath : rootlibexecdir,
24652465
install : true,
24662466
install_dir : rootbindir)
2467+
public_programs += systemctl
24672468

24682469
if conf.get('ENABLE_PORTABLED') == 1
24692470
dbus_programs += executable(
@@ -3282,13 +3283,22 @@ executable(
32823283
install : true,
32833284
install_dir : rootlibexecdir)
32843285

3285-
public_programs += executable(
3286+
systemd_id128 = executable(
32863287
'systemd-id128',
32873288
'src/id128/id128.c',
32883289
include_directories : includes,
32893290
link_with : [libshared],
32903291
install_rpath : rootlibexecdir,
32913292
install : true)
3293+
public_programs += systemd_id128
3294+
3295+
if want_tests != 'false'
3296+
test('test-systemctl-enable',
3297+
test_systemctl_enable_sh,
3298+
# https://github.com/mesonbuild/meson/issues/2681
3299+
args : [systemctl.full_path(),
3300+
systemd_id128.full_path()])
3301+
endif
32923302

32933303
public_programs += executable(
32943304
'systemd-path',

src/analyze/analyze-condition.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ static int log_helper(void *userdata, int level, int error, const char *file, in
7474
return r;
7575
}
7676

77-
static int verify_conditions(char **lines, UnitFileScope scope, const char *unit, const char *root) {
77+
static int verify_conditions(char **lines, LookupScope scope, const char *unit, const char *root) {
7878
_cleanup_(manager_freep) Manager *m = NULL;
7979
Unit *u;
8080
int r, q = 1;

src/analyze/analyze-plot.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static int acquire_host_info(sd_bus *bus, HostInfo **hi) {
7878
if (!host)
7979
return log_oom();
8080

81-
if (arg_scope != UNIT_FILE_SYSTEM) {
81+
if (arg_scope != LOOKUP_SCOPE_SYSTEM) {
8282
r = bus_connect_transport(arg_transport, arg_host, false, &system_bus);
8383
if (r < 0) {
8484
log_debug_errno(r, "Failed to connect to system bus, ignoring: %m");
@@ -183,7 +183,7 @@ int verb_plot(int argc, char *argv[], void *userdata) {
183183
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
184184
_cleanup_(unit_times_free_arrayp) UnitTimes *times = NULL;
185185
_cleanup_free_ char *pretty_times = NULL;
186-
bool use_full_bus = arg_scope == UNIT_FILE_SYSTEM;
186+
bool use_full_bus = arg_scope == LOOKUP_SCOPE_SYSTEM;
187187
BootTimes *boot;
188188
UnitTimes *u;
189189
int n, m = 1, y = 0, r;
@@ -201,7 +201,7 @@ int verb_plot(int argc, char *argv[], void *userdata) {
201201
if (n < 0)
202202
return n;
203203

204-
if (use_full_bus || arg_scope != UNIT_FILE_SYSTEM) {
204+
if (use_full_bus || arg_scope != LOOKUP_SCOPE_SYSTEM) {
205205
n = acquire_host_info(bus, &host);
206206
if (n < 0)
207207
return n;

src/analyze/analyze-security.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,7 +2646,7 @@ static int offline_security_check(Unit *u,
26462646

26472647
static int offline_security_checks(char **filenames,
26482648
JsonVariant *policy,
2649-
UnitFileScope scope,
2649+
LookupScope scope,
26502650
bool check_man,
26512651
bool run_generators,
26522652
unsigned threshold,
@@ -2758,7 +2758,7 @@ static int offline_security_checks(char **filenames,
27582758
static int analyze_security(sd_bus *bus,
27592759
char **units,
27602760
JsonVariant *policy,
2761-
UnitFileScope scope,
2761+
LookupScope scope,
27622762
bool check_man,
27632763
bool run_generators,
27642764
bool offline,

src/analyze/analyze-time-data.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ int acquire_boot_times(sd_bus *bus, BootTimes **ret) {
6767
"Please try again later.\n"
6868
"Hint: Use 'systemctl%s list-jobs' to see active jobs",
6969
times.finish_time,
70-
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
70+
arg_scope == LOOKUP_SCOPE_SYSTEM ? "" : " --user");
7171

72-
if (arg_scope == UNIT_FILE_SYSTEM && times.security_start_time > 0) {
72+
if (arg_scope == LOOKUP_SCOPE_SYSTEM && times.security_start_time > 0) {
7373
/* security_start_time is set when systemd is not running under container environment. */
7474
if (times.initrd_time > 0)
7575
times.kernel_done_time = times.initrd_time;

src/analyze/analyze-unit-files.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ int verb_unit_files(int argc, char *argv[], void *userdata) {
2121
char **v;
2222
int r;
2323

24-
r = lookup_paths_init(&lp, arg_scope, 0, NULL);
24+
r = lookup_paths_init_or_warn(&lp, arg_scope, 0, NULL);
2525
if (r < 0)
26-
return log_error_errno(r, "lookup_paths_init() failed: %m");
26+
return r;
2727

2828
r = unit_file_build_name_map(&lp, NULL, &unit_ids, &unit_names, NULL);
2929
if (r < 0)

src/analyze/analyze-unit-paths.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ int verb_unit_paths(int argc, char *argv[], void *userdata) {
99
_cleanup_(lookup_paths_free) LookupPaths paths = {};
1010
int r;
1111

12-
r = lookup_paths_init(&paths, arg_scope, 0, NULL);
12+
r = lookup_paths_init_or_warn(&paths, arg_scope, 0, NULL);
1313
if (r < 0)
14-
return log_error_errno(r, "lookup_paths_init() failed: %m");
14+
return r;
1515

1616
STRV_FOREACH(p, paths.search_path)
1717
puts(*p);

0 commit comments

Comments
 (0)
X Tutup