1
0
mirror of https://github.com/systemd/systemd synced 2026-04-23 23:44:50 +02:00

Compare commits

..

No commits in common. "8c70e8024ba8ff42c23f1a35b9e8fafddd5caa8d" and "0017be9d77448c37e52b710fbf18288f9ee63941" have entirely different histories.

85 changed files with 1419 additions and 2682 deletions

101
NEWS
View File

@ -1,15 +1,12 @@
systemd System and Service Manager
CHANGES WITH 251:
CHANGES WITH 251 in spe:
Backwards-incompatible changes:
* The minimum kernel version required has been bumped from 3.13 to 3.15,
and CLOCK_BOOTTIME is now assumed to always exist.
* C11 with GNU extensions (aka "gnu11") is now used to build our
components. Public API headers are still restricted to ISO C89.
* In v250, a systemd-networkd feature that automatically configures
routes to addresses specified in AllowedIPs= was added and enabled by
default. However, this causes network connectivity issues in many
@ -49,7 +46,7 @@ CHANGES WITH 251:
commands its executes into PCR 8, which makes it very hard to use
reasonably, hence separate ourselves from that and use PCR 12
instead, which is what certain Ubuntu editions already do. To retain
compatibility with systems running older systemd systems a new meson
compatibility with systems running older systemd systems a new Meson
option 'efi-tpm-pcr-compat' has been added (which defaults to false).
If enabled, the measurement is done twice: into the new-style PCR 12
*and* the old-style PCR 8. It's strongly advised to migrate all users
@ -71,7 +68,7 @@ CHANGES WITH 251:
(as exposed via the SystemCallFilter= setting in service unit files).
It is apparently used by the linker now.
Changes in the Boot Loader Specification, kernel-install and sd-boot:
Changes for Boot Loader Specification, kernel-install and sd-boot:
* kernel-install's and bootctl's Boot Loader Specification Type #1
entry generation logic has been reworked. The user may now pick
@ -126,11 +123,6 @@ CHANGES WITH 251:
os-release. Together, this means that on multiboot installations,
entries should be grouped and sorted in a predictable way.
* The sort order of boot entries has been updated: entries which have
the new field sort-key= are sorted by it first, and all entries
without it are ordered later. After that, entries are sorted by
version so that newest entries are towards the beginning of the list.
* The kernel-install tool gained a new 'inspect' verb which shows the
paths and other settings used.
@ -147,7 +139,7 @@ CHANGES WITH 251:
* 'bootctl list' gained support for a new --json= switch to output boot
menu entries in JSON format.
Changes in systemd-homed:
Changes for homed:
* Starting with v250 systemd-homed uses UID/GID mapping on the mounts
of activated home directories it manages (if the kernel and selected
@ -183,7 +175,7 @@ CHANGES WITH 251:
handling, and improving compatibility with home directories intended
to be portable like the ones managed by systemd-homed.
Changes in shared libraries:
Changes for shared libraries:
* A new libsystemd-core-<version>.so private shared library is
installed under /usr/lib/systemd/system, mirroring the existing
@ -191,20 +183,19 @@ CHANGES WITH 251:
installation size to be reduced by binary code reuse.
* The <version> tag used in the name of libsystemd-shared.so and
libsystemd-core.so can be configured via the meson option
'shared-lib-tag'. Distributions may build subsequent versions of the
systemd package with unique tags (e.g. the full package version),
thus allowing multiple installations of those shared libraries to be
available at the same time. This is intended to fix an issue where
programs that link to those libraries would fail to execute because
they were installed earlier or later than the appropriate version of
the library.
libsystemd-core.so can be configured. Distributions may build
subsequent versions of the systemd package with unique tags (e.g. the
full package version), thus allowing multiple installations of those
shared libraries to be available at the same time. This is intended
to fix an issue where programs that link to those libraries would
fail to execute because they were installed earlier or later than the
appropriate version of the library.
* The sd-id128 API gained a new call sd_id128_to_uuid_string() that is
similar to sd_id128_to_string() but formats the ID in RFC 4122 UUID
format instead of simple series of hex characters.
Changes in PID1, systemctl, and systemd-oomd:
Changes for PID1 and systemctl:
* A new set of service monitor environment variables will be passed to
OnFailure=/OnSuccess= handlers, but only if exactly one unit lists the
@ -228,13 +219,6 @@ CHANGES WITH 251:
(Only supported on kernels ≥5.6.)
* Units that were killed by systemd-oomd will now have a service result
of 'oom-kill'. The number of times a service was killed is tallied
in the 'user.oomd_ooms' extended attribute.
The OOMPolicy= unit file setting is now also honoured by
systemd-oomd.
* In unit files the new %y/%Y specifiers can be used to refer to
normalized unit file path, which is particularly useful for symlinked
unit files.
@ -273,14 +257,7 @@ CHANGES WITH 251:
* systemctl's --timestamp= option gained a new choice "unix", to show
timestamp as unix times, i.e. seconds since 1970, Jan 1st.
* 'systemctl enable' and similar commands will now create relative
symlinks in .wants/ and .requires/ and for aliases. Most of the time
systemd itself doesn't care, but absolute symlinks were causing wrong
behaviour in case of aliases to linked unit files. The change was
necessary to fix this aspect. Absolute links are interpreted as
before, and it is still possible to create them via other means.
Changes in systemd-journald:
Changes for journald:
* The journal JSON export format has been added to listed of stable
interfaces (https://systemd.io/PORTABILITY_AND_STABILITY/).
@ -293,7 +270,7 @@ CHANGES WITH 251:
https://systemd.io/JOURNAL_EXPORT_FORMATS
https://systemd.io/BUILDING_IMAGES
Changes in udev:
Changes for udev:
* Two new hwdb files have been added. One lists "handhelds" (PDAs,
calculators, etc.), the other AV production devices (DJ tables,
@ -320,7 +297,7 @@ CHANGES WITH 251:
* .link files gained support for [Link] SR-IOVVirtualFunctions= setting
and [SR-IOV] section to configure SR-IOV virtual functions.
Changes in systemd-networkd:
Changes for networkd:
* The default scope for unicast routes configured through [Route]
section is changed to "link", to make the behavior consistent with
@ -359,13 +336,13 @@ CHANGES WITH 251:
server name, and file name sent in the DHCP packet (e.g. to configure
PXE boot).
Changes in systemd-resolved:
Changes for resolved:
* systemd-resolved is started earlier (in sysinit.target), so it
available earlier and will also be started in the initrd if installed
there.
Changes in disk encryption:
Changes for disk encryption:
* systemd-cryptenroll can now control whether to require the user to
enter a PIN when using TPM-based unlocking of a volume via the new
@ -377,7 +354,7 @@ CHANGES WITH 251:
used, to ensure that communication between CPU and discrete TPM chips
cannot be eavesdropped to acquire disk encryption keys.
Changes in systemd-hostnamed:
Changes for hostnamed:
* HARDWARE_VENDOR= and HARDWARE_MODEL= can be set in /etc/machine-info
to override the values gleaned from the hwdb.
@ -389,7 +366,7 @@ CHANGES WITH 251:
* hostnamed's D-Bus interface gained a new method GetHardwareSerial()
for reading the hardware serial number, as reportd by DMI.
Changes in other components:
Changes for other components:
* /etc/locale.conf is now populated through tmpfiles.d factory /etc/
handling with the values that were configured during systemd build
@ -400,10 +377,6 @@ CHANGES WITH 251:
* The userdbctl tool will now show UID range information as part of the
list of known users.
* A new build-time configuration setting default-user-shell= can be
used to set the default shell for user records and nspawn shell
invocations (instead of of the default /bin/bash).
Experimental features:
* sd-boot gained a new *experimental* setting "reboot-for-bitlocker" in
@ -421,34 +394,6 @@ CHANGES WITH 251:
installation itself, or container images, portable service images,
and other assets. See the new systemd-sysupdate man page for updates.
Contributions from: 4piu, Adam Williamson, adrian5, Albert Brox,
AlexCatze, Alfonso Sánchez-Beato, Alvin Šipraga, Andrea Pappacoda,
Andy Chi, Anita Zhang, Antonio Alvarez Feijoo,
Arfrever Frehtes Taifersar Arahesis, ash, Bastien Nocera, Be,
bearhoney, Benjamin Berg, Christian Brauner, Clyde Byrd III,
Curtis Klein, Daan De Meyer, Danilo Krummrich, David, David Bond,
Davide Cavalca, David Tardon, dependabot[bot], Donald Chan,
Dorian Clay, Eduard Tolosa, Erik Sjölund, Evgeny Vereshchagin,
Federico Ceratto, Franck Bui, Frantisek Sumsal, Gaël PORTAY,
Georges Basile Stavracas Neto, Goffredo Baroncelli, Grigori Goronzy,
Hans de Goede, Heiko Becker, Hugo Carvalho, James Hilliard,
Jan Janssen, Jason A. Donenfeld, Joan Bruguera, Joerie de Gram,
Josh Triplett, Julia Kartseva, ksa678491784, Lan Tian, Laura Barcziova,
Lennart Poettering, Leviticoh, licunlong, Lidong Zhong, lincoln auster,
Lubomir Rintel, Luca Boccassi, Luca BRUNO, Ludwig Nussel,
Marcel Hellwig, march1993, Marco Scardovi, Markus Weippert,
Martin Wilck, Matija Skala, Matthias Lisin, Matt Walton, Max Gautier,
Michael Biebl, Michael Olbrich, Michal Koutný, Mike Gilbert,
Morten Linderud, Nishal Kulkarni, Noel Kuntze, Peter Hutterer,
Peter Morrow, Pigmy-penguin, prumian, Richard Neill,
Rike-Benjamin Schuppner, Romain Naour, Ruben Kerkhof, Ryan Hendrickson,
Santa Wiryaman, Seth Falco, Stephen Hemminger, tawefogo,
Temuri Doghonadze, Thomas Batten, Thomas Haller, Tobias Stoeckmann,
Tyson Whitehead, Vishal Chillara Srinivas, Vivien Didelot, Weblate,
Xiaotian Wu, yangmingtai, YmrDtnJu, Yonathan Randolph, Yu Watanabe,
Zbigniew Jędrzejewski-Szmek, наб
— Warsaw, 2022-03---
CHANGES WITH 250:
@ -550,9 +495,9 @@ CHANGES WITH 250:
time-out for the boot.
* A new setting DefaultOOMScoreAdjust= is now supported in
/etc/systemd/system.conf and /etc/systemd/user.conf. It may be used
to set the default process OOM score adjustment value for processes
started by the service manager. For per-user service managers this
/etc/systemd/system.conf + /etc/systemd/user.conf that may be used to
set the default process OOM score adjustment value for processes
forked off the service manager. For per-user service managers this
now defaults to 100, but for per-system service managers is left as
is. This means that by default now services forked off the user
service manager are more likely to be killed by the OOM killer than

View File

@ -43,11 +43,6 @@ All tools:
debugging, in order to test generators and other code against specific kernel
command lines.
* `$SYSTEMD_OS_RELEASE` — if set, use this path instead of `/etc/os-release` or
`/usr/lib/os-release`. When operating under some root (e.g. `systemctl
--root=…`), the path is taken relative to the outside root. Only useful for
debugging.
* `$SYSTEMD_FSTAB` — if set, use this path instead of `/etc/fstab`. Only useful
for debugging.

View File

@ -75,10 +75,6 @@
from earliest boot on, and hence must be located on the root file
system.</para>
<para><filename>os-release</filename> must not contain repeating keys. Nevertheless, readers should pick
the entries later in the file in case of repeats, similarly to how a shell sourcing the file would. A
reader may warn about repeating entries.</para>
<para>For a longer rationale for <filename>os-release</filename>
please refer to the <ulink
url="http://0pointer.de/blog/projects/os-release">Announcement of <filename>/etc/os-release</filename></ulink>.</para>

View File

@ -138,7 +138,7 @@
a symlink, so when <command>systemd</command> is asked through D-Bus to load
<filename>dbus-org.freedesktop.network1.service</filename>, it'll load
<filename>systemd-networkd.service</filename>. As another example, <filename>default.target</filename>
the default system target started at boot — is commonly aliased to either
the default system target started at boot — is commonly symlinked (aliased) to either
<filename>multi-user.target</filename> or <filename>graphical.target</filename> to select what is started
by default. Alias names may be used in commands like <command>disable</command>,
<command>start</command>, <command>stop</command>, <command>status</command>, and similar, and in all
@ -154,12 +154,8 @@
template instance (e.g. <literal>alias@inst.service</literal>) may be a symlink to different template
(e.g. <literal>template@inst.service</literal>). In that case, just this specific instance is aliased,
while other instances of the template (e.g. <literal>alias@foo.service</literal>,
<literal>alias@bar.service</literal>) are not aliased. Those rules preserve the requirement that the
instance (if any) is always uniquely defined for a given unit and all its aliases. The target of alias
symlink must point to a valid unit file location, i.e. the symlink target name must match the symlink
source name as described, and the destination path must be in one of the unit search paths, see UNIT FILE
LOAD PATH section below for more details. Note that the target file may not exist, i.e. the symlink may
be dangling.</para>
<literal>alias@bar.service</literal>) are not aliased. Those rule preserve the requirement that the
instance (if any) is always uniquely defined for a given unit and all its aliases.</para>
<para>Unit files may specify aliases through the <varname>Alias=</varname> directive in the [Install]
section. When the unit is enabled, symlinks will be created for those names, and removed when the unit is
@ -179,18 +175,11 @@
exists for <varname>Requires=</varname> type dependencies as well, the directory suffix is
<filename>.requires/</filename> in this case. This functionality is useful to hook units into the
start-up of other units, without having to modify their unit files. For details about the semantics of
<varname>Wants=</varname> and <varname>Requires=</varname>, see below. The preferred way to create
symlinks in the <filename>.wants/</filename> or <filename>.requires/</filename> directories is by
specifying the dependency in [Install] section of the target unit, and creating the symlink in the file
system with the <command>enable</command> or <command>preset</command> commands of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. The
target can be a normal unit (either plain or a specific instance of a template unit). In case when the
source unit is a template, the target can also be a template, in which case the instance will be
"propagated" to the target unit to form a valid unit instance. The target of symlinks in
<filename>.wants/</filename> or <filename>.requires/</filename> must thus point to a valid unit file
location, i.e. the symlink target name must satisfy the described requirements, and the destination path
must be in one of the unit search paths, see UNIT FILE LOAD PATH section below for more details. Note
that the target file may not exist, i.e. the symlink may be dangling.</para>
<varname>Wants=</varname>, see below. The preferred way to create symlinks in the
<filename>.wants/</filename> or <filename>.requires/</filename> directory of a unit file is by embedding
the dependency in [Install] section of the target unit, and creating the symlink in the file system with
the <command>enable</command> or <command>preset</command> commands of
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
<para>Along with a unit file <filename>foo.service</filename>, a "drop-in" directory
<filename>foo.service.d/</filename> may exist. All files with the suffix
@ -512,30 +501,13 @@
<programlisting>systemd-analyze --user unit-paths</programlisting>
</para>
<para>Moreover, additional units might be loaded into systemd from directories not on the unit load path
by creating a symlink pointing to a unit file in the directories. You can use <command>systemctl
link</command> for this; see
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. The file
system where the linked unit files are located must be accessible when systemd is started (e.g. anything
underneath <filename>/home/</filename> or <filename>/var/</filename> is not allowed, unless those
directories are located on the root file system).</para>
<para>It is important to distinguish "linked unit files" from "unit file aliases": any symlink where the
symlink <emphasis>target</emphasis> is within the unit load path becomes an alias: the source name and
the target file name must satisfy specific constraints listed above in the discussion of aliases, but the
symlink target doesn't have to exist, and in fact the symlink target path is not used, except to check
whether the target is within the unit load path. In constrast, a symlink which goes outside of the unit
load path signifies a linked unit file. The symlink is followed when loading the file, but the
destination name is otherwise unused (and may even not be a valid unit file name). For example, symlinks
<filename index='false'>/etc/systemd/system/alias1.service</filename><filename index='false'>service1.service</filename>,
<filename index='false'>/etc/systemd/system/alias2.service</filename><filename index='false'>/usr/lib/systemd/service1.service</filename>,
<filename index='false'>/etc/systemd/system/alias3.service</filename><filename index='false'>/etc/systemd/system/service1.service</filename>
are all valid aliases and <filename index='false'>service1.service</filename> will have
four names, even if the unit file is located at
<filename index='false'>/run/systemd/system/service1.service</filename>. In contrast,
a symlink <filename index='false'>/etc/systemd/system/link1.service</filename><filename index='false'>../link1_service_file</filename>
means that <filename index='false'>link1.service</filename> is a "linked unit" and the contents of
<filename index='false'>/etc/systemd/link1_service_file</filename> provide its configuration.</para>
<para>Moreover, additional units might be loaded into systemd from
directories not on the unit load path by creating a symlink pointing to a
unit file in the directories. You can use <command>systemctl link</command>
for this operation. See
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
for its usage and precaution.
</para>
</refsect1>
<refsect1>
@ -1904,31 +1876,34 @@
<term><varname>WantedBy=</varname></term>
<term><varname>RequiredBy=</varname></term>
<listitem><para>This option may be used more than once, or a space-separated list of unit names may
be given. A symbolic link is created in the <filename>.wants/</filename> or
<filename>.requires/</filename> directory of each of the listed units when this unit is installed by
<command>systemctl enable</command>. This has the effect of a dependency of type
<varname>Wants=</varname> or <varname>Requires=</varname> being added from the listed unit to the
current unit. The primary result is that the current unit will be started when the listed unit is
started, see the description of <varname>Wants=</varname> and <varname>Requires=</varname> in the
[Unit] section for details.</para>
<listitem><para>This option may be used more than once, or a
space-separated list of unit names may be given. A symbolic
link is created in the <filename>.wants/</filename> or
<filename>.requires/</filename> directory of each of the
listed units when this unit is installed by <command>systemctl
enable</command>. This has the effect that a dependency of
type <varname>Wants=</varname> or <varname>Requires=</varname>
is added from the listed unit to the current unit. The primary
result is that the current unit will be started when the
listed unit is started. See the description of
<varname>Wants=</varname> and <varname>Requires=</varname> in
the [Unit] section for details.</para>
<para>In case of template units listing non template units, the listing unit must have
<varname>DefaultInstance=</varname> set, or <command>systemctl enable</command> must be called with
an instance name. The instance (default or specified) will be added to the
<filename>.wants/</filename> or <filename>.requires/</filename> list of the listed unit. For example,
<command>WantedBy=getty.target</command> in a service <filename>getty@.service</filename> will result
in <command>systemctl enable getty@tty2.service</command> creating a
<filename>getty.target.wants/getty@tty2.service</filename> link to
<filename>getty@.service</filename>. This also applies to listing specific instances of templated
units: this specific instance will gain the dependency. A template unit may also list a template
unit, in which case a generic dependency will be added where each instance of the listing unit will
have a dependency on an instance of the listed template with the same instance value. For example,
<command>WantedBy=container@.target</command> in a service <filename>monitor@.service</filename> will
result in <command>systemctl enable monitor@.service</command> creating a
<filename>container@.target.wants/monitor@.service</filename> link to
<filename>monitor@.service</filename>, which applies to all instances of
<filename>container@.target</filename>.</para></listitem>
<para><command>WantedBy=foo.service</command> in a service
<filename>bar.service</filename> is mostly equivalent to
<command>Alias=foo.service.wants/bar.service</command> in the
same file. In case of template units listing non template units,
<command>systemctl enable</command> must be called with an
instance name, and this instance will be added to the
<filename>.wants/</filename> or
<filename>.requires/</filename> list of the listed unit. E.g.
<command>WantedBy=getty.target</command> in a service
<filename>getty@.service</filename> will result in
<command>systemctl enable getty@tty2.service</command>
creating a
<filename>getty.target.wants/getty@tty2.service</filename>
link to <filename>getty@.service</filename>.
</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
project('systemd', 'c',
version : '251',
version : '250',
license : 'LGPLv2+',
default_options: [
'c_std=gnu11',
@ -13,8 +13,8 @@ project('systemd', 'c',
meson_version : '>= 0.53.2',
)
libsystemd_version = '0.34.0'
libudev_version = '1.7.4'
libsystemd_version = '0.33.0'
libudev_version = '1.7.3'
conf = configuration_data()
conf.set_quoted('PROJECT_URL', 'https://www.freedesktop.org/wiki/Software/systemd')
@ -2450,7 +2450,7 @@ public_programs += executable(
install_rpath : rootlibexecdir,
install : true)
systemctl = executable(
public_programs += executable(
'systemctl',
systemctl_sources,
include_directories : includes,
@ -2464,7 +2464,6 @@ systemctl = executable(
install_rpath : rootlibexecdir,
install : true,
install_dir : rootbindir)
public_programs += systemctl
if conf.get('ENABLE_PORTABLED') == 1
dbus_programs += executable(
@ -3283,22 +3282,13 @@ executable(
install : true,
install_dir : rootlibexecdir)
systemd_id128 = executable(
public_programs += executable(
'systemd-id128',
'src/id128/id128.c',
include_directories : includes,
link_with : [libshared],
install_rpath : rootlibexecdir,
install : true)
public_programs += systemd_id128
if want_tests != 'false'
test('test-systemctl-enable',
test_systemctl_enable_sh,
# https://github.com/mesonbuild/meson/issues/2681
args : [systemctl.full_path(),
systemd_id128.full_path()])
endif
public_programs += executable(
'systemd-path',

View File

@ -74,7 +74,7 @@ static int log_helper(void *userdata, int level, int error, const char *file, in
return r;
}
static int verify_conditions(char **lines, LookupScope scope, const char *unit, const char *root) {
static int verify_conditions(char **lines, UnitFileScope scope, const char *unit, const char *root) {
_cleanup_(manager_freep) Manager *m = NULL;
Unit *u;
int r, q = 1;

View File

@ -78,7 +78,7 @@ static int acquire_host_info(sd_bus *bus, HostInfo **hi) {
if (!host)
return log_oom();
if (arg_scope != LOOKUP_SCOPE_SYSTEM) {
if (arg_scope != UNIT_FILE_SYSTEM) {
r = bus_connect_transport(arg_transport, arg_host, false, &system_bus);
if (r < 0) {
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) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(unit_times_free_arrayp) UnitTimes *times = NULL;
_cleanup_free_ char *pretty_times = NULL;
bool use_full_bus = arg_scope == LOOKUP_SCOPE_SYSTEM;
bool use_full_bus = arg_scope == UNIT_FILE_SYSTEM;
BootTimes *boot;
UnitTimes *u;
int n, m = 1, y = 0, r;
@ -201,7 +201,7 @@ int verb_plot(int argc, char *argv[], void *userdata) {
if (n < 0)
return n;
if (use_full_bus || arg_scope != LOOKUP_SCOPE_SYSTEM) {
if (use_full_bus || arg_scope != UNIT_FILE_SYSTEM) {
n = acquire_host_info(bus, &host);
if (n < 0)
return n;

View File

@ -2646,7 +2646,7 @@ static int offline_security_check(Unit *u,
static int offline_security_checks(char **filenames,
JsonVariant *policy,
LookupScope scope,
UnitFileScope scope,
bool check_man,
bool run_generators,
unsigned threshold,
@ -2758,7 +2758,7 @@ static int offline_security_checks(char **filenames,
static int analyze_security(sd_bus *bus,
char **units,
JsonVariant *policy,
LookupScope scope,
UnitFileScope scope,
bool check_man,
bool run_generators,
bool offline,

View File

@ -67,9 +67,9 @@ int acquire_boot_times(sd_bus *bus, BootTimes **ret) {
"Please try again later.\n"
"Hint: Use 'systemctl%s list-jobs' to see active jobs",
times.finish_time,
arg_scope == LOOKUP_SCOPE_SYSTEM ? "" : " --user");
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
if (arg_scope == LOOKUP_SCOPE_SYSTEM && times.security_start_time > 0) {
if (arg_scope == UNIT_FILE_SYSTEM && times.security_start_time > 0) {
/* security_start_time is set when systemd is not running under container environment. */
if (times.initrd_time > 0)
times.kernel_done_time = times.initrd_time;

View File

@ -21,9 +21,9 @@ int verb_unit_files(int argc, char *argv[], void *userdata) {
char **v;
int r;
r = lookup_paths_init_or_warn(&lp, arg_scope, 0, NULL);
r = lookup_paths_init(&lp, arg_scope, 0, NULL);
if (r < 0)
return r;
return log_error_errno(r, "lookup_paths_init() failed: %m");
r = unit_file_build_name_map(&lp, NULL, &unit_ids, &unit_names, NULL);
if (r < 0)

View File

@ -9,9 +9,9 @@ int verb_unit_paths(int argc, char *argv[], void *userdata) {
_cleanup_(lookup_paths_free) LookupPaths paths = {};
int r;
r = lookup_paths_init_or_warn(&paths, arg_scope, 0, NULL);
r = lookup_paths_init(&paths, arg_scope, 0, NULL);
if (r < 0)
return r;
return log_error_errno(r, "lookup_paths_init() failed: %m");
STRV_FOREACH(p, paths.search_path)
puts(*p);

View File

@ -242,7 +242,7 @@ static void set_destroy_ignore_pointer_max(Set** s) {
set_free_free(*s);
}
int verify_units(char **filenames, LookupScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root) {
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root) {
const ManagerTestRunFlags flags =
MANAGER_TEST_RUN_MINIMAL |
MANAGER_TEST_RUN_ENV_GENERATORS |

View File

@ -17,7 +17,7 @@ typedef enum RecursiveErrors {
int verify_generate_path(char **var, char **filenames);
int verify_prepare_filename(const char *filename, char **ret);
int verify_executable(Unit *u, const ExecCommand *exec, const char *root);
int verify_units(char **filenames, LookupScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root);
int verify_units(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, RecursiveErrors recursive_errors, const char *root);
const char* recursive_errors_to_string(RecursiveErrors i) _const_;
RecursiveErrors recursive_errors_from_string(const char *s) _pure_;

View File

@ -89,7 +89,7 @@ usec_t arg_fuzz = 0;
PagerFlags arg_pager_flags = 0;
BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
const char *arg_host = NULL;
LookupScope arg_scope = LOOKUP_SCOPE_SYSTEM;
UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
RecursiveErrors arg_recursive_errors = RECURSIVE_ERRORS_YES;
bool arg_man = true;
bool arg_generators = false;
@ -114,7 +114,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_unit, freep);
STATIC_DESTRUCTOR_REGISTER(arg_profile, freep);
int acquire_bus(sd_bus **bus, bool *use_full_bus) {
bool user = arg_scope != LOOKUP_SCOPE_SYSTEM;
bool user = arg_scope != UNIT_FILE_SYSTEM;
int r;
if (use_full_bus && *use_full_bus) {
@ -351,15 +351,15 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SYSTEM:
arg_scope = LOOKUP_SCOPE_SYSTEM;
arg_scope = UNIT_FILE_SYSTEM;
break;
case ARG_USER:
arg_scope = LOOKUP_SCOPE_USER;
arg_scope = UNIT_FILE_USER;
break;
case ARG_GLOBAL:
arg_scope = LOOKUP_SCOPE_GLOBAL;
arg_scope = UNIT_FILE_GLOBAL;
break;
case ARG_ORDER:
@ -500,12 +500,12 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --threshold= is only supported for security right now.");
if (arg_scope == LOOKUP_SCOPE_GLOBAL &&
if (arg_scope == UNIT_FILE_GLOBAL &&
!STR_IN_SET(argv[optind] ?: "time", "dot", "unit-paths", "verify"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --global only makes sense with verbs dot, unit-paths, verify.");
if (streq_ptr(argv[optind], "cat-config") && arg_scope == LOOKUP_SCOPE_USER)
if (streq_ptr(argv[optind], "cat-config") && arg_scope == UNIT_FILE_USER)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --user is not supported for cat-config right now.");

View File

@ -22,7 +22,7 @@ extern usec_t arg_fuzz;
extern PagerFlags arg_pager_flags;
extern BusTransport arg_transport;
extern const char *arg_host;
extern LookupScope arg_scope;
extern UnitFileScope arg_scope;
extern RecursiveErrors arg_recursive_errors;
extern bool arg_man;
extern bool arg_generators;

View File

@ -16,8 +16,9 @@ static int parse_env_file_internal(
FILE *f,
const char *fname,
int (*push) (const char *filename, unsigned line,
const char *key, char *value, void *userdata),
void *userdata) {
const char *key, char *value, void *userdata, int *n_pushed),
void *userdata,
int *n_pushed) {
size_t n_key = 0, n_value = 0, last_value_whitespace = SIZE_MAX, last_key_whitespace = SIZE_MAX;
_cleanup_free_ char *contents = NULL, *key = NULL, *value = NULL;
@ -98,7 +99,7 @@ static int parse_env_file_internal(
if (last_key_whitespace != SIZE_MAX)
key[last_key_whitespace] = 0;
r = push(fname, line, key, value, userdata);
r = push(fname, line, key, value, userdata, n_pushed);
if (r < 0)
return r;
@ -141,7 +142,7 @@ static int parse_env_file_internal(
if (last_key_whitespace != SIZE_MAX)
key[last_key_whitespace] = 0;
r = push(fname, line, key, value, userdata);
r = push(fname, line, key, value, userdata, n_pushed);
if (r < 0)
return r;
@ -260,7 +261,7 @@ static int parse_env_file_internal(
if (last_key_whitespace != SIZE_MAX)
key[last_key_whitespace] = 0;
r = push(fname, line, key, value, userdata);
r = push(fname, line, key, value, userdata, n_pushed);
if (r < 0)
return r;
@ -298,7 +299,8 @@ static int check_utf8ness_and_warn(
static int parse_env_file_push(
const char *filename, unsigned line,
const char *key, char *value,
void *userdata) {
void *userdata,
int *n_pushed) {
const char *k;
va_list aq, *ap = userdata;
@ -320,6 +322,9 @@ static int parse_env_file_push(
free(*v);
*v = value;
if (n_pushed)
(*n_pushed)++;
return 1;
}
}
@ -335,13 +340,16 @@ int parse_env_filev(
const char *fname,
va_list ap) {
int r;
int r, n_pushed = 0;
va_list aq;
va_copy(aq, ap);
r = parse_env_file_internal(f, fname, parse_env_file_push, &aq);
r = parse_env_file_internal(f, fname, parse_env_file_push, &aq, &n_pushed);
va_end(aq);
return r;
if (r < 0)
return r;
return n_pushed;
}
int parse_env_file_sentinel(
@ -362,7 +370,8 @@ int parse_env_file_sentinel(
static int load_env_file_push(
const char *filename, unsigned line,
const char *key, char *value,
void *userdata) {
void *userdata,
int *n_pushed) {
char ***m = userdata;
char *p;
int r;
@ -379,69 +388,78 @@ static int load_env_file_push(
if (r < 0)
return r;
if (n_pushed)
(*n_pushed)++;
free(value);
return 0;
}
int load_env_file(FILE *f, const char *fname, char ***rl) {
_cleanup_strv_free_ char **m = NULL;
char **m = NULL;
int r;
r = parse_env_file_internal(f, fname, load_env_file_push, &m);
if (r < 0)
r = parse_env_file_internal(f, fname, load_env_file_push, &m, NULL);
if (r < 0) {
strv_free(m);
return r;
}
*rl = TAKE_PTR(m);
*rl = m;
return 0;
}
static int load_env_file_push_pairs(
const char *filename, unsigned line,
const char *key, char *value,
void *userdata) {
char ***m = ASSERT_PTR(userdata);
void *userdata,
int *n_pushed) {
char ***m = userdata;
int r;
r = check_utf8ness_and_warn(filename, line, key, value);
if (r < 0)
return r;
/* Check if the key is present */
for (char **t = *m; t && *t; t += 2)
if (streq(t[0], key)) {
if (value)
return free_and_replace(t[1], value);
else
return free_and_strdup(t+1, "");
}
r = strv_extend(m, key);
if (r < 0)
return r;
return -ENOMEM;
if (value)
return strv_push(m, value);
else
return strv_extend(m, "");
if (!value) {
r = strv_extend(m, "");
if (r < 0)
return -ENOMEM;
} else {
r = strv_push(m, value);
if (r < 0)
return r;
}
if (n_pushed)
(*n_pushed)++;
return 0;
}
int load_env_file_pairs(FILE *f, const char *fname, char ***rl) {
_cleanup_strv_free_ char **m = NULL;
char **m = NULL;
int r;
r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m);
if (r < 0)
r = parse_env_file_internal(f, fname, load_env_file_push_pairs, &m, NULL);
if (r < 0) {
strv_free(m);
return r;
}
*rl = TAKE_PTR(m);
*rl = m;
return 0;
}
static int merge_env_file_push(
const char *filename, unsigned line,
const char *key, char *value,
void *userdata) {
void *userdata,
int *n_pushed) {
char ***env = userdata;
char *expanded_value;
@ -470,7 +488,7 @@ static int merge_env_file_push(
log_debug("%s:%u: setting %s=%s", filename, line, key, value);
return load_env_file_push(filename, line, key, value, env);
return load_env_file_push(filename, line, key, value, env, n_pushed);
}
int merge_env_file(
@ -482,7 +500,7 @@ int merge_env_file(
* plus "extended" substitutions, unlike other exported parsing functions.
*/
return parse_env_file_internal(f, fname, merge_env_file_push, env);
return parse_env_file_internal(f, fname, merge_env_file_push, env, NULL);
}
static void write_env_var(FILE *f, const char *v) {

View File

@ -170,19 +170,13 @@ int open_extension_release(const char *root, const char *extension, char **ret_p
}
}
} else {
const char *var = secure_getenv("SYSTEMD_OS_RELEASE");
if (var)
r = chase_symlinks(var, root, 0,
FOREACH_STRING(p, "/etc/os-release", "/usr/lib/os-release") {
r = chase_symlinks(p, root, CHASE_PREFIX_ROOT,
ret_path ? &q : NULL,
ret_fd ? &fd : NULL);
else
FOREACH_STRING(path, "/etc/os-release", "/usr/lib/os-release") {
r = chase_symlinks(path, root, CHASE_PREFIX_ROOT,
ret_path ? &q : NULL,
ret_fd ? &fd : NULL);
if (r != -ENOENT)
break;
}
if (r != -ENOENT)
break;
}
}
if (r < 0)
return r;

View File

@ -232,7 +232,7 @@ bool path_is_user_config_dir(const char *path) {
}
static int acquire_generator_dirs(
LookupScope scope,
UnitFileScope scope,
const char *tempdir,
char **generator,
char **generator_early,
@ -244,17 +244,17 @@ static int acquire_generator_dirs(
assert(generator);
assert(generator_early);
assert(generator_late);
assert(IN_SET(scope, LOOKUP_SCOPE_SYSTEM, LOOKUP_SCOPE_USER, LOOKUP_SCOPE_GLOBAL));
assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL));
if (scope == LOOKUP_SCOPE_GLOBAL)
if (scope == UNIT_FILE_GLOBAL)
return -EOPNOTSUPP;
if (tempdir)
prefix = tempdir;
else if (scope == LOOKUP_SCOPE_SYSTEM)
else if (scope == UNIT_FILE_SYSTEM)
prefix = "/run/systemd";
else {
/* LOOKUP_SCOPE_USER */
/* UNIT_FILE_USER */
const char *e;
e = getenv("XDG_RUNTIME_DIR");
@ -288,21 +288,21 @@ static int acquire_generator_dirs(
}
static int acquire_transient_dir(
LookupScope scope,
UnitFileScope scope,
const char *tempdir,
char **ret) {
char *transient;
assert(ret);
assert(IN_SET(scope, LOOKUP_SCOPE_SYSTEM, LOOKUP_SCOPE_USER, LOOKUP_SCOPE_GLOBAL));
assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER, UNIT_FILE_GLOBAL));
if (scope == LOOKUP_SCOPE_GLOBAL)
if (scope == UNIT_FILE_GLOBAL)
return -EOPNOTSUPP;
if (tempdir)
transient = path_join(tempdir, "transient");
else if (scope == LOOKUP_SCOPE_SYSTEM)
else if (scope == UNIT_FILE_SYSTEM)
transient = strdup("/run/systemd/transient");
else
return xdg_user_runtime_dir(ret, "/systemd/transient");
@ -313,7 +313,7 @@ static int acquire_transient_dir(
return 0;
}
static int acquire_config_dirs(LookupScope scope, char **persistent, char **runtime) {
static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **runtime) {
_cleanup_free_ char *a = NULL, *b = NULL;
int r;
@ -322,17 +322,17 @@ static int acquire_config_dirs(LookupScope scope, char **persistent, char **runt
switch (scope) {
case LOOKUP_SCOPE_SYSTEM:
case UNIT_FILE_SYSTEM:
a = strdup(SYSTEM_CONFIG_UNIT_DIR);
b = strdup("/run/systemd/system");
break;
case LOOKUP_SCOPE_GLOBAL:
case UNIT_FILE_GLOBAL:
a = strdup(USER_CONFIG_UNIT_DIR);
b = strdup("/run/systemd/user");
break;
case LOOKUP_SCOPE_USER:
case UNIT_FILE_USER:
r = xdg_user_config_dir(&a, "/systemd/user");
if (r < 0 && r != -ENXIO)
return r;
@ -364,7 +364,7 @@ static int acquire_config_dirs(LookupScope scope, char **persistent, char **runt
return 0;
}
static int acquire_control_dirs(LookupScope scope, char **persistent, char **runtime) {
static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **runtime) {
_cleanup_free_ char *a = NULL;
int r;
@ -373,7 +373,7 @@ static int acquire_control_dirs(LookupScope scope, char **persistent, char **run
switch (scope) {
case LOOKUP_SCOPE_SYSTEM: {
case UNIT_FILE_SYSTEM: {
_cleanup_free_ char *b = NULL;
a = strdup("/etc/systemd/system.control");
@ -389,7 +389,7 @@ static int acquire_control_dirs(LookupScope scope, char **persistent, char **run
break;
}
case LOOKUP_SCOPE_USER:
case UNIT_FILE_USER:
r = xdg_user_config_dir(&a, "/systemd/user.control");
if (r < 0 && r != -ENXIO)
return r;
@ -406,7 +406,7 @@ static int acquire_control_dirs(LookupScope scope, char **persistent, char **run
break;
case LOOKUP_SCOPE_GLOBAL:
case UNIT_FILE_GLOBAL:
return -EOPNOTSUPP;
default:
@ -419,7 +419,7 @@ static int acquire_control_dirs(LookupScope scope, char **persistent, char **run
}
static int acquire_attached_dirs(
LookupScope scope,
UnitFileScope scope,
char **ret_persistent,
char **ret_runtime) {
@ -429,7 +429,7 @@ static int acquire_attached_dirs(
assert(ret_runtime);
/* Portable services are not available to regular users for now. */
if (scope != LOOKUP_SCOPE_SYSTEM)
if (scope != UNIT_FILE_SYSTEM)
return -EOPNOTSUPP;
a = strdup("/etc/systemd/system.attached");
@ -508,8 +508,8 @@ static int get_paths_from_environ(const char *var, char ***paths, bool *append)
}
int lookup_paths_init(
LookupPaths *lp,
LookupScope scope,
LookupPaths *p,
UnitFileScope scope,
LookupPathsFlags flags,
const char *root_dir) {
@ -526,16 +526,16 @@ int lookup_paths_init(
_cleanup_strv_free_ char **paths = NULL;
int r;
assert(lp);
assert(p);
assert(scope >= 0);
assert(scope < _LOOKUP_SCOPE_MAX);
assert(scope < _UNIT_FILE_SCOPE_MAX);
#if HAVE_SPLIT_USR
flags |= LOOKUP_PATHS_SPLIT_USR;
#endif
if (!empty_or_root(root_dir)) {
if (scope == LOOKUP_SCOPE_USER)
if (scope == UNIT_FILE_USER)
return -EINVAL;
r = is_dir(root_dir, true);
@ -560,8 +560,8 @@ int lookup_paths_init(
if (r < 0)
return r;
if (scope == LOOKUP_SCOPE_USER) {
r = acquire_config_dirs(LOOKUP_SCOPE_GLOBAL, &global_persistent_config, &global_runtime_config);
if (scope == UNIT_FILE_USER) {
r = acquire_config_dirs(UNIT_FILE_GLOBAL, &global_persistent_config, &global_runtime_config);
if (r < 0)
return r;
}
@ -606,7 +606,7 @@ int lookup_paths_init(
switch (scope) {
case LOOKUP_SCOPE_SYSTEM:
case UNIT_FILE_SYSTEM:
add = strv_new(
/* If you modify this you also want to modify
* systemdsystemunitpath= in systemd.pc.in! */
@ -629,7 +629,7 @@ int lookup_paths_init(
STRV_IFNOTNULL(generator_late));
break;
case LOOKUP_SCOPE_GLOBAL:
case UNIT_FILE_GLOBAL:
add = strv_new(
/* If you modify this you also want to modify
* systemduserunitpath= in systemd.pc.in, and
@ -652,7 +652,7 @@ int lookup_paths_init(
STRV_IFNOTNULL(generator_late));
break;
case LOOKUP_SCOPE_USER:
case UNIT_FILE_USER:
add = user_dirs(persistent_config, runtime_config,
global_persistent_config, global_runtime_config,
generator, generator_early, generator_late,
@ -716,7 +716,7 @@ int lookup_paths_init(
if (r < 0)
return -ENOMEM;
*lp = (LookupPaths) {
*p = (LookupPaths) {
.search_path = strv_uniq(TAKE_PTR(paths)),
.persistent_config = TAKE_PTR(persistent_config),
@ -741,56 +741,46 @@ int lookup_paths_init(
return 0;
}
int lookup_paths_init_or_warn(LookupPaths *lp, LookupScope scope, LookupPathsFlags flags, const char *root_dir) {
int r;
r = lookup_paths_init(lp, scope, flags, root_dir);
if (r < 0)
return log_error_errno(r, "Failed to initialize unit search paths%s%s: %m",
isempty(root_dir) ? "" : " for root directory ", strempty(root_dir));
return r;
}
void lookup_paths_free(LookupPaths *lp) {
if (!lp)
void lookup_paths_free(LookupPaths *p) {
if (!p)
return;
lp->search_path = strv_free(lp->search_path);
p->search_path = strv_free(p->search_path);
lp->persistent_config = mfree(lp->persistent_config);
lp->runtime_config = mfree(lp->runtime_config);
p->persistent_config = mfree(p->persistent_config);
p->runtime_config = mfree(p->runtime_config);
lp->persistent_attached = mfree(lp->persistent_attached);
lp->runtime_attached = mfree(lp->runtime_attached);
p->persistent_attached = mfree(p->persistent_attached);
p->runtime_attached = mfree(p->runtime_attached);
lp->generator = mfree(lp->generator);
lp->generator_early = mfree(lp->generator_early);
lp->generator_late = mfree(lp->generator_late);
p->generator = mfree(p->generator);
p->generator_early = mfree(p->generator_early);
p->generator_late = mfree(p->generator_late);
lp->transient = mfree(lp->transient);
p->transient = mfree(p->transient);
lp->persistent_control = mfree(lp->persistent_control);
lp->runtime_control = mfree(lp->runtime_control);
p->persistent_control = mfree(p->persistent_control);
p->runtime_control = mfree(p->runtime_control);
lp->root_dir = mfree(lp->root_dir);
lp->temporary_dir = mfree(lp->temporary_dir);
p->root_dir = mfree(p->root_dir);
p->temporary_dir = mfree(p->temporary_dir);
}
void lookup_paths_log(LookupPaths *lp) {
assert(lp);
void lookup_paths_log(LookupPaths *p) {
assert(p);
if (strv_isempty(lp->search_path)) {
if (strv_isempty(p->search_path)) {
log_debug("Ignoring unit files.");
lp->search_path = strv_free(lp->search_path);
p->search_path = strv_free(p->search_path);
} else {
_cleanup_free_ char *t = NULL;
t = strv_join(lp->search_path, "\n\t");
t = strv_join(p->search_path, "\n\t");
log_debug("Looking for unit files in (higher priority first):\n\t%s", strna(t));
}
}
char **generator_binary_paths(LookupScope scope) {
char **generator_binary_paths(UnitFileScope scope) {
bool append = false; /* Add items from SYSTEMD_GENERATOR_PATH before normal directories */
_cleanup_strv_free_ char **paths = NULL;
int r;
@ -805,15 +795,15 @@ char **generator_binary_paths(LookupScope scope) {
switch (scope) {
case LOOKUP_SCOPE_SYSTEM:
case UNIT_FILE_SYSTEM:
add = strv_new("/run/systemd/system-generators",
"/etc/systemd/system-generators",
"/usr/local/lib/systemd/system-generators",
SYSTEM_GENERATOR_DIR);
break;
case LOOKUP_SCOPE_GLOBAL:
case LOOKUP_SCOPE_USER:
case UNIT_FILE_GLOBAL:
case UNIT_FILE_USER:
add = strv_new("/run/systemd/user-generators",
"/etc/systemd/user-generators",
"/usr/local/lib/systemd/user-generators",

View File

@ -3,7 +3,10 @@
#include <stdbool.h>
typedef struct LookupPaths LookupPaths;
#include "def.h"
#include "unit-file.h"
#include "macro.h"
typedef enum LookupPathsFlags {
@ -12,15 +15,7 @@ typedef enum LookupPathsFlags {
LOOKUP_PATHS_SPLIT_USR = 1 << 2,
} LookupPathsFlags;
typedef enum LookupScope {
LOOKUP_SCOPE_SYSTEM,
LOOKUP_SCOPE_GLOBAL,
LOOKUP_SCOPE_USER,
_LOOKUP_SCOPE_MAX,
_LOOKUP_SCOPE_INVALID = -EINVAL,
} LookupScope;
typedef struct LookupPaths {
struct LookupPaths {
/* Where we look for unit files. This includes the individual special paths below, but also any vendor
* supplied, static unit file paths. */
char **search_path;
@ -57,10 +52,9 @@ typedef struct LookupPaths {
/* A temporary directory when running in test mode, to be nuked */
char *temporary_dir;
} LookupPaths;
};
int lookup_paths_init(LookupPaths *lp, LookupScope scope, LookupPathsFlags flags, const char *root_dir);
int lookup_paths_init_or_warn(LookupPaths *lp, LookupScope scope, LookupPathsFlags flags, const char *root_dir);
int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
int xdg_user_dirs(char ***ret_config_dirs, char ***ret_data_dirs);
int xdg_user_runtime_dir(char **ret, const char *suffix);
@ -73,7 +67,7 @@ bool path_is_user_config_dir(const char *path);
void lookup_paths_log(LookupPaths *p);
void lookup_paths_free(LookupPaths *p);
char **generator_binary_paths(LookupScope scope);
char **generator_binary_paths(UnitFileScope scope);
char **env_generator_binary_paths(bool is_system);
#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))

View File

@ -127,22 +127,17 @@ bool null_or_empty(struct stat *st) {
return false;
}
int null_or_empty_path_with_root(const char *fn, const char *root) {
int null_or_empty_path(const char *fn) {
struct stat st;
int r;
assert(fn);
/* A symlink to /dev/null or an empty file?
* When looking under root_dir, we can't expect /dev/ to be mounted,
* so let's see if the path is a (possibly dangling) symlink to /dev/null. */
if (path_equal_ptr(path_startswith(fn, root ?: "/"), "dev/null"))
/* If we have the path, let's do an easy text comparison first. */
if (path_equal(fn, "/dev/null"))
return true;
r = chase_symlinks_and_stat(fn, root, CHASE_PREFIX_ROOT, NULL, &st, NULL);
if (r < 0)
return r;
if (stat(fn, &st) < 0)
return -errno;
return null_or_empty(&st);
}

View File

@ -31,13 +31,9 @@ static inline int dir_is_populated(const char *path) {
}
bool null_or_empty(struct stat *st) _pure_;
int null_or_empty_path_with_root(const char *fn, const char *root);
int null_or_empty_path(const char *fn);
int null_or_empty_fd(int fd);
static inline int null_or_empty_path(const char *fn) {
return null_or_empty_path_with_root(fn, NULL);
}
int path_is_read_only_fs(const char *path);
int files_same(const char *filea, const char *fileb, int flags);

View File

@ -69,7 +69,7 @@ int unit_symlink_name_compatible(const char *symlink, const char *target, bool i
return 0;
}
int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, const char *target) {
int unit_validate_alias_symlink_and_warn(const char *filename, const char *target) {
const char *src, *dst;
_cleanup_free_ char *src_instance = NULL, *dst_instance = NULL;
UnitType src_unit_type, dst_unit_type;
@ -82,8 +82,7 @@ int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, con
*
* -EINVAL is returned if the something is wrong with the source filename or the source unit type is
* not allowed to symlink,
* -EXDEV if the target filename is not a valid unit name or doesn't match the source,
* -ELOOP for an alias to self.
* -EXDEV if the target filename is not a valid unit name or doesn't match the source.
*/
src = basename(filename);
@ -93,56 +92,51 @@ int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, con
src_name_type = unit_name_to_instance(src, &src_instance);
if (src_name_type < 0)
return log_full_errno(log_level, src_name_type,
"%s: not a valid unit name \"%s\": %m", filename, src);
return log_notice_errno(src_name_type,
"%s: not a valid unit name \"%s\": %m", filename, src);
src_unit_type = unit_name_to_type(src);
assert(src_unit_type >= 0); /* unit_name_to_instance() checked the suffix already */
if (!unit_type_may_alias(src_unit_type))
return log_full_errno(log_level, SYNTHETIC_ERRNO(EINVAL),
"%s: symlinks are not allowed for units of this type, rejecting.",
filename);
return log_notice_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: symlinks are not allowed for units of this type, rejecting.",
filename);
if (src_name_type != UNIT_NAME_PLAIN &&
!unit_type_may_template(src_unit_type))
return log_full_errno(log_level, SYNTHETIC_ERRNO(EINVAL),
"%s: templates not allowed for %s units, rejecting.",
filename, unit_type_to_string(src_unit_type));
return log_notice_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: templates not allowed for %s units, rejecting.",
filename, unit_type_to_string(src_unit_type));
/* dst checks */
if (streq(src, dst))
return log_debug_errno(SYNTHETIC_ERRNO(ELOOP),
"%s: unit self-alias: %s → %s, ignoring.",
filename, src, dst);
dst_name_type = unit_name_to_instance(dst, &dst_instance);
if (dst_name_type < 0)
return log_full_errno(log_level, dst_name_type == -EINVAL ? SYNTHETIC_ERRNO(EXDEV) : dst_name_type,
"%s points to \"%s\" which is not a valid unit name: %m",
filename, dst);
return log_notice_errno(dst_name_type == -EINVAL ? SYNTHETIC_ERRNO(EXDEV) : dst_name_type,
"%s points to \"%s\" which is not a valid unit name: %m",
filename, dst);
if (!(dst_name_type == src_name_type ||
(src_name_type == UNIT_NAME_INSTANCE && dst_name_type == UNIT_NAME_TEMPLATE)))
return log_full_errno(log_level, SYNTHETIC_ERRNO(EXDEV),
"%s: symlink target name type \"%s\" does not match source, rejecting.",
filename, dst);
return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
"%s: symlink target name type \"%s\" does not match source, rejecting.",
filename, dst);
if (dst_name_type == UNIT_NAME_INSTANCE) {
assert(src_instance);
assert(dst_instance);
if (!streq(src_instance, dst_instance))
return log_full_errno(log_level, SYNTHETIC_ERRNO(EXDEV),
"%s: unit symlink target \"%s\" instance name doesn't match, rejecting.",
filename, dst);
return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
"%s: unit symlink target \"%s\" instance name doesn't match, rejecting.",
filename, dst);
}
dst_unit_type = unit_name_to_type(dst);
if (dst_unit_type != src_unit_type)
return log_full_errno(log_level, SYNTHETIC_ERRNO(EXDEV),
"%s: symlink target \"%s\" has incompatible suffix, rejecting.",
filename, dst);
return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
"%s: symlink target \"%s\" has incompatible suffix, rejecting.",
filename, dst);
return 0;
}
@ -265,110 +259,6 @@ static int directory_name_is_valid(const char *name) {
return false;
}
int unit_file_resolve_symlink(
const char *root_dir,
char **search_path,
const char *dir,
int dirfd,
const char *filename,
bool resolve_destination_target,
char **ret_destination) {
_cleanup_free_ char *target = NULL, *simplified = NULL, *dst = NULL, *_dir = NULL, *_filename = NULL;
int r;
/* This can be called with either dir+dirfd valid and filename just a name,
* or !dir && dirfd==AT_FDCWD, and filename being a full path.
*
* If resolve_destination_target is true, an absolute path will be returned.
* If not, an absolute path is returned for linked unit files, and a relative
* path otherwise.
*
* Returns an error, false if this is an alias, true if it's a linked unit file. */
assert(filename);
assert(ret_destination);
assert(dir || path_is_absolute(filename));
assert(dirfd >= 0 || dirfd == AT_FDCWD);
r = readlinkat_malloc(dirfd, filename, &target);
if (r < 0)
return log_warning_errno(r, "Failed to read symlink %s%s%s: %m",
dir, dir ? "/" : "", filename);
if (!dir) {
r = path_extract_directory(filename, &_dir);
if (r < 0)
return r;
dir = _dir;
r = path_extract_filename(filename, &_filename);
if (r < 0)
return r;
if (r == O_DIRECTORY)
return log_warning_errno(SYNTHETIC_ERRNO(EISDIR),
"Unexpected path to a directory \"%s\", refusing.", filename);
filename = _filename;
}
bool is_abs = path_is_absolute(target);
if (root_dir || !is_abs) {
char *target_abs = path_join(is_abs ? root_dir : dir, target);
if (!target_abs)
return log_oom();
free_and_replace(target, target_abs);
}
/* Get rid of "." and ".." components in target path */
r = chase_symlinks(target, root_dir, CHASE_NOFOLLOW | CHASE_NONEXISTENT, &simplified, NULL);
if (r < 0)
return log_warning_errno(r, "Failed to resolve symlink %s/%s pointing to %s: %m",
dir, filename, target);
assert(path_is_absolute(simplified));
/* Check if the symlink remain inside of of our search path.
* If yes, it is an alias. Verify that it is valid.
*
* If no, then this is a linked unit file or mask, and we don't care about the target name
* when loading units, and we return the link *source* (resolve_destination_target == false);
* When this is called for installation purposes, we want the final destination,
* so we return the *target*.
*/
const char *tail = path_startswith_strv(simplified, search_path);
if (tail) { /* An alias */
_cleanup_free_ char *target_name = NULL;
r = path_extract_filename(simplified, &target_name);
if (r < 0)
return r;
r = unit_validate_alias_symlink_or_warn(LOG_NOTICE, filename, simplified);
if (r < 0)
return r;
if (is_path(tail))
log_warning("Suspicious symlink %s/%s→%s, treating as alias.",
dir, filename, simplified);
dst = resolve_destination_target ? TAKE_PTR(simplified) : TAKE_PTR(target_name);
} else {
log_debug("Linked unit file: %s/%s → %s", dir, filename, simplified);
if (resolve_destination_target)
dst = TAKE_PTR(simplified);
else {
dst = path_join(dir, filename);
if (!dst)
return log_oom();
}
}
*ret_destination = TAKE_PTR(dst);
return !tail; /* true if linked unit file */
}
int unit_file_build_name_map(
const LookupPaths *lp,
uint64_t *cache_timestamp_hash,
@ -418,9 +308,10 @@ int unit_file_build_name_map(
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
_unused_ _cleanup_free_ char *_filename_free = NULL;
char *filename;
_cleanup_free_ char *dst = NULL;
_cleanup_free_ char *simplified = NULL;
bool symlink_to_dir = false;
const char *dst = NULL;
char *filename;
/* We only care about valid units and dirs with certain suffixes, let's ignore the
* rest. */
@ -504,35 +395,77 @@ int unit_file_build_name_map(
/* We don't explicitly check for alias loops here. unit_ids_map_get() which
* limits the number of hops should be used to access the map. */
r = unit_file_resolve_symlink(lp->root_dir, lp->search_path,
*dir, dirfd(d), de->d_name,
/* resolve_destination_target= */ false,
&dst);
if (r == -ENOMEM)
return r;
if (r < 0) /* we ignore other errors here */
continue;
_cleanup_free_ char *target = NULL;
} else {
dst = TAKE_PTR(_filename_free); /* Grab the copy we made previously, if available. */
if (!dst) {
dst = strdup(filename);
if (!dst)
return log_oom();
r = readlinkat_malloc(dirfd(d), de->d_name, &target);
if (r < 0) {
log_warning_errno(r, "Failed to read symlink %s/%s, ignoring: %m",
*dir, de->d_name);
continue;
}
const bool is_abs = path_is_absolute(target);
if (lp->root_dir || !is_abs) {
char *target_abs = path_join(is_abs ? lp->root_dir : *dir, target);
if (!target_abs)
return log_oom();
free_and_replace(target, target_abs);
}
/* Get rid of "." and ".." components in target path */
r = chase_symlinks(target, lp->root_dir, CHASE_NOFOLLOW | CHASE_NONEXISTENT, &simplified, NULL);
if (r < 0) {
log_warning_errno(r, "Failed to resolve symlink %s pointing to %s, ignoring: %m",
filename, target);
continue;
}
/* Check if the symlink goes outside of our search path.
* If yes, it's a linked unit file or mask, and we don't care about the target name.
* Let's just store the link source directly.
* If not, let's verify that it's a good symlink. */
char *tail = path_startswith_strv(simplified, lp->search_path);
if (!tail) {
log_debug("%s: linked unit file: %s → %s",
__func__, filename, simplified);
dst = filename;
} else {
bool self_alias;
dst = basename(simplified);
self_alias = streq(dst, de->d_name);
if (is_path(tail))
log_full(self_alias ? LOG_DEBUG : LOG_WARNING,
"Suspicious symlink %s→%s, treating as alias.",
filename, simplified);
r = unit_validate_alias_symlink_and_warn(filename, simplified);
if (r < 0)
continue;
if (self_alias) {
/* A self-alias that has no effect */
log_debug("%s: self-alias: %s/%s → %s, ignoring.",
__func__, *dir, de->d_name, dst);
continue;
}
log_debug("%s: alias: %s/%s → %s", __func__, *dir, de->d_name, dst);
}
} else {
dst = filename;
log_debug("%s: normal unit file: %s", __func__, dst);
}
_cleanup_free_ char *key = strdup(de->d_name);
if (!key)
return log_oom();
r = hashmap_ensure_put(&ids, &string_hash_ops_free_free, key, dst);
r = hashmap_put_strdup(&ids, de->d_name, dst);
if (r < 0)
return log_warning_errno(r, "Failed to add entry to hashmap (%s→%s): %m",
de->d_name, dst);
key = dst = NULL;
}
}

View File

@ -4,11 +4,12 @@
#include <stdbool.h>
#include "hashmap.h"
#include "path-lookup.h"
#include "time-util.h"
#include "unit-name.h"
typedef enum UnitFileState UnitFileState;
typedef enum UnitFileScope UnitFileScope;
typedef struct LookupPaths LookupPaths;
enum UnitFileState {
UNIT_FILE_ENABLED,
@ -28,23 +29,21 @@ enum UnitFileState {
_UNIT_FILE_STATE_INVALID = -EINVAL,
};
enum UnitFileScope {
UNIT_FILE_SYSTEM,
UNIT_FILE_GLOBAL,
UNIT_FILE_USER,
_UNIT_FILE_SCOPE_MAX,
_UNIT_FILE_SCOPE_INVALID = -EINVAL,
};
bool unit_type_may_alias(UnitType type) _const_;
bool unit_type_may_template(UnitType type) _const_;
int unit_symlink_name_compatible(const char *symlink, const char *target, bool instance_propagation);
int unit_validate_alias_symlink_or_warn(int log_level, const char *filename, const char *target);
int unit_validate_alias_symlink_and_warn(const char *filename, const char *target);
bool lookup_paths_timestamp_hash_same(const LookupPaths *lp, uint64_t timestamp_hash, uint64_t *ret_new);
int unit_file_resolve_symlink(
const char *root_dir,
char **search_path,
const char *dir,
int dirfd,
const char *filename,
bool resolve_destination_target,
char **ret_destination);
int unit_file_build_name_map(
const LookupPaths *lp,
uint64_t *cache_timestamp_hash,

View File

@ -2288,7 +2288,7 @@ fail:
static int method_enable_unit_files_generic(
sd_bus_message *message,
Manager *m,
int (*call)(LookupScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
bool carries_install_info,
sd_bus_error *error) {
@ -2352,7 +2352,7 @@ static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bu
return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
}
static int unit_file_preset_without_mode(LookupScope scope, UnitFileFlags flags, const char *root_dir, char **files, UnitFileChange **changes, size_t *n_changes) {
static int unit_file_preset_without_mode(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char **files, UnitFileChange **changes, size_t *n_changes) {
return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
}
@ -2412,7 +2412,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
static int method_disable_unit_files_generic(
sd_bus_message *message,
Manager *m,
int (*call)(LookupScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
sd_bus_error *error) {
_cleanup_strv_free_ char **l = NULL;
@ -2638,7 +2638,7 @@ static int method_get_unit_file_links(sd_bus_message *message, void *userdata, s
flags = UNIT_FILE_DRY_RUN |
(runtime ? UNIT_FILE_RUNTIME : 0);
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, flags, NULL, p, &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
if (r < 0)
return log_error_errno(r, "Failed to get file links for %s: %m", name);

View File

@ -62,7 +62,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (!getenv("SYSTEMD_LOG_LEVEL"))
log_set_max_level(LOG_CRIT);
assert_se(manager_new(LOOKUP_SCOPE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0);
assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0);
name = strjoina("a.", unit_type_to_string(t));
assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0);

View File

@ -2885,7 +2885,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
goto finish;
r = manager_new(arg_system ? LOOKUP_SCOPE_SYSTEM : LOOKUP_SCOPE_USER,
r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
arg_action == ACTION_TEST ? MANAGER_TEST_FULL : 0,
&m);
if (r < 0) {

View File

@ -775,13 +775,13 @@ static int manager_setup_sigchld_event_source(Manager *m) {
return 0;
}
int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) {
int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **_m) {
_cleanup_(manager_freep) Manager *m = NULL;
const char *e;
int r;
assert(_m);
assert(IN_SET(scope, LOOKUP_SCOPE_SYSTEM, LOOKUP_SCOPE_USER));
assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER));
m = new(Manager, 1);
if (!m)
@ -1700,7 +1700,7 @@ static void manager_preset_all(Manager *m) {
return;
/* If this is the first boot, and we are in the host system, then preset everything */
r = unit_file_preset_all(LOOKUP_SCOPE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
r = unit_file_preset_all(UNIT_FILE_SYSTEM, 0, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, NULL, 0);
if (r < 0)
log_full_errno(r == -EEXIST ? LOG_NOTICE : LOG_WARNING, r,
"Failed to populate /etc with preset unit settings, ignoring: %m");
@ -1751,11 +1751,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo
/* If we are running in test mode, we still want to run the generators,
* but we should not touch the real generator directories. */
r = lookup_paths_init_or_warn(&m->lookup_paths, m->unit_file_scope,
MANAGER_IS_TEST_RUN(m) ? LOOKUP_PATHS_TEMPORARY_GENERATED : 0,
root);
r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope,
MANAGER_IS_TEST_RUN(m) ? LOOKUP_PATHS_TEMPORARY_GENERATED : 0,
root);
if (r < 0)
return r;
return log_error_errno(r, "Failed to initialize path lookup table: %m");
dual_timestamp_get(m->timestamps + manager_timestamp_initrd_mangle(MANAGER_TIMESTAMP_GENERATORS_START));
r = manager_run_environment_generators(m);
@ -3343,9 +3343,9 @@ int manager_reload(Manager *m) {
m->uid_refs = hashmap_free(m->uid_refs);
m->gid_refs = hashmap_free(m->gid_refs);
r = lookup_paths_init_or_warn(&m->lookup_paths, m->unit_file_scope, 0, NULL);
r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL);
if (r < 0)
return r;
log_warning_errno(r, "Failed to initialize path lookup table, ignoring: %m");
(void) manager_run_environment_generators(m);
(void) manager_run_generators(m);

View File

@ -235,7 +235,7 @@ struct Manager {
int user_lookup_fds[2];
sd_event_source *user_lookup_event_source;
LookupScope unit_file_scope;
UnitFileScope unit_file_scope;
LookupPaths lookup_paths;
Hashmap *unit_id_map;
Hashmap *unit_name_map;
@ -463,8 +463,8 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
return m->default_timeout_abort_set ? m->default_timeout_abort_usec : m->default_timeout_stop_usec;
}
#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == LOOKUP_SCOPE_SYSTEM)
#define MANAGER_IS_USER(m) ((m)->unit_file_scope != LOOKUP_SCOPE_SYSTEM)
#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
#define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM)
#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
@ -475,7 +475,7 @@ static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
#define MANAGER_IS_TEST_RUN(m) ((m)->test_run_flags != 0)
int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager **m);
int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager **m);
Manager* manager_free(Manager *m);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);

View File

@ -183,7 +183,7 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
COMMON_SYSTEM_SPECIFIERS,
COMMON_CREDS_SPECIFIERS(u->manager->unit_file_scope),
COMMON_CREDS_SPECIFIERS,
{}
};
@ -253,7 +253,7 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
COMMON_SYSTEM_SPECIFIERS,
COMMON_CREDS_SPECIFIERS(u->manager->unit_file_scope),
COMMON_CREDS_SPECIFIERS,
COMMON_TMP_SPECIFIERS,
{}

View File

@ -47,27 +47,6 @@ int device_add_property(sd_device *device, const char *key, const char *value) {
return 0;
}
int device_add_propertyf(sd_device *device, const char *key, const char *format, ...) {
_cleanup_free_ char *value = NULL;
va_list ap;
int r;
assert(device);
assert(key);
if (!format)
return device_add_property(device, key, NULL);
va_start(ap, format);
r = vasprintf(&value, format, ap);
va_end(ap);
if (r < 0)
return -ENOMEM;
return device_add_property(device, key, value);
}
void device_set_devlink_priority(sd_device *device, int priority) {
assert(device);

View File

@ -36,7 +36,6 @@ int device_ensure_usec_initialized(sd_device *device, sd_device *device_old);
int device_add_devlink(sd_device *device, const char *devlink);
bool device_has_devlink(sd_device *device, const char *devlink);
int device_add_property(sd_device *device, const char *property, const char *value);
int device_add_propertyf(sd_device *device, const char *key, const char *format, ...) _printf_(3, 4);
int device_add_tag(sd_device *device, const char *tag, bool both);
void device_remove_tag(sd_device *device, const char *tag);
void device_cleanup_tags(sd_device *device);

View File

@ -601,8 +601,8 @@ static int get_search(uint64_t type, char ***list) {
case SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT:
case SD_PATH_SYSTEMD_SEARCH_USER_UNIT: {
_cleanup_(lookup_paths_free) LookupPaths lp = {};
const LookupScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT ?
LOOKUP_SCOPE_SYSTEM : LOOKUP_SCOPE_USER;
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT ?
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
r = lookup_paths_init(&lp, scope, 0, NULL);
if (r < 0)
@ -615,8 +615,8 @@ static int get_search(uint64_t type, char ***list) {
case SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR:
case SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR: {
char **t;
const LookupScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR ?
LOOKUP_SCOPE_SYSTEM : LOOKUP_SCOPE_USER;
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR ?
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
t = generator_binary_paths(scope);
if (!t)

View File

@ -231,7 +231,7 @@ static int extract_now(
/* Then, send unit file data to the parent (or/and add it to the hashmap). For that we use our usual unit
* discovery logic. Note that we force looking inside of /lib/systemd/system/ for units too, as we mightbe
* compiled for a split-usr system but the image might be a legacy-usr one. */
r = lookup_paths_init(&paths, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, where);
r = lookup_paths_init(&paths, UNIT_FILE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, where);
if (r < 0)
return log_debug_errno(r, "Failed to acquire lookup paths: %m");
@ -1340,12 +1340,12 @@ int portable_attach(
strempty(extensions_joined));
}
r = lookup_paths_init(&paths, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
r = lookup_paths_init(&paths, UNIT_FILE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
if (r < 0)
return r;
HASHMAP_FOREACH(item, unit_files) {
r = unit_file_exists(LOOKUP_SCOPE_SYSTEM, &paths, item->name);
r = unit_file_exists(UNIT_FILE_SYSTEM, &paths, item->name);
if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to determine whether unit '%s' exists on the host: %m", item->name);
if (!FLAGS_SET(flags, PORTABLE_REATTACH) && r > 0)
@ -1539,7 +1539,7 @@ int portable_detach(
assert(name_or_path);
r = lookup_paths_init(&paths, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
r = lookup_paths_init(&paths, UNIT_FILE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
if (r < 0)
return r;
@ -1573,7 +1573,7 @@ int portable_detach(
if (r == 0)
continue;
r = unit_file_lookup_state(LOOKUP_SCOPE_SYSTEM, &paths, de->d_name, &state);
r = unit_file_lookup_state(UNIT_FILE_SYSTEM, &paths, de->d_name, &state);
if (r < 0)
return log_debug_errno(r, "Failed to determine unit file state of '%s': %m", de->d_name);
if (!IN_SET(state, UNIT_FILE_STATIC, UNIT_FILE_DISABLED, UNIT_FILE_LINKED, UNIT_FILE_RUNTIME, UNIT_FILE_LINKED_RUNTIME))
@ -1717,7 +1717,7 @@ static int portable_get_state_internal(
assert(name_or_path);
assert(ret);
r = lookup_paths_init(&paths, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
r = lookup_paths_init(&paths, UNIT_FILE_SYSTEM, LOOKUP_PATHS_SPLIT_USR, NULL);
if (r < 0)
return r;
@ -1753,7 +1753,7 @@ static int portable_get_state_internal(
if (r == 0)
continue;
r = unit_file_lookup_state(LOOKUP_SCOPE_SYSTEM, &paths, de->d_name, &state);
r = unit_file_lookup_state(UNIT_FILE_SYSTEM, &paths, de->d_name, &state);
if (r < 0)
return log_debug_errno(r, "Failed to determine unit file state of '%s': %m", de->d_name);
if (!IN_SET(state, UNIT_FILE_STATIC, UNIT_FILE_DISABLED, UNIT_FILE_LINKED, UNIT_FILE_LINKED_RUNTIME))

View File

@ -785,8 +785,7 @@ static int condition_test_needs_update(Condition *c, char **env) {
if (r < 0) {
log_debug_errno(r, "Failed to parse timestamp file '%s', using mtime: %m", p);
return true;
}
if (isempty(timestamp_str)) {
} else if (r == 0) {
log_debug("No data in timestamp file '%s', using mtime.", p);
return true;
}

View File

@ -97,11 +97,7 @@ static int specifier_last_component(char specifier, const void *data, const char
return 0;
}
int install_name_printf(
LookupScope scope,
const UnitFileInstallInfo *info,
const char *format,
char **ret) {
int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret) {
/* This is similar to unit_name_printf() */
const Specifier table[] = {
@ -113,13 +109,13 @@ int install_name_printf(
COMMON_SYSTEM_SPECIFIERS,
COMMON_CREDS_SPECIFIERS(scope),
COMMON_CREDS_SPECIFIERS,
{}
};
assert(info);
assert(i);
assert(format);
assert(ret);
return specifier_printf(format, UNIT_NAME_MAX, table, info->root, info, ret);
return specifier_printf(format, UNIT_NAME_MAX, table, root, i, ret);
}

View File

@ -4,8 +4,4 @@
#include "install.h"
#include "unit-name.h"
int install_name_printf(
LookupScope scope,
const UnitFileInstallInfo *info,
const char *format,
char **ret);
int install_name_printf(const UnitFileInstallInfo *i, const char *format, const char *root, char **ret);

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,6 @@ typedef struct UnitFileInstallInfo UnitFileInstallInfo;
#include "macro.h"
#include "path-lookup.h"
#include "strv.h"
#include "unit-file.h"
#include "unit-name.h"
enum UnitFilePresetMode {
@ -71,8 +70,7 @@ struct UnitFileList {
enum UnitFileType {
UNIT_FILE_TYPE_REGULAR,
UNIT_FILE_TYPE_LINKED,
UNIT_FILE_TYPE_ALIAS,
UNIT_FILE_TYPE_SYMLINK,
UNIT_FILE_TYPE_MASKED,
_UNIT_FILE_TYPE_MAX,
_UNIT_FILE_TYPE_INVALID = -EINVAL,
@ -96,28 +94,28 @@ struct UnitFileInstallInfo {
};
int unit_file_enable(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_disable(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_reenable(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **names_or_paths,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_preset(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
@ -125,52 +123,52 @@ int unit_file_preset(
UnitFileChange **changes,
size_t *n_changes);
int unit_file_preset_all(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
UnitFilePresetMode mode,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_mask(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_unmask(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_link(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_revert(
LookupScope scope,
UnitFileScope scope,
const char *root_dir,
char **files,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_set_default(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
const char *file,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_get_default(
LookupScope scope,
UnitFileScope scope,
const char *root_dir,
char **name);
int unit_file_add_dependency(
LookupScope scope,
UnitFileScope scope,
UnitFileFlags flags,
const char *root_dir,
char **files,
@ -180,27 +178,22 @@ int unit_file_add_dependency(
size_t *n_changes);
int unit_file_lookup_state(
LookupScope scope,
UnitFileScope scope,
const LookupPaths *paths,
const char *name,
UnitFileState *ret);
int unit_file_get_state(LookupScope scope, const char *root_dir, const char *filename, UnitFileState *ret);
int unit_file_exists(LookupScope scope, const LookupPaths *paths, const char *name);
int unit_file_get_state(UnitFileScope scope, const char *root_dir, const char *filename, UnitFileState *ret);
int unit_file_exists(UnitFileScope scope, const LookupPaths *paths, const char *name);
int unit_file_get_list(LookupScope scope, const char *root_dir, Hashmap *h, char **states, char **patterns);
int unit_file_get_list(UnitFileScope scope, const char *root_dir, Hashmap *h, char **states, char **patterns);
Hashmap* unit_file_list_free(Hashmap *h);
int unit_file_changes_add(UnitFileChange **changes, size_t *n_changes, int type, const char *path, const char *source);
void unit_file_changes_free(UnitFileChange *changes, size_t n_changes);
void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *changes, size_t n_changes, bool quiet);
int unit_file_verify_alias(
const UnitFileInstallInfo *info,
const char *dst,
char **ret_dst,
UnitFileChange **changes,
size_t *n_changes);
int unit_file_verify_alias(const UnitFileInstallInfo *i, const char *dst, char **ret_dst);
typedef struct UnitFilePresetRule UnitFilePresetRule;
@ -211,7 +204,7 @@ typedef struct {
} UnitFilePresets;
void unit_file_presets_freep(UnitFilePresets *p);
int unit_file_query_preset(LookupScope scope, const char *root_dir, const char *name, UnitFilePresets *cached);
int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char *name, UnitFilePresets *cached);
const char *unit_file_state_to_string(UnitFileState s) _const_;
UnitFileState unit_file_state_from_string(const char *s) _pure_;

View File

@ -18,7 +18,6 @@
#include "id128-util.h"
#include "macro.h"
#include "os-util.h"
#include "path-lookup.h"
#include "path-util.h"
#include "specifier.h"
#include "string-util.h"
@ -163,8 +162,7 @@ int specifier_machine_id(char specifier, const void *data, const char *root, con
fd = chase_symlinks_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
if (fd < 0)
/* Translate error for missing os-release file to EUNATCH. */
return fd == -ENOENT ? -EUNATCH : fd;
return fd;
r = id128_read_fd(fd, ID128_PLAIN, &id);
} else
@ -271,54 +269,44 @@ int specifier_architecture(char specifier, const void *data, const char *root, c
}
/* Note: fields in /etc/os-release might quite possibly be missing, even if everything is entirely valid
* otherwise. We'll return an empty value or NULL in that case from the functions below. But if the
* os-release file is missing, we'll return -EUNATCH. This means that something is seriously wrong with the
* installation. */
static int parse_os_release_specifier(const char *root, const char *id, char **ret) {
int r;
assert(ret);
/* Translate error for missing os-release file to EUNATCH. */
r = parse_os_release(root, id, ret);
return r == -ENOENT ? -EUNATCH : r;
}
* otherwise. We'll return an empty value or NULL in that case from the functions below. */
int specifier_os_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "ID", ret);
assert(ret);
return parse_os_release(root, "ID", ret);
}
int specifier_os_version_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "VERSION_ID", ret);
assert(ret);
return parse_os_release(root, "VERSION_ID", ret);
}
int specifier_os_build_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "BUILD_ID", ret);
assert(ret);
return parse_os_release(root, "BUILD_ID", ret);
}
int specifier_os_variant_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "VARIANT_ID", ret);
assert(ret);
return parse_os_release(root, "VARIANT_ID", ret);
}
int specifier_os_image_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "IMAGE_ID", ret);
assert(ret);
return parse_os_release(root, "IMAGE_ID", ret);
}
int specifier_os_image_version(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
return parse_os_release_specifier(root, "IMAGE_VERSION", ret);
assert(ret);
return parse_os_release(root, "IMAGE_VERSION", ret);
}
int specifier_group_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
LookupScope scope = PTR_TO_INT(data);
char *t;
assert(ret);
if (scope == LOOKUP_SCOPE_GLOBAL)
return -EINVAL;
t = gid_to_name(scope == LOOKUP_SCOPE_USER ? getgid() : 0);
t = gid_to_name(getgid());
if (!t)
return -ENOMEM;
@ -327,42 +315,27 @@ int specifier_group_name(char specifier, const void *data, const char *root, con
}
int specifier_group_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
LookupScope scope = PTR_TO_INT(data);
gid_t gid;
assert(ret);
if (scope == LOOKUP_SCOPE_GLOBAL)
return -EINVAL;
gid = scope == LOOKUP_SCOPE_USER ? getgid() : 0;
if (asprintf(ret, UID_FMT, gid) < 0)
if (asprintf(ret, UID_FMT, getgid()) < 0)
return -ENOMEM;
return 0;
}
int specifier_user_name(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
LookupScope scope = PTR_TO_INT(data);
uid_t uid;
char *t;
assert(ret);
if (scope == LOOKUP_SCOPE_GLOBAL)
return -EINVAL;
/* If we are UID 0 (root), this will not result in NSS, otherwise it might. This is good, as we want to be able
* to run this in PID 1, where our user ID is 0, but where NSS lookups are not allowed.
uid = scope == LOOKUP_SCOPE_USER ? getuid() : 0;
/* If we are UID 0 (root), this will not result in NSS, otherwise it might. This is good, as we want
* to be able to run this in PID 1, where our user ID is 0, but where NSS lookups are not allowed.
* We don't use getusername_malloc() here, because we don't want to look at $USER, to remain
* consistent with specifer_user_id() below.
* We don't use getusername_malloc() here, because we don't want to look at $USER, to remain consistent with
* specifer_user_id() below.
*/
t = uid_to_name(uid);
t = uid_to_name(getuid());
if (!t)
return -ENOMEM;
@ -371,17 +344,9 @@ int specifier_user_name(char specifier, const void *data, const char *root, cons
}
int specifier_user_id(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
LookupScope scope = PTR_TO_INT(data);
uid_t uid;
assert(ret);
if (scope == LOOKUP_SCOPE_GLOBAL)
return -EINVAL;
uid = scope == LOOKUP_SCOPE_USER ? getuid() : 0;
if (asprintf(ret, UID_FMT, uid) < 0)
if (asprintf(ret, UID_FMT, getuid()) < 0)
return -ENOMEM;
return 0;

View File

@ -84,11 +84,11 @@ int specifier_var_tmp_dir(char specifier, const void *data, const char *root, co
{ 'w', specifier_os_version_id, NULL }, \
{ 'W', specifier_os_variant_id, NULL }
#define COMMON_CREDS_SPECIFIERS(scope) \
{ 'g', specifier_group_name, INT_TO_PTR(scope) }, \
{ 'G', specifier_group_id, INT_TO_PTR(scope) }, \
{ 'u', specifier_user_name, INT_TO_PTR(scope) }, \
{ 'U', specifier_user_id, INT_TO_PTR(scope) }
#define COMMON_CREDS_SPECIFIERS \
{ 'g', specifier_group_name, NULL }, \
{ 'G', specifier_group_id, NULL }, \
{ 'u', specifier_user_name, NULL }, \
{ 'U', specifier_user_id, NULL }
#define COMMON_TMP_SPECIFIERS \
{ 'T', specifier_tmp_dir, NULL }, \

View File

@ -25,7 +25,6 @@
#include "cgroup-util.h"
#include "env-file.h"
#include "env-util.h"
#include "fd-util.h"
#include "fs-util.h"
#include "log.h"
#include "namespace-util.h"
@ -34,7 +33,6 @@
#include "random-util.h"
#include "strv.h"
#include "tests.h"
#include "tmpfile-util.h"
char* setup_fake_runtime_dir(void) {
char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p;
@ -134,23 +132,6 @@ int log_tests_skipped_errno(int r, const char *message) {
return EXIT_TEST_SKIP;
}
int write_tmpfile(char *pattern, const char *contents) {
_cleanup_close_ int fd = -1;
assert(pattern);
assert(contents);
fd = mkostemp_safe(pattern);
if (fd < 0)
return fd;
ssize_t l = strlen(contents);
errno = 0;
if (write(fd, contents, l) != l)
return errno_or_else(EIO);
return 0;
}
bool have_namespaces(void) {
siginfo_t si = {};
pid_t pid;

View File

@ -30,8 +30,6 @@ void test_setup_logging(int level);
int log_tests_skipped(const char *message);
int log_tests_skipped_errno(int r, const char *message);
int write_tmpfile(char *pattern, const char *contents);
bool have_namespaces(void);
/* We use the small but non-trivial limit here */

View File

@ -37,9 +37,9 @@ int verb_cat(int argc, char *argv[], void *userdata) {
if (arg_transport != BUS_TRANSPORT_LOCAL)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot remotely cat units.");
r = lookup_paths_init_or_warn(&lp, arg_scope, 0, arg_root);
r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
return r;
return log_error_errno(r, "Failed to determine unit paths: %m");
r = acquire_bus(BUS_MANAGER, &bus);
if (r < 0)
@ -99,7 +99,7 @@ int verb_cat(int argc, char *argv[], void *userdata) {
ansi_highlight_red(),
ansi_highlight_red(),
ansi_highlight_red(),
arg_scope == LOOKUP_SCOPE_SYSTEM ? "" : " --user",
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
ansi_normal());
r = cat_files(fragment_path, dropin_paths, 0);
@ -406,8 +406,8 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
if (!path) {
if (!arg_force) {
log_info("Run 'systemctl edit%s --force --full %s' to create a new unit.",
arg_scope == LOOKUP_SCOPE_GLOBAL ? " --global" :
arg_scope == LOOKUP_SCOPE_USER ? " --user" : "",
arg_scope == UNIT_FILE_GLOBAL ? " --global" :
arg_scope == UNIT_FILE_USER ? " --user" : "",
*name);
return -ENOENT;
}
@ -507,9 +507,9 @@ int verb_edit(int argc, char *argv[], void *userdata) {
if (arg_transport != BUS_TRANSPORT_LOCAL)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot edit units remotely.");
r = lookup_paths_init_or_warn(&lp, arg_scope, 0, arg_root);
r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
return r;
return log_error_errno(r, "Failed to determine unit paths: %m");
r = mac_selinux_init();
if (r < 0)

View File

@ -141,7 +141,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
if (STR_IN_SET(verb, "mask", "unmask")) {
_cleanup_(lookup_paths_free) LookupPaths lp = {};
r = lookup_paths_init_or_warn(&lp, arg_scope, 0, arg_root);
r = lookup_paths_init(&lp, arg_scope, 0, arg_root);
if (r < 0)
return r;

View File

@ -18,7 +18,7 @@ static int show_installation_targets_client_side(const char *name) {
flags = UNIT_FILE_DRY_RUN |
(arg_runtime ? UNIT_FILE_RUNTIME : 0);
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, flags, NULL, p, &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
if (r < 0)
return log_error_errno(r, "Failed to get file links for %s: %m", name);

View File

@ -762,7 +762,7 @@ static void print_status_info(
getuid(),
get_output_flags() | OUTPUT_BEGIN_NEWLINE,
SD_JOURNAL_LOCAL_ONLY,
arg_scope == LOOKUP_SCOPE_SYSTEM,
arg_scope == UNIT_FILE_SYSTEM,
ellipsized);
if (i->need_daemon_reload)

View File

@ -246,10 +246,10 @@ int verb_start_special(int argc, char *argv[], void *userdata) {
int verb_start_system_special(int argc, char *argv[], void *userdata) {
/* Like start_special above, but raises an error when running in user mode */
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Bad action for %s mode.",
arg_scope == LOOKUP_SCOPE_GLOBAL ? "--global" : "--user");
arg_scope == UNIT_FILE_GLOBAL ? "--global" : "--user");
return verb_start_special(argc, argv, userdata);
}

View File

@ -168,8 +168,8 @@ fail:
BUS_ERROR_UNIT_MASKED,
BUS_ERROR_JOB_TYPE_NOT_APPLICABLE))
log_error("See %s logs and 'systemctl%s status%s %s' for details.",
arg_scope == LOOKUP_SCOPE_SYSTEM ? "system" : "user",
arg_scope == LOOKUP_SCOPE_SYSTEM ? "" : " --user",
arg_scope == UNIT_FILE_SYSTEM ? "system" : "user",
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
name[0] == '-' ? " --" : "",
name);
@ -242,7 +242,7 @@ static const char** make_extra_args(const char *extra_args[static 4]) {
assert(extra_args);
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
extra_args[n++] = "--user";
if (arg_transport == BUS_TRANSPORT_REMOTE) {

View File

@ -116,7 +116,7 @@ int enable_sysv_units(const char *verb, char **args) {
/* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
return 0;
if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
@ -128,7 +128,7 @@ int enable_sysv_units(const char *verb, char **args) {
"is-enabled"))
return 0;
r = lookup_paths_init_or_warn(&paths, arg_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
r = lookup_paths_init(&paths, arg_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
if (r < 0)
return r;

View File

@ -46,7 +46,7 @@ int acquire_bus(BusFocus focus, sd_bus **ret) {
if (!buses[focus]) {
bool user;
user = arg_scope != LOOKUP_SCOPE_SYSTEM;
user = arg_scope != UNIT_FILE_SYSTEM;
if (focus == BUS_MANAGER)
r = bus_connect_transport_systemd(arg_transport, arg_host, user, &buses[focus]);
@ -73,7 +73,7 @@ void ask_password_agent_open_maybe(void) {
if (arg_dry_run)
return;
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
return;
ask_password_agent_open_if_enabled(arg_transport, arg_ask_password);
@ -82,7 +82,7 @@ void ask_password_agent_open_maybe(void) {
void polkit_agent_open_maybe(void) {
/* Open the polkit agent as a child process if necessary */
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
return;
polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
@ -380,7 +380,7 @@ void warn_unit_file_changed(const char *unit) {
ansi_highlight_red(),
ansi_normal(),
unit,
arg_scope == LOOKUP_SCOPE_SYSTEM ? "" : " --user");
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
}
int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **ret_unit_path) {
@ -814,7 +814,7 @@ bool install_client_side(void) {
if (!isempty(arg_root))
return true;
if (arg_scope == LOOKUP_SCOPE_GLOBAL)
if (arg_scope == UNIT_FILE_GLOBAL)
return true;
/* Unsupported environment variable, mostly for debugging purposes */

View File

@ -66,7 +66,7 @@ char **arg_properties = NULL;
bool arg_all = false;
enum dependency arg_dependency = DEPENDENCY_FORWARD;
const char *_arg_job_mode = NULL;
LookupScope arg_scope = LOOKUP_SCOPE_SYSTEM;
UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
bool arg_wait = false;
bool arg_no_block = false;
int arg_legend = -1; /* -1: true, unless --quiet is passed, 1: true */
@ -616,15 +616,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_USER:
arg_scope = LOOKUP_SCOPE_USER;
arg_scope = UNIT_FILE_USER;
break;
case ARG_SYSTEM:
arg_scope = LOOKUP_SCOPE_SYSTEM;
arg_scope = UNIT_FILE_SYSTEM;
break;
case ARG_GLOBAL:
arg_scope = LOOKUP_SCOPE_GLOBAL;
arg_scope = UNIT_FILE_GLOBAL;
break;
case ARG_WAIT:
@ -924,10 +924,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
/* If we are in --user mode, there's no point in talking to PolicyKit or the infra to query system
* passwords */
if (arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_scope != UNIT_FILE_SYSTEM)
arg_ask_password = false;
if (arg_transport == BUS_TRANSPORT_REMOTE && arg_scope != LOOKUP_SCOPE_SYSTEM)
if (arg_transport == BUS_TRANSPORT_REMOTE && arg_scope != UNIT_FILE_SYSTEM)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Cannot access user instance remotely.");

View File

@ -51,7 +51,7 @@ extern char **arg_properties;
extern bool arg_all;
extern enum dependency arg_dependency;
extern const char *_arg_job_mode;
extern LookupScope arg_scope;
extern UnitFileScope arg_scope;
extern bool arg_wait;
extern bool arg_no_block;
extern int arg_legend;

View File

@ -747,7 +747,7 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
if (hashmap_contains(all_services, name))
continue;
r = unit_file_exists(LOOKUP_SCOPE_SYSTEM, lp, name);
r = unit_file_exists(UNIT_FILE_SYSTEM, lp, name);
if (r < 0 && !IN_SET(r, -ELOOP, -ERFKILL, -EADDRNOTAVAIL)) {
log_debug_errno(r, "Failed to detect whether %s exists, skipping: %m", name);
continue;
@ -891,9 +891,9 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
assert_se(arg_dest = dest_late);
r = lookup_paths_init_or_warn(&lp, LOOKUP_SCOPE_SYSTEM, LOOKUP_PATHS_EXCLUDE_GENERATED, NULL);
r = lookup_paths_init(&lp, UNIT_FILE_SYSTEM, LOOKUP_PATHS_EXCLUDE_GENERATED, NULL);
if (r < 0)
return r;
return log_error_errno(r, "Failed to find lookup paths: %m");
all_services = hashmap_new(&string_hash_ops);
if (!all_services)

View File

@ -97,7 +97,7 @@ int main(int argc, char *argv[]) {
/* The simple tests succeeded. Now let's try full unit-based use-case. */
assert_se(manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
assert_se(u = unit_new(m, sizeof(Service)));

View File

@ -301,7 +301,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
assert_se(test_bpf_cgroup_programs(m,

View File

@ -90,7 +90,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(manager_new(LOOKUP_SCOPE_SYSTEM, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
/* We need to enable access to the filesystem where the binary is so we

View File

@ -42,7 +42,7 @@ TEST_RET(cgroup_mask, .sd_booted = true) {
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (IN_SET(r, -EPERM, -EACCES)) {
log_error_errno(r, "manager_new: %m");
return log_tests_skipped("cannot create manager");

View File

@ -26,7 +26,7 @@ TEST_RET(default_memory_low, .sd_booted = true) {
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (IN_SET(r, -EPERM, -EACCES)) {
log_error_errno(r, "manager_new: %m");
return log_tests_skipped("cannot create manager");

View File

@ -343,8 +343,7 @@ TEST_RET(copy_holes) {
assert_se(fstat(fd, &stat) >= 0);
blksz = stat.st_blksize;
buf = alloca_safe(blksz);
memset(buf, 1, blksz);
buf = alloca0(blksz);
/* We need to make sure to create hole in multiples of the block size, otherwise filesystems (btrfs)
* might silently truncate/extend the holes. */

View File

@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new");
assert_se(r >= 0);

View File

@ -9,12 +9,7 @@
#include "tests.h"
#include "tmpfile-util.h"
/* In case of repeating keys, later entries win. */
#define env_file_1 \
"a=a\n" \
"a=b\n" \
"a=b\n" \
"a=a\n" \
"b=b\\\n" \
"c\n" \
@ -60,11 +55,18 @@
TEST(load_env_file_1) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_1) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
int r;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_1, strlen(env_file_1)) == strlen(env_file_1));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(streq(data[0], "a=a"));
assert_se(streq(data[1], "b=bc"));
assert_se(streq(data[2], "d=de f"));
@ -75,30 +77,50 @@ TEST(load_env_file_1) {
}
TEST(load_env_file_2) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_2) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
int r;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_2, strlen(env_file_2)) == strlen(env_file_2));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(streq(data[0], "a=a"));
assert_se(data[1] == NULL);
}
TEST(load_env_file_3) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_3) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
int r;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_3, strlen(env_file_3)) == strlen(env_file_3));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(data == NULL);
}
TEST(load_env_file_4) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_4) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
int r;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_4, strlen(env_file_4)) == strlen(env_file_4));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(streq(data[0], "HWMON_MODULES=coretemp f71882fg"));
assert_se(streq(data[1], "MODULE_0=coretemp"));
assert_se(streq(data[2], "MODULE_1=f71882fg"));
@ -106,22 +128,36 @@ TEST(load_env_file_4) {
}
TEST(load_env_file_5) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_5) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
int r;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_5, strlen(env_file_5)) == strlen(env_file_5));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(streq(data[0], "a="));
assert_se(streq(data[1], "b="));
assert_se(data[2] == NULL);
}
TEST(load_env_file_6) {
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
assert_se(write_tmpfile(name, env_file_6) == 0);
_cleanup_strv_free_ char **data = NULL;
assert_se(load_env_file(NULL, name, &data) == 0);
int r;
_cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
_cleanup_close_ int fd;
fd = mkostemp_safe(name);
assert_se(fd >= 0);
assert_se(write(fd, env_file_6, strlen(env_file_6)) == strlen(env_file_6));
r = load_env_file(NULL, name, &data);
assert_se(r == 0);
assert_se(streq(data[0], "a= n t x y '"));
assert_se(streq(data[1], "b=$'"));
assert_se(streq(data[2], "c= \\n\\t\\$\\`\\\\\n"));

View File

@ -1117,7 +1117,7 @@ typedef struct test_entry {
#define entry(x) {x, #x}
static int run_tests(LookupScope scope, const test_entry tests[], char **patterns) {
static int run_tests(UnitFileScope scope, const test_entry tests[], char **patterns) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
@ -1239,11 +1239,11 @@ int main(int argc, char *argv[]) {
assert_se(unsetenv("VAR2") == 0);
assert_se(unsetenv("VAR3") == 0);
r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
if (r != 0)
return r;
r = run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
r = run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
if (r != 0)
return r;
@ -1265,11 +1265,11 @@ int main(int argc, char *argv[]) {
can_unshare = false;
r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
if (r != 0)
return r;
return run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
return run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
#else
return 0;
#endif

View File

@ -109,7 +109,8 @@ TEST(parse_env_file) {
"eleven", &eleven,
"twelve", &twelve,
"thirteen", &thirteen);
assert_se(r == 0);
assert_se(r >= 0);
log_info("one=[%s]", strna(one));
log_info("two=[%s]", strna(two));

File diff suppressed because it is too large Load Diff

View File

@ -32,13 +32,13 @@ int main(int argc, char* argv[]) {
test_setup_logging(LOG_DEBUG);
h = hashmap_new(&string_hash_ops);
r = unit_file_get_list(LOOKUP_SCOPE_SYSTEM, NULL, h, NULL, NULL);
r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL);
assert_se(r == 0);
HASHMAP_FOREACH(p, h) {
UnitFileState s = _UNIT_FILE_STATE_INVALID;
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(p->path), &s);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(p->path), &s);
assert_se((r < 0 && p->state == UNIT_FILE_BAD) ||
(p->state == s));
@ -52,18 +52,18 @@ int main(int argc, char* argv[]) {
log_info("/*** enable **/");
r = unit_file_enable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** enable2 **/");
r = unit_file_enable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
@ -71,13 +71,13 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
@ -85,16 +85,16 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_mask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** mask2 ***/");
r = unit_file_mask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
@ -102,16 +102,16 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_unmask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** unmask2 ***/");
r = unit_file_unmask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
@ -119,13 +119,13 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_mask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_mask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
@ -133,16 +133,16 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
log_info("/*** disable2 ***/");
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_MASKED);
@ -150,13 +150,13 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_unmask(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
r = unit_file_unmask(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, files[0], &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, files[0], &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_DISABLED);
@ -164,13 +164,13 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_enable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
r = unit_file_enable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
@ -178,26 +178,26 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
log_info("/*** link files2 ***/");
changes = NULL;
n_changes = 0;
r = unit_file_link(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_LINKED);
@ -205,26 +205,26 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
log_info("/*** link files2 ***/");
changes = NULL;
n_changes = 0;
r = unit_file_link(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
r = unit_file_link(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_LINKED);
@ -232,13 +232,13 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_reenable(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
r = unit_file_reenable(UNIT_FILE_SYSTEM, 0, NULL, (char**) files2, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);
@ -246,25 +246,25 @@ int main(int argc, char* argv[]) {
changes = NULL;
n_changes = 0;
r = unit_file_disable(LOOKUP_SCOPE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
r = unit_file_disable(UNIT_FILE_SYSTEM, 0, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files2[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state);
assert_se(r < 0);
log_info("/*** preset files ***/");
changes = NULL;
n_changes = 0;
r = unit_file_preset(LOOKUP_SCOPE_SYSTEM, 0, NULL, (char**) files, UNIT_FILE_PRESET_FULL, &changes, &n_changes);
r = unit_file_preset(UNIT_FILE_SYSTEM, 0, NULL, (char**) files, UNIT_FILE_PRESET_FULL, &changes, &n_changes);
assert_se(r >= 0);
dump_changes(changes, n_changes);
unit_file_changes_free(changes, n_changes);
r = unit_file_get_state(LOOKUP_SCOPE_SYSTEM, NULL, basename(files[0]), &state);
r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files[0]), &state);
assert_se(r >= 0);
assert_se(state == UNIT_FILE_ENABLED);

View File

@ -42,7 +42,7 @@ TEST_RET(unit_file_get_set) {
h = hashmap_new(&string_hash_ops);
assert_se(h);
r = unit_file_get_list(LOOKUP_SCOPE_SYSTEM, NULL, h, NULL, NULL);
r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h, NULL, NULL);
if (IN_SET(r, -EPERM, -EACCES))
return log_tests_skipped_errno(r, "unit_file_get_list");
@ -101,7 +101,7 @@ TEST(config_parse_exec) {
_cleanup_(manager_freep) Manager *m = NULL;
_cleanup_(unit_freep) Unit *u = NULL;
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return;
@ -445,7 +445,7 @@ TEST(config_parse_log_extra_fields) {
_cleanup_(unit_freep) Unit *u = NULL;
ExecContext c = {};
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return;
@ -510,74 +510,59 @@ TEST(install_printf, .sd_booted = true) {
assert_se(user = uid_to_name(getuid()));
assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0);
#define expect(scope, src, pattern, result) \
#define expect(src, pattern, result) \
do { \
_cleanup_free_ char *t = NULL, \
*d1 = ASSERT_PTR(strdup(i.name)), \
*d2 = ASSERT_PTR(strdup(i.path)); \
int r = install_name_printf(scope, &src, pattern, &t); \
assert_se(result ? r >= 0 : r < 0); \
_cleanup_free_ char *t = NULL; \
_cleanup_free_ char \
*d1 = strdup(i.name), \
*d2 = strdup(i.path); \
assert_se(install_name_printf(&src, pattern, NULL, &t) >= 0 || !result); \
memzero(i.name, strlen(i.name)); \
memzero(i.path, strlen(i.path)); \
assert_se(d1 && d2); \
if (result) { \
printf("%s\n", t); \
assert_se(streq(t, result)); \
} else \
assert_se(!t); \
} else assert_se(t == NULL); \
strcpy(i.name, d1); \
strcpy(i.path, d2); \
} while (false)
expect(LOOKUP_SCOPE_SYSTEM, i, "%n", "name.service");
expect(LOOKUP_SCOPE_SYSTEM, i, "%N", "name");
expect(LOOKUP_SCOPE_SYSTEM, i, "%p", "name");
expect(LOOKUP_SCOPE_SYSTEM, i, "%i", "");
expect(LOOKUP_SCOPE_SYSTEM, i, "%j", "name");
expect(LOOKUP_SCOPE_SYSTEM, i, "%g", "root");
expect(LOOKUP_SCOPE_SYSTEM, i, "%G", "0");
expect(LOOKUP_SCOPE_SYSTEM, i, "%u", "root");
expect(LOOKUP_SCOPE_SYSTEM, i, "%U", "0");
expect(i, "%n", "name.service");
expect(i, "%N", "name");
expect(i, "%p", "name");
expect(i, "%i", "");
expect(i, "%j", "name");
expect(i, "%g", group);
expect(i, "%G", gid);
expect(i, "%u", user);
expect(i, "%U", uid);
expect(LOOKUP_SCOPE_SYSTEM, i, "%m", mid);
expect(LOOKUP_SCOPE_SYSTEM, i, "%b", bid);
expect(LOOKUP_SCOPE_SYSTEM, i, "%H", host);
expect(i, "%m", mid);
expect(i, "%b", bid);
expect(i, "%H", host);
expect(LOOKUP_SCOPE_SYSTEM, i2, "%g", "root");
expect(LOOKUP_SCOPE_SYSTEM, i2, "%G", "0");
expect(LOOKUP_SCOPE_SYSTEM, i2, "%u", "root");
expect(LOOKUP_SCOPE_SYSTEM, i2, "%U", "0");
expect(i2, "%g", group);
expect(i2, "%G", gid);
expect(i2, "%u", user);
expect(i2, "%U", uid);
expect(LOOKUP_SCOPE_USER, i2, "%g", group);
expect(LOOKUP_SCOPE_USER, i2, "%G", gid);
expect(LOOKUP_SCOPE_USER, i2, "%u", user);
expect(LOOKUP_SCOPE_USER, i2, "%U", uid);
expect(i3, "%n", "name@inst.service");
expect(i3, "%N", "name@inst");
expect(i3, "%p", "name");
expect(i3, "%g", group);
expect(i3, "%G", gid);
expect(i3, "%u", user);
expect(i3, "%U", uid);
/* gcc-12.0.1-0.9.fc36.x86_64 insist that streq(…, NULL) is called,
* even though the call is inside of a conditional where the pointer is checked. :( */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wnonnull"
expect(LOOKUP_SCOPE_GLOBAL, i2, "%g", NULL);
expect(LOOKUP_SCOPE_GLOBAL, i2, "%G", NULL);
expect(LOOKUP_SCOPE_GLOBAL, i2, "%u", NULL);
expect(LOOKUP_SCOPE_GLOBAL, i2, "%U", NULL);
#pragma GCC diagnostic pop
expect(i3, "%m", mid);
expect(i3, "%b", bid);
expect(i3, "%H", host);
expect(LOOKUP_SCOPE_SYSTEM, i3, "%n", "name@inst.service");
expect(LOOKUP_SCOPE_SYSTEM, i3, "%N", "name@inst");
expect(LOOKUP_SCOPE_SYSTEM, i3, "%p", "name");
expect(LOOKUP_SCOPE_USER, i3, "%g", group);
expect(LOOKUP_SCOPE_USER, i3, "%G", gid);
expect(LOOKUP_SCOPE_USER, i3, "%u", user);
expect(LOOKUP_SCOPE_USER, i3, "%U", uid);
expect(LOOKUP_SCOPE_SYSTEM, i3, "%m", mid);
expect(LOOKUP_SCOPE_SYSTEM, i3, "%b", bid);
expect(LOOKUP_SCOPE_SYSTEM, i3, "%H", host);
expect(LOOKUP_SCOPE_USER, i4, "%g", group);
expect(LOOKUP_SCOPE_USER, i4, "%G", gid);
expect(LOOKUP_SCOPE_USER, i4, "%u", user);
expect(LOOKUP_SCOPE_USER, i4, "%U", uid);
expect(i4, "%g", group);
expect(i4, "%G", gid);
expect(i4, "%u", user);
expect(i4, "%U", uid);
}
static uint64_t make_cap(int cap) {
@ -806,7 +791,7 @@ TEST(config_parse_unit_env_file) {
_cleanup_strv_free_ char **files = NULL;
int r;
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return;
@ -939,7 +924,7 @@ TEST(unit_is_recursive_template_dependency) {
Unit *u;
int r;
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return;

View File

@ -2,11 +2,8 @@
#include <errno.h>
#include "fs-util.h"
#include "log.h"
#include "os-util.h"
#include "string-util.h"
#include "strv.h"
#include "tests.h"
TEST(path_is_os_tree) {
@ -15,61 +12,4 @@ TEST(path_is_os_tree) {
assert_se(path_is_os_tree("/idontexist") == -ENOENT);
}
TEST(parse_os_release) {
/* Let's assume that we're running in a valid system, so os-release is available */
_cleanup_free_ char *id = NULL, *id2 = NULL, *name = NULL, *foobar = NULL;
assert_se(parse_os_release(NULL, "ID", &id) == 0);
log_info("ID: %s", id);
assert_se(setenv("SYSTEMD_OS_RELEASE", "/dev/null", 1) == 0);
assert_se(parse_os_release(NULL, "ID", &id2) == 0);
log_info("ID: %s", strnull(id2));
_cleanup_(unlink_tempfilep) char tmpfile[] = "/tmp/test-os-util.XXXXXX";
assert_se(write_tmpfile(tmpfile,
"ID=the-id \n"
"NAME=the-name") == 0);
assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1) == 0);
assert_se(parse_os_release(NULL, "ID", &id, "NAME", &name) == 0);
log_info("ID: %s NAME: %s", id, name);
assert_se(streq(id, "the-id"));
assert_se(streq(name, "the-name"));
_cleanup_(unlink_tempfilep) char tmpfile2[] = "/tmp/test-os-util.XXXXXX";
assert_se(write_tmpfile(tmpfile2,
"ID=\"ignored\" \n"
"ID=\"the-id\" \n"
"NAME='the-name'") == 0);
assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile2, 1) == 0);
assert_se(parse_os_release(NULL, "ID", &id, "NAME", &name) == 0);
log_info("ID: %s NAME: %s", id, name);
assert_se(streq(id, "the-id"));
assert_se(streq(name, "the-name"));
assert_se(parse_os_release(NULL, "FOOBAR", &foobar) == 0);
log_info("FOOBAR: %s", strnull(foobar));
assert_se(foobar == NULL);
assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);
}
TEST(load_os_release_pairs) {
_cleanup_(unlink_tempfilep) char tmpfile[] = "/tmp/test-os-util.XXXXXX";
assert_se(write_tmpfile(tmpfile,
"ID=\"ignored\" \n"
"ID=\"the-id\" \n"
"NAME='the-name'") == 0);
assert_se(setenv("SYSTEMD_OS_RELEASE", tmpfile, 1) == 0);
_cleanup_strv_free_ char **pairs = NULL;
assert_se(load_os_release_pairs(NULL, &pairs) == 0);
assert_se(strv_equal(pairs, STRV_MAKE("ID", "the-id",
"NAME", "the-name")));
assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -11,7 +11,7 @@
#include "tests.h"
#include "tmpfile-util.h"
static void test_paths_one(LookupScope scope) {
static void test_paths_one(UnitFileScope scope) {
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
_cleanup_(lookup_paths_free) LookupPaths lp_without_env = {};
_cleanup_(lookup_paths_free) LookupPaths lp_with_env = {};
@ -34,9 +34,9 @@ static void test_paths_one(LookupScope scope) {
}
TEST(paths) {
test_paths_one(LOOKUP_SCOPE_SYSTEM);
test_paths_one(LOOKUP_SCOPE_USER);
test_paths_one(LOOKUP_SCOPE_GLOBAL);
test_paths_one(UNIT_FILE_SYSTEM);
test_paths_one(UNIT_FILE_USER);
test_paths_one(UNIT_FILE_GLOBAL);
}
TEST(user_and_global_paths) {
@ -48,8 +48,8 @@ TEST(user_and_global_paths) {
assert_se(unsetenv("XDG_DATA_DIRS") == 0);
assert_se(unsetenv("XDG_CONFIG_DIRS") == 0);
assert_se(lookup_paths_init(&lp_global, LOOKUP_SCOPE_GLOBAL, 0, NULL) == 0);
assert_se(lookup_paths_init(&lp_user, LOOKUP_SCOPE_USER, 0, NULL) == 0);
assert_se(lookup_paths_init(&lp_global, UNIT_FILE_GLOBAL, 0, NULL) == 0);
assert_se(lookup_paths_init(&lp_user, UNIT_FILE_USER, 0, NULL) == 0);
g = lp_global.search_path;
u = lp_user.search_path;
@ -70,7 +70,7 @@ TEST(user_and_global_paths) {
log_info("+ %s", *p);
}
static void test_generator_binary_paths_one(LookupScope scope) {
static void test_generator_binary_paths_one(UnitFileScope scope) {
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
_cleanup_strv_free_ char **gp_without_env = NULL;
_cleanup_strv_free_ char **env_gp_without_env = NULL;
@ -85,13 +85,13 @@ static void test_generator_binary_paths_one(LookupScope scope) {
assert_se(unsetenv("SYSTEMD_ENVIRONMENT_GENERATOR_PATH") == 0);
gp_without_env = generator_binary_paths(scope);
env_gp_without_env = env_generator_binary_paths(scope == LOOKUP_SCOPE_SYSTEM ? true : false);
env_gp_without_env = env_generator_binary_paths(scope == UNIT_FILE_SYSTEM ? true : false);
log_info("Generators dirs (%s):", scope == LOOKUP_SCOPE_SYSTEM ? "system" : "user");
log_info("Generators dirs (%s):", scope == UNIT_FILE_SYSTEM ? "system" : "user");
STRV_FOREACH(dir, gp_without_env)
log_info(" %s", *dir);
log_info("Environment generators dirs (%s):", scope == LOOKUP_SCOPE_SYSTEM ? "system" : "user");
log_info("Environment generators dirs (%s):", scope == UNIT_FILE_SYSTEM ? "system" : "user");
STRV_FOREACH(dir, env_gp_without_env)
log_info(" %s", *dir);
@ -104,13 +104,13 @@ static void test_generator_binary_paths_one(LookupScope scope) {
assert_se(setenv("SYSTEMD_ENVIRONMENT_GENERATOR_PATH", systemd_env_generator_path, 1) == 0);
gp_with_env = generator_binary_paths(scope);
env_gp_with_env = env_generator_binary_paths(scope == LOOKUP_SCOPE_SYSTEM ? true : false);
env_gp_with_env = env_generator_binary_paths(scope == UNIT_FILE_SYSTEM ? true : false);
log_info("Generators dirs (%s):", scope == LOOKUP_SCOPE_SYSTEM ? "system" : "user");
log_info("Generators dirs (%s):", scope == UNIT_FILE_SYSTEM ? "system" : "user");
STRV_FOREACH(dir, gp_with_env)
log_info(" %s", *dir);
log_info("Environment generators dirs (%s):", scope == LOOKUP_SCOPE_SYSTEM ? "system" : "user");
log_info("Environment generators dirs (%s):", scope == UNIT_FILE_SYSTEM ? "system" : "user");
STRV_FOREACH(dir, env_gp_with_env)
log_info(" %s", *dir);
@ -119,8 +119,8 @@ static void test_generator_binary_paths_one(LookupScope scope) {
}
TEST(generator_binary_paths) {
test_generator_binary_paths_one(LOOKUP_SCOPE_SYSTEM);
test_generator_binary_paths_one(LOOKUP_SCOPE_USER);
test_generator_binary_paths_one(UNIT_FILE_SYSTEM);
test_generator_binary_paths_one(UNIT_FILE_USER);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -33,7 +33,7 @@ static int setup_test(Manager **m) {
if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available");
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &tmp);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &tmp);
if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new");
assert_se(r >= 0);

View File

@ -30,7 +30,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new");
assert_se(r >= 0);

View File

@ -135,7 +135,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("2000"), STRV_MAKE("any")) >= 0);

View File

@ -228,12 +228,17 @@ TEST(passfd_read) {
if (r == 0) {
/* Child */
char tmpfile[] = "/tmp/test-socket-util-passfd-read-XXXXXX";
_cleanup_close_ int tmpfd = -1;
pair[0] = safe_close(pair[0]);
char tmpfile[] = "/tmp/test-socket-util-passfd-read-XXXXXX";
assert_se(write_tmpfile(tmpfile, file_contents) == 0);
tmpfd = mkostemp_safe(tmpfile);
assert_se(tmpfd >= 0);
assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents));
tmpfd = safe_close(tmpfd);
_cleanup_close_ int tmpfd = open(tmpfile, O_RDONLY);
tmpfd = open(tmpfile, O_RDONLY);
assert_se(tmpfd >= 0);
assert_se(unlink(tmpfile) == 0);
@ -272,12 +277,16 @@ TEST(passfd_contents_read) {
/* Child */
struct iovec iov = IOVEC_INIT_STRING(wire_contents);
char tmpfile[] = "/tmp/test-socket-util-passfd-contents-read-XXXXXX";
_cleanup_close_ int tmpfd = -1;
pair[0] = safe_close(pair[0]);
assert_se(write_tmpfile(tmpfile, file_contents) == 0);
tmpfd = mkostemp_safe(tmpfile);
assert_se(tmpfd >= 0);
assert_se(write(tmpfd, file_contents, strlen(file_contents)) == (ssize_t) strlen(file_contents));
tmpfd = safe_close(tmpfd);
_cleanup_close_ int tmpfd = open(tmpfile, O_RDONLY);
tmpfd = open(tmpfile, O_RDONLY);
assert_se(tmpfd >= 0);
assert_se(unlink(tmpfile) == 0);

View File

@ -8,7 +8,6 @@
#include "string-util.h"
#include "strv.h"
#include "tests.h"
#include "unit-file.h"
static void test_specifier_escape_one(const char *a, const char *b) {
_cleanup_free_ char *x = NULL;
@ -47,7 +46,7 @@ TEST(specifier_escape_strv) {
static const Specifier specifier_table[] = {
COMMON_SYSTEM_SPECIFIERS,
COMMON_CREDS_SPECIFIERS(LOOKUP_SCOPE_USER),
COMMON_CREDS_SPECIFIERS,
{ 'h', specifier_user_home, NULL },
COMMON_TMP_SPECIFIERS,
@ -139,18 +138,4 @@ TEST(specifiers) {
}
}
TEST(specifiers_missing_data_ok) {
_cleanup_free_ char *resolved = NULL;
assert_se(setenv("SYSTEMD_OS_RELEASE", "/dev/null", 1) == 0);
assert_se(specifier_printf("%A-%B-%M-%o-%w-%W", SIZE_MAX, specifier_table, NULL, NULL, &resolved) >= 0);
assert_se(streq(resolved, "-----"));
assert_se(setenv("SYSTEMD_OS_RELEASE", "/nosuchfileordirectory", 1) == 0);
assert_se(specifier_printf("%A-%B-%M-%o-%w-%W", SIZE_MAX, specifier_table, NULL, NULL, &resolved) == -EUNATCH);
assert_se(streq(resolved, "-----"));
assert_se(unsetenv("SYSTEMD_OS_RELEASE") == 0);
}
DEFINE_TEST_MAIN(LOG_DEBUG);

View File

@ -18,30 +18,6 @@
#include "tests.h"
#include "tmpfile-util.h"
TEST(null_or_empty_path) {
assert_se(null_or_empty_path("/dev/null") == 1);
assert_se(null_or_empty_path("/dev/tty") == 1); /* We assume that any character device is "empty", bleh. */
assert_se(null_or_empty_path("../../../../../../../../../../../../../../../../../../../../dev/null") == 1);
assert_se(null_or_empty_path("/proc/self/exe") == 0);
assert_se(null_or_empty_path("/nosuchfileordir") == -ENOENT);
}
TEST(null_or_empty_path_with_root) {
assert_se(null_or_empty_path_with_root("/dev/null", NULL) == 1);
assert_se(null_or_empty_path_with_root("/dev/null", "/") == 1);
assert_se(null_or_empty_path_with_root("/dev/null", "/.././../") == 1);
assert_se(null_or_empty_path_with_root("/dev/null", "/.././..") == 1);
assert_se(null_or_empty_path_with_root("../../../../../../../../../../../../../../../../../../../../dev/null", NULL) == 1);
assert_se(null_or_empty_path_with_root("../../../../../../../../../../../../../../../../../../../../dev/null", "/") == 1);
assert_se(null_or_empty_path_with_root("/proc/self/exe", NULL) == 0);
assert_se(null_or_empty_path_with_root("/proc/self/exe", "/") == 0);
assert_se(null_or_empty_path_with_root("/nosuchfileordir", NULL) == -ENOENT);
assert_se(null_or_empty_path_with_root("/nosuchfileordir", "/.././../") == -ENOENT);
assert_se(null_or_empty_path_with_root("/nosuchfileordir", "/.././..") == -ENOENT);
assert_se(null_or_empty_path_with_root("/foobar/barbar/dev/null", "/foobar/barbar") == 1);
assert_se(null_or_empty_path_with_root("/foobar/barbar/dev/null", "/foobar/barbar/") == 1);
}
TEST(files_same) {
_cleanup_close_ int fd = -1;
char name[] = "/tmp/test-files_same.XXXXXX";

View File

@ -8,20 +8,20 @@
#include "unit-file.h"
TEST(unit_validate_alias_symlink_and_warn) {
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a.service", "/other/b.service") == 0);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a.service", "/other/b.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a.service", "/other/b.foobar") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@.service", "/other/b@.service") == 0);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@.service", "/other/b@.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@XXX.service", "/other/b@YYY.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@XXX.service", "/other/b@YYY.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@.service", "/other/b@YYY.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@XXX.service", "/other/b@XXX.service") == 0);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@XXX.service", "/other/b@.service") == 0);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@.service", "/other/b.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a.service", "/other/b@.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a@.slice", "/other/b.slice") == -EINVAL);
assert_se(unit_validate_alias_symlink_or_warn(LOG_INFO, "/path/a.slice", "/other/b.slice") == -EINVAL);
assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.service") == 0);
assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.foobar") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@.service") == 0);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@YYY.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@YYY.socket") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@YYY.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@XXX.service") == 0);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@.service") == 0);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b@.service") == -EXDEV);
assert_se(unit_validate_alias_symlink_and_warn("/path/a@.slice", "/other/b.slice") == -EINVAL);
assert_se(unit_validate_alias_symlink_and_warn("/path/a.slice", "/other/b.slice") == -EINVAL);
}
TEST(unit_file_build_name_map) {
@ -35,7 +35,7 @@ TEST(unit_file_build_name_map) {
ids = strv_skip(saved_argv, 1);
assert_se(lookup_paths_init(&lp, LOOKUP_SCOPE_SYSTEM, 0, NULL) >= 0);
assert_se(lookup_paths_init(&lp, UNIT_FILE_SYSTEM, 0, NULL) >= 0);
assert_se(unit_file_build_name_map(&lp, &mtime, &unit_ids, &unit_names, NULL) == 1);

View File

@ -228,7 +228,7 @@ TEST_RET(unit_printf, .sd_booted = true) {
assert_se(get_home_dir(&home) >= 0);
assert_se(get_shell(&shell) >= 0);
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new");
assert_se(r == 0);

View File

@ -31,7 +31,7 @@ TEST(deserialize_exec_command) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
r = manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return;

View File

@ -26,7 +26,7 @@ int main(int argc, char *argv[]) {
assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(manager_new(LOOKUP_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);
assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
assert_se(a = unit_new(m, sizeof(Service)));

View File

@ -204,6 +204,31 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret);
static int specifier_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret);
static const Specifier specifier_table[] = {
{ 'a', specifier_architecture, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'l', specifier_short_host_name, NULL },
{ 'm', specifier_machine_id_safe, NULL },
{ 'o', specifier_os_id, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{ 'h', specifier_user_home, NULL },
{ 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
{ 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
{ 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
{ 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
COMMON_CREDS_SPECIFIERS,
COMMON_TMP_SPECIFIERS,
{}
};
static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
int r;
@ -2712,7 +2737,7 @@ static bool should_include_path(const char *path) {
return false;
}
static int specifier_expansion_from_arg(const Specifier *specifier_table, Item *i) {
static int specifier_expansion_from_arg(Item *i) {
int r;
assert(i);
@ -2919,30 +2944,6 @@ static int parse_line(
assert(line >= 1);
assert(buffer);
const Specifier specifier_table[] = {
{ 'a', specifier_architecture, NULL },
{ 'b', specifier_boot_id, NULL },
{ 'B', specifier_os_build_id, NULL },
{ 'H', specifier_host_name, NULL },
{ 'l', specifier_short_host_name, NULL },
{ 'm', specifier_machine_id_safe, NULL },
{ 'o', specifier_os_id, NULL },
{ 'v', specifier_kernel_release, NULL },
{ 'w', specifier_os_version_id, NULL },
{ 'W', specifier_os_variant_id, NULL },
{ 'h', specifier_user_home, NULL },
{ 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
{ 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
{ 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
{ 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
COMMON_CREDS_SPECIFIERS(arg_user ? LOOKUP_SCOPE_USER : LOOKUP_SCOPE_SYSTEM),
COMMON_TMP_SPECIFIERS,
{}
};
r = extract_many_words(
&buffer,
NULL,
@ -3147,7 +3148,7 @@ static int parse_line(
if (!should_include_path(i.path))
return 0;
r = specifier_expansion_from_arg(specifier_table, &i);
r = specifier_expansion_from_arg(&i);
if (r == -ENXIO)
return log_unresolvable_specifier(fname, line);
if (r < 0) {

View File

@ -35,7 +35,6 @@
#include "device-monitor-private.h"
#include "device-private.h"
#include "device-util.h"
#include "errno-list.h"
#include "event-util.h"
#include "fd-util.h"
#include "fileio.h"
@ -158,15 +157,11 @@ typedef struct Worker {
/* passed from worker to main process */
typedef enum EventResult {
EVENT_RESULT_NERRNO_MIN = -ERRNO_MAX,
EVENT_RESULT_NERRNO_MAX = -1,
EVENT_RESULT_EXIT_STATUS_BASE = 0,
EVENT_RESULT_EXIT_STATUS_MAX = 255,
EVENT_RESULT_TRY_AGAIN = 256, /* when the block device is locked by another process. */
EVENT_RESULT_SIGNAL_BASE = 257,
EVENT_RESULT_SIGNAL_MAX = EVENT_RESULT_SIGNAL_BASE + _NSIG,
EVENT_RESULT_SUCCESS,
EVENT_RESULT_FAILED,
EVENT_RESULT_TRY_AGAIN, /* when the block device is locked by another process. */
_EVENT_RESULT_MAX,
_EVENT_RESULT_INVALID = -EINVAL,
_EVENT_RESULT_INVALID = -EINVAL,
} EventResult;
static Event *event_free(Event *event) {
@ -361,7 +356,7 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda
return 1;
}
static void device_broadcast(sd_device_monitor *monitor, sd_device *dev, int result) {
static void device_broadcast(sd_device_monitor *monitor, sd_device *dev) {
int r;
assert(dev);
@ -370,40 +365,13 @@ static void device_broadcast(sd_device_monitor *monitor, sd_device *dev, int res
if (!monitor)
return;
if (result != 0) {
(void) device_add_property(dev, "UDEV_WORKER_FAILED", "1");
switch (result) {
case EVENT_RESULT_NERRNO_MIN ... EVENT_RESULT_NERRNO_MAX:
(void) device_add_propertyf(dev, "UDEV_WORKER_ERRNO", "%i", -result);
(void) device_add_propertyf(dev, "UDEV_WORKER_ERRNO_NAME", "%s", strna(errno_to_name(result)));
break;
case EVENT_RESULT_EXIT_STATUS_BASE ... EVENT_RESULT_EXIT_STATUS_MAX:
(void) device_add_propertyf(dev, "UDEV_WORKER_EXIT_STATUS", "%i", result - EVENT_RESULT_EXIT_STATUS_BASE);
break;
case EVENT_RESULT_TRY_AGAIN:
assert_not_reached();
break;
case EVENT_RESULT_SIGNAL_BASE ... EVENT_RESULT_SIGNAL_MAX:
(void) device_add_propertyf(dev, "UDEV_WORKER_SIGNAL", "%i", result - EVENT_RESULT_SIGNAL_BASE);
(void) device_add_propertyf(dev, "UDEV_WORKER_SIGNAL_NAME", "%s", strna(signal_to_string(result - EVENT_RESULT_SIGNAL_BASE)));
break;
default:
log_device_warning(dev, "Unknown event result \"%i\", ignoring.", result);
}
}
r = device_monitor_send_device(monitor, NULL, dev);
if (r < 0)
log_device_warning_errno(dev, r,
"Failed to broadcast event to libudev listeners, ignoring: %m");
}
static int worker_send_result(Manager *manager, int result) {
static int worker_send_result(Manager *manager, EventResult result) {
assert(manager);
assert(manager->worker_watch[WRITE_END] >= 0);
@ -568,8 +536,6 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
*
* The user-facing side of this: https://systemd.io/BLOCK_DEVICE_LOCKING */
r = worker_lock_block_device(dev, &fd_lock);
if (r == -EAGAIN)
return EVENT_RESULT_TRY_AGAIN;
if (r < 0)
return r;
@ -602,25 +568,29 @@ static int worker_process_device(Manager *manager, sd_device *dev) {
static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *dev, void *userdata) {
Manager *manager = userdata;
EventResult result;
int r;
assert(dev);
assert(manager);
r = worker_process_device(manager, dev);
if (r == EVENT_RESULT_TRY_AGAIN)
if (r == -EAGAIN) {
/* if we couldn't acquire the flock(), then requeue the event */
log_device_debug(dev, "Block device is currently locked, requeueing the event.");
else {
if (r < 0)
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
result = EVENT_RESULT_TRY_AGAIN;
log_device_debug_errno(dev, r, "Block device is currently locked, requeueing the event.");
} else if (r < 0) {
result = EVENT_RESULT_FAILED;
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
} else
result = EVENT_RESULT_SUCCESS;
if (result != EVENT_RESULT_TRY_AGAIN)
/* send processed event back to libudev listeners */
device_broadcast(monitor, dev, r);
}
device_broadcast(monitor, dev);
/* send udevd the result of the event execution */
r = worker_send_result(manager, r);
r = worker_send_result(manager, result);
if (r < 0)
log_device_warning_errno(dev, r, "Failed to send signal to main daemon, ignoring: %m");
@ -1180,7 +1150,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
assert(manager);
for (;;) {
int result;
EventResult result;
struct iovec iovec = IOVEC_MAKE(&result, sizeof(result));
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
struct msghdr msghdr = {
@ -1204,7 +1174,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
cmsg_close_all(&msghdr);
if (size != sizeof(result)) {
if (size != sizeof(EventResult)) {
log_warning("Ignoring worker message with invalid size %zi bytes", size);
continue;
}
@ -1231,7 +1201,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
/* worker returned */
if (result == EVENT_RESULT_TRY_AGAIN &&
event_requeue(worker->event) < 0)
device_broadcast(manager->monitor, worker->event->dev, -ETIMEDOUT);
device_broadcast(manager->monitor, worker->event->dev);
/* When event_requeue() succeeds, worker->event is NULL, and event_free() handles NULL gracefully. */
event_free(worker->event);
@ -1573,9 +1543,7 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
device_tag_index(worker->event->dev, NULL, false);
/* Forward kernel event to libudev listeners */
device_broadcast(manager->monitor, worker->event->dev,
WIFEXITED(status) ? EVENT_RESULT_EXIT_STATUS_BASE + WEXITSTATUS(status):
WIFSIGNALED(status) ? EVENT_RESULT_SIGNAL_BASE + WTERMSIG(status) : 0);
device_broadcast(manager->monitor, worker->event->dev);
}
worker_free(worker);

View File

@ -88,7 +88,6 @@ endif
test_fstab_generator_sh = find_program('test-fstab-generator.sh')
test_network_generator_conversion_sh = find_program('test-network-generator-conversion.sh')
test_systemctl_enable_sh = find_program('test-systemctl-enable.sh')
test_systemd_tmpfiles_py = find_program('test-systemd-tmpfiles.py')
hwdb_test_sh = find_program('hwdb-test.sh')

View File

@ -1,694 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -ex
# Silence warning from running_in_chroot_or_offline()
export SYSTEMD_IGNORE_CHROOT=1
systemctl=${1:-systemctl}
systemd_id128=${2:-systemd-id128}
unset root
cleanup() {
[ -n "$root" ] && rm -rf "$root"
}
trap cleanup exit
root=$(mktemp -d --tmpdir systemctl-test.XXXXXX)
islink() {
test -h "$1" || return 1
test "$(readlink "$1")" = "$2" || return 2
}
: '------enable nonexistent------------------------------------'
( ! "$systemctl" --root="$root" enable test1.service )
: '------basic enablement--------------------------------------'
mkdir -p "$root/etc/systemd/system"
cat >"$root/etc/systemd/system/test1.service" <<EOF
[Install]
WantedBy=default.target
RequiredBy=special.target
EOF
"$systemctl" --root="$root" enable test1.service
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" reenable test1.service
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" disable test1.service
test ! -h "$root/etc/systemd/system/default.target.wants/test1.service"
test ! -h "$root/etc/systemd/system/special.target.requires/test1.service"
: '------enable when link already exists-----------------------'
# We don't read the symlink target, so it's OK for the symlink to point
# to something else. We should just silently accept this.
mkdir -p "$root/etc/systemd/system/default.target.wants"
mkdir -p "$root/etc/systemd/system/special.target.requires"
ln -s /usr/lib/systemd/system/test1.service "$root/etc/systemd/system/default.target.wants/test1.service"
ln -s /usr/lib/systemd/system/test1.service "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" enable test1.service
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" reenable test1.service
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" disable test1.service
test ! -h "$root/etc/systemd/system/default.target.wants/test1.service"
test ! -h "$root/etc/systemd/system/special.target.requires/test1.service"
: '------suffix guessing---------------------------------------'
"$systemctl" --root="$root" enable test1
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" reenable test1
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
"$systemctl" --root="$root" disable test1
test ! -e "$root/etc/systemd/system/default.target.wants/test1.service"
test ! -e "$root/etc/systemd/system/special.target.requires/test1.service"
: '-------aliases----------------------------------------------'
cat >>"$root/etc/systemd/system/test1.service" <<EOF
Alias=test1-goodalias.service
Alias=test1@badalias.service
Alias=test1-badalias.target
Alias=test1-badalias.socket
# we have a series of good, bad, and then good again
Alias=test1-goodalias2.service
EOF
( ! "$systemctl" --root="$root" enable test1 )
test -h "$root/etc/systemd/system/default.target.wants/test1.service"
test -h "$root/etc/systemd/system/special.target.requires/test1.service"
test -e "$root/etc/systemd/system/test1-goodalias.service"
test -h "$root/etc/systemd/system/test1-goodalias.service"
test ! -h "$root/etc/systemd/system/test1@badalias.service"
test ! -h "$root/etc/systemd/system/test1-badalias.target"
test ! -h "$root/etc/systemd/system/test1-badalias.socket"
test -e "$root/etc/systemd/system/test1-goodalias2.service"
test -h "$root/etc/systemd/system/test1-goodalias2.service"
: '-------aliases in reeanble----------------------------------'
( ! "$systemctl" --root="$root" reenable test1 )
islink "$root/etc/systemd/system/default.target.wants/test1.service" "../test1.service"
islink "$root/etc/systemd/system/test1-goodalias.service" "test1.service"
test ! -h "$root/etc/systemd/system/test1@badalias.service"
test ! -h "$root/etc/systemd/system/test1-badalias.target"
test ! -h "$root/etc/systemd/system/test1-badalias.socket"
"$systemctl" --root="$root" disable test1
test ! -h "$root/etc/systemd/system/default.target.wants/test1.service"
test ! -h "$root/etc/systemd/system/special.target.requires/test1.service"
test ! -h "$root/etc/systemd/system/test1-goodalias.service"
: '-------aliases when link already exists---------------------'
cat >"$root/etc/systemd/system/test1a.service" <<EOF
[Install]
Alias=test1a-alias.service
EOF
ln -s /usr/lib/systemd/system/test1a.service "$root/etc/systemd/system/test1a-alias.service"
"$systemctl" --root="$root" enable test1a.service
test -h "$root/etc/systemd/system/test1a-alias.service"
"$systemctl" --root="$root" disable test1a.service
test ! -h "$root/etc/systemd/system/test1a-alias.service"
: '-------also units-------------------------------------------'
cat >"$root/etc/systemd/system/test2.socket" <<EOF
[Install]
WantedBy=sockets.target
Also=test2.service
EOF
cat >"$root/etc/systemd/system/test2.service" <<EOF
[Install]
WantedBy=default.target
Also=test2.socket
EOF
"$systemctl" --root="$root" reenable test2.service
test -h "$root/etc/systemd/system/default.target.wants/test2.service"
test -h "$root/etc/systemd/system/sockets.target.wants/test2.socket"
"$systemctl" --root="$root" reenable test2.socket
test -h "$root/etc/systemd/system/default.target.wants/test2.service"
test -h "$root/etc/systemd/system/sockets.target.wants/test2.socket"
"$systemctl" --root="$root" disable test2.socket
test ! -e "$root/etc/systemd/system/default.target.wants/test2.service"
test ! -e "$root/etc/systemd/system/sockets.target.wants/test2.socket"
: '-------link-------------------------------------------------'
# File doesn't exist yet
test ! -e "$root/link1.path"
( ! "$systemctl" --root="$root" link '/link1.path' )
test ! -e "$root/etc/systemd/system/link1.path"
cat >"$root/link1.path" <<EOF
[Install]
WantedBy=paths.target
EOF
"$systemctl" --root="$root" link '/link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
: '-------link already linked same path------------------------'
SYSTEMD_LOG_LEVEL=debug "$systemctl" --root="$root" link '/link1.path' # this passes
islink "$root/etc/systemd/system/link1.path" "/link1.path"
: '-------link already linked different path-------------------'
mkdir "$root/subdir"
cp "$root/link1.path" "$root/subdir/"
( ! "$systemctl" --root="$root" link '/subdir/link1.path' )
islink "$root/etc/systemd/system/link1.path" "/link1.path"
: '-------link bad suffix--------------------------------------'
cp "$root/link1.path" "$root/subdir/link1.suffix"
( ! "$systemctl" --root="$root" link '/subdir/link1.suffix' )
test ! -e "$root/etc/systemd/system/link1.suffix"
: '-------unlink by unit name----------------------------------'
"$systemctl" --root="$root" disable 'link1.path'
test ! -e "$root/etc/systemd/system/link1.path"
: '-------unlink by path---------------------------------------'
"$systemctl" --root="$root" link '/link1.path'
test -h "$root/etc/systemd/system/link1.path"
"$systemctl" --root="$root" disable '/link1.path'
test ! -e "$root/etc/systemd/system/link1.path"
: '-------unlink by wrong path---------------------------------'
"$systemctl" --root="$root" link '/link1.path'
test -h "$root/etc/systemd/system/link1.path"
"$systemctl" --root="$root" disable '/subdir/link1.path' # we only care about the name
test ! -e "$root/etc/systemd/system/link1.path"
: '-------link and enable--------------------------------------'
"$systemctl" --root="$root" enable '/link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
islink "$root/etc/systemd/system/paths.target.wants/link1.path" "../link1.path"
: '-------enable already linked same path----------------------'
"$systemctl" --root="$root" enable '/link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
islink "$root/etc/systemd/system/paths.target.wants/link1.path" "../link1.path"
: '-------enable already linked different path-----------------'
( ! "$systemctl" --root="$root" enable '/subdir/link1.path' )
islink "$root/etc/systemd/system/link1.path" "/link1.path"
islink "$root/etc/systemd/system/paths.target.wants/link1.path" "../link1.path"
: '-------enable bad suffix------------------------------------'
cp "$root/link1.path" "$root/subdir/link1.suffix"
( ! "$systemctl" --root="$root" enable '/subdir/link1.suffix' )
test ! -e "$root/etc/systemd/system/link1.suffix"
test ! -e "$root/etc/systemd/system/paths.target.wants/link1.suffix"
: '-------disable by unit name---------------------------------'
"$systemctl" --root="$root" disable 'link1.path'
test ! -e "$root/etc/systemd/system/link1.path"
test ! -e "$root/etc/systemd/system/paths.target.wants/link1.path"
: '-------disable by path--------------------------------------'
"$systemctl" --root="$root" enable '/link1.path'
test -h "$root/etc/systemd/system/link1.path"
test -h "$root/etc/systemd/system/paths.target.wants/link1.path"
"$systemctl" --root="$root" disable '/link1.path'
test ! -e "$root/etc/systemd/system/link1.path"
test ! -e "$root/etc/systemd/system/paths.target.wants/link1.path"
: '-------link and enable-------------------------------------'
"$systemctl" --root="$root" link '/link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
test ! -h "$root/etc/systemd/system/paths.target.wants/link1.path"
"$systemctl" --root="$root" enable 'link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
islink "$root/etc/systemd/system/paths.target.wants/link1.path" "../link1.path"
"$systemctl" --root="$root" reenable 'link1.path'
islink "$root/etc/systemd/system/link1.path" "/link1.path"
islink "$root/etc/systemd/system/paths.target.wants/link1.path" "../link1.path"
: '-------manual link------------------------------------------'
cat >"$root/link3.suffix" <<EOF
[Install]
WantedBy=services.target
EOF
# We wouldn't create such a link ourselves, but it should accept it when present.
ln -s "/link3.suffix" "$root/etc/systemd/system/link3.service"
SYSTEMD_LOG_LEVEL=debug SYSTEMD_LOG_LOCATION=1 "$systemctl" --root="$root" enable 'link3.service'
islink "$root/etc/systemd/system/link3.service" "/link3.suffix"
islink "$root/etc/systemd/system/services.target.wants/link3.service" "../link3.service"
SYSTEMD_LOG_LEVEL=debug SYSTEMD_LOG_LOCATION=1 "$systemctl" --root="$root" disable 'link3.service'
test ! -h "$root/etc/systemd/system/link3.service"
test ! -h "$root/etc/systemd/system/services.target.wants/link3.service"
: '-------enable on masked-------------------------------------'
ln -s "/dev/null" "$root/etc/systemd/system/masked.service"
( ! "$systemctl" --root="$root" enable 'masked.service' )
( ! "$systemctl" --root="$root" enable '/etc/systemd/system/masked.service' )
: '-------enable on masked alias-------------------------------'
test -h "$root/etc/systemd/system/masked.service"
ln -s "masked.service" "$root/etc/systemd/system/masked-alias.service"
( ! "$systemctl" --root="$root" enable 'masked-alias.service' )
( ! "$systemctl" --root="$root" enable '/etc/systemd/system/masked-alias.service' )
: '-------issue 22000: link in subdirectory--------------------'
mkdir -p "$root/etc/systemd/system/myown.d"
cat >"$root/etc/systemd/system/link5-also.service" <<EOF
[Install]
WantedBy=services.target
Also=link5.service
EOF
cat >"$root/etc/systemd/system/myown.d/link5.service" <<EOF
[Install]
WantedBy=services.target
Also=link5-also.service
EOF
( ! "$systemctl" --root="$root" enable 'link5.service' )
test ! -h "$root/etc/systemd/system/services.target.wants/link5.service"
test ! -h "$root/etc/systemd/system/services.target.wants/link5-also.service"
"$systemctl" --root="$root" enable 'link5-also.service'
test ! -h "$root/etc/systemd/system/services.target.wants/link5.service"
islink "$root/etc/systemd/system/services.target.wants/link5-also.service" "../link5-also.service"
: '-------template enablement----------------------------------'
cat >"$root/etc/systemd/system/templ1@.service" <<EOF
[Install]
WantedBy=services.target
EOF
# No instance here — this can't succeed.
( ! "$systemctl" --root="$root" enable 'templ1@.service' )
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
"$systemctl" --root="$root" enable 'templ1@one.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "../templ1@one.service"
"$systemctl" --root="$root" enable 'templ1@two.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "../templ1@one.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "../templ1@two.service"
"$systemctl" --root="$root" disable 'templ1@one.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "../templ1@two.service"
"$systemctl" --root="$root" disable 'templ1@two.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
: '-------template enablement w/ default instance--------------'
cat >"$root/etc/systemd/system/templ1@.service" <<EOF
[Install]
# check enablement with
WantedBy=services.target services.target
RequiredBy=other@templ1.target other@%p.target
DefaultInstance=333
EOF
"$systemctl" --root="$root" enable 'templ1@.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@333.service" "../templ1@.service"
"$systemctl" --root="$root" enable 'templ1@one.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "../templ1@one.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@one.service" "../templ1@one.service"
"$systemctl" --root="$root" enable 'templ1@two.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@one.service" "../templ1@one.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@one.service" "../templ1@one.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "../templ1@two.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@two.service" "../templ1@two.service"
"$systemctl" --root="$root" disable 'templ1@one.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@333.service" "../templ1@.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@333.service" "../templ1@.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@one.service"
islink "$root/etc/systemd/system/services.target.wants/templ1@two.service" "../templ1@two.service"
islink "$root/etc/systemd/system/other@templ1.target.requires/templ1@two.service" "../templ1@two.service"
# disable remaining links here
"$systemctl" --root="$root" disable 'templ1@.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@333.service"
test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@333.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@one.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@two.service"
: '-------removal of relative enablement symlinks--------------'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
ln -s '../templ1@one.service' "$root/etc/systemd/system/services.target.wants/templ1@one.service"
ln -s 'templ1@two.service' "$root/etc/systemd/system/services.target.wants/templ1@two.service"
ln -s '../templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@three.service"
ln -s 'templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@four.service"
ln -s '/usr/lib/systemd/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@five.service"
ln -s '/etc/systemd/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@six.service"
ln -s '/run/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@seven.service"
# this should remove all links
"$systemctl" --root="$root" disable 'templ1@.service'
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@three.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@four.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@five.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@six.service"
test ! -h "$root/etc/systemd/system/services.target.wants/templ1@seven.service"
: '-------template enablement for another template-------------'
cat >"$root/etc/systemd/system/templ2@.service" <<EOF
[Install]
RequiredBy=another-template@.target
EOF
"$systemctl" --root="$root" enable 'templ2@.service'
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "../templ2@.service"
"$systemctl" --root="$root" enable 'templ2@two.service'
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "../templ2@.service"
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service" "../templ2@two.service"
"$systemctl" --root="$root" disable 'templ2@other.service'
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "../templ2@.service"
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service" "../templ2@two.service"
"$systemctl" --root="$root" disable 'templ2@two.service'
islink "$root/etc/systemd/system/another-template@.target.requires/templ2@.service" "../templ2@.service"
test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service"
"$systemctl" --root="$root" disable 'templ2@.service'
test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@.service"
test ! -h "$root/etc/systemd/system/another-template@.target.requires/templ2@two.service"
: '-------aliases w/ and w/o instance--------------------------'
test ! -e "$root/etc/systemd/system/link4.service"
cat >"$root/etc/systemd/system/link4.service" <<EOF
[Install]
Alias=link4.service
Alias=link4@.service
Alias=link4@inst.service
Alias=link4alias.service
Alias=link4alias2.service
EOF
( ! "$systemctl" --root="$root" enable 'link4.service' )
test ! -h "$root/etc/systemd/system/link4.service" # this is our file
test ! -h "$root/etc/systemd/system/link4@.service"
test ! -h "$root/etc/systemd/system/link4@inst.service"
islink "$root/etc/systemd/system/link4alias.service" "link4.service"
islink "$root/etc/systemd/system/link4alias2.service" "link4.service"
"$systemctl" --root="$root" disable 'link4.service'
test ! -h "$root/etc/systemd/system/link4.service"
test ! -h "$root/etc/systemd/system/link4@.service"
test ! -h "$root/etc/systemd/system/link4@inst.service"
test ! -h "$root/etc/systemd/system/link4alias.service"
test ! -h "$root/etc/systemd/system/link4alias2.service"
: '-------systemctl enable on path to unit file----------------'
cat >"$root/etc/systemd/system/link4.service" <<EOF
[Install]
Alias=link4alias.service
Alias=link4alias2.service
EOF
# Apparently this works. I'm not sure what to think.
"$systemctl" --root="$root" enable '/etc/systemd/system/link4.service'
test ! -h "$root/etc/systemd/system/link4.service" # this is our file
islink "$root/etc/systemd/system/link4alias.service" "link4.service"
islink "$root/etc/systemd/system/link4alias2.service" "link4.service"
"$systemctl" --root="$root" disable '/etc/systemd/system/link4.service'
test ! -h "$root/etc/systemd/system/link4.service"
test ! -h "$root/etc/systemd/system/link4alias.service"
test ! -h "$root/etc/systemd/system/link4alias2.service"
: '-------issue 661: enable on unit file--------------'
test ! -e "$root/etc/systemd/system/link5.service"
cat >"$root/etc/systemd/system/link5.service" <<EOF
[Install]
Alias=link5.service
Alias=link5alias.service
Alias=link5alias2.service
EOF
"$systemctl" --root="$root" enable 'link5.service'
test ! -h "$root/etc/systemd/system/link5.service" # this is our file
islink "$root/etc/systemd/system/link5alias.service" "link5.service"
islink "$root/etc/systemd/system/link5alias2.service" "link5.service"
"$systemctl" --root="$root" disable 'link5.service'
test ! -h "$root/etc/systemd/system/link5alias.service"
test ! -h "$root/etc/systemd/system/link5alias2.service"
: '-------issue 661: link and enable on unit file--------------'
test ! -e "$root/etc/systemd/system/link5copy.service"
cat >"$root/link5copy.service" <<EOF
[Install]
Alias=link5copy.service
Alias=link5alias.service
Alias=link5alias2.service
EOF
test ! -e "$root/etc/systemd/system/link5copy.service"
"$systemctl" --root="$root" link '/link5copy.service'
islink "$root/etc/systemd/system/link5copy.service" '/link5copy.service'
test ! -h "$root/etc/systemd/system/link5alias.service"
test ! -h "$root/etc/systemd/system/link5alias2.service"
"$systemctl" --root="$root" disable 'link5copy.service'
test ! -h "$root/etc/systemd/system/link5copy.service"
test ! -h "$root/etc/systemd/system/link5alias.service"
test ! -h "$root/etc/systemd/system/link5alias2.service"
"$systemctl" --root="$root" enable '/link5copy.service'
islink "$root/etc/systemd/system/link5copy.service" '/link5copy.service'
islink "$root/etc/systemd/system/link5alias.service" 'link5copy.service'
islink "$root/etc/systemd/system/link5alias2.service" 'link5copy.service'
"$systemctl" --root="$root" disable 'link5copy.service'
test ! -h "$root/etc/systemd/system/link5copy.service"
test ! -h "$root/etc/systemd/system/link5alias.service"
test ! -h "$root/etc/systemd/system/link5alias2.service"
: '----issue 19437: plain templates in .wants/ or .requires/---'
test ! -e "$root/etc/systemd/system/link5@.path"
cat >"$root/etc/systemd/system/link5@.path" <<EOF
[Install]
WantedBy=target5@.target
RequiredBy=target5@.target
WantedBy=target5@inst.target
RequiredBy=target5@inst.target
EOF
"$systemctl" --root="$root" enable 'link5@.path'
test ! -h "$root/etc/systemd/system/link5@.path" # this is our file
islink "$root/etc/systemd/system/target5@.target.wants/link5@.path" "../link5@.path"
islink "$root/etc/systemd/system/target5@.target.requires/link5@.path" "../link5@.path"
islink "$root/etc/systemd/system/target5@inst.target.wants/link5@.path" "../link5@.path"
islink "$root/etc/systemd/system/target5@inst.target.requires/link5@.path" "../link5@.path"
"$systemctl" --root="$root" disable 'link5@.path'
test ! -h "$root/etc/systemd/system/link5@.path" # this is our file
test ! -h "$root/etc/systemd/system/target5@.target.wants/link5@.path"
test ! -h "$root/etc/systemd/system/target5@.target.requires/link5@.path"
test ! -h "$root/etc/systemd/system/target5@inst.target.wants/link5@.path"
test ! -h "$root/etc/systemd/system/target5@inst.target.requires/link5@.path"
: '-------removal of symlinks not listed in [Install]----------'
# c.f. 66a19d85a533b15ed32f4066ec880b5a8c06babd
test ! -e "$root/etc/systemd/system/multilink.mount"
cat >"$root/etc/systemd/system/multilink.mount" <<EOF
[Install]
WantedBy=multilink.target
EOF
mkdir -p "$root/etc/systemd/system/default.target.wants"
ln -s ../multilink.mount "$root/etc/systemd/system/default.target.wants/"
ln -s ../multilink.mount "$root/etc/systemd/system/multilink-alias.mount"
ln -s ../multilink.mount "$root/etc/systemd/system/multilink-badalias.service"
"$systemctl" --root="$root" disable 'multilink.mount'
test -e "$root/etc/systemd/system/multilink.mount" # this is our file
test ! -h "$root/etc/systemd/system/default.target.wants/"
test ! -h "$root/etc/systemd/system/multilink-alias.mount"
test ! -h "$root/etc/systemd/system/multilink-badalias.service"
: '-------merge 20017: specifiers in the unit file-------------'
test ! -e "$root/etc/systemd/system/some-some-link6@.socket"
# c.f. de61a04b188f81a85cdb5c64ddb4987dcd9d30d3
check_alias() {
: "------------------ %$1 -------------------------------------"
cat >"$root/etc/systemd/system/some-some-link6@.socket" <<EOF
[Install]
Alias=target@$1:%$1.socket
EOF
SYSTEMD_LOG_LEVEL=debug "$systemctl" --root="$root" enable 'some-some-link6@.socket' || return 1
islink "$root/etc/systemd/system/target@$1:$2.socket" "some-some-link6@.socket" || return 2
}
# TODO: our architecture names are different than what uname -m returns.
# Add something like 'systemd-detect-virt --print-architecture' and use it here.
check_alias a "$(uname -m | tr '_' '-')" || :
test ! -e "$root/etc/os-release"
test ! -e "$root/usr/lib/os-release"
( ! check_alias A '' )
( ! check_alias B '' )
( ! check_alias M '' )
( ! check_alias o '' )
( ! check_alias w '' )
( ! check_alias W '' )
cat >"$root/etc/os-release" <<EOF
# empty
EOF
check_alias A ''
check_alias B ''
check_alias M ''
check_alias o ''
check_alias w ''
check_alias W ''
cat >"$root/etc/os-release" <<EOF
ID='the-id'
VERSION_ID=39a
BUILD_ID=build-id
VARIANT_ID=wrong
VARIANT_ID=right
IMAGE_ID="foobar"
IMAGE_VERSION='1-2-3'
EOF
check_alias A '1-2-3'
check_alias B 'build-id'
check_alias M 'foobar'
check_alias o 'the-id'
check_alias w '39a'
check_alias W 'right'
check_alias b "$("$systemd_id128" boot-id)"
# Specifiers not available for [Install]
( ! check_alias C '' )
( ! check_alias E '' )
( ! check_alias f '' )
( ! check_alias h '' )
( ! check_alias I '' )
( ! check_alias J '' )
( ! check_alias L '' )
( ! check_alias P '' )
( ! check_alias s '' )
( ! check_alias S '' )
( ! check_alias t '' )
( ! check_alias T '' )
( ! check_alias V '' )
check_alias g root
check_alias G 0
check_alias u root
check_alias U 0
check_alias i ""
check_alias j 'link6'
check_alias l "$(uname -n | sed 's/\..*//')"
test ! -e "$root/etc/machine-id"
( ! check_alias m '' )
"$systemd_id128" new >"$root/etc/machine-id"
check_alias m "$(cat "$root/etc/machine-id")"
check_alias n 'some-some-link6@.socket'
check_alias N 'some-some-link6@'
check_alias p 'some-some-link6'
uname -r | grep -q '[^a-zA-Z0-9_.\\-]' || \
check_alias v "$(uname -r)"
# % is not legal in unit name
( ! check_alias % '%' )
# %z is not defined
( ! check_alias z 'z' )
: '-------specifiers in WantedBy-------------------------------'
# We don't need to repeat all the tests. Let's do a basic check that specifier
# expansion is performed.
cat >"$root/etc/systemd/system/some-some-link7.socket" <<EOF
[Install]
WantedBy=target@%p.target
WantedBy=another-target@.target
RequiredBy=target2@%p.target
RequiredBy=another-target2@.target
EOF
"$systemctl" --root="$root" enable 'some-some-link7.socket'
islink "$root/etc/systemd/system/target@some-some-link7.target.wants/some-some-link7.socket" "../some-some-link7.socket"
islink "$root/etc/systemd/system/another-target@.target.wants/some-some-link7.socket" "../some-some-link7.socket"
islink "$root/etc/systemd/system/target2@some-some-link7.target.requires/some-some-link7.socket" "../some-some-link7.socket"
islink "$root/etc/systemd/system/another-target2@.target.requires/some-some-link7.socket" "../some-some-link7.socket"
"$systemctl" --root="$root" disable 'some-some-link7.socket'
test ! -h "$root/etc/systemd/system/target@some-some-link7.target.wants/some-some-link7.socket"
test ! -h "$root/etc/systemd/system/another-target@.target.wants/some-some-link7.socket"
test ! -h "$root/etc/systemd/system/target2@some-some-link7.target.requires/some-some-link7.socket"
test ! -h "$root/etc/systemd/system/another-target2@.target.requires/some-some-link7.socket"
# TODO: repeat the tests above for presets
: '-------SYSTEMD_OS_RELEASE relative to root-------------------'
# check that os-release overwriting works as expected with root
test -e "$root/etc/os-release"
cat >"$root/etc/os-release2" <<EOF
ID='the-id2'
EOF
SYSTEMD_OS_RELEASE="$root/etc/os-release2" check_alias o 'the-id2'

View File

@ -98,13 +98,13 @@ def test_valid_specifiers(*, user):
test_content('f {} - - - - %b', '{}'.format(id128.get_boot().hex), user=user)
test_content('f {} - - - - %H', '{}'.format(socket.gethostname()), user=user)
test_content('f {} - - - - %v', '{}'.format(os.uname().release), user=user)
test_content('f {} - - - - %U', '{}'.format(os.getuid() if user else 0), user=user)
test_content('f {} - - - - %G', '{}'.format(os.getgid() if user else 0), user=user)
test_content('f {} - - - - %U', '{}'.format(os.getuid()), user=user)
test_content('f {} - - - - %G', '{}'.format(os.getgid()), user=user)
puser = pwd.getpwuid(os.getuid() if user else 0)
puser = pwd.getpwuid(os.getuid())
test_content('f {} - - - - %u', '{}'.format(puser.pw_name), user=user)
pgroup = grp.getgrgid(os.getgid() if user else 0)
pgroup = grp.getgrgid(os.getgid())
test_content('f {} - - - - %g', '{}'.format(pgroup.gr_name), user=user)
# Note that %h is the only specifier in which we look the environment,

View File

@ -3,7 +3,6 @@
set -ex
test_rule="/run/udev/rules.d/49-test.rules"
KILL_PID=
setup() {
mkdir -p "${test_rule%/*}"
@ -23,37 +22,18 @@ EOF
teardown() {
set +e
if [[ -n "$KILL_PID" ]]; then
kill "$KILL_PID"
fi
rm -rf "$TMPDIR"
mv -f /etc/udev/udev.conf.bckp /etc/udev/udev.conf
rm -f "$test_rule"
systemctl restart systemd-udevd.service
}
run_test() {
local since
since="$(date '+%F %T')"
TMPDIR=$(mktemp -d -p /tmp udev-tests.XXXXXX)
udevadm monitor --udev --property --subsystem-match=mem >"$TMPDIR"/monitor.txt &
KILL_PID="$!"
SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --settle --action add /dev/null
SYSTEMD_LOG_LEVEL=debug udevadm trigger --verbose --action add /dev/null
for _ in {1..40}; do
for _ in {1..20}; do
if coredumpctl --since "$since" --no-legend --no-pager | grep /bin/udevadm ; then
kill "$KILL_PID"
KILL_PID=
cat "$TMPDIR"/monitor.txt
grep -q 'UDEV_WORKER_FAILED=1' "$TMPDIR"/monitor.txt
grep -q 'UDEV_WORKER_SIGNAL=6' "$TMPDIR"/monitor.txt
grep -q 'UDEV_WORKER_SIGNAL_NAME=ABRT' "$TMPDIR"/monitor.txt
return 0
fi
sleep .5

View File

@ -3,8 +3,7 @@
set -eu
tag="$(git describe --abbrev=0 --match 'v[0-9][0-9][0-9]')"
git log --pretty=tformat:%aN -s "${tag}.." |
grep -v noreply@weblate.org |
git log --pretty=tformat:%aN --author=noreply@weblate.org --invert-grep -s "${tag}.." | \
sed 's/ / /g; s/--/-/g; s/.*/\0,/' |
sort -u | tr '\n' ' ' | sed -e "s/^/Contributions from: /g" -e "s/,\s*$/\n/g" | fold -w 72 -s |
sort -u | tr '\n' ' ' | sed -e "s/^/Contributions from: /g" -e "s/,\s*$/\n/g" | fold -w 72 -s | \
sed -e "s/^/ /g" -e "s/\s*$//g"