]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18704 from keszybz/fallback-hostame-override
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 22 Feb 2021 23:41:27 +0000 (00:41 +0100)
committerGitHub <noreply@github.com>
Mon, 22 Feb 2021 23:41:27 +0000 (00:41 +0100)
Allow overriding of fallback hostname through envvar and os-release field

1  2 
NEWS
docs/ENVIRONMENT.md
man/systemd.unit.xml
src/basic/meson.build
src/core/main.c
src/shared/conf-parser.c

diff --combined NEWS
index 3ee238119188f5d19c32abd5602d5d579ede3369,b917262495e0ee44b1860e7a28cddd526421472c..50ef954cc872ecf7065288c5da98efc570f27a6a
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -21,66 -21,45 +21,66 @@@ CHANGES WITH 248
            supported system extension level.
  
          * A new configuration file /etc/veritytab may be used to configure
 -          integrity protection for block devices. Each line is in the format
 -          "volume-name data-device hash-device roothash options".
 +          dm-verity integrity protection for block devices. Each line is in the
 +          format "volume-name data-device hash-device roothash options",
 +          similar to /etc/crypttab.
  
 -        * A new kernel command-line option systemd.verity.root-options= may be
 +        * A new kernel command-line option systemd.verity.root_options= may be
            used to configure dm-verity behaviour for the root device.
  
          * The key file specified in /etc/crypttab (the third field) may now
 -          refer to a UNIX socket path. The key is acquired by connecting to
 -          that socket and reading from it. This allows the implementation of a
 -          service to provide key information dynamically, at the moment when it
 -          is needed.
 +          refer to an AF_UNIX/SOCK_STREAM socket in the file system. The key is
 +          acquired by connecting to that socket and reading from it. This
 +          allows the implementation of a service to provide key information
 +          dynamically, at the moment when it is needed.
  
 -        * Support has been added for extracting the PKCS#11 token URI and
 -          encrypted key from the LUKS2 JSON embedded metadata header. This
 -          allows the information how to open the encrypted device to be
 -          embedded directly in the device and obviates the need for
 -          configuration in an external file.
 +        * Support has been added to systemd-cryptsetup for extracting the
 +          PKCS#11 token URI and encrypted key from the LUKS2 JSON embedded
 +          metadata header. This allows the information how to open the
 +          encrypted device to be embedded directly in the device and obviates
 +          the need for configuration in an external file.
  
 -        * LUKS devices may now be unlocked using TPM2 hardware.
 +        * systemd-cryptsetup gained support for unlocking LUKS2 volumes using
 +          TPM2 hardware, as well as FIDO2 security tokens (in addition to the
 +          pre-existing support for PKCS#11 security tokens).
  
 -        * systemd-repart may lock partitions using TPM2 hardware. This may be
 -          useful for example to create an encrypted /var partition bound to the
 -          machine on first boot.
 +        * systemd-repart may enroll encrypted partitions using TPM2
 +          hardware. This may be useful for example to create an encrypted /var
 +          partition bound to the machine on first boot.
  
 -        * A new systemd-cryptenroll tool has been added to enroll FIDO2+PKCS#11
 -          security tokens to LUKS volumes, list and destroy them. See
 -          https://www.freedesktop.org/software/systemd/man/systemd-cryptenroll.html.
 +        * A new systemd-cryptenroll tool has been added to enroll TPM2, FIDO2
 +          and PKCS#11 security tokens to LUKS volumes, list and destroy
 +          them. See:
  
 -        * The manager may be configured at compile time to use fexecve instead
 -          of execve when spawning children. Using fexecve closes a window
 -          between checking the security context of an executable and spawning
 -          it, but unfortunately the kernel displays stale information in the
 -          comm field, which impacts ps output and such.
 +          http://0pointer.net/blog/unlocking-luks2-volumes-with-tpm2-fido2-pkcs11-security-hardware-on-systemd-248.html
 +
 +          It also supports enrolling "recovery keys" and regular passphrases.
 +
 +        * The libfido2 dependency is now based on dlopen(), so that the library
 +          is used at runtime when installed, but is not a hard runtime
 +          dependency.
 +
 +        * systemd-cryptsetup gained support for two new options in
 +          /etc/crypttab: "no-write-workqueue" and "no-read-workqueue" which
 +          request synchronous processing of encryption/decryption IO.
 +
 +        * The manager may be configured at compile time to use the fexecve()
 +          instead of the execve() system call when spawning processes. Using
 +          fexecve() closes a window between checking the security context of an
 +          executable and spawning it, but unfortunately the kernel displays
 +          stale information in the process' "comm" field, which impacts ps
 +          output and such.
  
          * The configuration option -Dcompat-gateway-hostname has been dropped.
            "_gateway" is now the only supported name.
  
 -        * The ConditionSecurity=tpm2 unit file setting may be used to check
 -          if the system has at least one TPM2 (tpmrm class) device.
 +        * The ConditionSecurity=tpm2 unit file setting may be used to check if
 +          the system has at least one TPM2 (tpmrm class) device.
 +
 +        * A new ConditionCPUFeature= has been added that may be used to
 +          conditionalize units based on CPU features. For example,
 +          ConditionCPUFeature=rdrand will condition a unit so that it is only
 +          run when the system CPU supports the RDRAND opcode.
  
          * The tables of system calls in seccomps filters are now automatically
            generated from kernel lists exported on
            respectively as 'systemctl bind <unit> <path>…' and
            'systemctl mount-image <unit> <image>…'.
  
 -        * The StandardOuput= and StandardError= settings can now specify files
 +        * The StandardOutput= and StandardError= settings can now specify files
            to be truncated for output (as "truncate:<path>").
  
          * The ExecPaths= and NoExecPaths= settings may be used to specify
            noexec for parts of the file system.
  
 -        * sd-bus has a new function sd_bus_open_use_machine() to open a
 +        * sd-bus has a new function sd_bus_open_user_machine() to open a
            connection to the session bus of a specific user in a local container
 -          or on the local host. It also gained a convenience function
 -          sd_bus_reply() to call sd_bus_send() with an existing reply message.
 +          or on the local host. This is exposed in the existing -M switch to
 +          systemctl and similar tools:
 +
 +              systemctl --user -M lennart@foobar start foo
 +
 +          This will connect to the user bus of a user "lennart" in container
 +          "foobar". If no container name is specified, the specified user on
 +          the host itself is connected to
 +
 +              systemctl --user -M lennart@ start quux
  
 -        * sd-event allows rate limits to be set on event sources. See the new
 -          man page sd_event_source_set_ratelimit(3) for details.
 +        * sd-bus also gained a convenience function sd_bus_message_send() to
 +          simplify invocations of sd_bus_send(), taking only a single
 +          parameter: the message to send.
 +
 +        * sd-event allows rate limits to be set on event sources, for dealing
 +          with high-priority event sources that might starve out others. See
 +          the new man page sd_event_source_set_ratelimit(3) for details.
  
          * systemd.link files gained a [Link] Promiscuous= switch, which allows
            the device to be raised in promiscuous mode.
            systemd.network files gained a [DHCPv6PrefixDelegation]
            ManageTemporaryAddress= switch.
  
 +          .network files gained a new ActivationPolicy= setting which allows
 +          configuration how the UP state of an interface shall be managed,
 +          i.e. whether the interface is always upped, always downed, or may be
 +          upped/downed by the user using "ip dev".
 +
          * systemd.netdev files gained a [VLAN] Protocol=, IngressQOSMaps=,
            EgressQOSMaps=, and [MACVLAN] BroadcastMulticastQueueLength=
            configuration options for VLAN packet handling.
            even a single device.
  
          * udev now exports the VOLUME_ID, LOGICAL_VOLUME_ID, VOLUME_SET_ID, and
 -          DATA_PREPARED_ID attributes for block devices (when available).
 +          DATA_PREPARED_ID properties for block devices with ISO9660 file
 +          systems.
  
 -        * udev now exports decoded DMI information about memory under the
 -          /sys/class/dmi/id/ pseudo device.
 +        * udev now exports decoded DMI information about installed memory slots
 +          as device properties under the /sys/class/dmi/id/ pseudo device.
  
 -        * /dev is not mounted noexec any more. This didn't provide any
 +        * /dev/ is not mounted noexec anymore. This didn't provide any
            significant security benefits and would conflicts with the executable
            mappings used with /dev/sgx device nodes.
  
            and /dev/vhost-net are owned by the kvm group.
  
          * The hardware database has been extended with a list of fingerprint
 -          readers that correctly support autosuspend using data from libfprint.
 +          readers that correctly support USB auto-suspend using data from
 +          libfprint.
  
          * systemd-resolved can now answer DNSSEC questions through the stub
            resolver interface in a way that allows local clients to do DNSSEC
            DNS query and respond with a mostly unmodified packet received from
            the upstream server.
  
 +        * systemd-resolved learnt a new boolean option CacheFromLocalhost= in
 +          resolved.conf. If true the service will provide caching even for DNS
 +          lookups made to an upstream DNS server on the 127.0.0.1/::1
 +          addresses. By default (and when the option is false) systemd-resolved
 +          will not cache such lookups, in order to avoid duplicate local
 +          caching, under the assumption the local upstream server caches
 +          anyway.
 +
 +        * systemd-resolved now implements RFC5001 NSID in its local DNS
 +          stub. This may be used by local clients to determine whether they are
 +          talking to the DNS resolver stub or a different DNS server.
 +
 +        * When resolving host names and other records resolvectl will now
 +          report where the data was acquired from (i.e. the local cache, the
 +          network, locally synthesized, …) and whether the network traffic it
 +          effected was encrypted or not. Moreover the tool acquired a number of
 +          new options --cache=, --synthesize=, --network=, --zone=,
 +          --trust-anchor=, --validate= that take booleans and may be used to
 +          tweak a lookup, i.e. whether it may be answered from cached
 +          information, locally synthesized information, information acquired
 +          through the network, the local mDNS/LLMNR zone, the DNSSEC trust
 +          anchor, and whether DNSSEC validation shall be executed for the
 +          lookup.
 +
          * systemd-nspawn gained a new --ambient-capability= setting
            (AmbientCapability= in .nspawn files) to configure ambient
            capabilities passed to the container payload.
  
          * systemd-nspawn gained the ability to configure the firewall using the
 -          nft subsystem (in addition to the existing iptables support).
 +          nftables subsystem (in addition to the existing iptables
 +          support). Similar, systemd-networkd's IPMasquerade= option now
 +          supports nftables as back-end, too. In both cases NAT on IPv6 is now
 +          supported too, in addition to IPv4 (the iptables back-end still is
 +          IPv4-only).
 +
 +        * systemd-importd will now download .verity and .roothash.p7s files
 +          along with the machine image (as exposed via machinectl pull-raw).
  
          * systemd-oomd now gained a new DefaultMemoryPressureDurationSec=
            setting to configure the time a unit's cgroup needs to exceed memory
          * systemd-stdio-bridge gained --system/--user options to connect to the
            system bus (previous default) or the user session bus.
  
 -        * When the hostname is set to "localhost", systemd-hostnamed will
 -          accept this. Previously such a setting would be mostly silently
 +        * When the hostname is set explicitly to "localhost", systemd-hostnamed
 +          will respect this. Previously such a setting would be mostly silently
            ignored. The goal is to honour configuration as specified by the
            user.
  
-         * systemd-hostnamed now exports the fallback hostname and the source of
-           the configured hostname ("static", "transient", or "fallback") as
+         * systemd-hostnamed now exports the default hostname and the source of
+           the configured hostname ("static", "transient", or "default") as
            D-Bus properties.
  
 -        * systemd-hostnamed now exports the HardwareVendor and HardwareModel
 -          D-Bus properties. hostnamectl shows this in the status output.
 +        * systemd-hostnamed now exports the "HardwareVendor" and
 +          "HardwareModel" D-Bus properties, which are supposed to contain a
 +          pair of cleaned up, human readable strings describing the system's
 +          vendor and model. It's typically sourced from the firmware's DMI
 +          tables, but may be augmented from a new hwdb database. hostnamectl
 +          shows this in the status output.
  
          * systemd-localed may now call locale-gen to generate missing locales
            on-demand (UTF-8-only). This improves integration with Debian-based
            distributions (Debian/Ubuntu/PureOS/Tanglu/...) and Arch Linux.
  
 -        * systemctl --check-inhibitors may now be used to obey inhibitors even
 -          when invoked non-interactively.
 +        * systemctl --check-inhibitors=true may now be used to obey inhibitors
 +          even when invoked non-interactively. The old --ignore-inhibitors
 +          switch is now deprecated and replaced by --check-inhibitors=false.
  
          * systemctl import-environment will now emit a warning when called
            without any arguments (i.e. to import the full environment block of
            directly calling the D-Bus API of the manager, should also push
            specific variables, and not the full inherited environment.
  
 +        * systemctl's status output now shows unit state with a more careful
 +          choice of Unicode characters: units in maintenance show a "○" symbol
 +          instead of the usual "●", failed units show "×", and services being
 +          reloaded "↻".
 +
          * coredumpctl gained a --debugger-arguments= switch to pass arguments
 -          to the debugger.
 +          to the debugger. It also gained support for showing coredump info in
 +          a simple JSON format.
 +
 +        * systemctl/loginctl/machinectl's --signal= option now accept a special
 +          value "list", which may be used to show a brief table with known
 +          process signals and their numbers.
  
          * networkctl now shows the link activation policy in status.
  
 -        * Various tools gained --pager/--no-pager/--json switches to
 +        * Various tools gained --pager/--no-pager/--json= switches to
            enable/disable the pager and provide JSON output.
  
 -        * Various tools now accept SYSTEMD_COLORS=16|256 to configure what
 -          colours are used in output.
 +        * Various tools now accept two new values for the SYSTEMD_COLORS
 +          environment variable: "16" and "256", to configure how many terminal
 +          colors are used in output.
  
 -        * less 568 or newer is now required. Link markup is now always used,
 -          and older versions will not display it properly. SYSTEMD_URLIFY=0 may
 -          be used to disable it.
 +        * less 568 or newer is now required for the auto-paging logic of the
 +          various tools. Hyperlink ANSI sequences in terminal output are now
 +          used even if a pager is used, and older versions of less are not able
 +          to display these sequences correctly. SYSTEMD_URLIFY=0 may be used to
 +          disable this output again.
  
 -        * Builds with support for separate / and /usr hierarchies (split-usr
 +        * Builds with support for separate / and /usr/ hierarchies ("split-usr"
            builds, non-merged-usr builds) are now officially deprecated. A
            warning is emitted during build. Support is slated to be removed in
            about a year (when the Debian Bookworm release development starts).
  
 -        * The main development branch has been renamed to 'main'.
 +        * The main git development branch has been renamed to 'main'.
  
          * mmcblk[0-9]boot[0-9] devices will no longer be probed automatically
            for partitions, as in the vast majority of cases they contain none
            and are used internally by the bootloader (eg: uboot).
  
 +        * systemd will now set the $SYSTEMD_EXEC_PID environment variable for
 +          spawned processes to the PID of the process itself. This may be used
 +          by programs for detecting whether they were forked off by the service
 +          manager itself or are a process forked off further down the tree.
 +
 +        * The sd-device API gained three new calls sd_device_get_action() (for
 +          determining the uevent add/remove/change/… action the device object
 +          has been seen for), sd_device_get_seqno() (for determining the uevent
 +          sequence number) and sd_device_new_from_stat_rdev() (for allocating a
 +          new sd_device object from stat() data of a device node).
 +
 +        * For most tools the --no-legend= switch has been replaced by
 +          --legend=no and --legend=yes, to force whether tables are shown with
 +          headers/legends.
 +
 +        * Units acquired a new property "Markers" that takes a list of zero,
 +          one or two of the following strings: "needs-reload" and
 +          "needs-restart". These markers may be set via "systemctl
 +          set-property". Once a marker is set, "systemctl reload-or-restart
 +          --marked" may be invoked to execute the operation the units are
 +          marked for. This is useful for package managers that want to mark
 +          units for restart/reload while updating, but effect the actual
 +          operations at a later step at once.
 +
 +        * The sd_bus_message_read_strv() API call of sd-bus may now also be
 +          used to parse arrays of D-Bus signatures and D-Bus paths, in addition
 +          to regular strings.
 +
 +        * bootctl will now report whether the UEFI firmware used a TPM2 device
 +          and measured the boot process into it.
 +
 +        * systemd-tmpfiles learnt support for a new environment variable
 +          $SYSTEMD_TMPFILES_FORCE_SUBVOL which takes a boolean value. If true
 +          the v/q/Q lines in tmpfiles.d/ snippets will create btrfs subvolumes
 +          even if the root fs of the system is not itself a btrfs volume.
 +
 +        * systemd-detect-virt/ConditionVirtualization= will now explicitly
 +          detect Docker/Podman environments where possible. Moreover, they
 +          should be able to generically detect any container manager as long as
 +          it assigns the container a cgroup.
 +
 +        * portablectl gained a new "reattach" verb for detaching/reattaching a
 +          portable service image, useful for updating images on-the-fly.
 +
  CHANGES WITH 247:
  
          * KERNEL API INCOMPATIBILITY: Linux 4.14 introduced two new uevents
diff --combined docs/ENVIRONMENT.md
index 7eec45593464f16dde61719a022e2c214dc756a8,07a65864bdebfcf04c9818b239af923092e13355..a3916f8cde0e427509252e9b1dce2027cab2b3fe
@@@ -19,17 -19,18 +19,17 @@@ documented in the proper man pages
  
  All tools:
  
 -* `$SYSTEMD_OFFLINE=[0|1]` — if set to `1`, then `systemctl` will
 -  refrain from talking to PID 1; this has the same effect as the historical
 -  detection of `chroot()`.  Setting this variable to `0` instead has a similar
 -  effect as `SYSTEMD_IGNORE_CHROOT=1`; i.e. tools will try to
 -  communicate with PID 1 even if a `chroot()` environment is detected.
 -  You almost certainly want to set this to `1` if you maintain a package build system
 -  or similar and are trying to use a modern container system and not plain
 -  `chroot()`.
 +* `$SYSTEMD_OFFLINE=[0|1]` — if set to `1`, then `systemctl` will refrain from
 +  talking to PID 1; this has the same effect as the historical detection of
 +  `chroot()`. Setting this variable to `0` instead has a similar effect as
 +  `SYSTEMD_IGNORE_CHROOT=1`; i.e. tools will try to communicate with PID 1 even
 +  if a `chroot()` environment is detected. You almost certainly want to set
 +  this to `1` if you maintain a package build system or similar and are trying
 +  to use a modern container system and not plain `chroot()`.
  
  * `$SYSTEMD_IGNORE_CHROOT=1` — if set, don't check whether being invoked in a
    `chroot()` environment. This is particularly relevant for systemctl, as it
 -  will not alter its behaviour for `chroot()` environments if set.  Normally it
 +  will not alter its behaviour for `chroot()` environments if set. Normally it
    refrains from talking to PID 1 in such a case; turning most operations such
    as `start` into no-ops.  If that's what's explicitly desired, you might
    consider setting `SYSTEMD_OFFLINE=1`.
    will print latency information at runtime.
  
  * `$SYSTEMD_PROC_CMDLINE` — if set, the contents are used as the kernel command
 -  line instead of the actual one in /proc/cmdline. This is useful for
 +  line instead of the actual one in `/proc/cmdline`. This is useful for
    debugging, in order to test generators and other code against specific kernel
    command lines.
  
 -* `$SYSTEMD_FSTAB` — if set, use this path instead of /etc/fstab. Only useful
 +* `$SYSTEMD_FSTAB` — if set, use this path instead of `/etc/fstab`. Only useful
    for debugging.
  
 -* `$SYSTEMD_CRYPTTAB` — if set, use this path instead of /etc/crypttab. Only
 -  useful for debugging. Currently only supported by systemd-cryptsetup-generator.
 +* `$SYSTEMD_CRYPTTAB` — if set, use this path instead of `/etc/crypttab`. Only
 +  useful for debugging. Currently only supported by
 +  `systemd-cryptsetup-generator`.
  
 -* `$SYSTEMD_VERITYTAB` — if set, use this path instead of /etc/veritytab. Only
 -  useful for debugging. Currently only supported by systemd-veritysetup-generator.
 +* `$SYSTEMD_VERITYTAB` — if set, use this path instead of
 +  `/etc/veritytab`. Only useful for debugging. Currently only supported by
 +  `systemd-veritysetup-generator`.
  
  * `$SYSTEMD_EFI_OPTIONS` — if set, used instead of the string in the
 -  SystemdOptions EFI variable. Analogous to `$SYSTEMD_PROC_CMDLINE`.
 +  `SystemdOptions` EFI variable. Analogous to `$SYSTEMD_PROC_CMDLINE`.
  
+ * `$SYSTEMD_DEFAULT_HOSTNAME` — override the compiled-in fallback hostname
+   (relevant in particular for the system manager and `systemd-hostnamed`).
+   Must be a valid hostname (either a single label or a FQDN).
  * `$SYSTEMD_IN_INITRD=[auto|lenient|0|1]` — if set, specifies initrd detection
    method. Defaults to `auto`. Behavior is defined as follows:
    `auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted
    to 0, then the built-in default is used.
  
  * `$SYSTEMD_MEMPOOL=0` — if set, the internal memory caching logic employed by
 -  hash tables is turned off, and libc malloc() is used for all allocations.
 +  hash tables is turned off, and libc `malloc()` is used for all allocations.
  
 -* `$SYSTEMD_EMOJI=0` — if set, tools such as "systemd-analyze security" will
 +* `$SYSTEMD_EMOJI=0` — if set, tools such as `systemd-analyze security` will
    not output graphical smiley emojis, but ASCII alternatives instead. Note that
    this only controls use of Unicode emoji glyphs, and has no effect on other
    Unicode glyphs.
  
  * `$RUNTIME_DIRECTORY` — various tools use this variable to locate the
 -  appropriate path under /run. This variable is also set by the manager when
 -  RuntimeDirectory= is used, see systemd.exec(5).
 +  appropriate path under `/run/`. This variable is also set by the manager when
 +  `RuntimeDirectory=` is used, see systemd.exec(5).
  
  * `$SYSTEMD_CRYPT_PREFIX` — if set configures the hash method prefix to use for
 -  UNIX crypt() when generating passwords. By default the system's "preferred
 -  method" is used, but this can be overridden with this environment
 -  variable. Takes a prefix such as `$6$` or `$y$`. (Note that this is only
 -  honoured on systems built with libxcrypt and is ignored on systems using
 -  glibc's original, internal crypt() implementation.)
 +  UNIX `crypt()` when generating passwords. By default the system's "preferred
 +  method" is used, but this can be overridden with this environment variable.
 +  Takes a prefix such as `$6$` or `$y$`. (Note that this is only honoured on
 +  systems built with libxcrypt and is ignored on systems using glibc's
 +  original, internal `crypt()` implementation.)
  
  * `$SYSTEMD_RDRAND=0` — if set, the RDRAND instruction will never be used,
    even if the CPU supports it.
    support for it is compiled in and available in the kernel.
  
  * `$SYSTEMD_LOG_SECCOMP=1` — if set, system calls blocked by seccomp filtering,
 -  for example in systemd-nspawn, will be logged to the audit log, if the current
 -  kernel version supports this.
 +  for example in `systemd-nspawn`, will be logged to the audit log, if the
 +  kernel supports this.
  
 -systemctl:
 +`systemctl`:
  
  * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus
    listener, and instead always connect through the dbus-daemon D-bus broker.
  * `$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 out to SysV compatibility hooks.
 +* `$SYSTEMCTL_SKIP_SYSV=1` — if set, do not call SysV compatibility hooks.
  
 -systemd-nspawn:
 +`systemd-nspawn`:
  
 -* `$SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1` — if set, force nspawn into unified
 -  cgroup hierarchy mode.
 +* `$SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=1` — if set, force `systemd-nspawn` into
 +  unified cgroup hierarchy mode.
  
 -* `$SYSTEMD_NSPAWN_API_VFS_WRITABLE=1` — if set, make /sys and /proc/sys and
 -  friends writable in the container. If set to "network", leave only
 -  /proc/sys/net writable.
 +* `$SYSTEMD_NSPAWN_API_VFS_WRITABLE=1` — if set, make `/sys/`, `/proc/sys/`,
 +  and friends writable in the container. If set to "network", leave only
 +  `/proc/sys/net/` writable.
  
  * `$SYSTEMD_NSPAWN_CONTAINER_SERVICE=…` — override the "service" name nspawn
    uses to register with machined. If unset defaults to "nspawn", but with this
  
  * `$SYSTEMD_NSPAWN_LOCK=0` — if set, do not lock container images when running.
  
 -* `$SYSTEMD_NSPAWN_TMPFS_TMP=0` — if set, do not overmount /tmp in the
 +* `$SYSTEMD_NSPAWN_TMPFS_TMP=0` — if set, do not overmount `/tmp/` in the
    container with a tmpfs, but leave the directory from the image in place.
  
 -systemd-logind:
 +`systemd-logind`:
  
  * `$SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1` — if set, report that
    hibernation is available even if the swap devices do not provide enough room
    for it.
  
 -* `$SYSTEMD_REBOOT_TO_FIRMWARE_SETUP` — if set overrides systemd-logind's
 -  built-in EFI logic of requesting a reboot into the firmware. Takes a
 -  boolean. If set to false the functionality is turned off entirely. If set to
 -  true instead of requesting a reboot into the firmware setup UI through EFI a
 -  file `/run/systemd/reboot-to-firmware-setup` is created whenever this is
 +* `$SYSTEMD_REBOOT_TO_FIRMWARE_SETUP` — if set, overrides `systemd-logind`'s
 +  built-in EFI logic of requesting a reboot into the firmware. Takes a boolean.
 +  If set to false, the functionality is turned off entirely. If set to true,
 +  instead of requesting a reboot into the firmware setup UI through EFI a file,
 +  `/run/systemd/reboot-to-firmware-setup` is created whenever this is
    requested. This file may be checked for by services run during system
    shutdown in order to request the appropriate operation from the firmware in
    an alternative fashion.
  
  * `$SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU` — similar to the above, allows
 -  overriding of systemd-logind's built-in EFI logic of requesting a reboot into
 -  the boot loader menu. Takes a boolean. If set to false the functionality is
 -  turned off entirely. If set to true instead of requesting a reboot into the
 -  boot loader menu through EFI a file `/run/systemd/reboot-to-boot-loader-menu`
 -  is created whenever this is requested. The file contains the requested boot
 -  loader menu timeout in µs, formatted in ASCII decimals, or zero in case no
 -  timeout is requested. This file may be checked for by services run during
 -  system shutdown in order to request the appropriate operation from the boot
 -  loader in an alternative fashion.
 +  overriding of `systemd-logind`'s built-in EFI logic of requesting a reboot
 +  into the boot loader menu. Takes a boolean. If set to false, the
 +  functionality is turned off entirely. If set to true, instead of requesting a
 +  reboot into the boot loader menu through EFI, the file
 +  `/run/systemd/reboot-to-boot-loader-menu` is created whenever this is
 +  requested. The file contains the requested boot loader menu timeout in µs,
 +  formatted in ASCII decimals, or zero in case no timeout is requested. This
 +  file may be checked for by services run during system shutdown in order to
 +  request the appropriate operation from the boot loader in an alternative
 +  fashion.
  
  * `$SYSTEMD_REBOOT_TO_BOOT_LOADER_ENTRY` — similar to the above, allows
 -  overriding of systemd-logind's built-in EFI logic of requesting a reboot into
 -  a specific boot loader entry. Takes a boolean. If set to false the
 -  functionality is turned off entirely. If set to true instead of requesting a
 -  reboot into a specific boot loader entry through EFI a file
 +  overriding of `systemd-logind`'s built-in EFI logic of requesting a reboot
 +  into a specific boot loader entry. Takes a boolean. If set to false, the
 +  functionality is turned off entirely. If set to true, instead of requesting a
 +  reboot into a specific boot loader entry through EFI, the file
    `/run/systemd/reboot-to-boot-loader-entry` is created whenever this is
    requested. The file contains the requested boot loader entry identifier. This
    file may be checked for by services run during system shutdown in order to
    `/run/boot-loader-entries/loader/entries/*.conf`, and the files referenced by
    the drop-ins (including the kernels and initrds) somewhere else below
    `/run/boot-loader-entries/`. Note that all these files may be (and are
 -  supposed to be) symlinks. systemd-logind will load these files on-demand,
 +  supposed to be) symlinks. `systemd-logind` will load these files on-demand,
    these files can hence be updated (ideally atomically) whenever the boot
    loader configuration changes. A foreign boot loader installer script should
    hence synthesize drop-in snippets and symlinks for all boot entries at boot
 -  or whenever they change if it wants to integrate with systemd-logind's APIs.
 +  or whenever they change if it wants to integrate with `systemd-logind`'s
 +  APIs.
  
 -systemd-udevd:
 +`systemd-udevd`:
  
  * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of
    "v238", "v239", "v240"…, or the special value "latest") as parameter. If
 -  specified udev's net_id builtin will follow the specified naming scheme when
 -  determining stable network interface names. This may be used to revert to
 -  naming schemes of older udev versions, in order to provide more stable naming
 -  across updates. This environment variable takes precedence over the kernel
 -  command line option `net.naming-scheme=`, except if the value is prefixed
 -  with `:` in which case the kernel command line option takes precedence, if it
 -  is specified as well.
 +  specified udev's `net_id` builtin will follow the specified naming scheme
 +  when determining stable network interface names. This may be used to revert
 +  to naming schemes of older udev versions, in order to provide more stable
 +  naming across updates. This environment variable takes precedence over the
 +  kernel command line option `net.naming-scheme=`, except if the value is
 +  prefixed with `:` in which case the kernel command line option takes
 +  precedence, if it is specified as well.
  
  installed systemd tests:
  
  * `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if
    a test executable is moved to an arbitrary location.
  
 -nss-systemd:
 +`nss-systemd`:
  
  * `$SYSTEMD_NSS_BYPASS_SYNTHETIC=1` — if set, `nss-systemd` won't synthesize
    user/group records for the `root` and `nobody` users if they are missing from
    dynamic user lookups. This is primarily useful to make `nss-systemd` work
    safely from within `dbus-daemon`.
  
 -systemd-timedated:
 +`systemd-timedated`:
  
  * `$SYSTEMD_TIMEDATED_NTP_SERVICES=…` — colon-separated list of unit names of
    NTP client services. If set, `timedatectl set-ntp on` enables and starts the
    first existing unit listed in the environment variable, and
    `timedatectl set-ntp off` disables and stops all listed units.
  
 -systemd-sulogin-shell:
 +`systemd-sulogin-shell`:
  
  * `$SYSTEMD_SULOGIN_FORCE=1` — This skips asking for the root password if the
    root password is not available (such as when the root account is locked).
    See `sulogin(8)` for more details.
  
 -bootctl and other tools that access the EFI System Partition (ESP):
 +`bootctl` and other tools that access the EFI System Partition (ESP):
  
  * `$SYSTEMD_RELAX_ESP_CHECKS=1` — if set, the ESP validation checks are
    relaxed. Specifically, validation checks that ensure the specified ESP path
  
  * `$SYSTEMD_ESP_PATH=…` — override the path to the EFI System Partition. This
    may be used to override ESP path auto detection, and redirect any accesses to
 -  the ESP to the specified directory. Not that unlike with bootctl's --path=
 -  switch only very superficial validation of the specified path is done when
 -  this environment variable is used.
 +  the ESP to the specified directory. Note that unlike with `bootctl`'s
 +  `--path=` switch only very superficial validation of the specified path is
 +  done when this environment variable is used.
  
 -systemd itself:
 +`systemd` itself:
  
  * `$SYSTEMD_ACTIVATION_UNIT` — set for all NSS and PAM module invocations that
    are done by the service manager on behalf of a specific unit, in child
    it is either set to `system` or `user` depending on whether the NSS/PAM
    module is called by systemd in `--system` or `--user` mode.
  
 -systemd-remount-fs:
 +`systemd-remount-fs`:
  
  * `$SYSTEMD_REMOUNT_ROOT_RW=1` — if set and no entry for the root directory
 -  exists in /etc/fstab (this file always takes precedence), then the root
 +  exists in `/etc/fstab` (this file always takes precedence), then the root
    directory is remounted writable. This is primarily used by
 -  systemd-gpt-auto-generator to ensure the root partition is mounted writable
 +  `systemd-gpt-auto-generator` to ensure the root partition is mounted writable
    in accordance to the GPT partition flags.
  
 -systemd-firstboot and localectl:
 +`systemd-firstboot` and `localectl`:
  
 -* `SYSTEMD_LIST_NON_UTF8_LOCALES=1` – if set non-UTF-8 locales are listed among
 +* `SYSTEMD_LIST_NON_UTF8_LOCALES=1` – if set, non-UTF-8 locales are listed among
    the installed ones. By default non-UTF-8 locales are suppressed from the
    selection, since we are living in the 21st century.
  
 -systemd-sysext:
 +`systemd-sysext`:
  
 -* `SYSTEMD_SYSEXT_HIERARCHIES` – if set to a colon-separated list of absolute
 -  paths this variable may be used to override which hierarchies to manage with
 -  `systemd-sysext`. By default only `/usr/` and `/opt/` are managed. With this
 -  environment variable this list may be changed, in order to add or remove
 -  directories from this list. This should only reference "real" file systems
 -  and directories that only contain "real" file systems as submounts — do not
 -  specify API file systems such as `/proc/` or `/sys/` here, or hierarchies
 -  that have them as submounts. In particular, do not specify the root directory
 -  `/` here.
 +* `SYSTEMD_SYSEXT_HIERARCHIES` – this variable may be used to override which
 +  hierarchies are managed by `systemd-sysext`. By default only `/usr/` and
 +  `/opt/` are managed, and directories may be added or removed to that list by
 +  setting this environment variable to a colon-separated list of absolute
 +  paths. Only "real" file systems and directories that only contain "real" file
 +  systems as submounts should be used. Do not specify API file systems such as
 +  `/proc/` or `/sys/` here, or hierarchies that have them as submounts. In
 +  particular, do not specify the root directory `/` here.
  
 -systemd-tmpfiles:
 +`systemd-tmpfiles`:
  
 -* `SYSTEMD_TMPFILES_FORCE_SUBVOL` - if unset, v/q/Q lines will create subvolumes only if the
 -  OS itself is installed into a subvolume. If set to 1 (or another true value), these lines will always create
 -  subvolumes (if the backing filesystem supports them). If set to 0, these lines will always create directories.
 +* `SYSTEMD_TMPFILES_FORCE_SUBVOL` - if unset, `v`/`q`/`Q` lines will create
 +  subvolumes only if the OS itself is installed into a subvolume. If set to `1`
 +  (or another value interpreted as true), these lines will always create
 +  subvolumes if the backing filesystem supports them. If set to `0`, these
 +  lines will always create directories.
diff --combined man/systemd.unit.xml
index 1a823b3feb4854cc59135877791f8b18c17594a8,f72e20329535921a7361dec8291e723cb30f803f..333449097f440487621f17c47ec907bee12ba9a5
@@@ -45,9 -45,9 +45,9 @@@
  <filename>/run/systemd/transient/*</filename>
  <filename>/run/systemd/generator.early/*</filename>
  <filename>/etc/systemd/system/*</filename>
 -<filename>/etc/systemd/systemd.attached/*</filename>
 +<filename>/etc/systemd/system.attached/*</filename>
  <filename>/run/systemd/system/*</filename>
 -<filename>/run/systemd/systemd.attached/*</filename>
 +<filename>/run/systemd/system.attached/*</filename>
  <filename>/run/systemd/generator/*</filename>
  <filename index='false'>…</filename>
  <filename>/usr/lib/systemd/system/*</filename>
@@@ -60,7 -60,7 +60,7 @@@
  <filename>$XDG_RUNTIME_DIR/systemd/user.control/*</filename>
  <filename>$XDG_RUNTIME_DIR/systemd/transient/*</filename>
  <filename>$XDG_RUNTIME_DIR/systemd/generator.early/*</filename>
- <filename>$XDG_CONFIG_HOME/systemd/user/*</filename>
+ <filename>~/.config/systemd/user/*</filename>
  <filename>$XDG_CONFIG_DIRS/systemd/user/*</filename>
  <filename>/etc/systemd/user/*</filename>
  <filename>$XDG_RUNTIME_DIR/systemd/user/*</filename>
      <refsect2>
        <title>Conditions and Asserts</title>
  
 -      <para>Unit files may also include a number of <varname index="false">Condition…=</varname> and
 -      <varname index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify
 -      that the specified conditions are true. If not, the starting of the unit will be (mostly silently)
 -      skipped. Failing conditions will not result in the unit being moved into the <literal>failed</literal>
 -      state. The conditions are checked at the time the queued start job is to be executed. The ordering
 -      dependencies are still respected, so other units are still pulled in and ordered as if this unit was
 -      successfully activated. Use condition expressions in order to skip units that do not apply to the local
 -      system, for example because the kernel or runtime environment doesn't require their functionality.
 +      <para>Unit files may also include a number of <varname index="false">Condition…=</varname> and <varname
 +      index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify that the
 +      specified conditions and asserts are true. If not, the starting of the unit will be (mostly silently)
 +      skipped (in case of conditions), or aborted with an error message (in case of asserts). Failing
 +      conditions or asserts will not result in the unit being moved into the <literal>failed</literal>
 +      state. The conditions and asserts are checked at the time the queued start job is to be executed. The
 +      ordering dependencies are still respected, so other units are still pulled in and ordered as if this
 +      unit was successfully activated, and the conditions and asserts are executed the precise moment the
 +      unit would normally start and thus can validate system state after the units ordered before completed
 +      initialization. Use condition expressions for skipping units that do not apply to the local system, for
 +      example because the kernel or runtime environment doesn't require their functionality.
        </para>
  
        <para>If multiple conditions are specified, the unit will be executed if all of them apply (i.e. a
        logical AND is applied). Condition checks can use a pipe symbol (<literal>|</literal>) after the equals
 -      sign (<literal>Condition…=|…</literal>), which causes the condition becomes a triggering condition. If
 -      at least one triggering condition is defined for a unit, then the unit will be executed if at least one
 -      of the triggering conditions apply and all of the non-triggering conditions. If you prefix an argument
 -      with the pipe symbol and an exclamation mark, the pipe symbol must be passed first, the exclamation
 -      second. If any of these options is assigned the empty string, the list of conditions is reset
 -      completely, all previous condition settings (of any kind) will have no effect.</para>
 +      sign (<literal>Condition…=|…</literal>), which causes the condition to become a
 +      <emphasis>triggering</emphasis> condition. If at least one triggering condition is defined for a unit,
 +      then the unit will be started if at least one of the triggering conditions of the unit applies and all
 +      of the regular (i.e. non-triggering) conditions apply. If you prefix an argument with the pipe symbol
 +      and an exclamation mark, the pipe symbol must be passed first, the exclamation second. If any of these
 +      options is assigned the empty string, the list of conditions is reset completely, all previous
 +      condition settings (of any kind) will have no effect.</para>
  
        <para>The <varname>AssertArchitecture=</varname>, <varname>AssertVirtualization=</varname>, … options
 -      provide a similar mechanism that causes the job to fail (instead of being skipped). The failed check is
 -      logged. Units with failed conditions are considered to be in a clean state and will be garbage
 +      are similar to conditions but cause the start job to fail (instead of being skipped). The failed check
 +      is logged. Units with failed conditions are considered to be in a clean state and will be garbage
        collected if they are not referenced. This means that when queried, the condition failure may or may
        not show up in the state of the unit.</para>
  
diff --combined src/basic/meson.build
index 88639bc9b531ba31ef990e891fd7252363d4ce37,bacd519a867a4c9eee71505c07eb042ff5939341..282118bb1ab9e9bf15882a4ca1cc19f1aa7bd55f
@@@ -170,14 -170,14 +170,16 @@@ basic_sources = files(''
          nulstr-util.h
          ordered-set.c
          ordered-set.h
+         os-util.c
+         os-util.h
          parse-util.c
          parse-util.h
          path-lookup.c
          path-lookup.h
          path-util.c
          path-util.h
 +        percent-util.c
 +        percent-util.h
          prioq.c
          prioq.h
          proc-cmdline.c
diff --combined src/core/main.c
index b8ff184af0281e0a8f7637bcffcb5eb3d7146989,1b47226d7395136d668eeb5893baa8f512502623..9ad7db192c897f5aa876ef18e52b6de2f1ec47a9
@@@ -134,6 -134,7 +134,7 @@@ static usec_t arg_kexec_watchdog
  static char *arg_early_core_pattern;
  static char *arg_watchdog_device;
  static char **arg_default_environment;
+ static char **arg_manager_environment;
  static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
  static uint64_t arg_capability_bounding_set;
  static bool arg_no_new_privs;
@@@ -163,6 -164,36 +164,36 @@@ static char **saved_env = NULL
  static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
                                 const struct rlimit *saved_rlimit_memlock);
  
+ static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) {
+         _cleanup_free_ char *base = NULL;
+         _cleanup_strv_free_ char **files = NULL, **dirs = NULL;
+         int r;
+         r = xdg_user_config_dir(&base, "/systemd");
+         if (r < 0)
+                 return r;
+         r = strv_extendf(&files, "%s/user.conf", base);
+         if (r < 0)
+                 return r;
+         r = strv_extend(&files, PKGSYSCONFDIR "/user.conf");
+         if (r < 0)
+                 return r;
+         r = strv_consume(&dirs, TAKE_PTR(base));
+         if (r < 0)
+                 return r;
+         r = strv_extend_strv(&dirs, CONF_PATHS_STRV("systemd"), false);
+         if (r < 0)
+                 return r;
+         *ret_files = TAKE_PTR(files);
+         *ret_dirs = TAKE_PTR(dirs);
+         return 0;
+ }
  _noreturn_ static void freeze_or_exit_or_reboot(void) {
  
          /* If we are running in a container, let's prefer exiting, after all we can propagate an exit code to
@@@ -640,6 -671,7 +671,7 @@@ static int parse_config_file(void) 
                  { "Manager", "DefaultStartLimitIntervalSec", config_parse_sec,                   0, &arg_default_start_limit_interval      },
                  { "Manager", "DefaultStartLimitBurst",       config_parse_unsigned,              0, &arg_default_start_limit_burst         },
                  { "Manager", "DefaultEnvironment",           config_parse_environ,               0, &arg_default_environment               },
+                 { "Manager", "ManagerEnvironment",           config_parse_environ,               0, &arg_manager_environment               },
                  { "Manager", "DefaultLimitCPU",              config_parse_rlimit,                RLIMIT_CPU, arg_default_rlimit            },
                  { "Manager", "DefaultLimitFSIZE",            config_parse_rlimit,                RLIMIT_FSIZE, arg_default_rlimit          },
                  { "Manager", "DefaultLimitDATA",             config_parse_rlimit,                RLIMIT_DATA, arg_default_rlimit           },
                  {}
          };
  
-         const char *fn, *conf_dirs_nulstr;
+         _cleanup_strv_free_ char **_free_files = NULL, **_free_dirs = NULL;
  
-         fn = arg_system ?
-                 PKGSYSCONFDIR "/system.conf" :
-                 PKGSYSCONFDIR "/user.conf";
+         const char *const *files, *const *dirs, *suffix;
+         int r;
  
-         conf_dirs_nulstr = arg_system ?
-                 CONF_PATHS_NULSTR("systemd/system.conf.d") :
-                 CONF_PATHS_NULSTR("systemd/user.conf.d");
+         if (arg_system) {
+                 files = STRV_MAKE_CONST(PKGSYSCONFDIR "/system.conf");
+                 dirs = (const char* const*) CONF_PATHS_STRV("systemd");
+                 suffix = "system.conf.d";
+         } else {
+                 r = manager_find_user_config_paths(&_free_files, &_free_dirs);
+                 if (r < 0)
+                         return log_error_errno(r, "Failed to determine config file paths: %m");
+                 files = (const char* const*) _free_files;
+                 dirs = (const char* const*) _free_dirs;
+                 suffix = "user.conf.d";
+         }
  
-         (void) config_parse_many_nulstr(
-                         fn, conf_dirs_nulstr,
+         (void) config_parse_many(
+                         files, dirs, suffix,
                          "Manager\0",
                          config_item_table_lookup, items,
                          CONFIG_PARSE_WARN,
                          NULL,
                          NULL);
  
-         /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
-          * like everywhere else. */
+         /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use
+          * USEC_INFINITY like everywhere else. */
          if (arg_default_timeout_start_usec <= 0)
                  arg_default_timeout_start_usec = USEC_INFINITY;
          if (arg_default_timeout_stop_usec <= 0)
@@@ -1256,8 -1296,8 +1296,8 @@@ static int bump_rlimit_memlock(struct r
           * must be unsigned, hence this is a given, but let's make this clear here. */
          assert_cc(RLIM_INFINITY > 0);
  
 -        mm = physical_memory() / 8; /* Let's scale how much we allow to be locked by the amount of physical
 -                                     * RAM. We allow an eighth to be locked by us, just to pick a value. */
 +        mm = physical_memory_scale(1, 8); /* Let's scale how much we allow to be locked by the amount of physical
 +                                           * RAM. We allow an eighth to be locked by us, just to pick a value. */
  
          new_rlimit = (struct rlimit) {
                  .rlim_cur = MAX3(HIGH_RLIMIT_MEMLOCK, saved_rlimit->rlim_cur, mm),
@@@ -1312,8 -1352,7 +1352,7 @@@ static int status_welcome(void) 
  
          r = parse_os_release(NULL,
                               "PRETTY_NAME", &pretty_name,
-                              "ANSI_COLOR", &ansi_color,
-                              NULL);
+                              "ANSI_COLOR", &ansi_color);
          if (r < 0)
                  log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
                                 "Failed to read os-release file, ignoring: %m");
@@@ -1415,7 -1454,7 +1454,7 @@@ static void redirect_telinit(int argc, 
          if (getpid_cached() == 1)
                  return;
  
 -        if (!strstr(program_invocation_short_name, "init"))
 +        if (!invoked_as(argv, "init"))
                  return;
  
          execv(SYSTEMCTL_BINARY_PATH, argv);
@@@ -2263,6 -2302,19 +2302,19 @@@ static void fallback_rlimit_memlock(con
          arg_default_rlimit[RLIMIT_MEMLOCK] = rl;
  }
  
+ static void setenv_manager_environment(void) {
+         char **p;
+         int r;
+         STRV_FOREACH(p, arg_manager_environment) {
+                 log_debug("Setting '%s' in our own environment.", *p);
+                 r = putenv_dup(*p, true);
+                 if (r < 0)
+                         log_warning_errno(errno, "Failed to setenv \"%s\", ignoring: %m", *p);
+         }
+ }
  static void reset_arguments(void) {
          /* Frees/resets arg_* variables, with a few exceptions commented below. */
  
          arg_watchdog_device = NULL;
  
          arg_default_environment = strv_free(arg_default_environment);
+         arg_manager_environment = strv_free(arg_manager_environment);
          rlimit_free_all(arg_default_rlimit);
  
          arg_capability_bounding_set = CAP_ALL;
@@@ -2357,6 -2410,9 +2410,9 @@@ static int parse_configuration(const st
          if (arg_show_status == _SHOW_STATUS_INVALID)
                  arg_show_status = SHOW_STATUS_YES;
  
+         /* Push variables into the manager environment block */
+         setenv_manager_environment();
          return 0;
  }
  
diff --combined src/shared/conf-parser.c
index df6472d4becc2e41153e9fa89c511f8277c22f7c,eb468390c286468fba70693c01c139d78a7674a0..64ed2571e9b5f183907e5a414264ac2e3d79cf6d
@@@ -22,7 -22,6 +22,7 @@@
  #include "nulstr-util.h"
  #include "parse-util.h"
  #include "path-util.h"
 +#include "percent-util.h"
  #include "process-util.h"
  #include "rlimit-util.h"
  #include "sd-id128.h"
@@@ -420,11 -419,11 +420,11 @@@ int config_parse
          if (ret_mtime)
                  *ret_mtime = mtime;
  
-         return 0;
+         return 1;
  }
  
  static int config_parse_many_files(
-                 const char *conf_file,
+                 const char* const* conf_files,
                  char **files,
                  const char *sections,
                  ConfigItemLookup lookup,
          char **fn;
          int r;
  
-         if (conf_file) {
-                 r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata, &mtime);
+         /* First read the first found main config file. */
+         STRV_FOREACH(fn, (char**) conf_files) {
+                 r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &mtime);
                  if (r < 0)
                          return r;
+                 if (r > 0)
+                         break;
          }
  
+         /* Then read all the drop-ins. */
          STRV_FOREACH(fn, files) {
                  usec_t t;
  
                  r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &t);
                  if (r < 0)
                          return r;
-                 if (t > mtime) /* Find the newest */
-                         mtime = t;
+                 mtime = MAX(mtime, t); /* Find the newest */
          }
  
          if (ret_mtime)
@@@ -477,12 -479,14 +480,14 @@@ int config_parse_many_nulstr
          if (r < 0)
                  return r;
  
-         return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
+         return config_parse_many_files(STRV_MAKE_CONST(conf_file),
+                                        files, sections, lookup, table, flags, userdata,
+                                        ret_mtime);
  }
  
  /* Parse each config file in the directories specified as strv. */
  int config_parse_many(
-                 const char *conf_file,
+                 const char* const* conf_files,
                  const char* const* conf_file_dirs,
                  const char *dropin_dirname,
                  const char *sections,
          if (r < 0)
                  return r;
  
-         return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
+         return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_mtime);
  }
  
  #define DEFINE_PARSER(type, vartype, conv_func)                         \