1
0
mirror of https://github.com/systemd/systemd synced 2026-03-17 10:34:46 +01:00

Compare commits

..

No commits in common. "3da9b65b304836c2c8b1812a8c328f0ce45b18f7" and "3fa3a4fd153c4ff836b3365d48adf02eac8c8221" have entirely different histories.

99 changed files with 1620 additions and 1951 deletions

View File

@ -121,6 +121,9 @@ policy:
- name: sysusers
keys: ['systemd-sysusers']
- name: sysv
keys: ['systemd-sysv-generator']
- name: tests
keys: ['tests']

9
.github/labeler.yml vendored
View File

@ -172,6 +172,9 @@ pstore:
random-seed:
- changed-files:
- any-glob-to-any-file: '**/*random-seed*'
rc-local-generator:
- changed-files:
- any-glob-to-any-file: 'src/rc-local-generator/*'
remount-fs:
- changed-files:
- any-glob-to-any-file: '**/*remount-fs*'
@ -265,6 +268,12 @@ sysupdate:
sysusers:
- changed-files:
- any-glob-to-any-file: '**/*sysusers*'
sysv-generator:
- changed-files:
- any-glob-to-any-file: '**/*sysv-generator*'
sysvcompat:
- changed-files:
- any-glob-to-any-file: '**/*sysv*'
tests:
- changed-files:
- any-glob-to-any-file: [

14
NEWS
View File

@ -4,20 +4,6 @@ CHANGES WITH 260 in spe:
Feature Removals and Incompatible Changes:
* Support for System V service scripts has been removed. Please make
sure to update your software *now* to include a native systemd unit
file instead of a legacy System V script.
The following components have been removed:
* systemd-rc-local-generator and rc-local.service,
* systemd-sysv-generator,
* systemd-sysv-install (hook for systemctl enable/disable/is-enabled).
The corresponding meson options '-Drc-local=', '-Dsysvinit-path=',
and '-Dsysvrcnd-path=' are deprecated, and will be dropped in a future
release.
* Meson options '-Dintegration-tests=' and '-Dcryptolib=' (deprecated
in v258) have been removed.

11
README
View File

@ -434,6 +434,17 @@ GLIBC NSS:
gshadow: files systemd
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
SYSV INIT.D SCRIPTS:
When calling "systemctl enable/disable/is-enabled" on a unit which is a
SysV init.d script, it calls /usr/lib/systemd/systemd-sysv-install;
this needs to translate the action into the distribution specific
mechanism such as chkconfig or update-rc.d. Packagers need to provide
this script if you need this functionality (you don't if you disabled
SysV init support).
Please see src/systemctl/systemd-sysv-install.SKELETON for how this
needs to look like, and provide an implementation at the marked places.
WARNINGS and TAINT FLAGS:
systemd requires that the /run mount point exists. systemd also
requires that /var/run is a symlink to /run. Taint flag 'var-run-bad'

17
TODO
View File

@ -137,20 +137,6 @@ Deprecations and removals:
Features:
* systemd-sysupdate: add support a "best before" in manifests (ie. SHA256SUMS)
files, to detect freshness, and refuse stale sources
* systemd-sysupdate: for each transfer support looking at multiple sources,
pick source with newest entry. If multiple sources have the same entry, use
first configured source. Usecase: "sideload" components from local dirs,
without disabling remote sources.
* systemd-sysupdate: support "revoked" items, which cause the client to
downgrade/upgrade
* portable services: attach not only unit files to host, but also simple
binaries to a tmpfs path in $PATH.
* systemd-sysext: add "exec" command or so that is a bit like "refresh" but
runs it in a new namespace and then just executes the selected binary within
it. Could be useful to run one-off binaries inside a sysext as a CLI tool.
@ -2261,7 +2247,7 @@ Features:
being properly synchronous we just keep open the fd and close it
when done. That means clients do not get a successful method reply,
but much rather a disconnect on success.
- when breaking cycles drop services from /run first, then from /etc, then from /usr
- when breaking cycles drop sysv services first, then services from /run, then from /etc, then from /usr
- when a bus name of a service disappears from the bus make sure to queue further activation requests
- maybe introduce CoreScheduling=yes/no to optionally set a PR_SCHED_CORE cookie, so that all
processes in a service's cgroup share the same cookie and are guaranteed not to share SMT cores
@ -2688,6 +2674,7 @@ Features:
* document:
- document that deps in [Unit] sections ignore Alias= fields in
[Install] units of other units, unless those units are disabled
- man: clarify that time-sync.target is not only sysv compat but also useful otherwise. Same for similar targets
- document that service reload may be implemented as service reexec
- add a man page containing packaging guidelines and recommending usage of things like Documentation=, PrivateTmp=, PrivateNetwork= and ReadOnlyDirectories=/etc /usr.
- document systemd-journal-flush.service properly

View File

@ -13,6 +13,7 @@ You need to make the follow changes to adapt systemd to your distribution:
1. Find the right configure parameters for:
* `-Drc-local=`
* `-Dloadkeys-path=`
* `-Dsetfont-path=`
* `-Dtty-gid=`

View File

@ -138,6 +138,8 @@ All tools:
* `$SYSTEMCTL_INSTALL_CLIENT_SIDE=1` — if set, enable or disable unit files on
the client side, instead of asking PID 1 to do this.
* `$SYSTEMCTL_SKIP_SYSV=1` — if set, do not call SysV compatibility hooks.
* `$SYSTEMCTL_SKIP_AUTO_KEXEC=1` — if set, do not automatically kexec instead of
reboot when a new kernel has been loaded.

View File

@ -81,6 +81,10 @@ Or you can even check /proc/$PID/cgroup directly. Also see [this blog story](htt
A: Unfortunately that would be a racy operation. For an explanation why and how we tried to improve the situation, see [the bugzilla report about this](https://bugzilla.redhat.com/show_bug.cgi?id=615527).
**Q: I have a native systemd service file and a SysV init script installed which share the same basename, e.g. /usr/lib/systemd/system/foobar.service vs. /etc/init.d/foobar -- which one wins?**
A: If both files are available the native unit file always takes precedence and the SysV init script is ignored, regardless whether either is enabled or disabled. Note that a SysV service that is enabled but overridden by a native service does not have the effect that the native service would be enabled, too. Enabling of native and SysV services is completely independent. Or in other words: you cannot enable a native service by enabling a SysV service by the same name, and if a SysV service is enabled but the respective native service is not, this will not have the effect that the SysV script is executed.
**Q: How can I use journalctl to display full (= not truncated) messages even if less is not used?**
A: Use:

View File

@ -70,10 +70,16 @@ For more details about those targets, see the
[systemd.special(7)](https://www.freedesktop.org/software/systemd/man/systemd.special.html)
man page.
## Compatibility with SysV init
LSB defines a `$network` dependency for legacy init scripts. Whenever systemd
encounters a `$network` dependency in LSB headers of init scripts it will
translate this to `Wants=` and `After=` dependencies on
`network-online.target`, staying relatively close to traditional LSB behaviour.
# Discussion
LSB defines a `$network` dependency for legacy init scripts.
However, it is defined [only very
The meaning of `$network` is defined [only very
unprecisely](http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/facilname.html)
and people tend to have different ideas what it is supposed to mean. Here are a
couple of ideas people came up with so far:

View File

@ -7,7 +7,7 @@ SPDX-License-Identifier: LGPL-2.1-or-later
systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager that runs as PID 1 and starts the rest of the system.
systemd provides aggressive parallelization capabilities, uses socket and D-Bus activation for starting services, offers on-demand starting of daemons, keeps track of processes using Linux control groups, maintains mount and automount points, and implements an elaborate transactional dependency-based service control logic.
systemd provides aggressive parallelization capabilities, uses socket and D-Bus activation for starting services, offers on-demand starting of daemons, keeps track of processes using Linux control groups, maintains mount and automount points, and implements an elaborate transactional dependency-based service control logic. systemd supports SysV and LSB init scripts and works as a replacement for sysvinit.
Other parts include a logging daemon, utilities to control basic system configuration like the hostname, date, locale, maintain a list of logged-in users and running containers and virtual machines, system accounts, runtime directories and settings, and daemons to manage simple network configuration, network time synchronization, log forwarding, and name resolution.

View File

@ -71,7 +71,3 @@ dmi:bvnLENOVO*
# Microsoft Surface 1's chassis type
dmi:bvnMicrosoft Corporation*:pvrSurface with Windows 8 Pro*
ID_CHASSIS=tablet
# GPD Pocket 4 chassis type
dmi:bvnAmericanMegatrendsInternational*:rvnGPD:rnG1628-04*
ID_CHASSIS=convertible

View File

@ -26,11 +26,11 @@
# Logitech
################
# Litra Beam
bluetooth:v046DpC901*
usb:v046DpC901*
bluetooth:v046dpc901*
usb:v046dpc901*
ID_AV_LIGHTS=1
# Litra Glow
bluetooth:v046DpC900*
usb:v046DpC900*
bluetooth:v046dpc900*
usb:v046dpc900*
ID_AV_LIGHTS=1

View File

@ -5,6 +5,7 @@
# So we don't "test" them.
hwdb_files_notest = files(
'README',
'20-dmi-id.hwdb',
'20-pci-vendor-model.hwdb',
'20-pci-classes.hwdb',
'20-usb-vendor-model.hwdb',
@ -14,11 +15,10 @@ hwdb_files_notest = files(
'20-bluetooth-vendor-product.hwdb',
'20-acpi-vendor.hwdb',
'20-OUI.hwdb',
'20-net-ifname.hwdb',
'20-vmbus-class.hwdb')
hwdb_files_test = files(
'20-dmi-id.hwdb',
'20-net-ifname.hwdb',
'60-autosuspend.hwdb',
'60-autosuspend-fingerprint-reader.hwdb',
'60-evdev.hwdb',
@ -31,7 +31,6 @@ hwdb_files_test = files(
'70-cameras.hwdb',
'70-hardware-wallets.hwdb',
'70-joystick.hwdb',
'70-lights.hwdb',
'70-maker-tools.hwdb',
'70-mouse.hwdb',
'70-pda.hwdb',

View File

@ -106,7 +106,6 @@ GENERAL_MATCHES = {'acpi',
'vmbus',
'OUI',
'ieee1394',
'dmi',
}
def upperhex_word(length):
@ -202,16 +201,6 @@ def property_grammar():
('ID_INFRARED_CAMERA', Or((Literal('0'), Literal('1')))),
('ID_CAMERA_DIRECTION', Or(('front', 'rear'))),
('SOUND_FORM_FACTOR', Or(('internal', 'webcam', 'speaker', 'headphone', 'headset', 'handset', 'microphone'))),
('ID_SYS_VENDOR_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_PRODUCT_NAME_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_PRODUCT_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_BOARD_VERSION_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_PRODUCT_SKU_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_CHASSIS_ASSET_TAG_IS_RUBBISH', Or((Literal('0'), Literal('1')))),
('ID_CHASSIS', name_literal),
('ID_SYSFS_ATTRIBUTE_MODEL', name_literal),
('ID_NET_NAME_FROM_DATABASE', name_literal),
('ID_NET_NAME_INCLUDE_DOMAIN', Or((Literal('0'), Literal('1')))),
)
fixed_props = [Literal(name)('NAME') - Suppress('=') - val('VALUE')
for name, val in props]
@ -254,9 +243,7 @@ def check_matches(groups):
# This is a partial check. The other cases could be also done, but those
# two are most commonly wrong.
grammars = {
'bluetooth' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*',
'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*',
grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4) + Optional(':')) + '*',
'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8) + Optional(':')) + '*',
}
@ -266,12 +253,12 @@ def check_matches(groups):
if gr:
# we check this first to provide an easy error message
if rest[-1] not in '*:':
error('Pattern {} does not end with "*" or ":"', match)
error('pattern {} does not end with "*" or ":"', match)
try:
gr.parseString(rest)
except ParseBaseException as e:
error('Pattern {} is invalid: {}', match, e)
error('Pattern {!r} is invalid: {}', rest, e)
continue
matches.sort()
@ -353,12 +340,7 @@ def print_summary(fname, groups):
error(f'{fname}: no matches or props')
if __name__ == '__main__':
args = sys.argv[1:] or sorted(
[
os.path.dirname(sys.argv[0]) + '/20-dmi-id.hwdb',
os.path.dirname(sys.argv[0]) + '/20-net-ifname.hwdb',
] + glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb')
)
args = sys.argv[1:] or sorted(glob.glob(os.path.dirname(sys.argv[0]) + '/[678][0-9]-*.hwdb'))
for fname in args:
groups = parse(fname)

View File

@ -12,6 +12,7 @@
<!ENTITY KILL_USER_PROCESSES "{{ 'yes' if KILL_USER_PROCESSES else 'no' }}">
<!ENTITY JOURNAL_STORAGE_DEFAULT "{{JOURNAL_STORAGE_DEFAULT}}">
<!ENTITY DEBUGTTY "{{DEBUGTTY}}">
<!ENTITY SYSTEM_SYSVRCLOCAL_PATH "{{SYSTEM_SYSVRCLOCAL_PATH}}">
<!ENTITY HIGH_RLIMIT_NOFILE "{{HIGH_RLIMIT_NOFILE}}">
<!ENTITY DEFAULT_DNSSEC_MODE "{{DEFAULT_DNSSEC_MODE_STR}}">
<!ENTITY DEFAULT_DNS_OVER_TLS_MODE "{{DEFAULT_DNS_OVER_TLS_MODE_STR}}">

View File

@ -1130,6 +1130,10 @@ manpages = [
'8',
['systemd-random-seed'],
'ENABLE_RANDOMSEED'],
['systemd-rc-local-generator',
'8',
['rc-local.service'],
'HAVE_SYSV_RC_LOCAL'],
['systemd-remount-fs.service', '8', ['systemd-remount-fs'], ''],
['systemd-repart', '8', ['systemd-repart.service'], 'ENABLE_REPART'],
['systemd-resolved.service', '8', ['systemd-resolved'], 'ENABLE_RESOLVE'],

View File

@ -1,32 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE refsect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!--
SPDX-License-Identifier: LGPL-2.1-or-later
-->
<refsect1>
<title/>
<para id="plural">When enabled for services running in per-user instances of the service manager
using mount options is disabled by default, due to the security implications. It is possible to use a
<ulink url="https://www.freedesktop.org/software/polkit/docs/latest/">polkit</ulink> policy to allow
specific mount options, for example:
<example id="example">
<title>A polkit policy that allows mounting the root partition with nosuid</title>
<para><filename index="false">/etc/polkit-1/rules.d/mountoptions.rules</filename>:
</para>
<programlisting>
polkit.addRule(function(action, subject) {
if (action.id == "io.systemd.mount-file-system.mount-untrusted-image-privately" &amp;&amp;
action.lookup("mount_options") == "root:nosuid") {
return polkit.Result.YES;
}
});
</programlisting>
</example>
</para>
</refsect1>

View File

@ -0,0 +1,80 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % entities SYSTEM "custom-entities.ent" >
%entities;
]>
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
<refentry id="systemd-rc-local-generator" conditional='HAVE_SYSV_RC_LOCAL'>
<refentryinfo>
<title>systemd-rc-local-generator</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>systemd-rc-local-generator</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
<refname>systemd-rc-local-generator</refname>
<refname>rc-local.service</refname>
<refpurpose>Compatibility generator and service to start <filename>&SYSTEM_SYSVRCLOCAL_PATH;</filename> during boot</refpurpose>
</refnamediv>
<refsynopsisdiv>
<para><filename>/usr/lib/systemd/system-generators/systemd-rc-local-generator</filename></para>
<para><filename>rc-local.service</filename></para>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><command>systemd-rc-local-generator</command> is a generator that checks whether
<filename>&SYSTEM_SYSVRCLOCAL_PATH;</filename> exists and is executable, and if it is, pulls the
<filename>rc-local.service</filename> unit into the boot process. This unit is responsible for running
this script during late boot. The script is run after <filename>network.target</filename>, but in
parallel with most other regular system services.</para>
<para>Note that <filename>rc-local.service</filename> runs with slightly different semantics than the
original System V version, which was executed "last" in the boot process, which is a concept that does
not translate to systemd.</para>
<para>Also note that <filename>rc-local.service</filename> is ordered after
<filename>network.target</filename>, which does not mean that the network is functional, see
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
If the script requires a configured network connection, it may be desirable to pull in and order it after
<filename>network-online.target</filename> with a drop-in:</para>
<programlisting># /etc/systemd/system/rc-local.service.d/network.conf
[Unit]
Wants=network-online.target
After=network-online.target
</programlisting>
<para>Support for <filename>&SYSTEM_SYSVRCLOCAL_PATH;</filename> is provided for compatibility with specific
System V systems only. However, it is strongly recommended to avoid using this script today, and instead
provide proper unit files with appropriate dependencies for any scripts to run during the boot process.
Note that the path to the script is set at compile time and varies between distributions.</para>
<para><filename>systemd-rc-local-generator</filename> implements
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>On systems with SELinux, when creating the file, make sure to set the appropriate context, e.g.
with "<command>sudo restorecon -v &SYSTEM_SYSVRCLOCAL_PATH;</command>".
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<para><simplelist type="inline">
<member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
</refentry>

View File

@ -226,9 +226,6 @@
<xi:include href="system-only.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="plural"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="example"/>
<xi:include href="version-info.xml" xpointer="v247"/></listitem>
</varlistentry>
@ -527,9 +524,6 @@
<xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="plural"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="example"/>
<xi:include href="version-info.xml" xpointer="v247"/></listitem>
</varlistentry>
@ -597,9 +591,6 @@
<xi:include href="system-or-user-ns-mountfsd.xml" xpointer="singular"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="plural"/>
<xi:include href="system-or-user-ns-mountfsd-mount-options.xml" xpointer="example"/>
<xi:include href="version-info.xml" xpointer="v248"/></listitem>
</varlistentry>

View File

@ -405,6 +405,7 @@ find $dir</programlisting>
<member><citerefentry><refentrytitle>systemd-getty-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-rc-local-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd-xdg-autostart-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>

View File

@ -934,28 +934,6 @@
<xi:include href="version-info.xml" xpointer="v245"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ScatterGather=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, enables offload feature where the hardware builds a network
packet from multiple non-contiguous memory buffers.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> tx-scatter-gather on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>ScatterGatherFragmentList=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, enables offload feature where the hardware builds a network
packet from a chained list of socket buffers.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> tx-scatter-gather-fraglist on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
@ -965,29 +943,6 @@
<xi:include href="version-info.xml" xpointer="v232"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCPECNSegmentationOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, TCP Segmentation Offload (TSO) is performed even when ECN
(Explicit Congestion Notification) flags are active in the TCP stream.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> tx-tcp-ecn-segmentation on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCPMangleIdSegmentationOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, TCP Segmentation Offload (TSO) is performed even if the
hardware is incapable of correctly incrementing the IPv4 Identification (ID) field for each
resulting packet.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> tx-tcp-mangleid-segmentation on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCP6SegmentationOffload=</varname></term>
<listitem>
@ -1036,26 +991,6 @@
<xi:include href="version-info.xml" xpointer="v250"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>GenericReceiveOffloadList=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, Generic Receive Offload (GRO) List for UDP is enabled.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> rx-gro-list on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>GenericReceiveOffloadUDPForwarding=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, Generic Receive Offload (GRO) for aggregating incoming UDP packets is enabled.
When unset, the kernel's default will be used. This corresponds to the command
<command>ethtool -K <replaceable>INTERFACE</replaceable> rx-udp-gro-forwarding on|off</command>.</para>
<xi:include href="version-info.xml" xpointer="v260"/>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>LargeReceiveOffload=</varname></term>
<listitem>

View File

@ -583,6 +583,10 @@
functionality to other hosts (as opposed to <emphasis>consume</emphasis> functionality of other
hosts) generally do not need to pull this in.</para>
<para>systemd automatically adds dependencies of type <varname>Wants=</varname> and
<varname>After=</varname> for this target unit to all SysV init script service units
with an LSB header referring to the <literal>$network</literal> facility.</para>
<para>Note that this unit is only useful during the original system start-up
logic. After the system has completed booting up, it will not track the online state of
the system anymore. Due to this it cannot be used as a network connection monitor
@ -675,6 +679,11 @@
<listitem>
<para>Similar to <filename>local-fs.target</filename>, but
for remote mount points.</para>
<para>systemd automatically adds dependencies of type
<varname>After=</varname> for this target unit to all SysV
init script service units with an LSB header referring to
the <literal>$remote_fs</literal> facility.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1176,7 +1185,9 @@ WantedBy=sleep.target</programlisting>
service lookups. Note that this is independent of UNIX user/group name lookups for which
<filename>nss-user-lookup.target</filename> should be used. All services for which the
availability of full host/network name resolution is essential should be ordered after
this target, but not pull it in.</para>
this target, but not pull it in. systemd automatically adds dependencies of type
<varname>After=</varname> for this target unit to all SysV init script service units
with an LSB header referring to the <literal>$named</literal> facility.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1213,7 +1224,11 @@ WantedBy=sleep.target</programlisting>
<term><filename>rpcbind.target</filename></term>
<listitem>
<para>The portmapper/rpcbind pulls in this target and orders
itself before it, to indicate its availability.</para>
itself before it, to indicate its availability. systemd
automatically adds dependencies of type
<varname>After=</varname> for this target unit to all SysV
init script service units with an LSB header referring to
the <literal>$portmap</literal> facility.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -1274,7 +1289,9 @@ WantedBy=sleep.target</programlisting>
unit, but not pull it in.</para>
<para>The service manager automatically adds dependencies of type <varname>After=</varname> for
this target unit to all timer units with at least one <varname>OnCalendar=</varname> directive.</para>
this target unit to all SysV init script service units with an LSB header referring to the
<literal>$time</literal> facility, as well to all timer units with at least one
<varname>OnCalendar=</varname> directive.</para>
<para>This target provides stricter clock accuracy guarantees than
<filename>time-set.target</filename> (see above), but likely requires

View File

@ -90,6 +90,8 @@ conf.set10('HAVE_SPLIT_BIN', split_bin,
have_standalone_binaries = get_option('standalone-binaries')
sysvrclocal_path = get_option('rc-local')
conf.set10('HAVE_SYSV_RC_LOCAL', sysvrclocal_path != '')
conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
if get_option('hibernate') and not get_option('initrd')
@ -297,6 +299,7 @@ conf.set_quoted('SYSTEM_GENERATOR_DIR', systemgeneratordir
conf.set_quoted('SYSTEM_PRESET_DIR', systempresetdir)
conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir)
conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir)
conf.set_quoted('SYSTEM_SYSVRCLOCAL_PATH', sysvrclocal_path)
conf.set_quoted('SYSUSERS_DIR', sysusersdir)
conf.set_quoted('TMPFILES_DIR', tmpfilesdir)
conf.set_quoted('USER_TMPFILES_DIR', usertmpfilesdir)
@ -2398,6 +2401,7 @@ subdir('src/pstore')
subdir('src/ptyfwd')
subdir('src/quotacheck')
subdir('src/random-seed')
subdir('src/rc-local-generator')
subdir('src/remount-fs')
subdir('src/repart')
subdir('src/reply-password')
@ -3018,6 +3022,7 @@ summary({
'sysconf directory' : sysconfdir,
'include directory' : includedir,
'lib directory' : libdir,
'SysV rc.local script' : sysvrclocal_path,
'PAM modules directory' : pamlibdir,
'PAM configuration directory' : pamconfdir,
'ssh server configuration directory' : sshdconfdir,
@ -3183,6 +3188,7 @@ foreach tuple : [
['man pages', want_man],
['html pages', want_html],
['man page indices', want_man and have_lxml],
['SysV compat'],
['compat-mutable-uid-boundaries'],
['utmp'],
['ldconfig'],

View File

@ -45,7 +45,7 @@ option('sysvinit-path', type : 'string', value : '/etc/init.d', deprecated : tru
description : 'This option is deprecated and will be removed in a future release')
option('sysvrcnd-path', type : 'string', value : '/etc/rc.d', deprecated : true,
description : 'This option is deprecated and will be removed in a future release')
option('rc-local', type : 'string', value : '/etc/rc.local', deprecated : true,
option('rc-local', type : 'string', value : '/etc/rc.local',
description : 'path to SysV rc.local script')
option('initrd', type : 'boolean',
description : 'install services for use when running systemd in initrd')

View File

@ -16,5 +16,6 @@ VolatilePackages=
systemd-networkd-debuginfo
systemd-portable-debuginfo
systemd-resolved-debuginfo
systemd-sysvcompat-debuginfo
systemd-testsuite-debuginfo
udev-debuginfo

View File

@ -27,7 +27,6 @@ while read -r filelist; do
-e '/(initctl|runlevel|telinit)/ d' \
-e 's/systemd-quotacheck.service.8/systemd-quotacheck@.service.8/' \
-e '/systemd-sysv-generator/d' \
-e '/rc-local/d' \
"$filelist" >"/tmp/$(basename "$filelist")"
mount --bind "/tmp/$(basename "$filelist")" "$filelist"
done < <(find "pkg/$PKG_SUBDIR${GIT_SUBDIR:+/$GIT_SUBDIR}" -name "files.*")

View File

@ -9,5 +9,5 @@ Environment=
GIT_URL=https://salsa.debian.org/systemd-team/systemd.git
GIT_SUBDIR=debian
GIT_BRANCH=debian/master
GIT_COMMIT=93a222266c23ff73720f4de009a027d3556baee4
GIT_COMMIT=f05328feafba2156f31e17e0e2c144cfa7c66e72
PKG_SUBDIR=debian

View File

@ -78,7 +78,7 @@ int verb_nvpcrs(int argc, char *argv[], void *userdata) {
&l,
".nvpcr",
/* root= */ NULL,
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX,
CONF_PATHS_NULSTR("nvpcr"));
if (r < 0)
return log_error_errno(r, "Failed to find .nvpcr files: %m");

View File

@ -86,7 +86,6 @@ union sockaddr_union;
typedef enum CGroupFlags CGroupFlags;
typedef enum CGroupMask CGroupMask;
typedef enum ChaseFlags ChaseFlags;
typedef enum ConfFilesFlags ConfFilesFlags;
typedef enum ExtractFlags ExtractFlags;
typedef enum ForkFlags ForkFlags;
typedef enum Glyph Glyph;

View File

@ -40,11 +40,7 @@ void conf_file_free_many(ConfFile **array, size_t n) {
free(array);
}
static int conf_files_log_level(ConfFilesFlags flags) {
return FLAGS_SET(flags, CONF_FILES_WARN) ? LOG_WARNING : LOG_DEBUG;
}
static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
static int prepare_dirs(const char *root, char * const *dirs, int *ret_rfd, char **ret_root, char ***ret_dirs) {
_cleanup_free_ char *root_abs = NULL;
_cleanup_strv_free_ char **dirs_abs = NULL;
int r;
@ -53,16 +49,14 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
assert(ret_root);
assert(ret_dirs || strv_isempty(dirs));
int log_level = conf_files_log_level(flags);
r = empty_or_root_harder_to_null(&root);
if (r < 0)
return log_full_errno(log_level, r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
return log_debug_errno(r, "Failed to determine if '%s' points to the root directory: %m", strempty(root));
if (ret_dirs) {
dirs_abs = strv_copy(dirs);
if (!dirs_abs)
return log_oom_full(log_level);
return log_oom();
}
if (root) {
@ -70,7 +64,7 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
* necessary to modify each config directories here. but needs to normalize the root directory. */
r = path_make_absolute_cwd(root, &root_abs);
if (r < 0)
return log_full_errno(log_level, r, "Failed to make '%s' absolute: %m", root);
return log_debug_errno(r, "Failed to make '%s' absolute: %m", root);
path_simplify(root_abs);
} else if (ret_dirs) {
@ -78,12 +72,12 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
* each config directory absolute if relative. */
r = path_strv_make_absolute_cwd(dirs_abs);
if (r < 0)
return log_full_errno(log_level, r, "Failed to make directories absolute: %m");
return log_debug_errno(r, "Failed to make directories absolute: %m");
}
_cleanup_close_ int rfd = open(empty_to_root(root_abs), O_CLOEXEC|O_DIRECTORY|O_PATH);
if (rfd < 0)
return log_full_errno(log_level, errno, "Failed to open '%s': %m", empty_to_root(root_abs));
return log_debug_errno(errno, "Failed to open '%s': %m", empty_to_root(root_abs));
*ret_rfd = TAKE_FD(rfd);
*ret_root = TAKE_PTR(root_abs);
@ -92,191 +86,46 @@ static int prepare_dirs(const char *root, ConfFilesFlags flags, char * const *di
return 0;
}
static int conf_file_prefix_root(ConfFile *c, const char *root, ConfFilesFlags flags) {
static int conf_file_prefix_root(ConfFile *c, const char *root) {
char *p;
int r;
assert(c);
int log_level = conf_files_log_level(flags);
r = chaseat_prefix_root(c->result, root, &p);
if (r < 0)
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
free_and_replace(c->result, p);
r = chaseat_prefix_root(c->resolved_path, root, &p);
if (r < 0)
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->resolved_path, root);
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->resolved_path, root);
free_and_replace(c->resolved_path, p);
/* Do not use chaseat_prefix_root(), as it is for the result of chaseat(), but the path is not chased. */
p = path_join(empty_to_root(root), skip_leading_slash(c->original_path));
if (!p)
return log_oom_full(log_level);
return log_oom_debug();
path_simplify(p);
return free_and_replace(c->original_path, p);
}
static bool conf_files_need_stat(ConfFilesFlags flags) {
return (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
}
static ChaseFlags conf_files_chase_flags(ConfFilesFlags flags) {
ChaseFlags chase_flags = CHASE_AT_RESOLVE_IN_ROOT;
if (!conf_files_need_stat(flags) || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK))
/* Even if no verification is requested, let's unconditionally call chaseat(),
* to drop unsafe symlinks. */
chase_flags |= CHASE_NONEXISTENT;
return chase_flags;
}
static int conf_file_chase_and_verify(
int rfd,
const char *root, /* for logging, can be NULL */
const char *original_path, /* for logging */
const char *path,
const char *name,
Set **masked, /* optional */
ConfFilesFlags flags,
char **ret_path,
int *ret_fd,
struct stat *ret_stat) {
_cleanup_free_ char *resolved_path = NULL;
_cleanup_close_ int fd = -EBADF;
struct stat st = {};
int r;
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(original_path);
assert(path);
assert(name);
int log_level = conf_files_log_level(flags);
root = empty_to_root(root);
r = chaseat(rfd, path, conf_files_chase_flags(flags), &resolved_path, &fd);
if (r < 0)
return log_full_errno(log_level, r, "Failed to chase '%s%s': %m",
root, skip_leading_slash(original_path));
if (r == 0) {
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
if (masked) {
/* Mark this one as masked */
r = set_put_strdup(masked, name);
if (r < 0)
return log_oom_full(log_level);
}
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
"File '%s%s' is a mask (symlink to /dev/null).",
root, skip_leading_slash(original_path));
}
}
if (conf_files_need_stat(flags))
/* If we need to have stat, skip the entry. */
return log_full_errno(log_level, SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s%s': %m",
root, skip_leading_slash(original_path));
}
/* Even if we do not need stat, let's take stat now. The caller may use the info later. */
if (fd >= 0 && fstat(fd, &st) < 0)
return log_full_errno(log_level, errno, "Failed to stat '%s%s': %m",
root, skip_leading_slash(original_path));
/* Is this a masking entry? */
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
if (masked) {
/* Mark this one as masked */
r = set_put_strdup(masked, name);
if (r < 0)
return log_oom_full(log_level);
}
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
"File '%s%s' is a mask (symlink to /dev/null).",
root, skip_leading_slash(original_path));
}
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
if (masked) {
/* Mark this one as masked */
r = set_put_strdup(masked, name);
if (r < 0)
return log_oom_full(log_level);
}
return log_debug_errno(SYNTHETIC_ERRNO(ERFKILL),
"File '%s%s' is a mask (an empty file).",
root, skip_leading_slash(original_path));
}
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
return log_debug_errno(SYNTHETIC_ERRNO(EBADFD),
"File '%s%s' is neither a regular file or directory.",
root, skip_leading_slash(original_path));
} else {
/* Is this node a regular file? */
if (FLAGS_SET(flags, CONF_FILES_REGULAR)) {
r = stat_verify_regular(&st);
if (r < 0)
return log_debug_errno(r, "File '%s%s' is not a regular file: %m",
root, skip_leading_slash(original_path));
}
/* Is this node a directory? */
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY)) {
r = stat_verify_directory(&st);
if (r < 0)
return log_debug_errno(r, "File '%s%s' is not a directory: %m",
root, skip_leading_slash(original_path));
}
}
/* Does this node have the executable bit set?
* As requested: check if the file is marked executable. Note that we don't check access(X_OK) here,
* as we care about whether the file is marked executable at all, and not whether it is executable
* for us, because if so, such errors are stuff we should log about. */
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0)
return log_debug_errno(SYNTHETIC_ERRNO(ENOEXEC),
"File '%s%s' is not marked executable.",
root, skip_leading_slash(original_path));
if (ret_path)
*ret_path = TAKE_PTR(resolved_path);
if (ret_fd)
*ret_fd = TAKE_FD(fd);
if (ret_stat)
*ret_stat = st;
free_and_replace(c->original_path, p);
return 0;
}
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret) {
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret) {
int r;
assert(path);
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
int log_level = conf_files_log_level(flags);
_cleanup_free_ char *root = NULL;
if (rfd >= 0)
if (rfd >= 0 && DEBUG_LOGGING)
(void) fd_get_path(rfd, &root);
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
if (!c)
return log_oom_full(log_level);
return log_oom_debug();
*c = (ConfFile) {
.original_path = strdup(path),
@ -284,55 +133,51 @@ int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile *
};
if (!c->original_path)
return log_oom_full(log_level);
return log_oom_debug();
r = path_extract_filename(path, &c->name);
if (r < 0)
return log_full_errno(log_level, r, "Failed to extract filename from '%s': %m", path);
return log_debug_errno(r, "Failed to extract filename from '%s': %m", path);
_cleanup_free_ char *dirpath = NULL, *resolved_dirpath = NULL;
r = path_extract_directory(path, &dirpath);
if (r < 0 && r != -EDESTADDRREQ)
return log_full_errno(log_level, r, "Failed to extract directory from '%s': %m", path);
return log_debug_errno(r, "Failed to extract directory from '%s': %m", path);
if (r >= 0) {
r = chaseat(rfd, dirpath,
CHASE_MUST_BE_DIRECTORY | conf_files_chase_flags(flags),
CHASE_AT_RESOLVE_IN_ROOT |
CHASE_MUST_BE_DIRECTORY |
(FLAGS_SET(chase_flags, CHASE_NONEXISTENT) ? CHASE_NONEXISTENT : 0),
&resolved_dirpath, /* ret_fd= */ NULL);
if (r < 0)
return log_full_errno(log_level, r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(dirpath));
}
c->result = path_join(resolved_dirpath, c->name);
if (!c->result)
return log_oom_full(log_level);
return log_oom_debug();
r = conf_file_chase_and_verify(
rfd,
root,
c->original_path,
c->result,
c->name,
/* masked= */ NULL,
flags,
&c->resolved_path,
&c->fd,
&c->st);
r = chaseat(rfd, c->result, CHASE_AT_RESOLVE_IN_ROOT | chase_flags, &c->resolved_path, &c->fd);
if (r < 0)
return r;
return log_debug_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(c->original_path));
if (c->fd >= 0 && fstat(c->fd, &c->st) < 0)
return log_debug_errno(r, "Failed to stat '%s%s': %m", empty_to_root(root), skip_leading_slash(c->resolved_path));
*ret = TAKE_PTR(c);
return 0;
}
int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, ConfFile **ret) {
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret) {
int r;
assert(path);
assert((chase_flags & (CHASE_PREFIX_ROOT | CHASE_STEP)) == 0);
assert(ret);
_cleanup_free_ char *root_abs = NULL;
_cleanup_close_ int rfd = -EBADF;
r = prepare_dirs(root, flags, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
r = prepare_dirs(root, /* dirs= */ NULL, &rfd, &root_abs, /* ret_dirs= */ NULL);
if (r < 0)
return r;
@ -340,17 +185,17 @@ int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, Conf
if (!root_abs) {
r = path_make_absolute_cwd(path, &path_abs);
if (r < 0)
return log_full_errno(conf_files_log_level(flags), r, "Failed to make '%s' absolute: %m", path);
return log_debug_errno(r, "Failed to make '%s' absolute: %m", path);
path = path_abs;
}
_cleanup_(conf_file_freep) ConfFile *c = NULL;
r = conf_file_new_at(path, rfd, flags, &c);
r = conf_file_new_at(path, rfd, chase_flags, &c);
if (r < 0)
return r;
r = conf_file_prefix_root(c, root_abs, flags);
r = conf_file_prefix_root(c, root_abs);
if (r < 0)
return r;
@ -383,61 +228,137 @@ static int files_add(
assert(files);
assert(masked);
int log_level = conf_files_log_level(flags);
root = strempty(root);
root = empty_to_root(root);
FOREACH_DIRENT(de, dir, return log_full_errno(log_level, errno, "Failed to read directory '%s%s': %m",
FOREACH_DIRENT(de, dir, return log_debug_errno(errno, "Failed to read directory '%s/%s': %m",
root, skip_leading_slash(original_dirpath))) {
_cleanup_free_ char *original_path = path_join(original_dirpath, de->d_name);
if (!original_path)
return log_oom_full(log_level);
return log_oom_debug();
/* Does this match the suffix? */
if (suffix && !endswith(de->d_name, suffix)) {
log_debug("Skipping file '%s%s', suffix is not '%s'.", root, skip_leading_slash(original_path), suffix);
log_debug("Skipping file '%s/%s', suffix is not '%s'.", root, skip_leading_slash(original_path), suffix);
continue;
}
/* Has this file already been found in an earlier directory? */
if (hashmap_contains(*files, de->d_name)) {
log_debug("Skipping overridden file '%s%s'.", root, skip_leading_slash(original_path));
log_debug("Skipping overridden file '%s/%s'.", root, skip_leading_slash(original_path));
continue;
}
/* Has this been masked in an earlier directory? */
if ((flags & CONF_FILES_FILTER_MASKED) != 0 && set_contains(*masked, de->d_name)) {
log_debug("File '%s%s' is masked by previous entry.", root, skip_leading_slash(original_path));
log_debug("File '%s/%s' is masked by previous entry.", root, skip_leading_slash(original_path));
continue;
}
_cleanup_free_ char *p = path_join(resolved_dirpath, de->d_name);
if (!p)
return log_oom_full(log_level);
return log_oom_debug();
_cleanup_free_ char *resolved_path = NULL;
_cleanup_close_ int fd = -EBADF;
struct stat st;
r = conf_file_chase_and_verify(
rfd,
root,
original_path,
p,
de->d_name,
masked,
flags,
&resolved_path,
&fd,
&st);
if (r == -ENOMEM)
return r;
if (r < 0)
bool need_stat = (flags & (CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_DIRECTORY | CONF_FILES_EXECUTABLE)) != 0;
ChaseFlags chase_flags = CHASE_AT_RESOLVE_IN_ROOT;
if (!need_stat || FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK))
/* Even if no verification is requested, let's unconditionally call chaseat(),
* to drop unsafe symlinks. */
chase_flags |= CHASE_NONEXISTENT;
r = chaseat(rfd, p, chase_flags, &resolved_path, &fd);
if (r < 0) {
log_debug_errno(r, "Failed to chase '%s/%s', ignoring: %m",
root, skip_leading_slash(original_path));
continue;
}
if (r == 0) {
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK)) {
/* If the path points to /dev/null in a image or so, then the device node may not exist. */
if (path_equal(skip_leading_slash(resolved_path), "dev/null")) {
/* Mark this one as masked */
r = set_put_strdup(masked, de->d_name);
if (r < 0)
return log_oom_debug();
log_debug("File '%s/%s' is a mask (symlink to /dev/null).",
root, skip_leading_slash(original_path));
continue;
}
}
if (need_stat) {
/* If we need to have stat, skip the entry. */
log_debug_errno(SYNTHETIC_ERRNO(ENOENT), "Failed to chase '%s/%s', ignoring.",
root, skip_leading_slash(original_path));
continue;
}
}
/* Even if we do not need stat, let's take stat now. The caller may use the info later. */
struct stat st = {};
if (fd >= 0 && fstat(fd, &st) < 0) {
log_debug_errno(errno, "Failed to stat '%s/%s', ignoring: %m",
root, skip_leading_slash(original_path));
continue;
}
/* Is this a masking entry? */
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_SYMLINK) && stat_may_be_dev_null(&st)) {
/* Mark this one as masked */
r = set_put_strdup(masked, de->d_name);
if (r < 0)
return log_oom_debug();
log_debug("File '%s/%s' is a mask (symlink to /dev/null).", root, skip_leading_slash(original_path));
continue;
}
if (FLAGS_SET(flags, CONF_FILES_FILTER_MASKED_BY_EMPTY) && stat_is_empty(&st)) {
/* Mark this one as masked */
r = set_put_strdup(masked, de->d_name);
if (r < 0)
return log_oom_debug();
log_debug("File '%s/%s' is a mask (an empty file).", root, skip_leading_slash(original_path));
continue;
}
if (FLAGS_SET(flags, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY)) {
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) {
log_debug("Ignoring '%s/%s', as it is neither a regular file or directory.", root, skip_leading_slash(original_path));
continue;
}
} else {
/* Is this node a regular file? */
if (FLAGS_SET(flags, CONF_FILES_REGULAR) && !S_ISREG(st.st_mode)) {
log_debug("Ignoring '%s/%s', as it is not a regular file.", root, skip_leading_slash(original_path));
continue;
}
/* Is this node a directory? */
if (FLAGS_SET(flags, CONF_FILES_DIRECTORY) && !S_ISDIR(st.st_mode)) {
log_debug("Ignoring '%s/%s', as it is not a directory.", root, skip_leading_slash(original_path));
continue;
}
}
/* Does this node have the executable bit set?
* As requested: check if the file is marked executable. Note that we don't check access(X_OK)
* here, as we care about whether the file is marked executable at all, and not whether it is
* executable for us, because if so, such errors are stuff we should log about. */
if (FLAGS_SET(flags, CONF_FILES_EXECUTABLE) && (st.st_mode & 0111) == 0) {
log_debug("Ignoring '%s/%s', as it is not marked executable.", root, skip_leading_slash(original_path));
continue;
}
_cleanup_(conf_file_freep) ConfFile *c = new(ConfFile, 1);
if (!c)
return log_oom_full(log_level);
return log_oom_debug();
*c = (ConfFile) {
.name = strdup(de->d_name),
@ -449,12 +370,12 @@ static int files_add(
};
if (!c->name)
return log_oom_full(log_level);
return log_oom_debug();
r = hashmap_ensure_put(files, &conf_file_hash_ops, c->name, c);
if (r < 0) {
assert(r == -ENOMEM);
return log_oom_full(log_level);
return log_oom_debug();
}
assert(r > 0);
@ -464,7 +385,7 @@ static int files_add(
return 0;
}
static int dump_files(Hashmap *fh, const char *root, ConfFilesFlags flags, ConfFile ***ret_files, size_t *ret_n_files) {
static int dump_files(Hashmap *fh, const char *root, ConfFile ***ret_files, size_t *ret_n_files) {
ConfFile **files = NULL;
size_t n_files = 0;
int r;
@ -477,7 +398,7 @@ static int dump_files(Hashmap *fh, const char *root, ConfFilesFlags flags, ConfF
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap. */
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
if (r < 0)
return log_oom_full(conf_files_log_level(flags));
return log_oom_debug();
/* Hence, we need to remove them from the hashmap. */
FOREACH_ARRAY(i, files, n_files)
@ -485,7 +406,7 @@ static int dump_files(Hashmap *fh, const char *root, ConfFilesFlags flags, ConfF
if (root)
FOREACH_ARRAY(i, files, n_files) {
r = conf_file_prefix_root(*i, root, flags);
r = conf_file_prefix_root(*i, root);
if (r < 0)
return r;
}
@ -509,13 +430,11 @@ static int copy_and_sort_files_from_hashmap(
assert(ret);
int log_level = conf_files_log_level(flags);
/* The entries in the array given by hashmap_dump_sorted() are still owned by the hashmap.
* Hence, do not use conf_file_free_many() for 'entries' */
r = hashmap_dump_sorted(fh, (void***) &files, &n_files);
if (r < 0)
return log_oom_full(log_level);
return log_oom_debug();
FOREACH_ARRAY(i, files, n_files) {
ConfFile *c = *i;
@ -528,7 +447,7 @@ static int copy_and_sort_files_from_hashmap(
r = chaseat_prefix_root(c->result, root, &p);
if (r < 0)
return log_full_errno(log_level, r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, root);
if (FLAGS_SET(flags, CONF_FILES_TRUNCATE_SUFFIX) && suffix) {
char *e = endswith(p, suffix);
@ -539,7 +458,7 @@ static int copy_and_sort_files_from_hashmap(
}
if (strv_consume_with_size(&results, &n_results, TAKE_PTR(p)) < 0)
return log_oom_full(log_level);
return log_oom_debug();
continue;
} else
@ -552,20 +471,20 @@ static int copy_and_sort_files_from_hashmap(
_cleanup_free_ char *n = strndup(add, e - add);
if (!n)
return log_oom_full(log_level);
return log_oom_debug();
r = strv_consume_with_size(&results, &n_results, TAKE_PTR(n));
} else
r = strv_extend_with_size(&results, &n_results, add);
if (r < 0)
return log_oom_full(log_level);
return log_oom_debug();
}
*ret = TAKE_PTR(results);
return 0;
}
static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlags flags, const ConfFile **ret) {
static int insert_replacement(Hashmap **fh, ConfFile *replacement, const ConfFile **ret) {
_cleanup_(conf_file_freep) ConfFile *c = ASSERT_PTR(replacement);
int r;
@ -585,7 +504,7 @@ static int insert_replacement(Hashmap **fh, ConfFile *replacement, ConfFilesFlag
r = hashmap_ensure_put(fh, &conf_file_hash_ops, c->name, c);
if (r < 0) {
assert(r == -ENOMEM);
return log_oom_full(conf_files_log_level(flags));
return log_oom_debug();
}
assert(r > 0);
@ -614,10 +533,8 @@ static int conf_files_list_impl(
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
root = empty_to_root(root);
if (replacement) {
r = conf_file_new_at(replacement, rfd, flags & CONF_FILES_WARN, &c);
r = conf_file_new_at(replacement, rfd, CHASE_NONEXISTENT, &c);
if (r < 0)
return r;
}
@ -629,14 +546,12 @@ static int conf_files_list_impl(
r = chase_and_opendirat(rfd, *p, CHASE_AT_RESOLVE_IN_ROOT, &path, &dir);
if (r < 0) {
if (r != -ENOENT)
log_full_errno(conf_files_log_level(flags), r,
"Failed to chase and open directory '%s%s', ignoring: %m",
root, skip_leading_slash(*p));
log_debug_errno(r, "Failed to chase and open directory '%s/%s', ignoring: %m", strempty(root), skip_leading_slash(*p));
continue;
}
if (c && streq_ptr(path_startswith(c->result, path), c->name)) {
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
if (r < 0)
return r;
}
@ -647,7 +562,7 @@ static int conf_files_list_impl(
}
if (c) {
r = insert_replacement(&fh, TAKE_PTR(c), flags, &inserted);
r = insert_replacement(&fh, TAKE_PTR(c), &inserted);
if (r < 0)
return r;
}
@ -673,7 +588,7 @@ int conf_files_list_strv(
assert(ret);
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
r = prepare_dirs(root, (char**) dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
@ -702,7 +617,7 @@ int conf_files_list_strv_full(
assert(ret_files);
assert(ret_n_files);
r = prepare_dirs(root, flags, (char**) dirs, &rfd, &root_abs, &dirs_abs);
r = prepare_dirs(root, (char**) dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
@ -711,7 +626,7 @@ int conf_files_list_strv_full(
if (r < 0)
return r;
return dump_files(fh, empty_to_root(root_abs), flags, ret_files, ret_n_files);
return dump_files(fh, empty_to_root(root_abs), ret_files, ret_n_files);
}
int conf_files_list_strv_at(
@ -728,7 +643,7 @@ int conf_files_list_strv_at(
assert(rfd >= 0 || rfd == AT_FDCWD);
assert(ret);
if (rfd >= 0)
if (rfd >= 0 && DEBUG_LOGGING)
(void) fd_get_path(rfd, &root); /* for logging */
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
@ -754,14 +669,14 @@ int conf_files_list_strv_at_full(
assert(ret_files);
assert(ret_n_files);
if (rfd >= 0)
if (rfd >= 0 && DEBUG_LOGGING)
(void) fd_get_path(rfd, &root); /* for logging */
r = conf_files_list_impl(suffix, rfd, root, flags, dirs, /* replacement= */ NULL, &fh, /* ret_inserted= */ NULL);
if (r < 0)
return r;
return dump_files(fh, /* root= */ NULL, flags, ret_files, ret_n_files);
return dump_files(fh, /* root= */ NULL, ret_files, ret_n_files);
}
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir) {
@ -787,7 +702,7 @@ int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, Co
d = strv_split_nulstr(dirs);
if (!d)
return log_oom_full(conf_files_log_level(flags));
return -ENOMEM;
return conf_files_list_strv(ret, suffix, root, flags, (const char**) d);
}
@ -800,7 +715,7 @@ int conf_files_list_nulstr_full(const char *suffix, const char *root, ConfFilesF
d = strv_split_nulstr(dirs);
if (!d)
return log_oom_full(conf_files_log_level(flags));
return -ENOMEM;
return conf_files_list_strv_full(suffix, root, flags, (const char**) d, ret_files, ret_n_files);
}
@ -812,7 +727,7 @@ int conf_files_list_nulstr_at(char ***ret, const char *suffix, int rfd, ConfFile
d = strv_split_nulstr(dirs);
if (!d)
return log_oom_full(conf_files_log_level(flags));
return -ENOMEM;
return conf_files_list_strv_at(ret, suffix, rfd, flags, (const char**) d);
}
@ -825,7 +740,7 @@ int conf_files_list_nulstr_at_full(const char *suffix, int rfd, ConfFilesFlags f
d = strv_split_nulstr(dirs);
if (!d)
return log_oom_full(conf_files_log_level(flags));
return -ENOMEM;
return conf_files_list_strv_at_full(suffix, rfd, flags, (const char**) d, ret_files, ret_n_files);
}
@ -839,7 +754,7 @@ int conf_files_list_with_replacement(
_cleanup_hashmap_free_ Hashmap *fh = NULL;
_cleanup_free_ char *inserted = NULL;
ConfFilesFlags flags = CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_WARN;
ConfFilesFlags flags = CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED_BY_SYMLINK;
_cleanup_close_ int rfd = -EBADF;
_cleanup_free_ char *root_abs = NULL;
_cleanup_strv_free_ char **dirs_abs = NULL;
@ -848,7 +763,7 @@ int conf_files_list_with_replacement(
assert(ret_files);
r = prepare_dirs(root, flags, config_dirs, &rfd, &root_abs, &dirs_abs);
r = prepare_dirs(root, config_dirs, &rfd, &root_abs, &dirs_abs);
if (r < 0)
return r;
@ -860,9 +775,7 @@ int conf_files_list_with_replacement(
if (c) {
r = chaseat_prefix_root(c->result, root_abs, &inserted);
if (r < 0)
return log_full_errno(conf_files_log_level(flags), r,
"Failed to prefix '%s' with root '%s': %m",
c->result, empty_to_root(root_abs));
return log_debug_errno(r, "Failed to prefix '%s' with root '%s': %m", c->result, empty_to_root(root_abs));
}
r = copy_and_sort_files_from_hashmap(fh, ".conf", empty_to_root(root_abs), flags, ret_files);
@ -878,7 +791,6 @@ int conf_files_list_dropins(
char ***ret,
const char *dropin_dirname,
const char *root,
ConfFilesFlags flags,
const char * const *dirs) {
_cleanup_strv_free_ char **dropin_dirs = NULL;
@ -892,9 +804,9 @@ int conf_files_list_dropins(
suffix = strjoina("/", dropin_dirname);
r = strv_extend_strv_concat(&dropin_dirs, dirs, suffix);
if (r < 0)
return log_oom_full(conf_files_log_level(flags));
return r;
return conf_files_list_strv(ret, ".conf", root, flags, (const char* const*) dropin_dirs);
return conf_files_list_strv(ret, ".conf", root, 0, (const char* const*) dropin_dirs);
}
/**

View File

@ -14,7 +14,6 @@ typedef enum ConfFilesFlags {
CONF_FILES_FILTER_MASKED_BY_EMPTY = 1 << 5, /* implement masking by empty file */
CONF_FILES_FILTER_MASKED = CONF_FILES_FILTER_MASKED_BY_SYMLINK | CONF_FILES_FILTER_MASKED_BY_EMPTY,
CONF_FILES_TRUNCATE_SUFFIX = 1 << 6, /* truncate specified suffix from return filename or path */
CONF_FILES_WARN = 1 << 7, /* warn on some errors */
} ConfFilesFlags;
typedef struct ConfFile {
@ -30,8 +29,8 @@ ConfFile* conf_file_free(ConfFile *c);
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfFile*, conf_file_free);
void conf_file_free_many(ConfFile **array, size_t n);
int conf_file_new_at(const char *path, int rfd, ConfFilesFlags flags, ConfFile **ret);
int conf_file_new(const char *path, const char *root, ConfFilesFlags flags, ConfFile **ret);
int conf_file_new_at(const char *path, int rfd, ChaseFlags chase_flags, ConfFile **ret);
int conf_file_new(const char *path, const char *root, ChaseFlags chase_flags, ConfFile **ret);
int conf_files_list(char ***ret, const char *suffix, const char *root, ConfFilesFlags flags, const char *dir);
int conf_files_list_at(char ***ret, const char *suffix, int rfd, ConfFilesFlags flags, const char *dir);
@ -57,7 +56,6 @@ int conf_files_list_dropins(
char ***ret,
const char *dropin_dirname,
const char *root,
ConfFilesFlags flags,
const char * const *dirs);
typedef int parse_line_t(

View File

@ -232,7 +232,7 @@ static int run(int argc, char *argv[]) {
} else {
_cleanup_strv_free_ char **files = NULL;
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN, (const char**) CONF_PATHS_STRV("binfmt.d"));
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
if (r < 0)
return log_error_errno(r, "Failed to enumerate binfmt.d files: %m");

View File

@ -438,7 +438,7 @@ static EFI_STATUS set_reboot_into_firmware(void) {
err = efivar_set_uint64_le(MAKE_GUID_PTR(EFI_GLOBAL_VARIABLE), u"OsIndications", osind, EFI_VARIABLE_NON_VOLATILE);
if (err != EFI_SUCCESS)
return log_warning_status(err, "Error setting OsIndications, ignoring: %m");
return log_error_status(err, "Error setting OsIndications, ignoring: %m");
return EFI_SUCCESS;
}
@ -1065,7 +1065,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
} else if (streq8(key, "default")) {
if (value[0] == '@' && !strcaseeq8(value, "@saved")) {
log_warning("Unsupported special entry identifier, ignoring: %s", value);
log_error("Unsupported special entry identifier, ignoring: %s", value);
continue;
}
free(config->entry_default_config);
@ -1073,31 +1073,31 @@ static void config_defaults_load_from_file(Config *config, char *content) {
} else if (streq8(key, "editor")) {
if (!parse_boolean(value, &config->editor))
log_warning("Error parsing 'editor' config option, ignoring: %s", value);
log_error("Error parsing 'editor' config option, ignoring: %s", value);
} else if (streq8(key, "auto-entries")) {
if (!parse_boolean(value, &config->auto_entries))
log_warning("Error parsing 'auto-entries' config option, ignoring: %s", value);
log_error("Error parsing 'auto-entries' config option, ignoring: %s", value);
} else if (streq8(key, "auto-firmware")) {
if (!parse_boolean(value, &config->auto_firmware))
log_warning("Error parsing 'auto-firmware' config option, ignoring: %s", value);
log_error("Error parsing 'auto-firmware' config option, ignoring: %s", value);
} else if (streq8(key, "auto-poweroff")) {
if (!parse_boolean(value, &config->auto_poweroff))
log_warning("Error parsing 'auto-poweroff' config option, ignoring: %s", value);
log_error("Error parsing 'auto-poweroff' config option, ignoring: %s", value);
} else if (streq8(key, "auto-reboot")) {
if (!parse_boolean(value, &config->auto_reboot))
log_warning("Error parsing 'auto-reboot' config option, ignoring: %s", value);
log_error("Error parsing 'auto-reboot' config option, ignoring: %s", value);
} else if (streq8(key, "beep")) {
if (!parse_boolean(value, &config->beep))
log_warning("Error parsing 'beep' config option, ignoring: %s", value);
log_error("Error parsing 'beep' config option, ignoring: %s", value);
} else if (streq8(key, "reboot-for-bitlocker")) {
if (!parse_boolean(value, &config->reboot_for_bitlocker))
log_warning("Error parsing 'reboot-for-bitlocker' config option, ignoring: %s",
log_error("Error parsing 'reboot-for-bitlocker' config option, ignoring: %s",
value);
} else if (streq8(key, "reboot-on-error")) {
@ -1106,7 +1106,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else {
bool reboot_yes_no;
if (!parse_boolean(value, &reboot_yes_no))
log_warning("Error parsing 'reboot-on-error' config option, ignoring: %s", value);
log_error("Error parsing 'reboot-on-error' config option, ignoring: %s", value);
else
config->reboot_on_error = reboot_yes_no ? REBOOT_YES : REBOOT_NO;
}
@ -1121,7 +1121,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else if (streq8(value, "off"))
config->secure_boot_enroll = ENROLL_OFF;
else
log_warning("Error parsing 'secure-boot-enroll' config option, ignoring: %s",
log_error("Error parsing 'secure-boot-enroll' config option, ignoring: %s",
value);
} else if (streq8(key, "secure-boot-enroll-action")) {
if (streq8(value, "reboot"))
@ -1129,7 +1129,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else if (streq8(value, "shutdown"))
config->secure_boot_enroll_action = ENROLL_ACTION_SHUTDOWN;
else
log_warning("Error parsing 'secure-boot-enroll-action' config option, ignoring: %s",
log_error("Error parsing 'secure-boot-enroll-action' config option, ignoring: %s",
value);
} else if (streq8(key, "secure-boot-enroll-timeout-sec")) {
if (streq8(value, "hidden"))
@ -1137,7 +1137,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else {
uint64_t u;
if (!parse_number8(value, &u, NULL) || u > ENROLL_TIMEOUT_MAX) {
log_warning("Error parsing 'secure-boot-enroll-timeout-sec' config option, ignoring: %s",
log_error("Error parsing 'secure-boot-enroll-timeout-sec' config option, ignoring: %s",
value);
continue;
}
@ -1153,7 +1153,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
else {
uint64_t u;
if (!parse_number8(value, &u, NULL) || u > CONSOLE_MODE_RANGE_MAX) {
log_warning("Error parsing 'console-mode' config option, ignoring: %s",
log_error("Error parsing 'console-mode' config option, ignoring: %s",
value);
continue;
}
@ -1161,7 +1161,7 @@ static void config_defaults_load_from_file(Config *config, char *content) {
}
} else if (streq8(key, "log-level")) {
if (log_set_max_level_from_string(value) < 0)
log_warning("Error parsing 'log-level' config option, ignoring: %s", value);
log_error("Error parsing 'log-level' config option, ignoring: %s", value);
}
}

View File

@ -2125,8 +2125,6 @@ static int method_enqueue_marked_jobs(sd_bus_message *message, void *userdata, s
char *k;
int ret = 0;
HASHMAP_FOREACH_KEY(u, k, m->units) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
/* ignore aliases */
if (u->id != k)
continue;
@ -2139,16 +2137,17 @@ static int method_enqueue_marked_jobs(sd_bus_message *message, void *userdata, s
else
continue;
r = mac_selinux_unit_access_check(u, message, "start", &error);
r = mac_selinux_unit_access_check(u, message, "start", reterr_error);
if (r >= 0)
r = bus_unit_queue_job_one(message, u,
JOB_TRY_RESTART, JOB_FAIL, flags,
reply, &error);
reply, reterr_error);
if (ERRNO_IS_NEG_RESOURCE(r))
return r;
if (r < 0) {
RET_GATHER(ret, r);
log_warning_errno(r, "%s", bus_error_message(&error, r));
if (ret >= 0)
ret = r;
sd_bus_error_free(reterr_error);
}
}

View File

@ -24,9 +24,9 @@
#include "manager.h"
#include "namespace-util.h"
#include "path-util.h"
#include "pidref.h"
#include "process-util.h"
#include "selinux-access.h"
#include "service.h"
#include "set.h"
#include "signal-util.h"
#include "special.h"
@ -1960,23 +1960,44 @@ int bus_unit_queue_job_one(
Job *j, *a;
int r;
assert(u);
if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
if (type == JOB_RESTART)
type = JOB_RELOAD_OR_START;
else if (type == JOB_TRY_RESTART)
type = JOB_TRY_RELOAD;
}
r = unit_queue_job_check_and_collapse_type(u, &type, /* reload_if_possible= */ FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE));
if (r == -ENOENT)
if (type == JOB_STOP && UNIT_IS_LOAD_ERROR(u->load_state) && unit_active_state(u) == UNIT_INACTIVE)
return sd_bus_error_setf(reterr_error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
if (r == -EUNATCH)
if ((type == JOB_START && u->refuse_manual_start) ||
(type == JOB_STOP && u->refuse_manual_stop) ||
(IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
return sd_bus_error_setf(reterr_error,
BUS_ERROR_ONLY_BY_DEPENDENCY,
"Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
u->id);
if (r == -ESHUTDOWN)
/* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
* gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
* job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
* job enqueuing early.
*
* Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
* here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
* to start Type=dbus services even when dbus is inactive. */
if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
Unit *dbus;
dbus = manager_get_unit(u->manager, dbus_unit);
if (dbus && unit_stop_pending(dbus))
return sd_bus_error_setf(reterr_error,
BUS_ERROR_SHUTTING_DOWN,
"Operation for unit %s refused, D-Bus is shutting down.",
u->id);
if (r < 0)
return r;
}
if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) {
affected = set_new(NULL);

View File

@ -36,7 +36,7 @@ int ipe_setup(void) {
&policies,
".p7b",
/* root= */ NULL,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
CONF_PATHS_NULSTR("ipe"));
if (r < 0)
return log_error_errno(r, "Failed to assemble list of IPE policies: %m");

View File

@ -2621,7 +2621,6 @@ int setup_namespace(const NamespaceParameters *p, char **reterr_path) {
r = mountfsd_mount_image(
p->root_image,
userns_fd,
p->root_image_options,
p->root_image_policy,
p->verity,
dissect_image_flags,

View File

@ -7003,57 +7003,3 @@ UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependency
assert_not_reached();
}
}
int unit_queue_job_check_and_collapse_type(
Unit *u,
JobType *type, /* input and output */
bool reload_if_possible) {
/* Returns:
*
* -ENOENT Unit not loaded
* -EUNATCH Unit can only be activated via dependency, not directly
* -ESHUTDOWN System bus is shutting down */
JobType t;
assert(u);
assert(type);
t = *type;
if (reload_if_possible && unit_can_reload(u)) {
if (t == JOB_RESTART)
t = JOB_RELOAD_OR_START;
else if (t == JOB_TRY_RESTART)
t = JOB_TRY_RELOAD;
}
if (t == JOB_STOP && UNIT_IS_LOAD_ERROR(u->load_state) && unit_active_state(u) == UNIT_INACTIVE)
return -ENOENT;
if ((t == JOB_START && u->refuse_manual_start) ||
(t == JOB_STOP && u->refuse_manual_stop) ||
(IN_SET(t, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
(t == JOB_RELOAD_OR_START && job_type_collapse(t, u) == JOB_START && u->refuse_manual_start))
return -EUNATCH;
/* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
* gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
* job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
* job enqueuing early.
*
* Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
* here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
* to start Type=dbus services even when dbus is inactive. */
if (t == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
Unit *dbus = manager_get_unit(u->manager, dbus_unit);
if (dbus && unit_stop_pending(dbus))
return -ESHUTDOWN;
}
*type = t;
return 0;
}

View File

@ -1092,8 +1092,6 @@ UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependency
DECLARE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);
int unit_queue_job_check_and_collapse_type(Unit *u, JobType *type, bool reload_if_possible);
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full_errno_zerook(unit, level, error, ...) \

View File

@ -6,13 +6,9 @@
#include "alloc-util.h"
#include "architecture.h"
#include "bitfield.h"
#include "build.h"
#include "bus-polkit.h"
#include "confidential-virt.h"
#include "dbus-job.h"
#include "errno-util.h"
#include "glyph-util.h"
#include "json-util.h"
#include "manager.h"
#include "pidref.h"
@ -24,7 +20,6 @@
#include "version.h"
#include "varlink-common.h"
#include "varlink-manager.h"
#include "varlink-unit.h"
#include "varlink-util.h"
#include "virt.h"
#include "watchdog.h"
@ -304,109 +299,3 @@ int vl_method_reexecute_manager(sd_varlink *link, sd_json_variant *parameters, s
return 1;
}
static int varlink_manager_queue_job_one(
sd_varlink *link,
Unit *u,
JobType type,
JobMode mode,
uint32_t *ret_job_id) {
int r;
assert(u);
r = unit_queue_job_check_and_collapse_type(u, &type, /* reload_if_possible= */ BIT_SET(u->markers, UNIT_MARKER_NEEDS_RELOAD));
if (r == -ENOENT)
return varlink_error_no_such_unit(link, "name");
if (r == -EUNATCH)
return sd_varlink_errorb(link, VARLINK_ERROR_MANAGER_ONLY_BY_DEPENDENCY);
if (r == -ESHUTDOWN)
return sd_varlink_errorb(link, VARLINK_ERROR_MANAGER_BUS_SHUTTING_DOWN);
if (r < 0)
return r;
Job *j;
r = manager_add_job(u->manager, type, u, mode, /* reterr_error= */ NULL, &j);
if (r < 0)
return r;
/* Before we send the method reply, force out the announcement JobNew for this job */
bus_job_send_pending_change_signal(j, /* including_new= */ true);
if (ret_job_id)
*ret_job_id = j->id;
return 0;
}
int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *manager = ASSERT_PTR(userdata);
int r;
assert(link);
assert(parameters);
r = sd_varlink_dispatch(link, parameters, /* dispatch_table= */ NULL, /* userdata= */ NULL);
if (r != 0)
return r;
r = mac_selinux_access_check_varlink(link, "start");
if (r < 0)
return r;
r = varlink_verify_polkit_async(
link,
manager->system_bus,
"org.freedesktop.systemd1.manage-units",
/* details= */ NULL,
&manager->polkit_registry);
if (r <= 0)
return r;
log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS));
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL, *reply = NULL;
Unit *u;
char *k;
int ret = 0;
HASHMAP_FOREACH_KEY(u, k, manager->units) {
uint32_t job_id = 0; /* silence 'maybe-uninitialized' compiler warning */
/* ignore aliases */
if (u->id != k)
continue;
if (u->markers == 0)
continue;
r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(JOB_TRY_RESTART));
if (r >= 0)
r = varlink_manager_queue_job_one(
link,
u,
JOB_TRY_RESTART,
JOB_FAIL,
&job_id);
if (ERRNO_IS_NEG_RESOURCE(r))
return r;
RET_GATHER(ret, r);
if (r >= 0) {
r = sd_json_variant_append_arrayb(&array, SD_JSON_BUILD_UNSIGNED(job_id));
if (r < 0)
return r;
}
}
if (ret < 0)
return ret;
/* Return parameter is not nullable, build empty array if there's nothing to return */
if (array)
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_VARIANT("JobIDs", array));
else
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_EMPTY_ARRAY("JobIDs"));
if (r < 0)
return r;
return sd_varlink_reply(link, reply);
}

View File

@ -4,10 +4,7 @@
#include "core-forward.h"
#define VARLINK_ERROR_MANAGER_RATE_LIMIT_REACHED "io.systemd.Manager.RateLimitReached"
#define VARLINK_ERROR_MANAGER_ONLY_BY_DEPENDENCY "io.systemd.Manager.OnlyByDependency"
#define VARLINK_ERROR_MANAGER_BUS_SHUTTING_DOWN "io.systemd.Manager.BusShuttingDown"
int vl_method_describe_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_reexecute_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_reload_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -382,7 +382,7 @@ static void unit_lookup_parameters_done(UnitLookupParameters *p) {
pidref_done(&p->pidref);
}
int varlink_error_no_such_unit(sd_varlink *v, const char *name) {
static int varlink_error_no_such_unit(sd_varlink *v, const char *name) {
return sd_varlink_errorbo(
ASSERT_PTR(v),
VARLINK_ERROR_UNIT_NO_SUCH_UNIT,

View File

@ -5,5 +5,4 @@
#define VARLINK_ERROR_UNIT_NO_SUCH_UNIT "io.systemd.Unit.NoSuchUnit"
int varlink_error_no_such_unit(sd_varlink *v, const char *name);
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -386,7 +386,6 @@ int manager_setup_varlink_server(Manager *m) {
"io.systemd.Manager.Describe", vl_method_describe_manager,
"io.systemd.Manager.Reexecute", vl_method_reexecute_manager,
"io.systemd.Manager.Reload", vl_method_reload_manager,
"io.systemd.Manager.EnqueueMarkedJobs", vl_method_enqueue_marked_jobs_manager,
"io.systemd.Unit.List", vl_method_list_units,
"io.systemd.service.Ping", varlink_method_ping,
"io.systemd.service.GetEnvironment", varlink_method_get_environment);

View File

@ -2190,7 +2190,6 @@ static int run(int argc, char *argv[]) {
r = mountfsd_mount_image(
arg_image,
userns_fd,
/* options= */ NULL,
arg_image_policy,
&arg_verity_settings,
arg_flags,

View File

@ -52,7 +52,7 @@ static int load_and_print(void) {
if (r < 0)
return r;
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN, (const char **) dirs);
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char **) dirs);
if (r < 0)
return r;

File diff suppressed because it is too large Load Diff

View File

@ -1521,7 +1521,7 @@ static int manager_load_public_keys(Manager *m) {
&files,
".public",
NULL,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
KEY_PATHS_NULSTR);
if (r < 0)
return log_error_errno(r, "Failed to assemble list of public key directories: %m");

View File

@ -685,7 +685,7 @@ static int context_load_plugins(Context *c) {
&c->plugins,
".install",
c->rfd,
CONF_FILES_EXECUTABLE | CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
CONF_FILES_EXECUTABLE | CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
STRV_MAKE_CONST("/etc/kernel/install.d", "/usr/lib/kernel/install.d"));
if (r < 0)
return log_error_errno(r, "Failed to find plugins: %m");

View File

@ -453,9 +453,7 @@ int catalog_update(const char *database, const char *root, const char* const *di
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
r = conf_files_list_strv_full(".catalog", root,
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
dirs, &files, &n_files);
r = conf_files_list_strv_full(".catalog", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, dirs, &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to get catalog files: %m");

View File

@ -265,12 +265,6 @@ static int varlink_idl_format_field(
fputs(colors[COLOR_RESET], f);
break;
case SD_VARLINK_ANY:
fputs(colors[COLOR_FIELD_TYPE], f);
fputs("any", f);
fputs(colors[COLOR_RESET], f);
break;
case SD_VARLINK_NAMED_TYPE:
fputs(colors[COLOR_IDENTIFIER], f);
fputs(ASSERT_PTR(field->named_type), f);
@ -873,9 +867,6 @@ static int varlink_idl_subparse_field_type(
} else if (startswith(*p, "object")) {
l = 6;
field->field_type = SD_VARLINK_OBJECT;
} else if (startswith(*p, "any")) {
l = 3;
field->field_type = SD_VARLINK_ANY;
} else if (**p == '(') {
_cleanup_(varlink_symbol_freep) sd_varlink_symbol *symbol = NULL;
size_t n_fields = 0;
@ -1435,7 +1426,7 @@ bool varlink_idl_symbol_name_is_valid(const char *name) {
/* We might want to reference VARLINK_STRUCT_TYPE and VARLINK_ENUM_TYPE symbols where we also
* reference native types, hence make sure the native type names are refused as symbol names. */
if (STR_IN_SET(name, "bool", "int", "float", "string", "object", "any"))
if (STR_IN_SET(name, "bool", "int", "float", "string", "object"))
return false;
/* Symbols must be named with an uppercase letter as first character */
@ -1763,10 +1754,6 @@ static int varlink_idl_validate_field_element_type(const sd_varlink_field *field
break;
case SD_VARLINK_ANY:
/* The any type accepts any JSON value, no validation needed */
break;
case _SD_VARLINK_FIELD_COMMENT:
break;

View File

@ -423,7 +423,7 @@ static int run(int argc, char *argv[]) {
RET_GATHER(ret, modules_list_append_dup(&module_set, *i));
r = conf_files_list_nulstr_full(".conf", /* root= */ NULL,
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
conf_file_dirs, &files, &n_files);
if (r < 0)
RET_GATHER(ret, log_error_errno(r, "Failed to enumerate modules-load.d files: %m"));

View File

@ -17,7 +17,6 @@
#include "dissect-image.h"
#include "env-util.h"
#include "errno-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fs-util.h"
#include "format-util.h"
@ -62,44 +61,6 @@ static const ImagePolicy image_policy_untrusted = {
.default_flags = PARTITION_POLICY_IGNORE,
};
static int json_dispatch_image_options(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
_cleanup_(mount_options_free_allp) MountOptions *options = NULL;
MountOptions **p = ASSERT_PTR(userdata);
if (sd_json_variant_is_null(variant)) {
*p = mount_options_free_all(*p);
return 0;
}
if (!sd_json_variant_is_object(variant))
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an object.", strna(name));
const char *k;
sd_json_variant *e;
JSON_VARIANT_OBJECT_FOREACH(k, e, variant) {
PartitionDesignator pd = partition_designator_from_string(k);
if (pd < 0)
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Invalid partition designator '%s'.", strna(k));
if (!sd_json_variant_is_string(e))
return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "Mount option for partition '%s' is not a string.", strna(k));
if (!options) {
options = new0(MountOptions, 1);
if (!options)
return -ENOMEM;
}
options->options[pd] = strdup(sd_json_variant_string(e));
if (!options->options[pd])
return -ENOMEM;
}
mount_options_free_all(*p);
*p = TAKE_PTR(options);
return 0;
}
static int json_dispatch_image_policy(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
_cleanup_(image_policy_freep) ImagePolicy *q = NULL;
ImagePolicy **p = ASSERT_PTR(userdata);
@ -131,7 +92,6 @@ typedef struct MountImageParameters {
int growfs;
char *password;
ImagePolicy *image_policy;
MountOptions *options;
bool verity_sharing;
struct iovec verity_root_hash;
struct iovec verity_root_hash_sig;
@ -145,7 +105,6 @@ static void mount_image_parameters_done(MountImageParameters *p) {
p->image_policy = image_policy_free(p->image_policy);
iovec_done(&p->verity_root_hash);
iovec_done(&p->verity_root_hash_sig);
p->options = mount_options_free_all(p->options);
}
static int validate_image_fd(int fd, MountImageParameters *p) {
@ -326,41 +285,6 @@ static int validate_userns(sd_varlink *link, int *userns_fd) {
return 0;
}
static int mount_options_to_polkit_details(const MountOptions *options, char **ret_mount_options_concat) {
_cleanup_free_ char *mount_options_concat = NULL;
int r;
assert(ret_mount_options_concat);
if (!options) {
*ret_mount_options_concat = NULL;
return 0;
}
for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
_cleanup_free_ char *escaped = NULL;
if (isempty(options->options[i]))
continue;
escaped = shell_escape(options->options[i], ":");
if (!escaped)
return log_oom_debug();
r = strextendf_with_separator(
&mount_options_concat,
",",
"%s:%s",
partition_designator_to_string(i),
escaped);
if (r < 0)
return r;
}
*ret_mount_options_concat = TAKE_PTR(mount_options_concat);
return 0;
}
static int vl_method_mount_image(
sd_varlink *link,
sd_json_variant *parameters,
@ -374,7 +298,6 @@ static int vl_method_mount_image(
{ "growFileSystems", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_tristate, offsetof(MountImageParameters, growfs), 0 },
{ "password", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(MountImageParameters, password), 0 },
{ "imagePolicy", SD_JSON_VARIANT_STRING, json_dispatch_image_policy, offsetof(MountImageParameters, image_policy), 0 },
{ "mountOptions", SD_JSON_VARIANT_OBJECT, json_dispatch_image_options, offsetof(MountImageParameters, options), 0 },
{ "veritySharing", SD_JSON_VARIANT_BOOLEAN, sd_json_dispatch_stdbool, offsetof(MountImageParameters, verity_sharing), 0 },
{ "verityDataFileDescriptor", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint, offsetof(MountImageParameters, verity_data_fd_idx), 0 },
{ "verityRootHash", SD_JSON_VARIANT_STRING, json_dispatch_unhex_iovec, offsetof(MountImageParameters, verity_root_hash), 0 },
@ -439,14 +362,10 @@ static int vl_method_mount_image(
if (r != 0)
return r;
/* Mount options could be used to thwart security measures such as ACLs or SELinux so if they are
* specified don't mark the image as trusted so that it requires additional privileges to use. */
if (!p.options) {
r = verify_trusted_image_fd_by_path(image_fd);
if (r < 0)
return r;
image_is_trusted = r;
}
if (p.verity_data_fd_idx != UINT_MAX) {
verity_data_fd = sd_varlink_peek_dup_fd(link, p.verity_data_fd_idx);
@ -466,16 +385,8 @@ static int vl_method_mount_image(
verity.root_hash_sig = TAKE_STRUCT(p.verity_root_hash_sig);
}
/* Let the polkit rule know what mount options the caller tries to use, so that rules can decide
* whether to allow or deny the operation based on what the options are. */
_cleanup_free_ char *mount_options_concat = NULL;
r = mount_options_to_polkit_details(p.options, &mount_options_concat);
if (r < 0)
return r;
const char *polkit_details[] = {
"read_only", one_zero(p.read_only > 0),
!isempty(mount_options_concat) ? "mount_options" : NULL, mount_options_concat,
NULL,
};
@ -499,7 +410,7 @@ static int vl_method_mount_image(
r = varlink_verify_polkit_async_full(
link,
/* bus= */ NULL,
p.options ? polkit_untrusted_action : polkit_action, /* Using mount options requires higher privs */
polkit_action,
polkit_details,
/* good_user= */ UID_INVALID,
polkit_flags,
@ -571,7 +482,7 @@ static int vl_method_mount_image(
r = dissect_loop_device(
loop,
&verity,
p.options,
/* mount_options= */ NULL,
use_policy,
/* image_filter= */ NULL,
dissect_flags,

View File

@ -1098,7 +1098,7 @@ int netdev_load(Manager *manager) {
assert(manager);
r = conf_files_list_strv(&files, ".netdev", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate netdev files: %m");
@ -1127,7 +1127,7 @@ int netdev_reload(Manager *manager) {
assert(manager);
r = conf_files_list_strv(&files, ".netdev", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate netdev files: %m");

View File

@ -106,7 +106,7 @@ static int get_config_files_by_name(
if (!dropin_dirname)
return -ENOMEM;
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
r = conf_files_list_dropins(ret_dropins, dropin_dirname, /* root= */ NULL, NETWORK_DIRS);
if (r < 0)
return r;
}

View File

@ -612,7 +612,7 @@ int network_load(Manager *manager, OrderedHashmap **ret) {
assert(manager);
assert(ret);
r = conf_files_list_strv(&files, ".network", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate network files: %m");

View File

@ -6384,7 +6384,6 @@ static int run(int argc, char *argv[]) {
r = mountfsd_mount_image(
arg_image,
userns_fd,
/* options= */ NULL,
arg_image_policy,
&arg_verity_settings,
dissect_image_flags,

View File

@ -1802,9 +1802,7 @@ static int event_log_add_component_dir(EventLog *el, const char *path, char **ba
return log_oom();
}
r = conf_files_list_strv(&files, ".pcrlock", /* root= */ NULL,
CONF_FILES_REGULAR|CONF_FILES_WARN,
(const char*const*) search);
r = conf_files_list_strv(&files, ".pcrlock", /* root= */ NULL, CONF_FILES_REGULAR, (const char*const*) search);
if (r < 0)
return log_error_errno(r, "Failed to enumerate .pcrlock files for component '%s': %m", id);
@ -1831,9 +1829,7 @@ static int event_log_load_components(EventLog *el) {
"/usr/local/lib/pcrlock.d",
"/usr/lib/pcrlock.d");
r = conf_files_list_strv(&files, /* suffix= */ NULL, /* root= */ NULL,
CONF_FILES_REGULAR|CONF_FILES_DIRECTORY|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
(const char*const*) dirs);
r = conf_files_list_strv(&files, NULL, NULL, CONF_FILES_REGULAR|CONF_FILES_DIRECTORY|CONF_FILES_FILTER_MASKED, (const char*const*) dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate .pcrlock files: %m");

View File

@ -0,0 +1,11 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
executables += [
generator_template + {
'name' : 'systemd-rc-local-generator',
'sources' : files('rc-local-generator.c'),
'conditions' : [
'HAVE_SYSV_RC_LOCAL',
],
},
]

View File

@ -0,0 +1,74 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <unistd.h>
#include "generator.h"
#include "initrd-util.h"
#include "log.h"
#include "mkdir-label.h"
#include "string-util.h"
static const char *arg_dest = NULL;
/* So you are reading this, and might wonder: why is this implemented as a generator rather than as a plain, statically
* enabled service that carries appropriate ConditionFileIsExecutable= lines? The answer is this: conditions bypass
* execution of a service's binary, but they have no influence on unit dependencies. Thus, a service that is
* conditioned out will still act as synchronization point in the dependency tree, and we'd rather not have that for
* these two legacy scripts. */
static int add_symlink(const char *service, const char *where) {
const char *from, *to;
assert(service);
assert(where);
from = strjoina(SYSTEM_DATA_UNIT_DIR "/", service);
to = strjoina(arg_dest, "/", where, ".wants/", service);
(void) mkdir_parents_label(to, 0755);
if (symlink(from, to) < 0) {
if (errno == EEXIST)
return 0;
return log_error_errno(errno, "Failed to create symlink %s: %m", to);
}
return 1;
}
static int check_executable(const char *path) {
assert(path);
if (access(path, X_OK) < 0) {
if (errno == ENOENT)
return log_debug_errno(errno, "%s does not exist, skipping.", path);
if (errno == EACCES)
return log_info_errno(errno, "%s is not marked executable, skipping.", path);
return log_warning_errno(errno, "Couldn't determine if %s exists and is executable, skipping: %m", path);
}
return 0;
}
static int run(const char *dest, const char *dest_early, const char *dest_late) {
int r = 0, k = 0;
assert_se(arg_dest = dest);
if (in_initrd()) {
log_debug("Skipping generator, running in the initrd.");
return EXIT_SUCCESS;
}
if (check_executable(SYSTEM_SYSVRCLOCAL_PATH) >= 0) {
log_debug("Automatically adding rc-local.service.");
r = add_symlink("rc-local.service", "multi-user.target");
}
return r < 0 ? r : k;
}
DEFINE_MAIN_GENERATOR_FUNCTION(run);

View File

@ -3375,7 +3375,7 @@ static int context_read_definitions(Context *context) {
&files,
".conf",
context->definitions ? NULL : arg_root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate *.conf files: %m");

View File

@ -211,7 +211,7 @@ int manager_load_delegates(Manager *m) {
assert(m);
r = conf_files_list_strv(&files, ".dns-delegate", /* root= */ NULL, CONF_FILES_WARN, DNS_DELEGATE_SEARCH_DIRS);
r = conf_files_list_strv(&files, ".dns-delegate", /* root= */ NULL, /* flags= */ 0, DNS_DELEGATE_SEARCH_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate .dns-delegate files: %m");

View File

@ -437,7 +437,7 @@ static int dns_trust_anchor_load_files(
assert(suffix);
assert(loader);
r = conf_files_list_nulstr(&files, suffix, /* root= */ NULL, CONF_FILES_WARN, trust_anchor_dirs);
r = conf_files_list_nulstr(&files, suffix, NULL, 0, trust_anchor_dirs);
if (r < 0)
return log_error_errno(r, "Failed to enumerate %s trust anchor files: %m", suffix);

View File

@ -225,7 +225,7 @@ int dnssd_load(Manager *manager) {
if (manager->mdns_support != RESOLVE_SUPPORT_YES)
return 0;
r = conf_files_list_strv(&files, ".dnssd", /* root= */ NULL, CONF_FILES_WARN, DNSSD_SERVICE_DIRS);
r = conf_files_list_strv(&files, ".dnssd", NULL, 0, DNSSD_SERVICE_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate .dnssd files: %m");

View File

@ -615,9 +615,7 @@ int config_parse_many(
assert(dropin_dirname);
assert(table);
r = conf_files_list_dropins(&files, dropin_dirname, root,
FLAGS_SET(flags, CONFIG_PARSE_WARN) ? CONF_FILES_WARN : 0,
conf_file_dirs);
r = conf_files_list_dropins(&files, dropin_dirname, root, conf_file_dirs);
if (r < 0)
return log_full_errno(FLAGS_SET(flags, CONFIG_PARSE_WARN) ? LOG_WARNING : LOG_DEBUG, r,
"Failed to list drop-ins in %s: %m", dropin_dirname);
@ -692,7 +690,7 @@ static int dropins_get_stats_by_path(
if (!strextend(&dropin_dirname, ".d"))
return -ENOMEM;
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, /* flags= */ 0, conf_file_dirs);
r = conf_files_list_dropins(&files, dropin_dirname, /* root= */ NULL, conf_file_dirs);
if (r < 0)
return r;
@ -717,7 +715,7 @@ static int dropins_get_stats_by_path(
int config_get_stats_by_path(
const char *suffix,
const char *root,
ConfFilesFlags flags,
unsigned flags,
const char* const* dirs,
bool check_dropins,
Hashmap **ret) {

View File

@ -112,7 +112,7 @@ static inline int config_parse_standard_file_with_dropins(
int config_get_stats_by_path(
const char *suffix,
const char *root,
ConfFilesFlags flags,
unsigned flags,
const char* const* dirs,
bool check_dropins,
Hashmap **ret);

View File

@ -4934,7 +4934,6 @@ int verity_dissect_and_mount(
r = mountfsd_mount_image(
src_fd >= 0 ? FORMAT_PROC_FD_PATH(src_fd) : src,
userns_fd,
options,
image_policy,
verity,
dissect_image_flags,
@ -5101,7 +5100,6 @@ static void mount_image_reply_parameters_done(MountImageReplyParameters *p) {
int mountfsd_mount_image_fd(
int image_fd,
int userns_fd,
const MountOptions *options,
const ImagePolicy *image_policy,
const VeritySettings *verity,
DissectImageFlags flags,
@ -5173,19 +5171,6 @@ int mountfsd_mount_image_fd(
return log_error_errno(r, "Failed to push verity data fd into varlink connection: %m");
}
_cleanup_(sd_json_variant_unrefp) sd_json_variant *mount_options = NULL;
for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
const char *o = mount_options_from_designator(options, i);
if (!o)
continue;
r = sd_json_variant_merge_objectbo(
&mount_options,
SD_JSON_BUILD_PAIR_STRING(partition_designator_to_string(i), o));
if (r < 0)
return log_error_errno(r, "Failed to build mount options array: %m");
}
sd_json_variant *reply = NULL;
r = varlink_callbo_and_log(
vl,
@ -5197,7 +5182,6 @@ int mountfsd_mount_image_fd(
SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", FLAGS_SET(flags, DISSECT_IMAGE_MOUNT_READ_ONLY)),
SD_JSON_BUILD_PAIR_BOOLEAN("growFileSystems", FLAGS_SET(flags, DISSECT_IMAGE_GROWFS)),
SD_JSON_BUILD_PAIR_CONDITION(!!ps, "imagePolicy", SD_JSON_BUILD_STRING(ps)),
JSON_BUILD_PAIR_VARIANT_NON_NULL("mountOptions", mount_options),
SD_JSON_BUILD_PAIR_BOOLEAN("veritySharing", FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)),
SD_JSON_BUILD_PAIR_CONDITION(verity_data_fd >= 0, "verityDataFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd >= 0 ? 2 : 1)),
SD_JSON_BUILD_PAIR_CONDITION(verity && iovec_is_set(&verity->root_hash), "verityRootHash", JSON_BUILD_IOVEC_HEX(&verity->root_hash)),
@ -5290,7 +5274,6 @@ int mountfsd_mount_image_fd(
int mountfsd_mount_image(
const char *path,
int userns_fd,
const MountOptions *options,
const ImagePolicy *image_policy,
const VeritySettings *verity,
DissectImageFlags flags,
@ -5306,7 +5289,7 @@ int mountfsd_mount_image(
return log_error_errno(errno, "Failed to open '%s': %m", path);
_cleanup_(dissected_image_unrefp) DissectedImage *di = NULL;
r = mountfsd_mount_image_fd(image_fd, userns_fd, options, image_policy, verity, flags, &di);
r = mountfsd_mount_image_fd(image_fd, userns_fd, image_policy, verity, flags, &di);
if (r < 0)
return r;

View File

@ -268,8 +268,8 @@ static inline const char* dissected_partition_fstype(const DissectedPartition *m
int get_common_dissect_directory(char **ret);
int mountfsd_mount_image_fd(int image_fd, int userns_fd, const MountOptions *options, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const MountOptions *options, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_image_fd(int image_fd, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_image(const char *path, int userns_fd, const ImagePolicy *image_policy, const VeritySettings *verity, DissectImageFlags flags, DissectedImage **ret);
int mountfsd_mount_directory_fd(int directory_fd, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);
int mountfsd_mount_directory(const char *path, int userns_fd, DissectImageFlags flags, int *ret_mount_fd);

View File

@ -287,7 +287,7 @@ int unit_file_find_dropin_paths(
return 0;
}
r = conf_files_list_strv(ret, file_suffix, /* root= */ NULL, CONF_FILES_WARN, (const char**) dirs);
r = conf_files_list_strv(ret, file_suffix, NULL, 0, (const char**) dirs);
if (r < 0)
return log_warning_errno(r, "Failed to create the list of configuration files: %m");

View File

@ -323,7 +323,7 @@ int execute_directories(
&paths,
/* suffix= */ NULL,
/* root= */ NULL,
CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
directories);
if (r < 0)
return log_error_errno(r, "%s: failed to enumerate executables: %m", name);

View File

@ -610,9 +610,7 @@ int hwdb_update(const char *root, const char *hwdb_bin_dir, bool strict, bool co
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
r = conf_files_list_strv_full(".hwdb", root,
CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
conf_file_dirs, &files, &n_files);
r = conf_files_list_strv_full(".hwdb", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, conf_file_dirs, &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to enumerate hwdb files: %m");

View File

@ -418,7 +418,7 @@ static int relabel_extra(void) {
*/
r = conf_files_list(&files, ".relabel", NULL,
CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR | CONF_FILES_WARN,
CONF_FILES_FILTER_MASKED | CONF_FILES_REGULAR,
"/run/systemd/relabel-extra.d/");
if (r < 0)
return log_error_errno(r, "Failed to enumerate /run/systemd/relabel-extra.d/, ignoring: %m");

View File

@ -6,6 +6,7 @@
#include <unistd.h>
#include "alloc-util.h"
#include "chase.h"
#include "color-util.h"
#include "conf-files.h"
#include "constants.h"
@ -324,22 +325,9 @@ static int cat_file_by_path(const char *p, bool *newline, CatFlags flags) {
assert(p);
r = conf_file_new(p, /* root= */ NULL, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN, &c);
if (r == -ERFKILL) { /* masked */
if (newline) {
if (*newline)
putc('\n', stdout);
*newline = true;
}
printf("%s# %s is a mask.%s\n",
ansi_highlight_magenta(),
p,
ansi_normal());
return 0;
}
r = conf_file_new(p, /* root= */ NULL, CHASE_MUST_BE_REGULAR, &c);
if (r < 0)
return r;
return log_error_errno(r, "Failed to chase '%s': %m", p);
return cat_file(c, newline, flags);
}
@ -470,8 +458,7 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) {
if (!p)
return log_oom();
r = conf_file_new(p, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
if (r >= 0 || r == -ERFKILL) /* Found a regular file or masked file */
if (conf_file_new(p, root, CHASE_MUST_BE_REGULAR, &c) >= 0)
break;
}
@ -486,7 +473,7 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) {
ConfFile **dropins = NULL;
size_t n_dropins = 0;
CLEANUP_ARRAY(dropins, n_dropins, conf_file_free_many);
r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN, (const char* const*) dirs, &dropins, &n_dropins);
r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, (const char* const*) dirs, &dropins, &n_dropins);
if (r < 0)
return log_error_errno(r, "Failed to query file list: %m");

View File

@ -181,17 +181,8 @@ static SD_VARLINK_DEFINE_METHOD(
static SD_VARLINK_DEFINE_METHOD(
Reload);
static SD_VARLINK_DEFINE_METHOD(
EnqueueMarkedJobs,
SD_VARLINK_FIELD_COMMENT("IDs of enqueued jobs"),
SD_VARLINK_DEFINE_OUTPUT(JobIDs, SD_VARLINK_INT, SD_VARLINK_ARRAY));
static SD_VARLINK_DEFINE_ERROR(RateLimitReached);
static SD_VARLINK_DEFINE_ERROR(OnlyByDependency);
static SD_VARLINK_DEFINE_ERROR(BusShuttingDown);
SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Manager,
"io.systemd.Manager",
@ -200,13 +191,7 @@ SD_VARLINK_DEFINE_INTERFACE(
&vl_method_Reexecute,
SD_VARLINK_SYMBOL_COMMENT("Reload the manager configuration"),
&vl_method_Reload,
SD_VARLINK_SYMBOL_COMMENT("Enqueue all marked jobs"),
&vl_method_EnqueueMarkedJobs,
&vl_error_RateLimitReached,
SD_VARLINK_SYMBOL_COMMENT("Unit operation may be requested by dependency only"),
&vl_error_OnlyByDependency,
SD_VARLINK_SYMBOL_COMMENT("Operation refused, the bus is shutting down"),
&vl_error_BusShuttingDown,
&vl_type_ManagerContext,
&vl_type_ManagerRuntime,
&vl_type_Timestamp,

View File

@ -60,8 +60,6 @@ static SD_VARLINK_DEFINE_METHOD(
SD_VARLINK_DEFINE_INPUT(password, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Takes an image policy string (see systemd.image-policy(7) for details) to apply while mounting the image"),
SD_VARLINK_DEFINE_INPUT(imagePolicy, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("The mount options to be used for the partitions of the image, keyed by the partition designator. Requires elevated privileges via polkit if specified, the polkit request details will list them in the 'mount_options' field."),
SD_VARLINK_DEFINE_INPUT(mountOptions, SD_VARLINK_STRING, SD_VARLINK_MAP|SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Whether to automatically reuse already set up dm-verity devices that share the same roothash."),
SD_VARLINK_DEFINE_INPUT(veritySharing, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("File descriptor of the file containing the dm-verity data, if the image is a bare filesystem rather than a DDI."),

View File

@ -461,8 +461,7 @@ static int run(int argc, char *argv[]) {
} else {
_cleanup_strv_free_ char **files = NULL;
r = conf_files_list_strv(&files, ".conf", /* root= */ NULL, CONF_FILES_WARN,
(const char**) CONF_PATHS_STRV("sysctl.d"));
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("sysctl.d"));
if (r < 0)
return log_error_errno(r, "Failed to enumerate sysctl.d files: %m");

View File

@ -67,7 +67,6 @@ __extension__ typedef enum _SD_ENUM_TYPE_S64(sd_varlink_field_type_t) {
SD_VARLINK_FLOAT,
SD_VARLINK_STRING,
SD_VARLINK_OBJECT,
SD_VARLINK_ANY,
SD_VARLINK_ENUM_VALUE,
_SD_VARLINK_FIELD_COMMENT, /* Not really a field, just a comment about a field */
_SD_VARLINK_FIELD_TYPE_MAX,

View File

@ -136,9 +136,7 @@ static int read_definitions(
assert(dirs);
assert(suffix);
r = conf_files_list_strv_full(suffix, arg_root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
dirs, &files, &n_files);
r = conf_files_list_strv_full(suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs, &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix);
@ -211,7 +209,7 @@ static int context_read_definitions(Context *c, const char* node, bool requires_
CLEANUP_ARRAY(files, n_files, conf_file_free_many);
r = conf_files_list_strv_full(".feature", arg_root,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
(const char**) dirs, &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to enumerate sysupdate.d/*.feature definitions: %m");
@ -1560,8 +1558,7 @@ static int verb_components(int argc, char **argv, void *userdata) {
CLEANUP_ARRAY(directories, n_directories, conf_file_free_many);
r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY|CONF_FILES_WARN,
(const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY, (const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
if (r < 0)
return log_error_errno(r, "Failed to enumerate directories: %m");

View File

@ -4,11 +4,8 @@
#include <unistd.h>
#include "alloc-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "rm-rf.h"
#include "tests.h"
#include "tmpfile-util.h"
#define CYLON_WIDTH 6
@ -56,13 +53,6 @@ TEST(cat_files) {
if (access("/etc/fstab", R_OK) >= 0)
assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0);
/* Test masked file (symlink to /dev/null) - should succeed with exit code 0 */
_cleanup_(rm_rf_physical_and_freep) char *tmp = NULL;
ASSERT_OK(mkdtemp_malloc("/tmp/test-cat-files-XXXXXX", &tmp));
_cleanup_free_ char *masked_file = ASSERT_NOT_NULL(path_join(tmp, "masked.conf"));
ASSERT_OK_ERRNO(symlink("/dev/null", masked_file));
ASSERT_OK(cat_files(masked_file, /* dropins= */ NULL, /* flags= */ 0));
}
TEST(red_green_cross_check_mark) {

View File

@ -102,13 +102,6 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_DEFINE_FIELD(ooom, SD_VARLINK_OBJECT, SD_VARLINK_MAP),
SD_VARLINK_DEFINE_FIELD(ooonm, SD_VARLINK_OBJECT, SD_VARLINK_NULLABLE|SD_VARLINK_MAP),
SD_VARLINK_DEFINE_FIELD(aaa, SD_VARLINK_ANY, 0),
SD_VARLINK_DEFINE_FIELD(aaan, SD_VARLINK_ANY, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD(aaaa, SD_VARLINK_ANY, SD_VARLINK_ARRAY),
SD_VARLINK_DEFINE_FIELD(aaana, SD_VARLINK_ANY, SD_VARLINK_NULLABLE|SD_VARLINK_ARRAY),
SD_VARLINK_DEFINE_FIELD(aaam, SD_VARLINK_ANY, SD_VARLINK_MAP),
SD_VARLINK_DEFINE_FIELD(aaanm, SD_VARLINK_ANY, SD_VARLINK_NULLABLE|SD_VARLINK_MAP),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(eee, EnumTest, 0),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(eeen, EnumTest, SD_VARLINK_NULLABLE),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(eeea, EnumTest, SD_VARLINK_ARRAY),
@ -275,7 +268,6 @@ TEST(symbol_name_is_valid) {
assert_se(!varlink_idl_symbol_name_is_valid("float"));
assert_se(!varlink_idl_symbol_name_is_valid("string"));
assert_se(!varlink_idl_symbol_name_is_valid("object"));
assert_se(!varlink_idl_symbol_name_is_valid("any"));
}
TEST(field_name_is_valid) {

View File

@ -184,9 +184,7 @@ static int context_parse_ntp_services_from_disk(Context *c) {
_cleanup_strv_free_ char **files = NULL;
int r;
r = conf_files_list_strv(&files, ".list", /* root= */ NULL,
CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
UNIT_LIST_DIRS);
r = conf_files_list_strv(&files, ".list", NULL, CONF_FILES_FILTER_MASKED, UNIT_LIST_DIRS);
if (r < 0)
return log_error_errno(r, "Failed to enumerate .list files: %m");

View File

@ -450,7 +450,7 @@ static int setup_nvpcr(void) {
&l,
".nvpcr",
/* root= */ NULL,
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX|CONF_FILES_WARN,
CONF_FILES_REGULAR|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED|CONF_FILES_TRUNCATE_SUFFIX,
CONF_PATHS_NULSTR("nvpcr"));
if (r < 0)
return log_error_errno(r, "Failed to find .nvpcr files: %m");

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include "chase.h"
#include "conf-files.h"
#include "fd-util.h"
#include "fuzz.h"
@ -28,7 +29,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
assert_se(rules = udev_rules_new(RESOLVE_NAME_EARLY));
_cleanup_(conf_file_freep) ConfFile *c = NULL;
ASSERT_OK(conf_file_new(filename, /* root= */ NULL, CONF_FILES_REGULAR, &c));
ASSERT_OK(conf_file_new(filename, /* root= */ NULL, CHASE_MUST_BE_REGULAR, &c));
r = udev_rules_parse_file(rules, c, /* extra_checks= */ false, /* ret= */ NULL);
log_info_errno(r, "Parsing %s: %m", filename);

View File

@ -72,19 +72,13 @@ Link.WakeOnLanPassword, config_parse_wol_password,
/* ethtool features */
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RXCSUM])
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TXCSUM])
Link.ScatterGather, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_SG])
Link.ScatterGatherFragmentList, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_FRAGLIST])
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
Link.TCPECNSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO_ECN])
Link.TCPMangleIdSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO_MANGLEID])
Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
Link.PartialGenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO_PARTIAL])
Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0
Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
Link.GenericReceiveOffloadHardware, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_HW])
Link.GenericReceiveOffloadList, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_FRAGLIST])
Link.GenericReceiveOffloadUDPForwarding, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO_UDP_FWD])
Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
Link.ReceiveVLANCTAGHardwareAcceleration, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_CTAG_RX])
Link.TransmitVLANCTAGHardwareAcceleration, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_HW_VLAN_CTAG_TX])

View File

@ -342,7 +342,7 @@ int link_config_load(LinkConfigContext *ctx) {
link_configs_free(ctx);
r = conf_files_list_strv(&files, ".link", /* root= */ NULL, CONF_FILES_WARN, NETWORK_DIRS);
r = conf_files_list_strv(&files, ".link", NULL, 0, NETWORK_DIRS);
if (r < 0)
return log_error_errno(r, "failed to enumerate link files: %m");

View File

@ -7,6 +7,7 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
#include "chase.h"
#include "conf-files.h"
#include "constants.h"
#include "device-private.h"
@ -248,15 +249,11 @@ static int search_rules_file_in_conf_dirs(const char *s, const char *root, ConfF
return log_oom();
_cleanup_(conf_file_freep) ConfFile *c = NULL;
r = conf_file_new(path, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
if (r == -ERFKILL) {
log_warning_errno(r, "File '%s%s' is a mask, ignoring.", empty_to_root(root), skip_leading_slash(path));
return 1; /* Found masked file. */
}
r = conf_file_new(path, root, CHASE_MUST_BE_REGULAR, &c);
if (r == -ENOENT)
continue;
if (r < 0)
return log_error_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(path));
return log_error_errno(r, "Failed to chase \"%s\": %m", path);
if (!GREEDY_REALLOC_APPEND(*files, *n_files, &c, 1))
return log_oom();
@ -282,11 +279,7 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
/* If not found, or if it is a path, then chase it. */
_cleanup_(conf_file_freep) ConfFile *c = NULL;
r = conf_file_new(s, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, &c);
if (r == -ERFKILL) {
log_warning_errno(r, "File '%s%s' is a mask, ignoring.", empty_to_root(root), skip_leading_slash(s));
return 0; /* Found masked file. */
}
r = conf_file_new(s, root, CHASE_MUST_BE_REGULAR, &c);
if (r >= 0) {
if (!GREEDY_REALLOC_APPEND(*files, *n_files, &c, 1))
return log_oom();
@ -296,7 +289,7 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
}
if (r != -EISDIR)
return log_error_errno(r, "Failed to chase '%s%s': %m", empty_to_root(root), skip_leading_slash(s));
return log_error_errno(r, "Failed to chase \"%s\": %m", s);
/* If a directory is specified, then find all rules file in the directory. */
ConfFile **f = NULL;
@ -304,9 +297,9 @@ static int search_rules_file(const char *s, const char *root, ConfFile ***files,
CLEANUP_ARRAY(f, n, conf_file_free_many);
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_WARN, (const char* const*) STRV_MAKE_CONST(s), &f, &n);
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR, (const char* const*) STRV_MAKE_CONST(s), &f, &n);
if (r < 0)
return log_error_errno(r, "Failed to enumerate rules files in '%s%s': %m", empty_to_root(root), skip_leading_slash(s));
return log_error_errno(r, "Failed to enumerate rules files in '%s': %m", s);
if (!GREEDY_REALLOC_APPEND(*files, *n_files, f, n))
return log_oom();
@ -327,7 +320,7 @@ int search_rules_files(char * const *a, const char *root, ConfFile ***ret_files,
assert(ret_n_files);
if (strv_isempty(a)) {
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED | CONF_FILES_WARN,
r = conf_files_list_strv_full(".rules", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED,
(const char* const*) CONF_PATHS_STRV("udev/rules.d"), &files, &n_files);
if (r < 0)
return log_error_errno(r, "Failed to enumerate rules files: %m");

View File

@ -38,7 +38,7 @@ udevadm cat 99-systemd
udevadm cat 99-systemd.rules
udevadm cat /usr/lib/udev/rules.d/99-systemd.rules
udevadm cat /usr/lib/udev/rules.d
udevadm cat /dev/null
(! udevadm cat /dev/null)
udevadm cat --config
udevadm cat -h

View File

@ -118,7 +118,8 @@ assert_1 --resolve-names=now
assert_1 ./nosuchfile
# Failed to parse rules file ./nosuchfile: No such file or directory
assert_1 ./nosuchfile /dev/null
assert_0 /dev/null
# '/dev/null' is neither a regular file nor a directory: File descriptor in bad state
assert_1 /dev/null
rules_dir='etc/udev/rules.d'
mkdir -p "${rules_dir}"

View File

@ -29,7 +29,8 @@ fi
for unit_file in "${UNIT_FILES[@]}"; do
# Skip the check for a couple of units, namely:
# - syslog.socket: the corresponding syslog.service might not be installed
if [[ "$unit_file" =~ /syslog.socket$ ]]; then
# - rc-local.service: compat API, /etc/rc.d/rc.local most likely won't be present
if [[ "$unit_file" =~ /(syslog.socket|rc-local.service)$ ]]; then
continue
fi

View File

@ -376,14 +376,6 @@ systemctl show -P Markers "$UNIT_NAME" | grep needs-restart
systemctl reload-or-restart --marked
(! systemctl show -P Markers "$UNIT_NAME" | grep needs-restart)
# again, but with varlinkctl instead
systemctl restart "$UNIT_NAME"
systemctl set-property "$UNIT_NAME" Markers=needs-restart
systemctl show -P Markers "$UNIT_NAME" | grep needs-restart
varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Manager.EnqueueMarkedJobs '{}'
timeout 30 bash -c "until systemctl list-jobs $UNIT_NAME | grep \"No jobs\" 2>/dev/null; do sleep 1; done"
(! systemctl show -P Markers "$UNIT_NAME" | grep needs-restart)
# --dry-run with destructive verbs
# kexec is skipped intentionally, as it requires a bit more involved setup
VERBS=(

View File

@ -578,10 +578,8 @@ cleanup_ssh() (
systemctl is-active -q mysshserver.socket && systemctl stop mysshserver.socket
rm -f /tmp/homed.id_ecdsa /run/systemd/system/mysshserver{@.service,.socket}
systemctl daemon-reload
if homectl inspect homedsshtest &>/dev/null; then
wait_for_state homedsshtest inactive
homectl remove homedsshtest
fi
for dir in /etc /usr/lib; do
if [[ -f "$dir/pam.d/sshd.bak" ]]; then
mv "$dir/pam.d/sshd.bak" "$dir/pam.d/sshd"

View File

@ -91,43 +91,6 @@ if [ "$VERITY_SIG_SUPPORTED" -eq 1 ]; then
--property ExtensionImagePolicy=root=verity+signed+absent:usr=verity+signed+absent \
bash -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(</tmp/app0.roothash)-verity\"")
mv /tmp/app0.roothash.p7s.bak /tmp/app0.roothash.p7s
# Mount options should not be allowed without elevated privileges
(! systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.gpt" \
--property RootImageOptions="root:ro,noatime,nosuid home:ro,dev nosuid,dev" \
--property RootImageOptions="home:ro,dev nosuid,dev,%%foo" \
true)
(! systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.raw" \
--property ExtensionImages=/tmp/app0.raw \
--property MountImages=/tmp/app0.raw:/var/tmp:noatime,nosuid \
true)
mkdir -p /etc/polkit-1/rules.d
cat >/etc/polkit-1/rules.d/mountoptions.rules <<'EOF'
polkit.addRule(function(action, subject) {
if (action.id == "io.systemd.mount-file-system.mount-untrusted-image-privately" &&
action.lookup("mount_options") == "root:nosuid") {
return polkit.Result.YES;
}
});
EOF
systemctl try-reload-or-restart polkit.service
systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.gpt" \
--property RootImageOptions="root:nosuid" \
sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && mount | grep -F squashfs | grep -q -F nosuid"
systemd-run -M testuser@ --user --pipe --wait \
--property RootImage="$MINIMAL_IMAGE.raw" \
--property ExtensionImages=/tmp/app0.raw \
--property MountImages=/tmp/app0.raw:/var/tmp:nosuid \
sh -c "test -e \"/dev/mapper/${MINIMAL_IMAGE_ROOTHASH}-verity\" && test -e \"/dev/mapper/$(</tmp/app0.roothash)-verity\" && mount | grep -F /var/tmp | grep -q -F nosuid"
rm -f /etc/polkit-1/rules.d/mountoptions.rules
systemctl try-reload-or-restart polkit.service
fi
# Bare squashfs without any verity or signature also should be rejected, even if we ask to trust it

View File

@ -25,7 +25,6 @@ at_exit() {
done < <(find "${IMAGE_DIR}" -mindepth 1 -maxdepth 1 -type d)
rm -rf "$IMAGE_DIR"
rm -rf /etc/polkit-1/rules.d/mountoptions.rules
rm -f /etc/polkit-1/rules.d/sysext-unpriv.rules

View File

@ -11,6 +11,9 @@
Description=Console Getty
Documentation=man:agetty(8) man:systemd-getty-generator(8)
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
{% if HAVE_SYSV_RC_LOCAL %}
After=rc-local.service
{% endif %}
Before=getty.target
# OCI containers may be run without a console

View File

@ -12,6 +12,9 @@ Description=Container Getty on /dev/pts/%I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=man:machinectl(1)
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
{% if HAVE_SYSV_RC_LOCAL %}
After=rc-local.service
{% endif %}
Before=getty.target
IgnoreOnIsolate=yes
ConditionPathExists=/dev/pts/%I

View File

@ -12,6 +12,9 @@ Description=Getty on %I
Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=https://0pointer.de/blog/projects/serial-console.html
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
{% if HAVE_SYSV_RC_LOCAL %}
After=rc-local.service
{% endif %}
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though

View File

@ -174,6 +174,10 @@ units = [
'file' : 'quotaon-root.service.in',
'conditions' : ['ENABLE_QUOTACHECK'],
},
{
'file' : 'rc-local.service.in',
'conditions' : ['HAVE_SYSV_RC_LOCAL'],
},
{
'file' : 'reboot.target',
'symlinks' : ['ctrl-alt-del.target'],

23
units/rc-local.service.in Normal file
View File

@ -0,0 +1,23 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if {{SYSTEM_SYSVRCLOCAL_PATH}} is executable.
[Unit]
Description={{SYSTEM_SYSVRCLOCAL_PATH}} Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable={{SYSTEM_SYSVRCLOCAL_PATH}}
After=network.target
[Service]
Type=forking
ExecStart={{SYSTEM_SYSVRCLOCAL_PATH}} start
TimeoutSec=infinity
RemainAfterExit=yes
GuessMainPID=no

View File

@ -13,6 +13,9 @@ Documentation=man:agetty(8) man:systemd-getty-generator(8)
Documentation=https://0pointer.de/blog/projects/serial-console.html
BindsTo=dev-%i.device
After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
{% if HAVE_SYSV_RC_LOCAL %}
After=rc-local.service
{% endif %}
# If additional gettys are spawned during boot then we should make
# sure that this is synchronized before getty.target, even though