summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.mailmap11
-rw-r--r--Makefile-man.am11
-rw-r--r--Makefile.am50
-rw-r--r--NEWS351
-rw-r--r--README6
-rw-r--r--README.md4
-rw-r--r--catalog/systemd.be.catalog.in10
-rw-r--r--catalog/systemd.be@latin.catalog.in10
-rw-r--r--catalog/systemd.bg.catalog.in10
-rw-r--r--catalog/systemd.catalog.in10
-rw-r--r--catalog/systemd.da.catalog.in10
-rw-r--r--catalog/systemd.fr.catalog.in10
-rw-r--r--catalog/systemd.hr.catalog.in10
-rw-r--r--catalog/systemd.hu.catalog.in10
-rw-r--r--catalog/systemd.it.catalog.in8
-rw-r--r--catalog/systemd.ko.catalog.in10
-rw-r--r--catalog/systemd.pl.catalog.in10
-rw-r--r--catalog/systemd.pt_BR.catalog.in10
-rw-r--r--catalog/systemd.ru.catalog.in10
-rw-r--r--catalog/systemd.sr.catalog.in10
-rw-r--r--catalog/systemd.zh_CN.catalog.in10
-rw-r--r--catalog/systemd.zh_TW.catalog.in10
-rw-r--r--configure.ac17
-rw-r--r--docs/sysvinit/README.in2
-rw-r--r--hwdb/70-pointingstick.hwdb4
-rwxr-xr-xman/50-xdg-data-dirs.sh12
-rwxr-xr-xman/90-rearrange-path.py40
-rw-r--r--man/bootctl.xml4
-rw-r--r--man/busctl.xml2
-rw-r--r--man/environment.d.xml122
-rw-r--r--man/file-hierarchy.xml2
-rw-r--r--man/journalctl.xml8
-rw-r--r--man/kernel-install.xml2
-rw-r--r--man/sd-bus.xml2
-rw-r--r--man/sd-login.xml2
-rw-r--r--man/sd_journal_get_catalog.xml2
-rw-r--r--man/systemctl.xml2
-rw-r--r--man/systemd-ask-password-console.service.xml2
-rw-r--r--man/systemd-ask-password.xml2
-rw-r--r--man/systemd-coredump.xml2
-rw-r--r--man/systemd-cryptsetup@.service.xml2
-rw-r--r--man/systemd-environment-d-generator.xml80
-rw-r--r--man/systemd-getty-generator.xml2
-rw-r--r--man/systemd-gpt-auto-generator.xml2
-rw-r--r--man/systemd-hostnamed.service.xml2
-rw-r--r--man/systemd-importd.service.xml2
-rw-r--r--man/systemd-inhibit.xml2
-rw-r--r--man/systemd-journal-gatewayd.service.xml6
-rw-r--r--man/systemd-journal-remote.xml2
-rw-r--r--man/systemd-localed.service.xml2
-rw-r--r--man/systemd-logind.service.xml6
-rw-r--r--man/systemd-machine-id-setup.xml2
-rw-r--r--man/systemd-machined.service.xml2
-rw-r--r--man/systemd-nspawn.xml4
-rw-r--r--man/systemd-remount-fs.service.xml2
-rw-r--r--man/systemd-resolved.service.xml4
-rw-r--r--man/systemd-suspend.service.xml2
-rw-r--r--man/systemd-timedated.service.xml2
-rw-r--r--man/systemd-tty-ask-password-agent.xml2
-rw-r--r--man/systemd.environment-generator.xml160
-rw-r--r--man/systemd.exec.xml27
-rw-r--r--man/systemd.generator.xml3
-rw-r--r--man/systemd.journal-fields.xml4
-rw-r--r--man/systemd.mount.xml2
-rw-r--r--man/systemd.offline-updates.xml4
-rw-r--r--man/systemd.preset.xml2
-rw-r--r--man/systemd.resource-control.xml2
-rw-r--r--man/systemd.scope.xml2
-rw-r--r--man/systemd.service.xml2
-rw-r--r--man/systemd.slice.xml2
-rw-r--r--man/systemd.special.xml6
-rw-r--r--man/systemd.unit.xml2
-rw-r--r--man/systemd.xml8
-rw-r--r--src/analyze/analyze.c2
-rw-r--r--src/basic/conf-files.c2
-rw-r--r--src/basic/copy.c2
-rw-r--r--src/basic/def.h14
-rw-r--r--src/basic/env-util.c212
-rw-r--r--src/basic/env-util.h18
-rw-r--r--src/basic/exec-util.c360
-rw-r--r--src/basic/exec-util.h40
-rw-r--r--src/basic/fileio.c147
-rw-r--r--src/basic/fileio.h3
-rw-r--r--src/basic/fs-util.h6
-rw-r--r--src/basic/log.c7
-rw-r--r--src/basic/log.h1
-rw-r--r--src/basic/process-util.c2
-rw-r--r--src/basic/util.c143
-rw-r--r--src/basic/util.h2
-rw-r--r--src/boot/bootctl.c152
-rw-r--r--src/core/execute.c10
-rw-r--r--src/core/killall.c3
-rw-r--r--src/core/macros.systemd.in2
-rw-r--r--src/core/main.c15
-rw-r--r--src/core/manager.c128
-rw-r--r--src/core/shutdown.c3
-rw-r--r--src/coredump/coredumpctl.c68
-rw-r--r--src/dissect/dissect.c8
l---------src/environment-d-generator/Makefile1
-rw-r--r--src/environment-d-generator/environment-d-generator.c107
-rw-r--r--src/import/importd.c7
-rw-r--r--src/journal/journalctl.c2
-rw-r--r--src/journal/journald-server.c24
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c9
-rw-r--r--src/libsystemd/sd-device/sd-device.c43
-rw-r--r--src/libsystemd/sd-netlink/netlink-socket.c4
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c4
-rw-r--r--src/login/logind-seat.c9
-rw-r--r--src/mount/mount-tool.c2
-rw-r--r--src/network/networkd-address.c7
-rw-r--r--src/network/networkd-route.c2
-rw-r--r--src/resolve/resolved-resolv-conf.c6
-rw-r--r--src/shared/firewall-util.c5
-rw-r--r--src/shared/pager.c8
-rw-r--r--src/shared/path-lookup.c3
-rw-r--r--src/sleep/sleep.c5
-rw-r--r--src/systemctl/systemctl.c118
-rw-r--r--src/systemd/sd-bus-vtable.h54
-rw-r--r--src/test/test-conf-files.c24
-rw-r--r--src/test/test-env-util.c117
-rw-r--r--src/test/test-exec-util.c348
-rw-r--r--src/test/test-fd-util.c10
-rw-r--r--src/test/test-fileio.c112
-rw-r--r--src/test/test-stat-util.c4
-rw-r--r--src/test/test-util.c45
-rw-r--r--src/udev/udev-builtin-net_id.c3
-rw-r--r--src/update-done/update-done.c2
128 files changed, 2877 insertions, 734 deletions
diff --git a/.gitignore b/.gitignore
index 924b995bb3..01cb6e7db7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
/*.tar.bz2
/*.tar.gz
/*.tar.xz
+/30-systemd-environment-d-generator
/GPATH
/GRTAGS
/GSYMS
@@ -194,6 +195,7 @@
/test-env-util
/test-escape
/test-event
+/test-exec-util
/test-execute
/test-extract-word
/test-fd-util
diff --git a/.mailmap b/.mailmap
index d007ba741e..c32db0f21b 100644
--- a/.mailmap
+++ b/.mailmap
@@ -89,3 +89,14 @@ Eric Cook <llua@users.noreply.github.com>
Lukáš Nykrýn <lnykryn@redhat.com>
Heikki Kemppainen <heikki.kemppainen@nokia.com>
Hendrik Brueckner <hbrueckner@users.noreply.github.com>
+Alexandros Frantzis <alexandros.frantzis@canonical.com>
+Alexander Kochetkov <al.kochet@gmail.com>
+Fionn Cleary <clearyf@tcd.ie>
+Michel Kraus <github@demonsphere.de> <27o@users.noreply.github.com>
+Charles (Chas) Williams <ciwillia@brocade.com>
+Emil Soleyman <emil@soleyman.com>
+Dmitry Khlebnikov <dmitry.khlebnikov@rea-group.com> <galaxy4public@users.noreply.github.com>
+Antoine Eiche <lewo@abesis.fr>
+Gianluca Boiano <morf3089@gmail.com>
+Paolo Giangrandi <paolo@luccalug.it>
+Karl Kraus <karl.kraus@tum.de> <laqueray@gmail.com>
diff --git a/Makefile-man.am b/Makefile-man.am
index e20187d0df..d5626411a5 100644
--- a/Makefile-man.am
+++ b/Makefile-man.am
@@ -11,6 +11,7 @@ MANPAGES += \
man/bootup.7 \
man/busctl.1 \
man/daemon.7 \
+ man/environment.d.5 \
man/file-hierarchy.7 \
man/halt.8 \
man/hostname.5 \
@@ -110,6 +111,7 @@ MANPAGES += \
man/systemd-debug-generator.8 \
man/systemd-delta.1 \
man/systemd-detect-virt.1 \
+ man/systemd-environment-d-generator.8 \
man/systemd-escape.1 \
man/systemd-fsck@.service.8 \
man/systemd-fstab-generator.8 \
@@ -146,6 +148,7 @@ MANPAGES += \
man/systemd.1 \
man/systemd.automount.5 \
man/systemd.device.5 \
+ man/systemd.environment-generator.7 \
man/systemd.exec.5 \
man/systemd.generator.7 \
man/systemd.journal-fields.7 \
@@ -184,6 +187,7 @@ MANPAGES += \
man/udev_new.3 \
man/udevadm.8
MANPAGES_ALIAS += \
+ man/30-systemd-environment-d-generator.8 \
man/SD_ALERT.3 \
man/SD_BUS_ERROR_ACCESS_DENIED.3 \
man/SD_BUS_ERROR_ADDRESS_IN_USE.3 \
@@ -542,6 +546,7 @@ MANPAGES_ALIAS += \
man/udev_ref.3 \
man/udev_unref.3 \
man/user.conf.d.5
+man/30-systemd-environment-d-generator.8: man/systemd-environment-d-generator.8
man/SD_ALERT.3: man/sd-daemon.3
man/SD_BUS_ERROR_ACCESS_DENIED.3: man/sd-bus-errors.3
man/SD_BUS_ERROR_ADDRESS_IN_USE.3: man/sd-bus-errors.3
@@ -900,6 +905,9 @@ man/udev_monitor_unref.3: man/udev_monitor_new_from_netlink.3
man/udev_ref.3: man/udev_new.3
man/udev_unref.3: man/udev_new.3
man/user.conf.d.5: man/systemd-system.conf.5
+man/30-systemd-environment-d-generator.html: man/systemd-environment-d-generator.html
+ $(html-alias)
+
man/SD_ALERT.html: man/sd-daemon.html
$(html-alias)
@@ -2640,6 +2648,7 @@ EXTRA_DIST += \
man/crypttab.xml \
man/daemon.xml \
man/dnssec-trust-anchors.d.xml \
+ man/environment.d.xml \
man/file-hierarchy.xml \
man/halt.xml \
man/hostname.xml \
@@ -2772,6 +2781,7 @@ EXTRA_DIST += \
man/systemd-debug-generator.xml \
man/systemd-delta.xml \
man/systemd-detect-virt.xml \
+ man/systemd-environment-d-generator.xml \
man/systemd-escape.xml \
man/systemd-firstboot.xml \
man/systemd-fsck@.service.xml \
@@ -2832,6 +2842,7 @@ EXTRA_DIST += \
man/systemd-volatile-root.service.xml \
man/systemd.automount.xml \
man/systemd.device.xml \
+ man/systemd.environment-generator.xml \
man/systemd.exec.xml \
man/systemd.generator.xml \
man/systemd.journal-fields.xml \
diff --git a/Makefile.am b/Makefile.am
index 09e550da65..292f63c408 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,12 +39,12 @@ SUBDIRS = . po
.PRECIOUS: $(TEST_SUITE_LOG) Makefile
LIBUDEV_CURRENT=7
-LIBUDEV_REVISION=5
+LIBUDEV_REVISION=6
LIBUDEV_AGE=6
-LIBSYSTEMD_CURRENT=17
+LIBSYSTEMD_CURRENT=18
LIBSYSTEMD_REVISION=0
-LIBSYSTEMD_AGE=17
+LIBSYSTEMD_AGE=18
# Dirs of external packages
dbuspolicydir=@dbuspolicydir@
@@ -68,6 +68,7 @@ catalogstatedir=$(systemdstatedir)/catalog
xinitrcdir=$(sysconfdir)/X11/xinit/xinitrc.d
# Our own, non-special dirs
+environmentdir=$(prefix)/lib/environment.d
pkgsysconfdir=$(sysconfdir)/systemd
userunitdir=$(prefix)/lib/systemd/user
userpresetdir=$(prefix)/lib/systemd/user-preset
@@ -80,6 +81,8 @@ networkdir=$(rootprefix)/lib/systemd/network
pkgincludedir=$(includedir)/systemd
systemgeneratordir=$(rootlibexecdir)/system-generators
usergeneratordir=$(prefix)/lib/systemd/user-generators
+systemenvgeneratordir=$(prefix)/lib/systemd/system-environment-generators
+userenvgeneratordir=$(prefix)/lib/systemd/user-environment-generators
systemshutdowndir=$(rootlibexecdir)/system-shutdown
systemsleepdir=$(rootlibexecdir)/system-sleep
systemunitdir=$(rootprefix)/lib/systemd/system
@@ -207,6 +210,8 @@ AM_CPPFLAGS = \
-DSYSTEMD_CRYPTSETUP_PATH=\"$(rootlibexecdir)/systemd-cryptsetup\" \
-DSYSTEM_GENERATOR_PATH=\"$(systemgeneratordir)\" \
-DUSER_GENERATOR_PATH=\"$(usergeneratordir)\" \
+ -DSYSTEM_ENV_GENERATOR_PATH=\"$(systemenvgeneratordir)\" \
+ -DUSER_ENV_GENERATOR_PATH=\"$(userenvgeneratordir)\" \
-DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
-DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
@@ -307,6 +312,10 @@ endef
install-directories-hook:
$(MKDIR_P) $(addprefix $(DESTDIR),$(INSTALL_DIRS))
+install-environment-conf-hook: install-directories-hook
+ $(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(sysconfdir)/environment \
+ $(DESTDIR)$(environmentdir)/99-environment.conf
+
install-aliases-hook:
set -- $(SYSTEM_UNIT_ALIASES) && \
dir=$(systemunitdir) && $(install-aliases)
@@ -340,10 +349,13 @@ INSTALL_EXEC_HOOKS += \
install-target-wants-hook \
install-directories-hook \
install-aliases-hook \
- install-touch-usr-hook
+ install-touch-usr-hook \
+ install-busnames-target-wants-hook
+if ENABLE_ENVIRONMENT_D
INSTALL_EXEC_HOOKS += \
- install-busnames-target-wants-hook
+ install-environment-conf-hook
+endif
# ------------------------------------------------------------------------------
AM_V_M4 = $(AM_V_M4_$(V))
@@ -425,6 +437,11 @@ systemgenerator_PROGRAMS = \
systemd-system-update-generator \
systemd-debug-generator
+if ENABLE_ENVIRONMENT_D
+userenvgenerator_PROGRAMS = \
+ 30-systemd-environment-d-generator
+endif
+
dist_bashcompletion_data = \
shell-completion/bash/busctl \
shell-completion/bash/journalctl \
@@ -764,7 +781,9 @@ EXTRA_DIST += \
tools/make-man-rules.py \
tools/make-directive-index.py \
tools/xml_helper.py \
- man/glib-event-glue.c
+ man/glib-event-glue.c \
+ man/50-xdg-data-dirs.sh \
+ man/90-rearrange-path.py
# ------------------------------------------------------------------------------
noinst_LTLIBRARIES += \
@@ -876,6 +895,8 @@ libbasic_la_SOURCES = \
src/basic/bus-label.h \
src/basic/ratelimit.h \
src/basic/ratelimit.c \
+ src/basic/exec-util.c \
+ src/basic/exec-util.h \
src/basic/exit-status.c \
src/basic/exit-status.h \
src/basic/virt.c \
@@ -1533,6 +1554,7 @@ tests += \
test-ellipsize \
test-util \
test-mount-util \
+ test-exec-util \
test-cpu-set-util \
test-hexdecoct \
test-escape \
@@ -1921,6 +1943,12 @@ test_mount_util_SOURCES = \
test_mount_util_LDADD = \
libsystemd-shared.la
+test_exec_util_SOURCES = \
+ src/test/test-exec-util.c
+
+test_exec_util_LDADD = \
+ libsystemd-shared.la
+
test_hexdecoct_SOURCES = \
src/test/test-hexdecoct.c
@@ -2822,6 +2850,13 @@ systemd_system_update_generator_LDADD = \
libsystemd-shared.la
# ------------------------------------------------------------------------------
+30_systemd_environment_d_generator_SOURCES = \
+ src/environment-d-generator/environment-d-generator.c
+
+30_systemd_environment_d_generator_LDADD = \
+ libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
if ENABLE_HIBERNATE
systemgenerator_PROGRAMS += \
systemd-hibernate-resume-generator
@@ -6222,6 +6257,8 @@ substitutions = \
'|sysctldir=$(sysctldir)|' \
'|systemgeneratordir=$(systemgeneratordir)|' \
'|usergeneratordir=$(usergeneratordir)|' \
+ '|systemenvgeneratordir=$(systemenvgeneratordir)|' \
+ '|userenvgeneratordir=$(userenvgeneratordir)|' \
'|CERTIFICATEROOT=$(CERTIFICATEROOT)|' \
'|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \
'|PACKAGE_NAME=$(PACKAGE_NAME)|' \
@@ -6485,6 +6522,7 @@ INSTALL_DIRS += \
endif
INSTALL_DIRS += \
+ $(environmentdir) \
$(prefix)/lib/modules-load.d \
$(sysconfdir)/modules-load.d \
$(prefix)/lib/systemd/network \
diff --git a/NEWS b/NEWS
index 23f555fc53..a3b3fef627 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ systemd System and Service Manager
CHANGES WITH 233 in spe
+ [ LIST FAR FROM COMPLETE YET ]
+
* DBus policy files are now installed into /usr rather than /etc. Make
sure your system has dbus >= 1.9.18 running before upgrading to this
version, or override the install path with --with-dbuspolicydir= .
@@ -26,21 +28,342 @@ CHANGES WITH 233 in spe
The 'n' choice for the confirmation spawn prompt has been removed,
because its meaning was confusing.
+ The prompt may now also be redirected to an alternative console by
+ specifying the console as parameter to systemd.confirm_spawn=.
+
* Services of Type=notify require a READY=1 notification to be sent
during startup. If no such message is sent, the service now fails,
even if the main process exited with a successful exit code.
- * The option MulticastDNS= of network configuration files has got
- actual implementation. With MulticastDNS=yes a host can resolve
- names of remote hosts and to reply to mDNS's A and AAAA requests
- from the hosts.
+ * Services that fail to start up correctly now always have their
+ ExecStopPost= commands executed. Previously, they'd enter "failed"
+ state directly, without executing these commands.
+
+ * The option MulticastDNS= of network configuration files has acquired
+ an actual implementation. With MulticastDNS=yes a host can resolve
+ names of remote hosts and to reply to mDNS's A and AAAA requests from
+ the hosts.
* When units are about to be started an additional check is now done to
ensure that all dependencies of type BindsTo= (when used in
combination with After=) have been started.
+ * systemd-analyze gained a new verb "syscall-filter" which shows which
+ system call groups are defined for the SystemCallFilter= unit file
+ setting, and which system calls they precisely contain.
+
+ * A new system call filter group "@filesystem" has been added,
+ consisting of various file system related system calls. A group
+ "@reboot" has been added, covering reboot, kexec and shutdown related
+ calls. Finally, a group "@swap" has been added covering swap
+ configuration related calls.
+
+ * A new unit file option RestrictNamespaces= has been added that may be
+ used to restrict access to the various process namespace types the
+ Linux kernel provides. Specifically, it may be used to take away the
+ right for specific service units to create additional file system,
+ networking, user, and other namespaces. This sandboxing option is
+ particularly relevant due to the high amount of recently discovered
+ namespacing related vulnerabilities in the kernel.
+
+ * .link gained support for a new AutoNegotiation= setting for
+ configuring Ethernet auto-negotiation.
+
+ * systemd-networkd's .network files gained support for a new
+ ListenPort= setting in the [DHCP] section to explicitly configure the
+ UDP client port the DHCP client shall listen on.
+
+ * New systemd-specific mount options are now understood in /etc/fstab:
+
+ x-systemd.mount-timeout= may be used to configure the maximum
+ permitted runtime of the mount command.
+
+ x-systemd.device-bound may be set to bind a mount point to its
+ backing device unit, in order to automatically remove a mount point
+ if its backing device is unplugged. This option may also be
+ configured through the new SYSTEMD_MOUNT_DEVICE_BOUND udev property
+ on the block device, which is now automatically set for all CDROM
+ drives, so that mounted CDs are automatically unmounted when they are
+ removed from the drive.
+
+ x-systemd.after= and x-systemd.before= may be use to explicitly order
+ a mount after or before another unit or mount point.
+
+ * Enqueued start jobs for device units are now automatically garbage
+ collected if there are no jobs waiting for them anymore.
+
+ * systemctl list-jobs gained two new switches: With --after, every
+ queued job shows which other queued job is waiting for it; with
+ --before it shows which other jobs every job is waiting for.
+
+ * systemd-nspawn gained support for ephemeral boots from disk images
+ (or in other words: --ephemeral and --image= may now be
+ combined). Moreover, ephemeral boots are now supported for normal
+ directories, even if the backing file system is not btrfs. Of course,
+ if the file system does not support file system snapshots or
+ reflinks, the initial copy operation will be relatively expensive, but
+ this should still be suitable for many use cases.
+
+ * Calendar time specifications in .timer units now support
+ specifications relative to the end of a month by using "~" instead of
+ "-" as separator between month and day. For example, "*-02~03" means
+ "The third last day in February". In addition a new syntax for
+ repeated events has been added using the "/" character. For example,
+ "9..17/2:00" means "every two hours from 9am to 5pm".
+
+ * systemd-socket-proxyd gained a new parameter --connections-max= for
+ configuring the maximum number of concurrent connections.
+
+ * All python scripts shipped with systemd (specifically: the various
+ tests written in Python) now require Python 3.
+
+ * sd-id128 gained a new API for generating unique IDs for the host
+ that does not leak the machine ID. Specifically,
+ sd_id128_get_machine_app_specific() derives an ID based on the
+ machine ID a in well-defined, non-reversible, stable way. This is
+ useful whenever an identifier for the host is needed but where the
+ identifier shall not be useful to identify the system beyond the
+ scope of the application itself. (Internally this uses HMAC-SHA256 as
+ keyed hash function using the machine ID as input.)
+
+ * NotifyAccess= gained a new supported value "exec". When set
+ notifications are accepted from all processes systemd itself invoked,
+ including all control processes.
+
+ * .nspawn files gained support for defining overlay mounts using the
+ Overlay= and OverlayReadOnly= options. Previously this functionality
+ was only available on the systemd-nspawn command line.
+
+ * systemd-nspawn's --bind= and --overlay= options gained support for
+ bind/overlay mounts whose source lies within the container tree by
+ prefixing the source path with "+".
+
+ * systemd-nspawn's --bind= and --overlay= options gained support for
+ automatically allocating a temporary source directory in /var/tmp
+ that is removed when the container dies. Specifically, if the source
+ directory is specified as empty string this mechanism is selected. An
+ example usage is --overlay=+/var::/var, which creates an overlay
+ mount based on the original /var contained in the image, overlayed
+ with a temporary directory in the host's /var/tmp. This way changes
+ to /var are automatically flushed when the container shuts down.
+
+ * .network files gained a new Unmanaged= boolean setting for explicitly
+ excluding one or more interfaces from management by systemd-networkd.
+
+ * systemd-nspawn --image= option does now permit raw file system block
+ devices (in addition to images containing partition tables, as
+ before).
+
+ * The disk image dissection logic in systemd-nspawn gained support for
+ automatically setting up LUKS encrypted as well as Verity protected
+ partitions. When a container is booted from an encrypted image the
+ passphrase is queried at start-up time. When a container with Verity
+ data is started, the root hash is search in a ".roothash" file
+ accompanying the disk image (alternatively, pass the root hash via
+ the new --root-hash= command line option).
+
+ * A new tool /usr/lib/systemd/systemd-dissect has been added that may
+ be used to dissect disk images the same way as systemd-nspawn does
+ it, following the Bootable Partition Specification. It may even be
+ used to mount disk images with complex partition setups (including
+ LUKS and Verity partitions) to a local host directory, in order to
+ inspect them. This tool is not considered public API (yet), and is
+ thus not installed into /usr/bin. Please do not rely on its
+ existance, since it might go away or be changed in later systemd
+ versions.
+
+ * A new generator "systemd-verity-generator" has been added, similar in
+ style to "systemd-cryptsetup-generator", permitting automatic setup of
+ Verity root partitions when systemd boots up. In order to make use of
+ this your partition setup should follow the Discoverable Partitions
+ Specification, and the GPT partition ID of the root file system
+ partition should be identical to the upper 128bit of the Verity root
+ hash. The GPT partition ID of the Verity partition protecting it
+ should be the lower 128bit of the Verity root hash. If the partition
+ image follows this model it is sufficient to specify a single
+ "roothash=" kernel command line argument to both configure which root
+ image and verity partition to use as well as the root hash for
+ it. Note that systemd-nspawn's Verity support follows the same
+ semantics, meaning that disk images with proper Verity data in place
+ may be booted in containers with systemd-nspawn as well as on
+ physical systems via the verity generator. Also note that the "mkosi"
+ tool available at https://github.com/systemd/mkosi has been updated
+ to generate Verity protected disk images following this scheme. In
+ fact, it has been updated to generate disk images that optionally
+ implement a complete UEFI SecureBoot trust chain, involving a signed
+ kernel and initrd image that incorporates such a root hash as well as
+ a Verity-enabled root partition.
+
+ * Support for the %c, %r, %R specifiers in unit files has been
+ removed. Specifiers are not supposed to be dependent on configuration
+ of unit files themselves (so that they resolve to the same regardless
+ where used in the unit files), but these options were due to the
+ existence of the Slice= option.
+
+ * The various options in the [Match] section of .network files gained
+ support for negative matching.
+
+ * The hardware database (hwdb) udev supports has been updated to carry
+ accelerometer quirks.
+
+ * All system services are now run with a fresh kernel keyring set up
+ for them. The invocation ID is stored by default in it, thus
+ providing a safe, non-overridable way to determine the invocation
+ ID of each service.
+
+ * Service unit files gained new BindPaths= and BindReadOnlyPaths=
+ options for bind mounting arbitrary paths in a service-specific
+ way. When these options are used, arbitrary host or service files and
+ directories may be mounted to arbitrary locations in the service's
+ view.
+
+ * Documentation has been added that lists all of systemd's low-level
+ environment variables:
+
+ https://github.com/systemd/systemd/blob/master/ENVIRONMENT.md
+
+ * sd-daemon gained a new API sd_is_socket_sockaddr() for determining
+ whether a specific socket file descriptor matches a specified socket
+ address.
+
+ * systemd-firstboot has been updated to check for the
+ systemd.firstboot= kernel command line option. It accepts a boolean
+ and when set to false the first boot questions are skipped.
+
+ * The systemd-networkd ProxyARP= option has been renamed to
+ IPV4ProxyARP=. Similar, VXLAN-specific option ARPProxy= has been
+ renamed to ReduceARPProxy=. The old names continue to be available
+ for compatibility.
+
+ * systemd-networkd's bonding device support gained support for two new
+ configuration options ActiveSlave= and PrimarySlave=.
+
+ * systemd-fstab-generator has been updated to check for the
+ systemd.volatile= kernel command line option, which either takes a
+ boolean parameter or the special value "state". If used the system
+ may be booted in a "volatile" boot mode. Specifically,
+ systemd.volatile=yes is used, the root directory will be mounted as
+ tmpfs, and only /usr is mounted from the actual root file system. If
+ systemd.volatile=state is used, the root directory will be mounted as
+ usual, but /var is mounted as tmpfs. This concept provides similar
+ functionality as systemd-nspawn's --volatile= option, but provides it
+ on physical boots. Use this option for implementing stateless
+ systems, or testing systems with all state and/or configuration reset
+ to the defaults. (Note though that many distributions are not
+ prepared to boot up without a populated /etc or /var, though)
+
+ * systemd-gpt-auto-generator gained support for LUKS encrypted root
+ partitions. Previously it only supported LUKS encrypted partitions
+ for all other uses, except for the root partition itself.
+
+ * Socket units gained support for listening on AF_VSOCK sockets for
+ communication in virtualized QEMU environments.
+
+ * The "configure" script gained a new option --with-fallback-hostname=
+ for specifying the fallback hostname to use if none is configured in
+ /etc/hostname. For example, by specifying
+ --with-fallback-hostname=fedora it is possible to default to a
+ hostname of "fedora" when the user didn't specify anything
+ explicitly.
+
+ * systemd-cgls gained support for a new --unit= switch for listing only
+ the control groups of a specific unit. Similar --user-unit= has been
+ added for listing only the control groups of a specific user unit.
+
+ * systemd-mount gained a new --umount switch for unmounting a mount or
+ automount point (and all mount/automount points below it).
+
+ * systemd will now refuse full configuration reloads (via systemctl
+ daemon-reload and related calls) unless at least 16MiB of free space
+ are available in /run. This is a safety precaution in order to ensure
+ that generators can safely operate after the reload completed.
+
+ * A new unit file option RootImage= has been added, which has a similar
+ effect as RootDirectory= but mounts the service's root directory from
+ a disk image instead of plain directory. This logic reuses the same
+ image dissection and mount logic that systemd-nspawn already uses,
+ and hence supports any disk images systemd-nspawn supports, including
+ those following the Discoverable Partition Specification, as well as
+ Verity enabled images. This option enables systemd to run system
+ services directly off disk images acting as resource bundles,
+ possibly even including full integrity data.
+
+ * A new MountAPIVFS= unit file option has been added, taking a boolean
+ argument. If enabled /proc, /sys and /dev (collectively called the
+ "API VFS") will be mounted for the service. This is only relevant if
+ RootDirectory= or RootImage= is used for the service, as these mounts
+ are of course in place in the host mount namespace anyway.
+
+ * systemd-nspawn gained support for a new --pivot-root= switch. If
+ specified the root directory within the container image is pivoted to
+ the specified mount point, while the original root disk is moved to a
+ different place. This option enables booting of ostree images
+ directly with systemd-nspawn.
+
+ * systemd-networkd gained support for configuring IPv6 Proxy NDP
+ addresses via the new IPv6ProxyNDPAddress= .network file setting.
+
+ * The systemd build scripts will no longer complain if the NTP server
+ addresses are not changed from the defaults. Google is now supporting
+ these NTP servers officially. We still recommend downstreams to
+ properly register an NTP pool with the NTP pool project though.
+
+ * coredumpctl gained new new "--reverse" option for printing the list
+ of coredumps in reverse order.
+
+ * The systemd-coredump logic has been improved so that it may be reused
+ for collecting backtraces in non-compiled languages, for example in
+ scripting languages such as Python.
+
+ * machinectl will now show the UID shift of local containers, if user
+ namespacing is enabled for them.
+
+ * systemd will now optionally run "environment generator" binaries at
+ configuration load time. They may be used to add environment
+ variables to the environment block passed to services invoked. One
+ user environment generator is shipped by default that sets up
+ environment variables based on files dropped into
+ ~/.config/environment.d/.
+
+ Contributions from: Adrián López, Alexander Galanin, Alexander
+ Kochetkov, Alexandros Frantzis, Andrey Ulanov, Antoine Eiche, Baruch
+ Siach, Bastien Nocera, Benjamin Robin, Björn, Brandon Philips, Cédric
+ Schieli, Charles (Chas) Williams, Christian Hesse, Daniele Medri,
+ Daniel Drake, Daniel Rusek, Daniel Wagner, Dan Streetman, Dave Reisner,
+ David Glasser, David Herrmann, David Michael, Djalal Harouni, Dmitry
+ Khlebnikov, Dmitry Rozhkov, Dongsu Park, Douglas Christman, Earnestly,
+ Emil Soleyman, Eric Cook, Evgeny Vereshchagin, Felipe Sateler, Fionn
+ Cleary, Florian Klink, Francesco Brozzu, Franck Bui, Gabriel Rauter,
+ Gianluca Boiano, Graeme Lawes, Hans de Goede, Harald Hoyer, Ian
+ Kelling, Ivan Shapovalov, Jakub Wilk, Janne Heß, Jan Synacek, Jason
+ Reeder, Jonathan Boulle, Jörg Thalheim, Jouke Witteveen, Karl Kraus,
+ Kees Cook, Keith Busch, Kieran Colford, kilian-k, Lennart Poettering,
+ Lubomir Rintel, Lucas Werkmeister, Lukas Rusak, Maarten de Vries, Maks
+ Naumov, Mantas Mikulėnas, Marc-Andre Lureau, Marcin Bachry, Mark
+ Stosberg, Martin Ejdestig, Martin Pitt, micah, Michael Biebl, Michael
+ Shields, Michal Schmidt, Michal Sekletar, Michel Kraus, Mike Gilbert,
+ Mirza Krak, Namhyung Kim, nikolaof, peoronoob, Peter Hutterer, Peter
+ Körner, Philip Withnall, Piotr Drąg, Ray Strode, Reverend Homer,
+ Rike-Benjamin Schuppner, Robert Kreuzer, Ronny Chevalier, Ruslan
+ Bilovol, sammynx, Sergey Ptashnick, Sergiusz Urbaniak, Stefan Berger,
+ Stefan Hajnoczi, Stefan Schweter, Susant Sahani, Sylvain Plantefève,
+ Taylor Smock, Thomas Blume, Thomas H. P. Andersen, Tobias Stoeckmann,
+ Tom Gundersen, Torstein Husebø, Viktar Vaŭčkievič, Viktor Mihajlovski,
+ Waldemar Brodkorb, Walter Garcia-Fontes, Wim de With, Yassine
+ Imounachen, Yi EungJun, Yu Watanabe, Zbigniew Jędrzejewski-Szmek,
+ Александр Тихонов
+
+ — Berlin, 2017-02-XX
+
CHANGES WITH 232:
+ * udev now runs with MemoryDenyWriteExecute=, RestrictRealtime= and
+ RestrictAddressFamilies= enabled. These sandboxing options should
+ generally be compatible with the various external udev call-out
+ binaries we are aware of, however there may be exceptions, in
+ particular when exotic languages for these call-outs are used. In
+ this case, consider turning off these settings locally.
+
* The new RemoveIPC= option can be used to remove IPC objects owned by
the user or group of a service when that service exits.
@@ -1892,7 +2215,7 @@ CHANGES WITH 220:
gudev from the Gnome project instead. gudev is still included
in systemd, for now. It will be removed soon, though. Please
also see the announcement-thread on systemd-devel:
- http://lists.freedesktop.org/archives/systemd-devel/2015-May/032070.html
+ https://lists.freedesktop.org/archives/systemd-devel/2015-May/032070.html
* systemd now exposes a CPUUsageNSec= property for each
service unit on the bus, that contains the overall consumed
@@ -3795,7 +4118,7 @@ CHANGES WITH 211:
also supports LUKS-encrypted partitions now. With this in
place, automatic discovery of partitions to mount following
the Discoverable Partitions Specification
- (http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec)
+ (https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec)
is now a lot more complete. This allows booting without
/etc/fstab and without root= on the kernel command line on
systems prepared appropriately.
@@ -5147,7 +5470,7 @@ CHANGES WITH 199:
* A new libsystemd-bus module has been added that implements a
pretty complete D-Bus client library. For details see:
- http://lists.freedesktop.org/archives/systemd-devel/2013-March/009797.html
+ https://lists.freedesktop.org/archives/systemd-devel/2013-March/009797.html
* journald will now explicitly flush the journal files to disk
at the latest 5min after each write. The file will then also
@@ -5297,7 +5620,7 @@ CHANGES WITH 198:
only in conjunction with Gummiboot, but could be supported
by other boot loaders too. For details see:
- http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface
+ https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface
* A new generator has been added that automatically mounts the
EFI System Partition (ESP) to /boot, if that directory
@@ -5373,7 +5696,7 @@ CHANGES WITH 198:
* A new tool kernel-install has been added that can install
kernel images according to the Boot Loader Specification:
- http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec
+ https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec
* Boot time console output has been improved to provide
animated boot time output for hanging jobs.
@@ -5463,7 +5786,7 @@ CHANGES WITH 197:
of these policies is now the default. Please see this wiki
document for details:
- http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
+ https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
* Auke Kok's bootchart implementation has been added to the
systemd tree. It is an optional component that can graph the
@@ -5611,7 +5934,7 @@ CHANGES WITH 196:
indexed database to link up additional information with
journal entries. For further details please check:
- http://www.freedesktop.org/wiki/Software/systemd/catalog
+ https://www.freedesktop.org/wiki/Software/systemd/catalog
The indexed message catalog database also needs to be
rebuilt after installation of message catalog files. Use
@@ -6463,7 +6786,7 @@ CHANGES WITH 183:
* A framework for implementing offline system updates is now
integrated, for details see:
- http://freedesktop.org/wiki/Software/systemd/SystemUpdates
+ https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates
* A new service type Type=idle is available now which helps us
avoiding ugly interleaving of getty output and boot status
@@ -6744,7 +7067,7 @@ CHANGES WITH 39:
* New unit file option ControlGroupPersistent= to make cgroups
persistent, following the mechanisms outlined in
- http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups
+ https://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups
* Support multiple local RTCs in a sane way
@@ -6831,7 +7154,7 @@ CHANGES WITH 38:
* Processes with '@' in argv[0][0] are now excluded from the
final shut-down killing spree, following the logic explained
in:
- http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
+ https://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
* All processes remaining in a service cgroup when we enter
the START or START_PRE states are now killed with
diff --git a/README b/README
index dc88d5b261..ac8620c75b 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ DETAILS:
http://0pointer.de/blog/projects/systemd.html
WEB SITE:
- http://www.freedesktop.org/wiki/Software/systemd
+ https://www.freedesktop.org/wiki/Software/systemd
GIT:
git@github.com:systemd/systemd.git
@@ -14,7 +14,7 @@ GITWEB:
https://github.com/systemd/systemd
MAILING LIST:
- http://lists.freedesktop.org/mailman/listinfo/systemd-devel
+ https://lists.freedesktop.org/mailman/listinfo/systemd-devel
IRC:
#systemd on irc.freenode.org
@@ -269,7 +269,7 @@ WARNINGS:
requires that /var/run is a symlink to /run.
For more information on this issue consult
- http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
+ https://www.freedesktop.org/wiki/Software/systemd/separate-usr-is-broken
To run systemd under valgrind, compile with VALGRIND defined
(e.g. ./configure CPPFLAGS='... -DVALGRIND=1'). Otherwise,
diff --git a/README.md b/README.md
index 35ab9663ca..82fb799b42 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
## Details
-General information about systemd can be found in the [systemd Wiki](http://www.freedesktop.org/wiki/Software/systemd).
+General information about systemd can be found in the [systemd Wiki](https://www.freedesktop.org/wiki/Software/systemd).
Information about build requirements are provided in the [README file](../master/README).
@@ -17,4 +17,4 @@ Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for
When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/CODING_STYLE).
-If you are looking for support, please contact our [mailing list](http://lists.freedesktop.org/mailman/listinfo/systemd-devel) or join our [IRC channel](irc://irc.freenode.org/%23systemd).
+If you are looking for support, please contact our [mailing list](https://lists.freedesktop.org/mailman/listinfo/systemd-devel) or join our [IRC channel](irc://irc.freenode.org/%23systemd).
diff --git a/catalog/systemd.be.catalog.in b/catalog/systemd.be.catalog.in
index 5b237f0558..5b1cdf2492 100644
--- a/catalog/systemd.be.catalog.in
+++ b/catalog/systemd.be.catalog.in
@@ -20,7 +20,7 @@
# Belarusian translation
# Фармат каталога апісаны на старонцы
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -94,7 +94,7 @@ Documentation: man:core(5)
Subject: Новая сесія № @SESSION_ID@ створана для карыстальніка @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Новая сесія з № @SESSION_ID@ створана для карыстальніка @USER_ID@.
@@ -104,7 +104,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Сесія № @SESSION_ID@ спынена
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Сесія № @SESSION_ID@ спынена.
@@ -112,7 +112,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Даступна новае працоўнае месца № @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Новае працоўнае месца № @SEAT_ID@ наладжана і даступна для выкарыстання.
@@ -120,7 +120,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Працоўнае месца № @SEAT_ID@ выдалена
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Працоўнае месца № @SEAT_ID@ выдалена і больш не даступна.
diff --git a/catalog/systemd.be@latin.catalog.in b/catalog/systemd.be@latin.catalog.in
index fc9f7cad16..764432c0dc 100644
--- a/catalog/systemd.be@latin.catalog.in
+++ b/catalog/systemd.be@latin.catalog.in
@@ -20,7 +20,7 @@
# Belarusian Latin translation
# Farmat kataloha apisany na staroncy
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -95,7 +95,7 @@ Rekamiendujecca paviedamić ab hetym raspracoŭnikam.
Subject: Novaja siesija № @SESSION_ID@ stvorana dlia karystaĺnika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novaja siesija z № @SESSION_ID@ stvorana dlia karystaĺnika @USER_ID@.
@@ -105,7 +105,7 @@ Lidar hetaj siesii pad № @LEADER@.
Subject: Siesija № @SESSION_ID@ spyniena
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Siesija № @SESSION_ID@ spyniena.
@@ -113,7 +113,7 @@ Siesija № @SESSION_ID@ spyniena.
Subject: Dastupna novaje pracoŭnaje miesca № @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novaje pracoŭnaje miesca № @SEAT_ID@ naladžana i dastupna dlia
vykarystannia.
@@ -122,7 +122,7 @@ vykarystannia.
Subject: Pracoŭnaje miesca № @SEAT_ID@ vydaliena
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Pracoŭnaje miesca № @SEAT_ID@ vydaliena i boĺš nie dastupna.
diff --git a/catalog/systemd.bg.catalog.in b/catalog/systemd.bg.catalog.in
index 76b0ce8f17..4b6cf118be 100644
--- a/catalog/systemd.bg.catalog.in
+++ b/catalog/systemd.bg.catalog.in
@@ -19,7 +19,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -95,7 +95,7 @@ Documentation: man:core(5)
Subject: Създадена е нова сесия № @SESSION_ID@ за потребителя „@USER_ID@“
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
За потребителя „@USER_ID@“ е създадена нова сесия № @SESSION_ID@.
@@ -105,7 +105,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Сесия № @SESSION_ID@ приключи
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Сесия № @SESSION_ID@ приключи работа.
@@ -113,7 +113,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Налично е ново работно място № @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Новото работно място № @SEAT_ID@ е настроено и готово за работа.
@@ -121,7 +121,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Работното място № @SEAT_ID@ е премахнато
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Работното място № @SEAT_ID@ вече не е налично.
diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
index cb0ac0ca88..9cd3e6bac3 100644
--- a/catalog/systemd.catalog.in
+++ b/catalog/systemd.catalog.in
@@ -18,7 +18,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -115,7 +115,7 @@ als Fehler dem jeweiligen Hersteller gemeldet werden.
Subject: A new session @SESSION_ID@ has been created for user @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A new session with the ID @SESSION_ID@ has been created for the user @USER_ID@.
@@ -125,7 +125,7 @@ The leading process of the session is @LEADER@.
Subject: Session @SESSION_ID@ has been terminated
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A session with the ID @SESSION_ID@ has been terminated.
@@ -133,7 +133,7 @@ A session with the ID @SESSION_ID@ has been terminated.
Subject: A new seat @SEAT_ID@ is now available
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A new seat @SEAT_ID@ has been configured and is now available.
@@ -141,7 +141,7 @@ A new seat @SEAT_ID@ has been configured and is now available.
Subject: Seat @SEAT_ID@ has now been removed
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A seat @SEAT_ID@ has been removed and is no longer available.
diff --git a/catalog/systemd.da.catalog.in b/catalog/systemd.da.catalog.in
index bc7d94476f..a5570f47d5 100644
--- a/catalog/systemd.da.catalog.in
+++ b/catalog/systemd.da.catalog.in
@@ -19,7 +19,7 @@
# Danish translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -79,7 +79,7 @@ og burde blive reporteret som en bug til folkene bag
Subject: En ny session @SESSION_ID@ er blevet lavet for bruger @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En ny session med ID @SESSION_ID@ er blevet lavet for brugeren @USER_ID@.
@@ -89,7 +89,7 @@ Den ledende process for sessionen er @LEADER@.
Subject: Session @SESSION_ID@ er blevet lukket ned
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En session med ID @SESSION_ID@ er blevet lukket ned.
@@ -97,7 +97,7 @@ En session med ID @SESSION_ID@ er blevet lukket ned.
Subject: En ny arbejdsstation $SEAT_ID@ er nu tilgængelig
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En ny arbejdsstation @SEAT_ID@ er blevet konfigureret og er nu tilgængelig.
@@ -105,7 +105,7 @@ En ny arbejdsstation @SEAT_ID@ er blevet konfigureret og er nu tilgængelig.
Subject: Arbejdsstation @SEAT_ID@ er nu blevet fjernet
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
En arbejdsstation @SEAT_ID@ er blevet fjernet og er ikke længere tilgængelig.
diff --git a/catalog/systemd.fr.catalog.in b/catalog/systemd.fr.catalog.in
index d69dd0a520..c4b1a81ceb 100644
--- a/catalog/systemd.fr.catalog.in
+++ b/catalog/systemd.fr.catalog.in
@@ -20,7 +20,7 @@
# French translation
# Le format du catalogue de messages est décrit (en anglais) içi :
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
-- f77379a8490b408bbe5f6940505a777b
Subject: Le journal a été démarré
@@ -96,7 +96,7 @@ incriminé, et cela devrait être notifié à son concepteur comme un défaut (b
Subject: Une nouvelle session @SESSION_ID@ a été créée pour l'utilisateur @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Une nouvelle session a été créée pour l'utilisateur @USER_ID@ avec
l'identifiant (ID) @SESSION_ID@.
@@ -107,7 +107,7 @@ Le processus maître de la session est @LEADER@.
Subject: La session @SESSION_ID@ s'est terminée
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La session d'identifiant (ID) @SESSION_ID@ s'est terminée.
@@ -115,7 +115,7 @@ La session d'identifiant (ID) @SESSION_ID@ s'est terminée.
Subject: Un nouveau poste (seat) @SEAT_ID@ est disponible
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Un nouveau poste (seat) @SEAT_ID@ a été configuré et est maintenant
disponible.
@@ -124,7 +124,7 @@ disponible.
Subject: Le poste (seat) @SEAT_ID@ a été retiré
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Le poste (seat) @SEAT_ID@ a été retiré et n'est plus disponible.
diff --git a/catalog/systemd.hr.catalog.in b/catalog/systemd.hr.catalog.in
index 7502aed741..d30e955e28 100644
--- a/catalog/systemd.hr.catalog.in
+++ b/catalog/systemd.hr.catalog.in
@@ -19,7 +19,7 @@
# Croatian translation
# Format kataloga je dokumentiran na
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Za pojašnjenje zašto ovo radimo, posjetite https://xkcd.com/1024/
@@ -93,7 +93,7 @@ trebalo bi se prijaviti razvijatelju kao greška.
Subject: Nova sesija @SESSION_ID@ je stvorena za korisnika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nova sesija sa ID @SESSION_ID@ je stvorena za korisnika @USER_ID@.
@@ -103,7 +103,7 @@ Glavni proces sesije je @LEADER@.
Subject: Sesija @SESSION_ID@ je prekinuta
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sesija sa ID @SESSION_ID@ je prekinuta.
@@ -111,7 +111,7 @@ Sesija sa ID @SESSION_ID@ je prekinuta.
Subject: Novo sjedište @SEAT_ID@ je sada dostupno
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Novo sjedište @SEAT_ID@ je podešeno i sada je dostupno.
@@ -119,7 +119,7 @@ Novo sjedište @SEAT_ID@ je podešeno i sada je dostupno.
Subject: Sjedište @SEAT_ID@ je sada uklonjeno
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sjedište @SEAT_ID@ je uklonjeno i više nije dostupno.
diff --git a/catalog/systemd.hu.catalog.in b/catalog/systemd.hu.catalog.in
index f538b7f958..23c1cd44db 100644
--- a/catalog/systemd.hu.catalog.in
+++ b/catalog/systemd.hu.catalog.in
@@ -19,7 +19,7 @@
# Message catalog for systemd's own messages
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -78,7 +78,7 @@ a szállítója felé kell bejelenteni.
Subject: Új munkamenet (@SESSION_ID@) létrehozva, felhasználója: @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Létrejött egy új munkamenet @SESSION_ID@ azonosítóval ezen felhasználóhoz:
@USER_ID@.
@@ -89,7 +89,7 @@ A munkamenet vezető folyamata: @LEADER@.
Subject: Munkamenet (@SESSION_ID@) befejezve
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A következő azonosítójú munkamenet befejeződött: @SESSION_ID@.
@@ -97,7 +97,7 @@ A következő azonosítójú munkamenet befejeződött: @SESSION_ID@.
Subject: Elérhető egy új munkaállomás: @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Beállításra kerül és használható egy új munkaállomás: @SEAT_ID@.
@@ -105,7 +105,7 @@ Beállításra kerül és használható egy új munkaállomás: @SEAT_ID@.
Subject: A munkaállomás eltávolítva: @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
A munkaállomás el lett távolítva, és már nem érhető el: @SEAT_ID@
diff --git a/catalog/systemd.it.catalog.in b/catalog/systemd.it.catalog.in
index 02c35f1f69..208ac2bfdc 100644
--- a/catalog/systemd.it.catalog.in
+++ b/catalog/systemd.it.catalog.in
@@ -98,7 +98,7 @@ segnalare la troncatura.
Subject: La nuova sessione @SESSION_ID@ è stata creata per l'utente @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Una nuova sessione con ID @SESSION_ID@ è stata creata per l'utente @USER_ID@.
@@ -108,7 +108,7 @@ Il processo primario della sessione è @LEADER@.
Subject: La sessione @SESSION_ID@ è terminata
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La sessione con ID @SESSION_ID@ è terminata.
@@ -116,7 +116,7 @@ La sessione con ID @SESSION_ID@ è terminata.
Subject: La nuova postazione @SEAT_ID@ è ora disponibile
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La nuova postazione @SEAT_ID@ è stata configurata ed è ora disponibile.
@@ -124,7 +124,7 @@ La nuova postazione @SEAT_ID@ è stata configurata ed è ora disponibile.
Subject: La postazione @SEAT_ID@ è stata rimossa
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
La postazione @SEAT_ID@ è stata rimossa e non è più disponibile.
diff --git a/catalog/systemd.ko.catalog.in b/catalog/systemd.ko.catalog.in
index 0249cba747..4e8d7008c3 100644
--- a/catalog/systemd.ko.catalog.in
+++ b/catalog/systemd.ko.catalog.in
@@ -19,7 +19,7 @@
# Korean translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
#
@@ -101,7 +101,7 @@ Documentation: man:core(5)
Subject: @USER_ID@ 사용자의 새 @SESSION_ID@ 세션 만듦
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@USER_ID@ 사용자의 새 @SESSION_ID@ 세션을 만들었습니다.
@@ -111,7 +111,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: @SESSION_ID@ 세션 마침
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@SESSION_ID@ 세션을 끝냈습니다.
@@ -119,7 +119,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 새 @SEAT_ID@ 시트 사용할 수 있음
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
새 @SEAT_ID@ 시트를 설정했고 사용할 수 있습니다.
@@ -127,7 +127,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: @SEAT_ID@ 시트 제거함
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
@SEAT_ID@ 시트를 제거했으며 더이상 사용할 수 없습니다.
diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in
index a93c63d0f6..981fefb7b9 100644
--- a/catalog/systemd.pl.catalog.in
+++ b/catalog/systemd.pl.catalog.in
@@ -20,7 +20,7 @@
# Polish translation
# The catalog format is documented on
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -106,7 +106,7 @@ gdb(1) będą ostrzegały o skróceniu pliku.
Subject: Utworzono nową sesję @SESSION_ID@ dla użytkownika @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nowa sesja o identyfikatorze @SESSION_ID@ została utworzona dla użytkownika
@USER_ID@.
@@ -117,7 +117,7 @@ Proces prowadzący sesji: @LEADER@.
Subject: Zakończono sesję @SESSION_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Sesja o identyfikatorze @SESSION_ID@ została zakończona.
@@ -125,7 +125,7 @@ Sesja o identyfikatorze @SESSION_ID@ została zakończona.
Subject: Dostępne jest nowe stanowisko @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Nowe stanowisko @SEAT_ID@ zostało skonfigurowane i jest teraz dostępne.
@@ -133,7 +133,7 @@ Nowe stanowisko @SEAT_ID@ zostało skonfigurowane i jest teraz dostępne.
Subject: Usunięto stanowisko @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Stanowisko @SEAT_ID@ zostało usunięte i nie jest już dostępne.
diff --git a/catalog/systemd.pt_BR.catalog.in b/catalog/systemd.pt_BR.catalog.in
index e461c2b2ba..192fd33c1c 100644
--- a/catalog/systemd.pt_BR.catalog.in
+++ b/catalog/systemd.pt_BR.catalog.in
@@ -19,7 +19,7 @@
# Catálogo de mensagens para as mensagens do próprio systemd
# O formato do catálogo está documentado em
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Para uma explicação do porquê de fazermos tudo isso, veja
# https://xkcd.com/1024/
@@ -79,7 +79,7 @@ deveria ser relatado para seu fabricante como um erro.
Subject: A nova sessão @SESSION_ID@ foi criada para usuário o @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Uma nova sessão com o ID @SESSION_ID@ foi criada para o usuário @USER_ID@.
@@ -89,7 +89,7 @@ O processo originador da sessão é @LEADER@.
Subject: Sessão @SESSION_ID@ foi terminada
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um sessão com o ID @SESSION_ID@ foi terminada.
@@ -97,7 +97,7 @@ Um sessão com o ID @SESSION_ID@ foi terminada.
Subject: Um novo seat @SEAT_ID@ está disponível
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um novo seat @SEAT_ID@ foi configurado e está disponível.
@@ -105,7 +105,7 @@ Um novo seat @SEAT_ID@ foi configurado e está disponível.
Subject: Seat @SEAT_ID@ foi removido agora
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Um seat @SEAT_ID@ foi removido e não está mais disponível.
diff --git a/catalog/systemd.ru.catalog.in b/catalog/systemd.ru.catalog.in
index 3ee1ed63c0..367ed89d96 100644
--- a/catalog/systemd.ru.catalog.in
+++ b/catalog/systemd.ru.catalog.in
@@ -20,7 +20,7 @@
# Russian translation
# Формат каталога сообщений описан по ссылке
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Перед каждым элементом в комментарии указан Subject исходного
# сообщения (на английском).
@@ -119,7 +119,7 @@ Documentation: man:coredump.conf(5)
Subject: Для пользователя @USER_ID@ создан новый сеанс @SESSION_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Для пользователя @USER_ID@ создан новый сеанс с идентификатором @SESSION_ID@.
@@ -130,7 +130,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Сеанс @SESSION_ID@ завершен
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Сеанс с идентификатором @SESSION_ID@ завершился.
@@ -139,7 +139,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Добавлено новое рабочее место @SEAT_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Новое рабочее место (seat) @SEAT_ID@ полностью настроено и готово к
использованию.
@@ -149,7 +149,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Рабочее место @SEAT_ID@ отключено
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Рабочее место (seat) @SEAT_ID@ было отключено.
diff --git a/catalog/systemd.sr.catalog.in b/catalog/systemd.sr.catalog.in
index 06a0ff648c..674eb557b5 100644
--- a/catalog/systemd.sr.catalog.in
+++ b/catalog/systemd.sr.catalog.in
@@ -19,7 +19,7 @@
# Serbian translation
# Формат каталога је документован на
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# Да бисте видели зашто ово радимо, погледајте https://xkcd.com/1024/
@@ -78,7 +78,7 @@ Documentation: man:core(5)
Subject: Нова сесија @SESSION_ID@ је направљена за корисника @USER_ID@
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Нова сесија са ИБ-ом @SESSION_ID@ је направљена за корисника @USER_ID@.
@@ -88,7 +88,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Сесија @SESSION_ID@ је окончана
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Сесија са ИБ-ом @SESSION_ID@ је окончана.
@@ -96,7 +96,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Ново седиште @SEAT_ID@ је сада доступно
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Ново седиште @SEAT_ID@ је исподешавано и сада је доступно.
@@ -104,7 +104,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: Седиште @SEAT_ID@ је сада уклоњено
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
Седиште @SEAT_ID@ је сада уклоњено и више није доступно.
diff --git a/catalog/systemd.zh_CN.catalog.in b/catalog/systemd.zh_CN.catalog.in
index 13030e14dc..78a8a8ca62 100644
--- a/catalog/systemd.zh_CN.catalog.in
+++ b/catalog/systemd.zh_CN.catalog.in
@@ -20,7 +20,7 @@
# Simplified Chinese translation
# 本 catalog 文档格式被记载在
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# 如需了解我们为什么做这些工作,请见 https://xkcd.com/1024/
@@ -76,7 +76,7 @@ Documentation: man:core(5)
Subject: 一个新会话 @SESSION_ID@ 已为用户 @USER_ID@ 建立
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一个 ID 为 @SESSION_ID@ 的新会话已为用户 @USER_ID@ 建立。
@@ -86,7 +86,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 会话 @SESSION_ID@ 已终止
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一个 ID 为 @SESSION_ID@ 的会话已终止。
@@ -94,7 +94,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 一个新的座位 @SEAT_ID@ 可用
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一个新的座位 @SEAT_ID@ 已被配置并已可用。
@@ -102,7 +102,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 座位 @SEAT_ID@ 已被移除
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
座位 @SEAT_ID@ 已被移除并不再可用。
diff --git a/catalog/systemd.zh_TW.catalog.in b/catalog/systemd.zh_TW.catalog.in
index f7b42fa1c7..d262b88a01 100644
--- a/catalog/systemd.zh_TW.catalog.in
+++ b/catalog/systemd.zh_TW.catalog.in
@@ -20,7 +20,7 @@
# Traditional Chinese translation
# Catalog 的格式記錄於
-# http://www.freedesktop.org/wiki/Software/systemd/catalog
+# https://www.freedesktop.org/wiki/Software/systemd/catalog
# For an explanation why we do all this, see https://xkcd.com/1024/
@@ -79,7 +79,7 @@ Documentation: man:core(5)
Subject: 新的工作階段 @SESSION_ID@ 已為使用者 @USER_ID@ 建立
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一個新的工作階段,ID @SESSION_ID@ 已為使用者 @USER_ID@ 建立。
@@ -89,7 +89,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 工作階段 @SESSION_ID@ 已結束
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一個工作階段,ID @SESSION_ID@ 已結束。
@@ -97,7 +97,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 新的座位 @SEAT_ID@ 可用
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
一個新的座位 @SEAT_ID@ 已被設定且現在可用。
@@ -105,7 +105,7 @@ Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
Subject: 座位 @SEAT_ID@ 已被移除
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation: https://www.freedesktop.org/wiki/Software/systemd/multiseat
座位 @SEAT_ID@ 已被移除且不再可用。
diff --git a/configure.ac b/configure.ac
index eff7fbb291..d98cc4d9ba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,10 +20,10 @@
AC_PREREQ([2.64])
AC_INIT([systemd],
- [232],
- [http://github.com/systemd/systemd/issues],
+ [233],
+ [https://github.com/systemd/systemd/issues],
[systemd],
- [http://www.freedesktop.org/wiki/Software/systemd])
+ [https://www.freedesktop.org/wiki/Software/systemd])
AC_CONFIG_SRCDIR([src/core/main.c])
AC_CONFIG_MACRO_DIR([m4])
@@ -581,7 +581,7 @@ AC_ARG_WITH([support-url],
AS_HELP_STRING([--with-support-url=URL],
[specify the support URL to show in catalog entries included in systemd]),
[SUPPORT_URL="$withval"],
- [SUPPORT_URL=http://lists.freedesktop.org/mailman/listinfo/systemd-devel])
+ [SUPPORT_URL=https://lists.freedesktop.org/mailman/listinfo/systemd-devel])
AC_SUBST(SUPPORT_URL)
@@ -1058,6 +1058,14 @@ fi
AM_CONDITIONAL(ENABLE_TMPFILES, [test "$have_tmpfiles" = "yes"])
# ------------------------------------------------------------------------------
+have_environment_d=no
+AC_ARG_ENABLE(environment-d, AS_HELP_STRING([--disable-environment-d], [disable environment.d support]))
+if test "x$enable_environment_d" != "xno"; then
+ have_environment_d=yes
+fi
+AM_CONDITIONAL(ENABLE_ENVIRONMENT_D, [test "$have_environment_d" = "yes"])
+
+# ------------------------------------------------------------------------------
have_sysusers=no
AC_ARG_ENABLE(sysusers, AS_HELP_STRING([--disable-sysusers], [disable sysusers support]))
if test "x$enable_sysusers" != "xno"; then
@@ -1669,6 +1677,7 @@ AC_MSG_RESULT([
vconsole: ${have_vconsole}
quotacheck: ${have_quotacheck}
tmpfiles: ${have_tmpfiles}
+ environment.d: ${have_environment_d}
sysusers: ${have_sysusers}
firstboot: ${have_firstboot}
randomseed: ${have_randomseed}
diff --git a/docs/sysvinit/README.in b/docs/sysvinit/README.in
index 996402d06b..de5d80d902 100644
--- a/docs/sysvinit/README.in
+++ b/docs/sysvinit/README.in
@@ -24,4 +24,4 @@ Further reading:
man:systemctl(1)
man:systemd(1)
http://0pointer.de/blog/projects/systemd-for-admins-3.html
- http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
+ https://www.freedesktop.org/wiki/Software/systemd/Incompatibilities
diff --git a/hwdb/70-pointingstick.hwdb b/hwdb/70-pointingstick.hwdb
index cfdfef567a..65c87aeac7 100644
--- a/hwdb/70-pointingstick.hwdb
+++ b/hwdb/70-pointingstick.hwdb
@@ -82,6 +82,10 @@
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:pvr*
POINTINGSTICK_CONST_ACCEL=0.5
+# Latitude E5570
+evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE5570*:pvr*
+ POINTINGSTICK_CONST_ACCEL=0.1
+
# Latitude E6320
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:pvr*
POINTINGSTICK_CONST_ACCEL=2.0
diff --git a/man/50-xdg-data-dirs.sh b/man/50-xdg-data-dirs.sh
new file mode 100755
index 0000000000..073174cb40
--- /dev/null
+++ b/man/50-xdg-data-dirs.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# set the default value
+XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share}"
+
+# add a directory if it exists
+if [[ -d /opt/foo/share ]]; then
+ XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS}
+fi
+
+# write our output
+echo XDG_DATA_DIRS=$XDG_DATA_DIRS
diff --git a/man/90-rearrange-path.py b/man/90-rearrange-path.py
new file mode 100755
index 0000000000..c6ff32210f
--- /dev/null
+++ b/man/90-rearrange-path.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python3
+
+"""
+
+Proof-of-concept systemd environment generator that makes sure that bin dirs
+are always after matching sbin dirs in the path.
+(Changes /sbin:/bin:/foo/bar to /bin:/sbin:/foo/bar.)
+
+This generator shows how to override the configuration possibly created by
+earlier generators. It would be easier to write in bash, but let's have it
+in Python just to prove that we can, and to serve as a template for more
+interesting generators.
+
+"""
+
+import os
+import pathlib
+
+def rearrange_bin_sbin(path):
+ """Make sure any pair of …/bin, …/sbin directories is in this order
+
+ >>> rearrange_bin_sbin('/bin:/sbin:/usr/sbin:/usr/bin')
+ '/bin:/sbin:/usr/bin:/usr/sbin'
+ """
+ items = [pathlib.Path(p) for p in path.split(':')]
+ for i in range(len(items)):
+ if 'sbin' in items[i].parts:
+ ind = items[i].parts.index('sbin')
+ bin = pathlib.Path(*items[i].parts[:ind], 'bin', *items[i].parts[ind+1:])
+ if bin in items[i+1:]:
+ j = i + 1 + items[i+1:].index(bin)
+ items[i], items[j] = items[j], items[i]
+ return ':'.join(p.as_posix() for p in items)
+
+if __name__ == '__main__':
+ path = os.environ['PATH'] # This should be always set.
+ # If it's not, we'll just crash, we is OK too.
+ new = rearrange_bin_sbin(path)
+ if new != path:
+ print('PATH={}'.format(new))
diff --git a/man/bootctl.xml b/man/bootctl.xml
index e2575a4751..675e0174e9 100644
--- a/man/bootctl.xml
+++ b/man/bootctl.xml
@@ -118,8 +118,8 @@
<refsect1>
<title>See Also</title>
<para>
- <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">Systemd boot loader interface</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface">Systemd boot loader interface</ulink>
</para>
</refsect1>
</refentry>
diff --git a/man/busctl.xml b/man/busctl.xml
index f63d0d5bab..28b36f09d0 100644
--- a/man/busctl.xml
+++ b/man/busctl.xml
@@ -472,7 +472,7 @@ o "/org/freedesktop/systemd1/job/42684"</programlisting>
<para>
<citerefentry project='dbus'><refentrytitle>dbus-daemon</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
- <ulink url="http://freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
+ <ulink url="https://www.freedesktop.org/wiki/Software/dbus">D-Bus</ulink>,
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/environment.d.xml b/man/environment.d.xml
new file mode 100644
index 0000000000..be7758a2f9
--- /dev/null
+++ b/man/environment.d.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
+<!--
+ This file is part of systemd.
+
+ Copyright 2016 Red Hat, Inc.
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="environment.d" xmlns:xi="http://www.w3.org/2001/XInclude">
+
+ <refentryinfo>
+ <title>environment.d</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Ray</firstname>
+ <surname>Strode</surname>
+ <email>rstrode@redhat.com</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>environment.d</refentrytitle>
+ <manvolnum>5</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>environment.d</refname>
+ <refpurpose>Definition of user session environment</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>~/.config/environment.d/*.conf</filename></para>
+ <para><filename>/etc/environment.d/*.conf</filename></para>
+ <para><filename>/run/environment.d/*.conf</filename></para>
+ <para><filename>/usr/lib/environment.d/*.conf</filename></para>
+ <para><filename>/etc/environment</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The <filename>environment.d</filename> directories contain a list of "global" environment
+ variable assignments for the user environment.
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ parses them and updates the environment exported by the systemd user instance to the services it
+ starts.</para>
+
+ <para>It is recommended to use numerical prefixes for file names to simplify ordering.</para>
+
+ <para>For backwards compatibility, a symlink to <filename>/etc/environment</filename> is
+ installed, so this file is also parsed.</para>
+ </refsect1>
+
+ <xi:include href="standard-conf.xml" xpointer="confd" />
+
+ <refsect1>
+ <title>Configuration Format</title>
+
+ <para>The configuration files contain a list of
+ <literal><replaceable>KEY</replaceable>=<replaceable>VALUE</replaceable></literal> environment
+ variable assignments, separated by newlines. The right hand side of these assignments may
+ reference previously defined environment variables, using the <literal>${OTHER_KEY}</literal>
+ and <literal>$OTHER_KEY</literal> format. It is also possible to use
+
+ <literal>${<replaceable>FOO</replaceable>:-<replaceable>DEFAULT_VALUE</replaceable>}</literal>
+ to expand in the same way as <literal>${<replaceable>FOO</replaceable>}</literal> unless the
+ expansion would be empty, in which case it expands to <replaceable>DEFAULT_VALUE</replaceable>,
+ and use
+ <literal>${<replaceable>FOO</replaceable>:+<replaceable>ALTERNATE_VALUE</replaceable>}</literal>
+ to expand to <replaceable>ALTERNATE_VALUE</replaceable> as long as
+ <literal>${<replaceable>FOO</replaceable>}</literal> would have expanded to a non-empty value.
+ No other elements of shell syntax are supported.</para>
+
+ <para>Each<replaceable>KEY</replaceable> must be a valid variable name. Empty lines
+ and lines beginning with the comment character <literal>#</literal> are ignored.</para>
+
+ <refsect2>
+ <title>Example</title>
+ <example>
+ <title>Setup environment to allow access to a program installed in
+ <filename noindex='true'>/opt/foo</filename></title>
+
+ <para><filename>/etc/environment.d/60-foo.conf</filename>:
+ </para>
+ <programlisting>
+ FOO_DEBUG=force-software-gl,log-verbose
+ PATH=/opt/foo/bin:$PATH
+ LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}/opt/foo/lib
+ XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS:-/usr/local/share/:/usr/share/}
+ </programlisting>
+ </example>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml
index 538a592f8d..ab52ccfe0c 100644
--- a/man/file-hierarchy.xml
+++ b/man/file-hierarchy.xml
@@ -502,7 +502,7 @@
url="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG
Base Directory Specification</ulink>. Additional locations for
high-level user resources are defined by <ulink
- url="http://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
+ url="https://www.freedesktop.org/wiki/Software/xdg-user-dirs/">xdg-user-dirs</ulink>.</para>
<variablelist>
<varlistentry>
diff --git a/man/journalctl.xml b/man/journalctl.xml
index eacba048bc..cae5312db2 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -318,7 +318,7 @@
<para>serializes the journal into a binary (but mostly
text-based) stream suitable for backups and network
transfer (see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
for more information). To import the binary stream back
into native journald format use
<citerefentry><refentrytitle>systemd-journal-remote</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
@@ -332,7 +332,7 @@
<listitem>
<para>formats entries as JSON data structures, one per
line (see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal JSON Format</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal JSON Format</ulink>
for more information).</para>
</listitem>
</varlistentry>
@@ -401,7 +401,7 @@
manuals. Note that help texts are not available for all
messages, but only for selected ones. For more information on
the message catalog, please refer to the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Message Catalog Developer Documentation</ulink>.</para>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/catalog">Message Catalog Developer Documentation</ulink>.</para>
<para>Note: when attaching <command>journalctl</command>
output to bug reports, please do <emphasis>not</emphasis> use
@@ -677,7 +677,7 @@
a new 128-bit ID suitable for identifying messages. This is
intended for usage by developers who need a new identifier for
a new message they introduce and want to make
- recognizable. This will print the new ID in three different
+ recognizable. This will print the new ID in four different
formats which can be copied into source code or similar.
</para></listitem>
</varlistentry>
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
index 99b7970457..94b6b1110d 100644
--- a/man/kernel-install.xml
+++ b/man/kernel-install.xml
@@ -189,7 +189,7 @@
<para>
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <ulink url="http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec">Boot loader specification</ulink>
</para>
</refsect1>
diff --git a/man/sd-bus.xml b/man/sd-bus.xml
index 66b1c96c15..6439395549 100644
--- a/man/sd-bus.xml
+++ b/man/sd-bus.xml
@@ -62,7 +62,7 @@
<title>Description</title>
<para><filename>sd-bus.h</filename> provides an implementation of a D-Bus IPC client. See
- <ulink url="http://www.freedesktop.org/software/dbus/" />
+ <ulink url="https://www.freedesktop.org/software/dbus/" />
for more information about D-Bus IPC.
</para>
diff --git a/man/sd-login.xml b/man/sd-login.xml
index 328f71164d..6861fbe257 100644
--- a/man/sd-login.xml
+++ b/man/sd-login.xml
@@ -67,7 +67,7 @@
local system. </para>
<para>See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+ url="https://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
on Linux</ulink> for an introduction into multi-seat support on
Linux, the background for this set of APIs.</para>
diff --git a/man/sd_journal_get_catalog.xml b/man/sd_journal_get_catalog.xml
index 35ec46f63e..604deb4e8c 100644
--- a/man/sd_journal_get_catalog.xml
+++ b/man/sd_journal_get_catalog.xml
@@ -90,7 +90,7 @@
<para>For more information about the journal message catalog
please refer to the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/catalog">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/catalog">Journal
Message Catalogs</ulink> documentation page.</para>
</refsect1>
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 25db00e5f6..d0b39d771b 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -1181,7 +1181,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
For more information on the concept of presets, please consult the
- <ulink url="http://freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
document.</para>
</listitem>
</varlistentry>
diff --git a/man/systemd-ask-password-console.service.xml b/man/systemd-ask-password-console.service.xml
index 479e5f2e5b..3c1537d942 100644
--- a/man/systemd-ask-password-console.service.xml
+++ b/man/systemd-ask-password-console.service.xml
@@ -71,7 +71,7 @@
properly notified.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
developer documentation</ulink> for more information about the
system password logic.</para>
diff --git a/man/systemd-ask-password.xml b/man/systemd-ask-password.xml
index 8d3355819b..51d8ef5d82 100644
--- a/man/systemd-ask-password.xml
+++ b/man/systemd-ask-password.xml
@@ -109,7 +109,7 @@
<para>Additional password agents may be implemented according to
the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">systemd
Password Agent Specification</ulink>.</para>
<para>If a password is queried on a TTY, the user may press TAB to
diff --git a/man/systemd-coredump.xml b/man/systemd-coredump.xml
index 7243467dc2..2c285bcb22 100644
--- a/man/systemd-coredump.xml
+++ b/man/systemd-coredump.xml
@@ -91,7 +91,7 @@
<para>It is also possible to invoke <command>systemd-coredump</command> with
<option>--backtrace</option> option. In this case, <command>systemd-coredump</command> expects
a journal entry in the journal
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal Export Format</ulink>
on standard input. The entry should contain a <varname>MESSAGE=</varname> field and any additional
metadata fields the caller deems reasonable. <command>systemd-coredump</command> will append
additional metadata fields in the same way it does for core dumps received from the kernel. In
diff --git a/man/systemd-cryptsetup@.service.xml b/man/systemd-cryptsetup@.service.xml
index fb8b06714d..73bd5b78ab 100644
--- a/man/systemd-cryptsetup@.service.xml
+++ b/man/systemd-cryptsetup@.service.xml
@@ -61,7 +61,7 @@
<para><filename>systemd-cryptsetup@.service</filename> will ask
for hard disk passwords via the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
+ url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">
password agent logic</ulink>, in order to query the user for the
password using the right mechanism at boot and during
runtime.</para>
diff --git a/man/systemd-environment-d-generator.xml b/man/systemd-environment-d-generator.xml
new file mode 100644
index 0000000000..cc00a5256d
--- /dev/null
+++ b/man/systemd-environment-d-generator.xml
@@ -0,0 +1,80 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+<refentry id="systemd-environment-d-generator">
+
+ <refentryinfo>
+ <title>systemd-environment-d-generator</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Zbigniew</firstname>
+ <surname>Jędrzejewski-Szmek</surname>
+ <email>zbyszek@in.waw.pl</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd-environment-d-generator</refentrytitle>
+ <manvolnum>8</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd-environment-d-generator</refname>
+ <refname>30-systemd-environment-d-generator</refname>
+ <refpurpose>Load variables specified by <filename>environment.d</filename>
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <para><filename>&userenvgeneratordir;/30-systemd-environment-d-generator</filename></para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para><filename>systemd-environment-d-generator</filename> is a
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ that reads environment configuration specified by
+ <citerefentry><refentrytitle>environment.d</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ configuration files and passes it to the
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ user manager instance.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <para>
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/man/systemd-getty-generator.xml b/man/systemd-getty-generator.xml
index 338925964d..8bff3bb7f4 100644
--- a/man/systemd-getty-generator.xml
+++ b/man/systemd-getty-generator.xml
@@ -64,7 +64,7 @@
<filename>container-getty@.service</filename> instances for
additional container pseudo TTYs as requested by the container
manager (see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/"><filename>Container
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/"><filename>Container
Interface</filename></ulink>). This should ensure that the user is
shown a login prompt at the right place, regardless of which
environment the system is started in. For example, it is
diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml
index 3af423b553..eb7a2c4c28 100644
--- a/man/systemd-gpt-auto-generator.xml
+++ b/man/systemd-gpt-auto-generator.xml
@@ -62,7 +62,7 @@
partitions and creates mount and swap units for them, based on the
partition type GUIDs of GUID partition tables (GPT). It implements
the <ulink
- url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
Partitions Specification</ulink>. Note that this generator has no
effect on non-GPT systems, or where the directories under the
mount points are already non-empty. Also, on systems where the
diff --git a/man/systemd-hostnamed.service.xml b/man/systemd-hostnamed.service.xml
index 6990d41b02..17755aa69e 100644
--- a/man/systemd-hostnamed.service.xml
+++ b/man/systemd-hostnamed.service.xml
@@ -66,7 +66,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/hostnamed">
+ url="https://www.freedesktop.org/wiki/Software/systemd/hostnamed">
developer documentation</ulink> for information about the APIs
<filename>systemd-hostnamed</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-importd.service.xml b/man/systemd-importd.service.xml
index 8fdced475c..70a618ce46 100644
--- a/man/systemd-importd.service.xml
+++ b/man/systemd-importd.service.xml
@@ -64,7 +64,7 @@
<command>import-tar</command>, <command>export-raw</command>, and <command>export-tar</command> commands.</para>
<para>See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/importd">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/importd">
importd D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-importd</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-inhibit.xml b/man/systemd-inhibit.xml
index ce169960d8..09b82b82c1 100644
--- a/man/systemd-inhibit.xml
+++ b/man/systemd-inhibit.xml
@@ -72,7 +72,7 @@
should not be interrupted.</para>
<para>For more information see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
Lock Developer Documentation</ulink>.</para>
</refsect1>
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index 22294542f3..3ee344e50b 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -197,7 +197,7 @@
one per line
(like <command>journalctl --output json</command>).
See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal
JSON Format</ulink> for more information.</para>
</listitem>
</varlistentry>
@@ -222,7 +222,7 @@
transfer
(like <command>journalctl --output export</command>).
See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink> for more information.</para>
</listitem>
</varlistentry>
@@ -289,7 +289,7 @@
<title>Examples</title>
<para>Retrieve events from this boot from local journal
in <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink>:
<programlisting>curl --silent -H'Accept: application/vnd.fdo.journal' \
'http://localhost:19531/entries?boot'</programlisting>
diff --git a/man/systemd-journal-remote.xml b/man/systemd-journal-remote.xml
index ee2d5c2486..d7750e416e 100644
--- a/man/systemd-journal-remote.xml
+++ b/man/systemd-journal-remote.xml
@@ -64,7 +64,7 @@
<filename>systemd-journal-remote</filename> is a command to
receive serialized journal events and store them to the journal.
Input streams are in the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/export">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/export">
Journal Export Format
</ulink>,
i.e. like the output from
diff --git a/man/systemd-localed.service.xml b/man/systemd-localed.service.xml
index 06aa78c0e4..2a796c9045 100644
--- a/man/systemd-localed.service.xml
+++ b/man/systemd-localed.service.xml
@@ -68,7 +68,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/localed">
+ url="https://www.freedesktop.org/wiki/Software/systemd/localed">
developer documentation</ulink> for information about the APIs
<filename>systemd-localed</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml
index 9288f48f07..5433269638 100644
--- a/man/systemd-logind.service.xml
+++ b/man/systemd-logind.service.xml
@@ -99,17 +99,17 @@
for information about the configuration of this service.</para>
<para>See <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
+ url="https://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
on Linux</ulink> for an introduction into basic concepts of logind
such as users, sessions and seats.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/logind">
+ url="https://www.freedesktop.org/wiki/Software/systemd/logind">
logind D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-logind</filename> provides.</para>
<para>For more information on the inhibition logic see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
Lock Developer Documentation</ulink>.</para>
</refsect1>
diff --git a/man/systemd-machine-id-setup.xml b/man/systemd-machine-id-setup.xml
index 944e899bd4..714317c945 100644
--- a/man/systemd-machine-id-setup.xml
+++ b/man/systemd-machine-id-setup.xml
@@ -92,7 +92,7 @@
environment and a UUID is configured for the container, this is
used to initialize the machine ID. For details, see the
documentation of the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container
Interface</ulink>.</para></listitem>
<listitem><para>Otherwise, a new ID is randomly
diff --git a/man/systemd-machined.service.xml b/man/systemd-machined.service.xml
index 999aeee1c6..c4f173f79b 100644
--- a/man/systemd-machined.service.xml
+++ b/man/systemd-machined.service.xml
@@ -71,7 +71,7 @@
names.</para>
<para>See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/machined">
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/machined">
machined D-Bus API Documentation</ulink> for information about the
APIs <filename>systemd-machined</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 96f8c3a61f..a7af8c25db 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -135,7 +135,7 @@
container.</para>
<para><command>systemd-nspawn</command> implements the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink>
+ url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink>
specification.</para>
<para>While running, containers invoked with <command>systemd-nspawn</command> are registered with the
@@ -233,7 +233,7 @@
a server data partition which are mounted to the appropriate
places in the container. All these partitions must be
identified by the partition types defined by the <ulink
- url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable
Partitions Specification</ulink>.</para></listitem>
<listitem><para>No partition table, and a single file system spanning the whole image.</para></listitem>
diff --git a/man/systemd-remount-fs.service.xml b/man/systemd-remount-fs.service.xml
index 176f2b2d20..6a5f0e6e38 100644
--- a/man/systemd-remount-fs.service.xml
+++ b/man/systemd-remount-fs.service.xml
@@ -72,7 +72,7 @@
systems.</para>
<para>For a longer discussion of kernel API file systems see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
File Systems</ulink>.</para>
</refsect1>
diff --git a/man/systemd-resolved.service.xml b/man/systemd-resolved.service.xml
index 6465193cc5..f6831848c7 100644
--- a/man/systemd-resolved.service.xml
+++ b/man/systemd-resolved.service.xml
@@ -62,7 +62,7 @@
<itemizedlist>
<listitem><para>The native, fully-featured API <command>systemd-resolved</command> exposes on the bus. See the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved">API Documentation</ulink> for
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/resolved">API Documentation</ulink> for
details. Usage of this API is generally recommended to clients as it is asynchronous and fully featured (for
example, properly returns DNSSEC validation status and interface scope for addresses as necessary for supporting
link-local networking).</para></listitem>
@@ -156,7 +156,7 @@
per-interface domains are exclusively routed to the matching
interfaces.</para>
- <para>See the <ulink url="http://www.freedesktop.org/wiki/Software/systemd/resolved"> resolved D-Bus API
+ <para>See the <ulink url="https://www.freedesktop.org/wiki/Software/systemd/resolved"> resolved D-Bus API
Documentation</ulink> for information about the APIs <filename>systemd-resolved</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml
index c7733f2885..2aa172e990 100644
--- a/man/systemd-suspend.service.xml
+++ b/man/systemd-suspend.service.xml
@@ -91,7 +91,7 @@
for local use only and should be considered hacks. If applications
want to react to system suspend/hibernation and resume,
they should rather use the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
+ url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
interface</ulink>.</para>
<para>Note that
diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml
index e44163aefb..fee860204d 100644
--- a/man/systemd-timedated.service.xml
+++ b/man/systemd-timedated.service.xml
@@ -67,7 +67,7 @@
is a command line client to this service.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/timedated">
+ url="https://www.freedesktop.org/wiki/Software/systemd/timedated">
developer documentation</ulink> for information about the APIs
<filename>systemd-timedated</filename> provides.</para>
</refsect1>
diff --git a/man/systemd-tty-ask-password-agent.xml b/man/systemd-tty-ask-password-agent.xml
index 2e4b31be07..2c114f4631 100644
--- a/man/systemd-tty-ask-password-agent.xml
+++ b/man/systemd-tty-ask-password-agent.xml
@@ -66,7 +66,7 @@
runtime.</para>
<para><command>systemd-tty-ask-password-agent</command> implements
- the <ulink url="http://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password
+ the <ulink url="https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents">Password
Agents Specification</ulink>, and is one of many possible response agents which
answer to queries formulated with
<citerefentry><refentrytitle>systemd-ask-password</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
diff --git a/man/systemd.environment-generator.xml b/man/systemd.environment-generator.xml
new file mode 100644
index 0000000000..fedbd60175
--- /dev/null
+++ b/man/systemd.environment-generator.xml
@@ -0,0 +1,160 @@
+<?xml version='1.0'?> <!--*-nxml-*-->
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
+%entities;
+]>
+
+<!--
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<refentry id="systemd.environment-generator" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <refentryinfo>
+ <title>systemd.environment-generator</title>
+ <productname>systemd</productname>
+
+ <authorgroup>
+ <author>
+ <contrib>Developer</contrib>
+ <firstname>Zbigniew</firstname>
+ <surname>Jędrzejewski-Szmek</surname>
+ <email>zbyszek@in.waw.pl</email>
+ </author>
+ </authorgroup>
+ </refentryinfo>
+
+ <refmeta>
+ <refentrytitle>systemd.environment-generator</refentrytitle>
+ <manvolnum>7</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>systemd.environment-generator</refname>
+ <refpurpose>Systemd environment file generators</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&systemenvgeneratordir;/some-generator</command>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>&userenvgeneratordir;/some-generator</command>
+ </cmdsynopsis>
+
+ <para>
+ <literallayout><filename>/run/systemd/system-environment-generators/*</filename>
+<filename>/etc/systemd/system-environment-generators/*</filename>
+<filename>/usr/local/lib/systemd/system-environment-generators/*</filename>
+<filename>&systemenvgeneratordir;/*</filename></literallayout>
+ </para>
+
+ <para>
+ <literallayout><filename>/run/systemd/user-environment-generators/*</filename>
+<filename>/etc/systemd/user-environment-generators/*</filename>
+<filename>/usr/local/lib/systemd/user-environment-generators/*</filename>
+<filename>&userenvgeneratordir;/*</filename></literallayout>
+ </para>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>Generators are small executables that live in
+ <filename>&systemenvgeneratordir;/</filename> and other directories listed above.
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> will
+ execute those binaries very early at the startup of each manager and at configuration
+ reload time, before running the generators described in
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ and before starting any units. Environment generators can override the environment that the
+ manager exports to services and other processes.</para>
+
+ <para>Generators are loaded from a set of paths determined during compilation, as listed
+ above. System and user environment generators are loaded from directories with names ending in
+ <filename>system-environment-generators/</filename> and
+ <filename>user-environment-generators/</filename>, respectively. Generators found in directories
+ listed earlier override the ones with the same name in directories lower in the list. A symlink
+ to <filename>/dev/null</filename> or an empty file can be used to mask a generator, thereby
+ preventing it from running. Please note that the order of the two directories with the highest
+ priority is reversed with respect to the unit load path, and generators in
+ <filename>/run</filename> overwrite those in <filename>/etc</filename>.</para>
+
+ <para>After installing new generators or updating the configuration, <command>systemctl
+ daemon-reload</command> may be executed. This will re-run all generators, updating environment
+ configuration. It will be used for any services that are started subsequently.</para>
+
+ <para>Environment file generators are executed similarly to unit file generators described
+ in
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ with the following differences:</para>
+
+ <itemizedlist>
+ <listitem>
+ <para>Generators are executed sequentially in the alphanumerical order of the final
+ component of their name. The output of each generator output is immediately parsed and used
+ to update the environment for generators that run after that. Thus, later generators can use
+ and/or modify the output of earlier generators.</para>
+ </listitem>
+
+ <listitem>
+ <para>Generators are run by every manager instance, their output can be different for each
+ user.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>It is recommended to use numerical prefixes for generator names to simplify ordering.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <example>
+ <title>A simple generator that extends an environment variable if a directory exists in the file system</title>
+
+ <programlisting># 50-xdg-data-dirs.sh
+
+<xi:include href="50-xdg-data-dirs.sh" parse="text" /></programlisting>
+ </example>
+
+ <example>
+ <title>A more complicated generator which reads existing configuration and mutates one variable</title>
+
+ <programlisting># 90-rearrange-path.py
+
+<xi:include href="90-rearrange-path.py" parse="text" /></programlisting>
+ </example>
+
+ <example>
+ <title>Debugging a generator</title>
+
+ <programlisting>SYSTEMD_LOG_LEVEL=debug VAR_A=something VAR_B="something else" \
+&systemenvgeneratordir;/path-to-generator
+</programlisting>
+ </example>
+ </refsect1>
+
+ <refsect1>
+ <title>See also</title>
+
+ <para>
+ <citerefentry><refentrytitle>systemd-environment-d-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 16f0f07db7..5d4986b6bf 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -142,7 +142,7 @@
file instead of a directory. The device node or file system image file needs to contain a file system without a
partition table, or a file system within an MBR/MS-DOS or GPT partition table with only a single
Linux-compatible partition, or a set of file systems within a GPT partition table that follows the <ulink
- url="http://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable Partitions
+ url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable Partitions
Specification</ulink>.</para></listitem>
</varlistentry>
@@ -1151,16 +1151,18 @@
<filename>/proc/sys</filename>, <filename>/sys</filename>, <filename>/proc/sysrq-trigger</filename>,
<filename>/proc/latency_stats</filename>, <filename>/proc/acpi</filename>,
<filename>/proc/timer_stats</filename>, <filename>/proc/fs</filename> and <filename>/proc/irq</filename> will
- be made read-only to all processes of the unit. Usually, tunable kernel variables should only be written at
- boot-time, with the <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- mechanism. Almost no services need to write to these at runtime; it is hence recommended to turn this on for
- most services. For this setting the same restrictions regarding mount propagation and privileges apply as for
- <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off.
- If turned on and if running in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant>
- capability (e.g. setting <varname>User=</varname>), <varname>NoNewPrivileges=yes</varname>
- is implied. Note that this option does not prevent kernel tuning through IPC interfaces
- and external programs. However <varname>InaccessiblePaths=</varname> can be used to
- make some IPC file system objects inaccessible.</para></listitem>
+ be made read-only to all processes of the unit. Usually, tunable kernel variables should be initialized only at
+ boot-time, for example with the
+ <citerefentry><refentrytitle>sysctl.d</refentrytitle><manvolnum>5</manvolnum></citerefentry> mechanism. Few
+ services need to write to these at runtime; it is hence recommended to turn this on for most services. For this
+ setting the same restrictions regarding mount propagation and privileges apply as for
+ <varname>ReadOnlyPaths=</varname> and related calls, see above. Defaults to off. If turned on and if running
+ in user mode, or in system mode, but without the <constant>CAP_SYS_ADMIN</constant> capability (e.g. services
+ for which <varname>User=</varname> is set), <varname>NoNewPrivileges=yes</varname> is implied. Note that this
+ option does not prevent indirect changes to kernel tunables effected by IPC calls to other processes. However,
+ <varname>InaccessiblePaths=</varname> may be used to make relevant IPC file system objects inaccessible. If
+ <varname>ProtectKernelTunables=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+ implied.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1196,7 +1198,8 @@
unit. Except for container managers no services should require write access to the control groups hierarchies;
it is hence recommended to turn this on for most services. For this setting the same restrictions regarding
mount propagation and privileges apply as for <varname>ReadOnlyPaths=</varname> and related calls, see
- above. Defaults to off.</para></listitem>
+ above. Defaults to off. If <varname>ProtectControlGroups=</varname> is set, <varname>MountAPIVFS=yes</varname> is
+ implied.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.generator.xml b/man/systemd.generator.xml
index b268104c9d..fb0f0c4da8 100644
--- a/man/systemd.generator.xml
+++ b/man/systemd.generator.xml
@@ -342,7 +342,8 @@ find $dir</programlisting>
<citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-sysv-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd.environment-generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index 2b0acee407..747d985aa1 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -467,9 +467,9 @@
<para>During serialization into external formats, such as the
<ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/export">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/export">Journal
Export Format</ulink> or the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/json">Journal
+ url="https://www.freedesktop.org/wiki/Software/systemd/json">Journal
JSON Format</ulink>, the addresses of journal entries are
serialized into fields prefixed with double underscores. Note that
these are not proper fields when stored in the journal but for
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index 598b5772fd..4a404fb424 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -104,7 +104,7 @@
for kernel-to-userspace and userspace-to-userspace interfaces. Some
of them may not be changed via mount units, and cannot be
disabled. For a longer discussion see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
+ url="https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems">API
File Systems</ulink>.</para>
</refsect1>
diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml
index 06690b41f4..b4dce3e92d 100644
--- a/man/systemd.offline-updates.xml
+++ b/man/systemd.offline-updates.xml
@@ -154,7 +154,7 @@
script exits uncleanly (by non-zero error code, or signal/coredump). If your script succeeds
you should trigger the reboot in your own code, for example by invoking logind's
<command>Reboot()</command> call or calling <command>systemctl reboot</command>. See
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/logind">logind dbus API</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/logind">logind dbus API</ulink>
for details.</para>
</listitem>
@@ -170,7 +170,7 @@
<title>See also</title>
<para>
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/SystemUpdates/">Implementing Offline System Updates</ulink>,
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
diff --git a/man/systemd.preset.xml b/man/systemd.preset.xml
index d09167baaf..92eb4e8280 100644
--- a/man/systemd.preset.xml
+++ b/man/systemd.preset.xml
@@ -72,7 +72,7 @@
<para>For more information on the preset logic please have a look
at the <ulink
- url="http://freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
+ url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
document.</para>
<para>It is not recommended to ship preset files within the
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
index 02878b28a0..9b1f5dbbab 100644
--- a/man/systemd.resource-control.xml
+++ b/man/systemd.resource-control.xml
@@ -87,7 +87,7 @@
Those options complement options listed here.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of resource control APIs from programs.</para>
</refsect1>
diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
index f69b2ef635..36f24d46a1 100644
--- a/man/systemd.scope.xml
+++ b/man/systemd.scope.xml
@@ -69,7 +69,7 @@
command line.</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of scope units from programs.</para>
</refsect1>
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 627176750f..52eb2bb424 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -84,7 +84,7 @@
This is useful for compatibility with SysV. Note that this
compatibility is quite comprehensive but not 100%. For details
about the incompatibilities, see the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
+ url="https://www.freedesktop.org/wiki/Software/systemd/Incompatibilities">Incompatibilities
with SysV</ulink> document.</para>
</refsect1>
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index eee98d99ee..3ff3cc5188 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -97,7 +97,7 @@
</para>
<para>See the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
+ url="https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/">New
Control Group Interfaces</ulink> for an introduction on how to make
use of slice units from programs.</para>
</refsect1>
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index a81cc3579d..fa3dc1c5d4 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -399,7 +399,7 @@
is part of the boot of most systems, while
<filename>network-online.target</filename> is not, except
when at least one unit requires it. Also see <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
+ url="https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
Services After the Network is up</ulink> for more
information.</para>
@@ -616,7 +616,7 @@
on. All userspace log messages will be made available on
this socket. For more information about syslog integration,
please consult the <ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/syslog">Syslog
+ url="https://www.freedesktop.org/wiki/Software/systemd/syslog">Syslog
Interface</ulink> document.</para>
</listitem>
</varlistentry>
@@ -785,7 +785,7 @@
is shut down. It is hence useful when writing service files
that require network access on shutdown, which should order
themselves after this target, but not pull it in. Also see
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget">Running
Services After the Network is up</ulink> for more
information. Also see
<filename>network-online.target</filename> described
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 2208b6a287..44841ac7dd 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -256,7 +256,7 @@
<para>The unit file format is covered by the
<ulink
- url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+ url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
Stability Promise</ulink>.</para>
</refsect1>
diff --git a/man/systemd.xml b/man/systemd.xml
index bc1563d5e1..4856dea824 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -453,7 +453,7 @@
<para>Note that some but not all interfaces provided
by systemd are covered by the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/InterfaceStabilityPromise">Interface
Stability Promise</ulink>.</para>
<para>Units may be generated dynamically at boot and system
@@ -463,8 +463,8 @@
<para>Systems which invoke systemd in a container or initrd
environment should implement the
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink> or
- <ulink url="http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd Interface</ulink>
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">Container Interface</ulink> or
+ <ulink url="https://www.freedesktop.org/wiki/Software/systemd/InitrdInterface">initrd Interface</ulink>
specifications, respectively.</para>
</refsect1>
@@ -1187,7 +1187,7 @@
<refsect1>
<title>See Also</title>
<para>
- The <ulink url="http://www.freedesktop.org/wiki/Software/systemd/">systemd Homepage</ulink>,
+ The <ulink url="https://www.freedesktop.org/wiki/Software/systemd/">systemd Homepage</ulink>,
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index a9402fdb28..ac0470b20d 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -1362,7 +1362,7 @@ static void help(void) {
" blame Print list of running units ordered by time to init\n"
" critical-chain Print a tree of the time critical chain of units\n"
" plot Output SVG graphic showing service initialization\n"
- " dot Output dependency graph in dot(1) format\n"
+ " dot Output dependency graph in man:dot(1) format\n"
" set-log-level LEVEL Set logging threshold for manager\n"
" set-log-target TARGET Set logging target for manager\n"
" dump Output state serialization of service manager\n"
diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c
index b5780194df..b8f0f5d03d 100644
--- a/src/basic/conf-files.c
+++ b/src/basic/conf-files.c
@@ -137,7 +137,6 @@ int conf_files_list(char ***strv, const char *suffix, const char *root, const ch
va_list ap;
assert(strv);
- assert(suffix);
va_start(ap, dir);
dirs = strv_new_ap(dir, ap);
@@ -153,7 +152,6 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, c
_cleanup_strv_free_ char **dirs = NULL;
assert(strv);
- assert(suffix);
dirs = strv_split_nulstr(d);
if (!dirs)
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 6273ac9b47..e120b9eb4e 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -558,7 +558,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, unsigned cha
} else
r = rename_noreplace(AT_FDCWD, t, AT_FDCWD, to);
if (r < 0) {
- (void) unlink_noerrno(t);
+ (void) unlink(t);
return r;
}
diff --git a/src/basic/def.h b/src/basic/def.h
index fbab066564..200ea973c1 100644
--- a/src/basic/def.h
+++ b/src/basic/def.h
@@ -75,18 +75,18 @@
#define NOTIFY_BUFFER_MAX PIPE_BUF
#ifdef HAVE_SPLIT_USR
-#define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
+# define _CONF_PATHS_SPLIT_USR(n) "/lib/" n "\0"
#else
-#define _CONF_PATHS_SPLIT_USR(n)
+# define _CONF_PATHS_SPLIT_USR(n)
#endif
/* Return a nulstr for a standard cascade of configuration paths,
* suitable to pass to conf_files_list_nulstr() or config_parse_many_nulstr()
* to implement drop-in directories for extending configuration
* files. */
-#define CONF_PATHS_NULSTR(n) \
- "/etc/" n "\0" \
- "/run/" n "\0" \
- "/usr/local/lib/" n "\0" \
- "/usr/lib/" n "\0" \
+#define CONF_PATHS_NULSTR(n) \
+ "/etc/" n "\0" \
+ "/run/" n "\0" \
+ "/usr/local/lib/" n "\0" \
+ "/usr/lib/" n "\0" \
_CONF_PATHS_SPLIT_USR(n)
diff --git a/src/basic/env-util.c b/src/basic/env-util.c
index 96da38d45e..1ec574e8a0 100644
--- a/src/basic/env-util.c
+++ b/src/basic/env-util.c
@@ -26,6 +26,7 @@
#include "alloc-util.h"
#include "env-util.h"
+#include "escape.h"
#include "extract-word.h"
#include "macro.h"
#include "parse-util.h"
@@ -247,7 +248,7 @@ fail:
return NULL;
}
-_pure_ static bool env_match(const char *t, const char *pattern) {
+static bool env_match(const char *t, const char *pattern) {
assert(t);
assert(pattern);
@@ -273,6 +274,19 @@ _pure_ static bool env_match(const char *t, const char *pattern) {
return false;
}
+static bool env_entry_has_name(const char *entry, const char *name) {
+ const char *t;
+
+ assert(entry);
+ assert(name);
+
+ t = startswith(entry, name);
+ if (!t)
+ return false;
+
+ return *t == '=';
+}
+
char **strv_env_delete(char **x, unsigned n_lists, ...) {
size_t n, i = 0;
char **k, **r;
@@ -386,18 +400,24 @@ char **strv_env_unset_many(char **l, ...) {
int strv_env_replace(char ***l, char *p) {
char **f;
+ const char *t, *name;
assert(p);
/* Replace first occurrence of the env var or add a new one in the
* string list. Drop other occurences. Edits in-place. Does not copy p.
+ * p must be a valid key=value assignment.
*/
+ t = strchr(p, '=');
+ assert(t);
+
+ name = strndupa(p, t - p);
+
for (f = *l; f && *f; f++)
- if (env_match(*f, p)) {
- free(*f);
- *f = p;
- strv_env_unset(f + 1, p);
+ if (env_entry_has_name(*f, name)) {
+ free_and_replace(*f, p);
+ strv_env_unset(f + 1, *f);
return 0;
}
@@ -434,7 +454,7 @@ fail:
return NULL;
}
-char *strv_env_get_n(char **l, const char *name, size_t k) {
+char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) {
char **i;
assert(name);
@@ -442,18 +462,25 @@ char *strv_env_get_n(char **l, const char *name, size_t k) {
if (k <= 0)
return NULL;
- STRV_FOREACH(i, l)
+ STRV_FOREACH_BACKWARDS(i, l)
if (strneq(*i, name, k) &&
(*i)[k] == '=')
return *i + k + 1;
+ if (flags & REPLACE_ENV_USE_ENVIRONMENT) {
+ const char *t;
+
+ t = strndupa(name, k);
+ return getenv(t);
+ };
+
return NULL;
}
char *strv_env_get(char **l, const char *name) {
assert(name);
- return strv_env_get_n(l, name, strlen(name));
+ return strv_env_get_n(l, name, strlen(name), 0);
}
char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) {
@@ -492,19 +519,26 @@ char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const cha
return e;
}
-char *replace_env(const char *format, char **env) {
+char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) {
enum {
WORD,
CURLY,
- VARIABLE
+ VARIABLE,
+ VARIABLE_RAW,
+ TEST,
+ DEFAULT_VALUE,
+ ALTERNATE_VALUE,
} state = WORD;
- const char *e, *word = format;
- char *r = NULL, *k;
+ const char *e, *word = format, *test_value;
+ char *k;
+ _cleanup_free_ char *r = NULL;
+ size_t i, len;
+ int nest = 0;
assert(format);
- for (e = format; *e; e ++) {
+ for (e = format, i = 0; *e && i < n; e ++, i ++) {
switch (state) {
@@ -517,24 +551,36 @@ char *replace_env(const char *format, char **env) {
if (*e == '{') {
k = strnappend(r, word, e-word-1);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
word = e-1;
state = VARIABLE;
-
+ nest++;
} else if (*e == '$') {
k = strnappend(r, word, e-word);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
word = e+1;
state = WORD;
+
+ } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
+ k = strnappend(r, word, e-word-1);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e-1;
+ state = VARIABLE_RAW;
+
} else
state = WORD;
break;
@@ -543,31 +589,109 @@ char *replace_env(const char *format, char **env) {
if (*e == '}') {
const char *t;
- t = strempty(strv_env_get_n(env, word+2, e-word-2));
+ t = strv_env_get_n(env, word+2, e-word-2, flags);
k = strappend(r, t);
if (!k)
- goto fail;
+ return NULL;
free(r);
r = k;
word = e+1;
state = WORD;
+ } else if (*e == ':') {
+ if (!(flags & REPLACE_ENV_ALLOW_EXTENDED))
+ /* Treat this as unsupported syntax, i.e. do no replacement */
+ state = WORD;
+ else {
+ len = e-word-2;
+ state = TEST;
+ }
+ }
+ break;
+
+ case TEST:
+ if (*e == '-')
+ state = DEFAULT_VALUE;
+ else if (*e == '+')
+ state = ALTERNATE_VALUE;
+ else {
+ state = WORD;
+ break;
+ }
+
+ test_value = e+1;
+ break;
+
+ case DEFAULT_VALUE: /* fall through */
+ case ALTERNATE_VALUE:
+ assert(flags & REPLACE_ENV_ALLOW_EXTENDED);
+
+ if (*e == '{') {
+ nest++;
+ break;
+ }
+
+ if (*e != '}')
+ break;
+
+ nest--;
+ if (nest == 0) {
+ const char *t;
+ _cleanup_free_ char *v = NULL;
+
+ t = strv_env_get_n(env, word+2, len, flags);
+
+ if (t && state == ALTERNATE_VALUE)
+ t = v = replace_env_n(test_value, e-test_value, env, flags);
+ else if (!t && state == DEFAULT_VALUE)
+ t = v = replace_env_n(test_value, e-test_value, env, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e+1;
+ state = WORD;
+ }
+ break;
+
+ case VARIABLE_RAW:
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
+
+ if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
+ const char *t;
+
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+
+ k = strappend(r, t);
+ if (!k)
+ return NULL;
+
+ free(r);
+ r = k;
+
+ word = e--;
+ i--;
+ state = WORD;
}
break;
}
}
- k = strnappend(r, word, e-word);
- if (!k)
- goto fail;
+ if (state == VARIABLE_RAW) {
+ const char *t;
- free(r);
- return k;
+ assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
-fail:
- return mfree(r);
+ t = strv_env_get_n(env, word+1, e-word-1, flags);
+ return strappend(r, t);
+ } else
+ return strnappend(r, word, e-word);
}
char **replace_env_argv(char **argv, char **env) {
@@ -623,7 +747,7 @@ char **replace_env_argv(char **argv, char **env) {
}
/* If ${FOO} appears as part of a word, replace it by the variable as-is */
- ret[k] = replace_env(*i, env);
+ ret[k] = replace_env(*i, env, 0);
if (!ret[k]) {
strv_free(ret);
return NULL;
@@ -644,3 +768,39 @@ int getenv_bool(const char *p) {
return parse_boolean(e);
}
+
+int serialize_environment(FILE *f, char **environment) {
+ char **e;
+
+ STRV_FOREACH(e, environment) {
+ _cleanup_free_ char *ce;
+
+ ce = cescape(*e);
+ if (!ce)
+ return -ENOMEM;
+
+ fprintf(f, "env=%s\n", *e);
+ }
+
+ /* caller should call ferror() */
+
+ return 0;
+}
+
+int deserialize_environment(char ***environment, const char *line) {
+ char *uce = NULL;
+ int r;
+
+ assert(line);
+ assert(environment);
+
+ assert(startswith(line, "env="));
+ r = cunescape(line + 4, UNESCAPE_RELAX, &uce);
+ if (r < 0)
+ return r;
+
+ if (!env_assignment_is_valid(uce))
+ return -EINVAL;
+
+ return strv_env_replace(environment, uce);
+}
diff --git a/src/basic/env-util.h b/src/basic/env-util.h
index 8cb0fc2131..e88fa6aac0 100644
--- a/src/basic/env-util.h
+++ b/src/basic/env-util.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <stddef.h>
+#include <stdio.h>
#include "macro.h"
@@ -28,9 +29,19 @@ bool env_name_is_valid(const char *e);
bool env_value_is_valid(const char *e);
bool env_assignment_is_valid(const char *e);
-char *replace_env(const char *format, char **env);
+enum {
+ REPLACE_ENV_USE_ENVIRONMENT = 1u,
+ REPLACE_ENV_ALLOW_BRACELESS = 2u,
+ REPLACE_ENV_ALLOW_EXTENDED = 4u,
+};
+
+char *replace_env_n(const char *format, size_t n, char **env, unsigned flags);
char **replace_env_argv(char **argv, char **env);
+static inline char *replace_env(const char *format, char **env, unsigned flags) {
+ return replace_env_n(format, strlen(format), env, flags);
+}
+
bool strv_env_is_valid(char **e);
#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL)
char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata);
@@ -46,7 +57,10 @@ char **strv_env_unset(char **l, const char *p); /* In place ... */
char **strv_env_unset_many(char **l, ...) _sentinel_;
int strv_env_replace(char ***l, char *p); /* In place ... */
-char *strv_env_get_n(char **l, const char *name, size_t k) _pure_;
+char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_;
char *strv_env_get(char **x, const char *n) _pure_;
int getenv_bool(const char *p);
+
+int serialize_environment(FILE *f, char **environment);
+int deserialize_environment(char ***environment, const char *line);
diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c
new file mode 100644
index 0000000000..aced9e8e3d
--- /dev/null
+++ b/src/basic/exec-util.c
@@ -0,0 +1,360 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <dirent.h>
+#include <errno.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "alloc-util.h"
+#include "conf-files.h"
+#include "env-util.h"
+#include "exec-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "hashmap.h"
+#include "macro.h"
+#include "process-util.h"
+#include "set.h"
+#include "signal-util.h"
+#include "stat-util.h"
+#include "string-util.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "util.h"
+
+/* Put this test here for a lack of better place */
+assert_cc(EAGAIN == EWOULDBLOCK);
+
+static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid) {
+
+ pid_t _pid;
+
+ if (null_or_empty_path(path)) {
+ log_debug("%s is empty (a mask).", path);
+ return 0;
+ }
+
+ _pid = fork();
+ if (_pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+ if (_pid == 0) {
+ char *_argv[2];
+
+ assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+ if (stdout_fd >= 0) {
+ /* If the fd happens to be in the right place, go along with that */
+ if (stdout_fd != STDOUT_FILENO &&
+ dup2(stdout_fd, STDOUT_FILENO) < 0)
+ return -errno;
+
+ fd_cloexec(STDOUT_FILENO, false);
+ }
+
+ if (!argv) {
+ _argv[0] = (char*) path;
+ _argv[1] = NULL;
+ argv = _argv;
+ } else
+ argv[0] = (char*) path;
+
+ execv(path, argv);
+ log_error_errno(errno, "Failed to execute %s: %m", path);
+ _exit(EXIT_FAILURE);
+ }
+
+ log_debug("Spawned %s as " PID_FMT ".", path, _pid);
+ *pid = _pid;
+ return 1;
+}
+
+static int do_execute(
+ char **directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ int output_fd,
+ char *argv[]) {
+
+ _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
+ _cleanup_strv_free_ char **paths = NULL;
+ char **path;
+ int r;
+
+ /* We fork this all off from a child process so that we can somewhat cleanly make
+ * use of SIGALRM to set a time limit.
+ *
+ * If callbacks is nonnull, execution is serial. Otherwise, we default to parallel.
+ */
+
+ (void) reset_all_signal_handlers();
+ (void) reset_signal_mask();
+
+ assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+ r = conf_files_list_strv(&paths, NULL, NULL, (const char* const*) directories);
+ if (r < 0)
+ return r;
+
+ if (!callbacks) {
+ pids = hashmap_new(NULL);
+ if (!pids)
+ return log_oom();
+ }
+
+ /* Abort execution of this process after the timout. We simply rely on SIGALRM as
+ * default action terminating the process, and turn on alarm(). */
+
+ if (timeout != USEC_INFINITY)
+ alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
+
+ STRV_FOREACH(path, paths) {
+ _cleanup_free_ char *t = NULL;
+ _cleanup_close_ int fd = -1;
+ pid_t pid;
+
+ t = strdup(*path);
+ if (!t)
+ return log_oom();
+
+ if (callbacks) {
+ fd = open_serialization_fd(basename(*path));
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open serialization file: %m");
+ }
+
+ r = do_spawn(t, argv, fd, &pid);
+ if (r <= 0)
+ continue;
+
+ if (pids) {
+ r = hashmap_put(pids, PID_TO_PTR(pid), t);
+ if (r < 0)
+ return log_oom();
+ t = NULL;
+ } else {
+ r = wait_for_terminate_and_warn(t, pid, true);
+ if (r < 0)
+ continue;
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ return log_error_errno(errno, "Failed to seek on serialization fd: %m");
+
+ r = callbacks[STDOUT_GENERATE](fd, callback_args[STDOUT_GENERATE]);
+ fd = -1;
+ if (r < 0)
+ return log_error_errno(r, "Failed to process output from %s: %m", *path);
+ }
+ }
+
+ if (callbacks) {
+ r = callbacks[STDOUT_COLLECT](output_fd, callback_args[STDOUT_COLLECT]);
+ if (r < 0)
+ return log_error_errno(r, "Callback two failed: %m");
+ }
+
+ while (!hashmap_isempty(pids)) {
+ _cleanup_free_ char *t = NULL;
+ pid_t pid;
+
+ pid = PTR_TO_PID(hashmap_first_key(pids));
+ assert(pid > 0);
+
+ t = hashmap_remove(pids, PID_TO_PTR(pid));
+ assert(t);
+
+ wait_for_terminate_and_warn(t, pid, true);
+ }
+
+ return 0;
+}
+
+int execute_directories(
+ const char* const* directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ char *argv[]) {
+
+ pid_t executor_pid;
+ char *name;
+ char **dirs = (char**) directories;
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ assert(!strv_isempty(dirs));
+
+ name = basename(dirs[0]);
+ assert(!isempty(name));
+
+ if (callbacks) {
+ assert(callback_args);
+ assert(callbacks[STDOUT_GENERATE]);
+ assert(callbacks[STDOUT_COLLECT]);
+ assert(callbacks[STDOUT_CONSUME]);
+
+ fd = open_serialization_fd(name);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open serialization file: %m");
+ }
+
+ /* Executes all binaries in the directories serially or in parallel and waits for
+ * them to finish. Optionally a timeout is applied. If a file with the same name
+ * exists in more than one directory, the earliest one wins. */
+
+ executor_pid = fork();
+ if (executor_pid < 0)
+ return log_error_errno(errno, "Failed to fork: %m");
+
+ if (executor_pid == 0) {
+ r = do_execute(dirs, timeout, callbacks, callback_args, fd, argv);
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
+
+ r = wait_for_terminate_and_warn(name, executor_pid, true);
+ if (r < 0)
+ return log_error_errno(r, "Execution failed: %m");
+ if (r > 0) {
+ /* non-zero return code from child */
+ log_error("Forker process failed.");
+ return -EREMOTEIO;
+ }
+
+ if (!callbacks)
+ return 0;
+
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ return log_error_errno(errno, "Failed to rewind serialization fd: %m");
+
+ r = callbacks[STDOUT_CONSUME](fd, callback_args[STDOUT_CONSUME]);
+ fd = -1;
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse returned data: %m");
+ return 0;
+}
+
+static int gather_environment_generate(int fd, void *arg) {
+ char ***env = arg, **x, **y;
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_strv_free_ char **new;
+ int r;
+
+ /* Read a series of VAR=value assignments from fd, use them to update the list of
+ * variables in env. Also update the exported environment.
+ *
+ * fd is always consumed, even on error.
+ */
+
+ assert(env);
+
+ f = fdopen(fd, "r");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ r = load_env_file_pairs(f, NULL, NULL, &new);
+ if (r < 0)
+ return r;
+
+ STRV_FOREACH_PAIR(x, y, new) {
+ char *p;
+
+ if (!env_name_is_valid(*x)) {
+ log_warning("Invalid variable assignment \"%s=...\", ignoring.", *x);
+ continue;
+ }
+
+ p = strjoin(*x, "=", *y);
+ if (!p)
+ return -ENOMEM;
+
+ r = strv_env_replace(env, p);
+ if (r < 0)
+ return r;
+
+ if (setenv(*x, *y, true) < 0)
+ return -errno;
+ }
+
+ return r;
+}
+
+static int gather_environment_collect(int fd, void *arg) {
+ char ***env = arg;
+ _cleanup_fclose_ FILE *f = NULL;
+ int r;
+
+ /* Write out a series of env=cescape(VAR=value) assignments to fd. */
+
+ assert(env);
+
+ f = fdopen(fd, "w");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ r = serialize_environment(f, *env);
+ if (r < 0)
+ return r;
+
+ if (ferror(f))
+ return errno > 0 ? -errno : -EIO;
+
+ return 0;
+}
+
+static int gather_environment_consume(int fd, void *arg) {
+ char ***env = arg;
+ _cleanup_fclose_ FILE *f = NULL;
+ char line[LINE_MAX];
+ int r = 0, k;
+
+ /* Read a series of env=cescape(VAR=value) assignments from fd into env. */
+
+ assert(env);
+
+ f = fdopen(fd, "r");
+ if (!f) {
+ safe_close(fd);
+ return -errno;
+ }
+
+ FOREACH_LINE(line, f, return -EIO) {
+ truncate_nl(line);
+
+ k = deserialize_environment(env, line);
+ if (k < 0)
+ log_error_errno(k, "Invalid line \"%s\": %m", line);
+ if (k < 0 && r == 0)
+ r = k;
+ }
+
+ return r;
+}
+
+const gather_stdout_callback_t gather_environment[] = {
+ gather_environment_generate,
+ gather_environment_collect,
+ gather_environment_consume,
+};
diff --git a/src/basic/exec-util.h b/src/basic/exec-util.h
new file mode 100644
index 0000000000..72009799b2
--- /dev/null
+++ b/src/basic/exec-util.h
@@ -0,0 +1,40 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+
+#include "time-util.h"
+
+typedef int (*gather_stdout_callback_t) (int fd, void *arg);
+
+enum {
+ STDOUT_GENERATE, /* from generators to helper process */
+ STDOUT_COLLECT, /* from helper process to main process */
+ STDOUT_CONSUME, /* process data in main process */
+ _STDOUT_CONSUME_MAX,
+};
+
+int execute_directories(
+ const char* const* directories,
+ usec_t timeout,
+ gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
+ void* const callback_args[_STDOUT_CONSUME_MAX],
+ char *argv[]);
+
+extern const gather_stdout_callback_t gather_environment[_STDOUT_CONSUME_MAX];
diff --git a/src/basic/fileio.c b/src/basic/fileio.c
index c43b0583a4..7c2c2b38f5 100644
--- a/src/basic/fileio.c
+++ b/src/basic/fileio.c
@@ -30,6 +30,7 @@
#include "alloc-util.h"
#include "ctype.h"
+#include "env-util.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
@@ -553,13 +554,14 @@ static int parse_env_file_internal(
}
}
- if (state == PRE_VALUE ||
- state == VALUE ||
- state == VALUE_ESCAPE ||
- state == SINGLE_QUOTE_VALUE ||
- state == SINGLE_QUOTE_VALUE_ESCAPE ||
- state == DOUBLE_QUOTE_VALUE ||
- state == DOUBLE_QUOTE_VALUE_ESCAPE) {
+ if (IN_SET(state,
+ PRE_VALUE,
+ VALUE,
+ VALUE_ESCAPE,
+ SINGLE_QUOTE_VALUE,
+ SINGLE_QUOTE_VALUE_ESCAPE,
+ DOUBLE_QUOTE_VALUE,
+ DOUBLE_QUOTE_VALUE_ESCAPE)) {
key[n_key] = 0;
@@ -586,14 +588,9 @@ fail:
return r;
}
-static int parse_env_file_push(
+static int check_utf8ness_and_warn(
const char *filename, unsigned line,
- const char *key, char *value,
- void *userdata,
- int *n_pushed) {
-
- const char *k;
- va_list aq, *ap = userdata;
+ const char *key, char *value) {
if (!utf8_is_valid(key)) {
_cleanup_free_ char *p = NULL;
@@ -611,6 +608,23 @@ static int parse_env_file_push(
return -EINVAL;
}
+ return 0;
+}
+
+static int parse_env_file_push(
+ const char *filename, unsigned line,
+ const char *key, char *value,
+ void *userdata,
+ int *n_pushed) {
+
+ const char *k;
+ va_list aq, *ap = userdata;
+ int r;
+
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
+
va_copy(aq, *ap);
while ((k = va_arg(aq, const char *))) {
@@ -662,27 +676,19 @@ static int load_env_file_push(
char *p;
int r;
- if (!utf8_is_valid(key)) {
- _cleanup_free_ char *t = utf8_escape_invalid(key);
-
- log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
- return -EINVAL;
- }
-
- if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *t = utf8_escape_invalid(value);
-
- log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
- return -EINVAL;
- }
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
- p = strjoin(key, "=", strempty(value));
+ p = strjoin(key, "=", value);
if (!p)
return -ENOMEM;
- r = strv_consume(m, p);
- if (r < 0)
+ r = strv_env_replace(m, p);
+ if (r < 0) {
+ free(p);
return r;
+ }
if (n_pushed)
(*n_pushed)++;
@@ -716,19 +722,9 @@ static int load_env_file_push_pairs(
char ***m = userdata;
int r;
- if (!utf8_is_valid(key)) {
- _cleanup_free_ char *t = utf8_escape_invalid(key);
-
- log_error("%s:%u: invalid UTF-8 for key '%s', ignoring.", strna(filename), line, t);
- return -EINVAL;
- }
-
- if (value && !utf8_is_valid(value)) {
- _cleanup_free_ char *t = utf8_escape_invalid(value);
-
- log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, t);
- return -EINVAL;
- }
+ r = check_utf8ness_and_warn(filename, line, key, value);
+ if (r < 0)
+ return r;
r = strv_extend(m, key);
if (r < 0)
@@ -767,6 +763,52 @@ int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char **
return 0;
}
+static int merge_env_file_push(
+ const char *filename, unsigned line,
+ const char *key, char *value,
+ void *userdata,
+ int *n_pushed) {
+
+ char ***env = userdata;
+ char *expanded_value;
+
+ assert(env);
+
+ if (!value) {
+ log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
+ return 0;
+ }
+
+ if (!env_name_is_valid(key)) {
+ log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
+ free(value);
+ return 0;
+ }
+
+ expanded_value = replace_env(value, *env,
+ REPLACE_ENV_USE_ENVIRONMENT|
+ REPLACE_ENV_ALLOW_BRACELESS|
+ REPLACE_ENV_ALLOW_EXTENDED);
+ if (!expanded_value)
+ return -ENOMEM;
+
+ free_and_replace(value, expanded_value);
+
+ return load_env_file_push(filename, line, key, value, env, n_pushed);
+}
+
+int merge_env_file(
+ char ***env,
+ FILE *f,
+ const char *fname) {
+
+ /* NOTE: this function supports braceful and braceless variable expansions,
+ * plus "extended" substitutions, unlike other exported parsing functions.
+ */
+
+ return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
+}
+
static void write_env_var(FILE *f, const char *v) {
const char *p;
@@ -1342,6 +1384,25 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
return fd;
}
+int open_serialization_fd(const char *ident) {
+ int fd = -1;
+
+ fd = memfd_create(ident, MFD_CLOEXEC);
+ if (fd < 0) {
+ const char *path;
+
+ path = getpid() == 1 ? "/run/systemd" : "/tmp";
+ fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ log_debug("Serializing %s to %s.", ident, path);
+ } else
+ log_debug("Serializing %s to memfd.", ident);
+
+ return fd;
+}
+
int link_tmpfile(int fd, const char *path, const char *target) {
assert(fd >= 0);
diff --git a/src/basic/fileio.h b/src/basic/fileio.h
index 17b38a5d60..e547614cc4 100644
--- a/src/basic/fileio.h
+++ b/src/basic/fileio.h
@@ -48,6 +48,8 @@ int parse_env_file(const char *fname, const char *separator, ...) _sentinel_;
int load_env_file(FILE *f, const char *fname, const char *separator, char ***l);
int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l);
+int merge_env_file(char ***env, FILE *f, const char *fname);
+
int write_env_file(const char *fname, char **l);
int executable_is_script(const char *path, char **interpreter);
@@ -84,6 +86,7 @@ int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space)
int open_tmpfile_unlinkable(const char *directory, int flags);
int open_tmpfile_linkable(const char *target, int flags, char **ret_path);
+int open_serialization_fd(const char *ident);
int link_tmpfile(int fd, const char *path, const char *target);
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 5fe5c71ff0..094acf1799 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -91,3 +91,9 @@ static inline void rmdir_and_free(char *p) {
free(p);
}
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
+
+static inline void unlink_and_free(char *p) {
+ (void) unlink(p);
+ free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
diff --git a/src/basic/log.c b/src/basic/log.c
index e6d2d61d72..36efc9ac7d 100644
--- a/src/basic/log.c
+++ b/src/basic/log.c
@@ -72,6 +72,7 @@ static bool show_color = false;
static bool show_location = false;
static bool upgrade_syslog_to_journal = false;
+static bool always_reopen_console = false;
/* Akin to glibc's __abort_msg; which is private and we hence cannot
* use here. */
@@ -95,7 +96,7 @@ static int log_open_console(void) {
if (console_fd >= 0)
return 0;
- if (getpid() == 1) {
+ if (always_reopen_console) {
console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
if (console_fd < 0)
return console_fd;
@@ -1171,3 +1172,7 @@ int log_syntax_internal(
unit_fmt, unit,
NULL);
}
+
+void log_set_always_reopen_console(bool b) {
+ always_reopen_console = b;
+}
diff --git a/src/basic/log.h b/src/basic/log.h
index 9cacbb6b70..72714e02e5 100644
--- a/src/basic/log.h
+++ b/src/basic/log.h
@@ -220,6 +220,7 @@ LogTarget log_target_from_string(const char *s) _pure_;
void log_received_signal(int level, const struct signalfd_siginfo *si);
void log_set_upgrade_syslog_to_journal(bool b);
+void log_set_always_reopen_console(bool b);
int log_syntax_internal(
const char *unit,
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index eead8b00da..87e5586027 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -703,7 +703,7 @@ int kill_and_sigcont(pid_t pid, int sig) {
/* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
* affected by a process being suspended anyway. */
- if (r >= 0 && !IN_SET(SIGCONT, SIGKILL))
+ if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
(void) kill(pid, SIGCONT);
return r;
diff --git a/src/basic/util.c b/src/basic/util.c
index 6204906f37..3dce0ea92e 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -59,9 +59,6 @@
#include "user-util.h"
#include "util.h"
-/* Put this test here for a lack of better place */
-assert_cc(EAGAIN == EWOULDBLOCK);
-
int saved_argc = 0;
char **saved_argv = NULL;
static int saved_in_initrd = -1;
@@ -80,146 +77,6 @@ size_t page_size(void) {
return pgsz;
}
-static int do_execute(char **directories, usec_t timeout, char *argv[]) {
- _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
- _cleanup_set_free_free_ Set *seen = NULL;
- char **directory;
-
- /* We fork this all off from a child process so that we can
- * somewhat cleanly make use of SIGALRM to set a time limit */
-
- (void) reset_all_signal_handlers();
- (void) reset_signal_mask();
-
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
- pids = hashmap_new(NULL);
- if (!pids)
- return log_oom();
-
- seen = set_new(&string_hash_ops);
- if (!seen)
- return log_oom();
-
- STRV_FOREACH(directory, directories) {
- _cleanup_closedir_ DIR *d;
- struct dirent *de;
-
- d = opendir(*directory);
- if (!d) {
- if (errno == ENOENT)
- continue;
-
- return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
- }
-
- FOREACH_DIRENT(de, d, break) {
- _cleanup_free_ char *path = NULL;
- pid_t pid;
- int r;
-
- if (!dirent_is_file(de))
- continue;
-
- if (set_contains(seen, de->d_name)) {
- log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
- continue;
- }
-
- r = set_put_strdup(seen, de->d_name);
- if (r < 0)
- return log_oom();
-
- path = strjoin(*directory, "/", de->d_name);
- if (!path)
- return log_oom();
-
- if (null_or_empty_path(path)) {
- log_debug("%s is empty (a mask).", path);
- continue;
- }
-
- pid = fork();
- if (pid < 0) {
- log_error_errno(errno, "Failed to fork: %m");
- continue;
- } else if (pid == 0) {
- char *_argv[2];
-
- assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
-
- if (!argv) {
- _argv[0] = path;
- _argv[1] = NULL;
- argv = _argv;
- } else
- argv[0] = path;
-
- execv(path, argv);
- return log_error_errno(errno, "Failed to execute %s: %m", path);
- }
-
- log_debug("Spawned %s as " PID_FMT ".", path, pid);
-
- r = hashmap_put(pids, PID_TO_PTR(pid), path);
- if (r < 0)
- return log_oom();
- path = NULL;
- }
- }
-
- /* Abort execution of this process after the timout. We simply
- * rely on SIGALRM as default action terminating the process,
- * and turn on alarm(). */
-
- if (timeout != USEC_INFINITY)
- alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
-
- while (!hashmap_isempty(pids)) {
- _cleanup_free_ char *path = NULL;
- pid_t pid;
-
- pid = PTR_TO_PID(hashmap_first_key(pids));
- assert(pid > 0);
-
- path = hashmap_remove(pids, PID_TO_PTR(pid));
- assert(path);
-
- wait_for_terminate_and_warn(path, pid, true);
- }
-
- return 0;
-}
-
-void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
- pid_t executor_pid;
- int r;
- char *name;
- char **dirs = (char**) directories;
-
- assert(!strv_isempty(dirs));
-
- name = basename(dirs[0]);
- assert(!isempty(name));
-
- /* Executes all binaries in the directories in parallel and waits
- * for them to finish. Optionally a timeout is applied. If a file
- * with the same name exists in more than one directory, the
- * earliest one wins. */
-
- executor_pid = fork();
- if (executor_pid < 0) {
- log_error_errno(errno, "Failed to fork: %m");
- return;
-
- } else if (executor_pid == 0) {
- r = do_execute(dirs, timeout, argv);
- _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
- }
-
- wait_for_terminate_and_warn(name, executor_pid, true);
-}
-
bool plymouth_running(void) {
return access("/run/plymouth/pid", F_OK) >= 0;
}
diff --git a/src/basic/util.h b/src/basic/util.h
index c3802a811c..c7da6c39bf 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -65,8 +65,6 @@ static inline const char* enable_disable(bool b) {
return b ? "enable" : "disable";
}
-void execute_directories(const char* const* directories, usec_t timeout, char *argv[]);
-
bool plymouth_running(void);
bool display_is_local(const char *display) _pure_;
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index b747a95133..116608bbd3 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -38,20 +38,22 @@
#include "alloc-util.h"
#include "blkid-util.h"
+#include "copy.h"
#include "dirent-util.h"
#include "efivars.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "locale-util.h"
#include "parse-util.h"
#include "rm-rf.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
#include "umask-util.h"
#include "util.h"
#include "verbs.h"
#include "virt.h"
-#include "stat-util.h"
static char *arg_path = NULL;
static bool arg_touch_variables = true;
@@ -476,16 +478,16 @@ static int compare_version(const char *a, const char *b) {
return strverscmp(a, b);
}
-static int version_check(int fd, const char *from, const char *to) {
+static int version_check(int fd_from, const char *from, int fd_to, const char *to) {
_cleanup_free_ char *a = NULL, *b = NULL;
- _cleanup_close_ int fd2 = -1;
int r;
- assert(fd >= 0);
+ assert(fd_from >= 0);
assert(from);
+ assert(fd_to >= 0);
assert(to);
- r = get_file_version(fd, &a);
+ r = get_file_version(fd_from, &a);
if (r < 0)
return r;
if (r == 0) {
@@ -493,15 +495,7 @@ static int version_check(int fd, const char *from, const char *to) {
return -EINVAL;
}
- fd2 = open(to, O_RDONLY|O_CLOEXEC);
- if (fd2 < 0) {
- if (errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
- }
-
- r = get_file_version(fd2, &b);
+ r = get_file_version(fd_to, &b);
if (r < 0)
return r;
if (r == 0 || compare_product(a, b) != 0) {
@@ -517,90 +511,59 @@ static int version_check(int fd, const char *from, const char *to) {
return 0;
}
-static int copy_file(const char *from, const char *to, bool force) {
- _cleanup_fclose_ FILE *f = NULL, *g = NULL;
- char *p;
+static int copy_file_with_version_check(const char *from, const char *to, bool force) {
+ _cleanup_close_ int fd_from = -1, fd_to = -1;
+ _cleanup_free_ char *t = NULL;
int r;
- struct timespec t[2];
- struct stat st;
- assert(from);
- assert(to);
-
- f = fopen(from, "re");
- if (!f)
+ fd_from = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd_from < 0)
return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", from);
if (!force) {
- /* If this is an update, then let's compare versions first */
- r = version_check(fileno(f), from, to);
- if (r < 0)
- return r;
- }
-
- p = strjoina(to, "~");
- g = fopen(p, "wxe");
- if (!g) {
- /* Directory doesn't exist yet? Then let's skip this... */
- if (!force && errno == ENOENT)
- return 0;
-
- return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", to);
- }
+ fd_to = open(to, O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd_to < 0) {
+ if (errno != -ENOENT)
+ return log_error_errno(errno, "Failed to open \"%s\" for reading: %m", to);
+ } else {
+ r = version_check(fd_from, from, fd_to, to);
+ if (r < 0)
+ return r;
- rewind(f);
- do {
- size_t k;
- uint8_t buf[32*1024];
+ if (lseek(fd_from, 0, SEEK_SET) == (off_t) -1)
+ return log_error_errno(errno, "Failed to seek in \%s\": %m", from);
- k = fread(buf, 1, sizeof(buf), f);
- if (ferror(f)) {
- r = log_error_errno(EIO, "Failed to read \"%s\": %m", from);
- goto error;
+ fd_to = safe_close(fd_to);
}
+ }
- if (k == 0)
- break;
-
- fwrite(buf, 1, k, g);
- if (ferror(g)) {
- r = log_error_errno(EIO, "Failed to write \"%s\": %m", to);
- goto error;
- }
- } while (!feof(f));
+ r = tempfn_random(to, NULL, &t);
+ if (r < 0)
+ return log_oom();
- r = fflush_and_check(g);
- if (r < 0) {
- log_error_errno(r, "Failed to write \"%s\": %m", to);
- goto error;
+ RUN_WITH_UMASK(0000) {
+ fd_to = open(t, O_WRONLY|O_CREAT|O_CLOEXEC|O_EXCL|O_NOFOLLOW, 0644);
+ if (fd_to < 0)
+ return log_error_errno(errno, "Failed to open \"%s\" for writing: %m", t);
}
- r = fstat(fileno(f), &st);
+ r = copy_bytes(fd_from, fd_to, (uint64_t) -1, COPY_REFLINK);
if (r < 0) {
- r = log_error_errno(errno, "Failed to get file timestamps of \"%s\": %m", from);
- goto error;
+ unlink(t);
+ return log_error_errno(errno, "Failed to copy data from \"%s\" to \"%s\": %m", from, t);
}
- t[0] = st.st_atim;
- t[1] = st.st_mtim;
+ (void) copy_times(fd_from, fd_to);
- r = futimens(fileno(g), t);
+ r = renameat(AT_FDCWD, t, AT_FDCWD, to);
if (r < 0) {
- r = log_error_errno(errno, "Failed to set file timestamps on \"%s\": %m", p);
- goto error;
- }
-
- if (rename(p, to) < 0) {
- r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", p, to);
- goto error;
+ (void) unlink_noerrno(t);
+ return log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", t, to);
}
log_info("Copied \"%s\" to \"%s\".", from, to);
- return 0;
-error:
- (void) unlink(p);
- return r;
+ return 0;
}
static int mkdir_one(const char *prefix, const char *suffix) {
@@ -644,7 +607,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
p = strjoina(BOOTLIBDIR "/", name);
q = strjoina(esp_path, "/EFI/systemd/", name);
- r = copy_file(p, q, force);
+ r = copy_file_with_version_check(p, q, force);
if (startswith(name, "systemd-boot")) {
int k;
@@ -654,7 +617,7 @@ static int copy_one_file(const char *esp_path, const char *name, bool force) {
v = strjoina(esp_path, "/EFI/BOOT/BOOT", name + strlen("systemd-boot"));
ascii_strupper(strrchr(v, '/') + 1);
- k = copy_file(p, v, force);
+ k = copy_file_with_version_check(p, v, force);
if (k < 0 && r == 0)
r = k;
}
@@ -950,20 +913,31 @@ static int remove_variables(sd_id128_t uuid, const char *path, bool in_order) {
static int install_loader_config(const char *esp_path) {
- _cleanup_fclose_ FILE *f = NULL;
char machine_string[SD_ID128_STRING_MAX];
+ _cleanup_(unlink_and_freep) char *t = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
sd_id128_t machine_id;
const char *p;
- int r;
+ int r, fd;
r = sd_id128_get_machine(&machine_id);
if (r < 0)
return log_error_errno(r, "Failed to get machine did: %m");
p = strjoina(esp_path, "/loader/loader.conf");
- f = fopen(p, "wxe");
- if (!f)
- return log_error_errno(errno, "Failed to open loader.conf for writing: %m");
+
+ if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
+ return 0;
+
+ fd = open_tmpfile_linkable(p, O_WRONLY|O_CLOEXEC, &t);
+ if (fd < 0)
+ return log_error_errno(fd, "Failed to open \"%s\" for writing: %m", p);
+
+ f = fdopen(fd, "we");
+ if (!f) {
+ safe_close(fd);
+ return log_oom();
+ }
fprintf(f, "#timeout 3\n");
fprintf(f, "default %s-*\n", sd_id128_to_string(machine_id, machine_string));
@@ -972,7 +946,15 @@ static int install_loader_config(const char *esp_path) {
if (r < 0)
return log_error_errno(r, "Failed to write \"%s\": %m", p);
- return 0;
+ r = link_tmpfile(fd, t, p);
+ if (r == -EEXIST)
+ return 0; /* Silently skip creation if the file exists now (recheck) */
+ if (r < 0)
+ return log_error_errno(r, "Failed to move \"%s\" into place: %m", p);
+
+ t = mfree(t);
+
+ return 1;
}
static int help(int argc, char *argv[], void *userdata) {
diff --git a/src/core/execute.c b/src/core/execute.c
index f455afa962..d7798387c5 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1144,11 +1144,13 @@ static int setup_pam(
/* Tell the parent that our setup is done. This is especially
* important regarding dropping privileges. Otherwise, unit
- * setup might race against our setresuid(2) call. */
- barrier_place(&barrier);
+ * setup might race against our setresuid(2) call.
+ *
+ * If the parent aborted, we'll detect this below, hence ignore
+ * return failure here. */
+ (void) barrier_place(&barrier);
- /* Check if our parent process might already have
- * died? */
+ /* Check if our parent process might already have died? */
if (getppid() == parent_pid) {
sigset_t ss;
diff --git a/src/core/killall.c b/src/core/killall.c
index 7a9df546ee..3fe9fa2ed0 100644
--- a/src/core/killall.c
+++ b/src/core/killall.c
@@ -213,7 +213,8 @@ static int killall(int sig, Set *pids, bool send_sighup) {
if (get_ctty_devnr(pid, NULL) >= 0)
- kill(pid, SIGHUP);
+ /* it's OK if the process is gone, just ignore the result */
+ (void) kill(pid, SIGHUP);
}
}
diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in
index 8d7ce1c238..a2a7edd1ee 100644
--- a/src/core/macros.systemd.in
+++ b/src/core/macros.systemd.in
@@ -31,6 +31,8 @@
%_binfmtdir @binfmtdir@
%_systemdgeneratordir @systemgeneratordir@
%_systemdusergeneratordir @usergeneratordir@
+%_systemd_system_env_generator_dir @systemenvgeneratordir@
+%_systemd_user_env_generator_dir @userenvgeneratordir@
%systemd_requires \
Requires(post): systemd \
diff --git a/src/core/main.c b/src/core/main.c
index ad2ce1330e..bcf9ea5f25 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1414,10 +1414,17 @@ int main(int argc, char *argv[]) {
log_set_upgrade_syslog_to_journal(true);
- /* Disable the umask logic */
- if (getpid() == 1)
+ if (getpid() == 1) {
+ /* Disable the umask logic */
umask(0);
+ /* Always reopen /dev/console when running as PID 1 or one of its pre-execve() children. This is
+ * important so that we never end up logging to any foreign stderr, for example if we have to log in a
+ * child process right before execve()'ing the actual binary, at a point in time where socket
+ * activation stderr/stdout area already set up. */
+ log_set_always_reopen_console(true);
+ }
+
if (getpid() == 1 && detect_container() <= 0) {
/* Running outside of a container as PID 1 */
@@ -1830,8 +1837,10 @@ int main(int argc, char *argv[]) {
before_startup = now(CLOCK_MONOTONIC);
r = manager_startup(m, arg_serialization, fds);
- if (r < 0)
+ if (r < 0) {
log_error_errno(r, "Failed to fully start up daemon: %m");
+ goto finish;
+ }
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
diff --git a/src/core/manager.c b/src/core/manager.c
index b2cd352a0c..ea80585329 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -52,6 +52,7 @@
#include "dirent-util.h"
#include "env-util.h"
#include "escape.h"
+#include "exec-util.h"
#include "exit-status.h"
#include "fd-util.h"
#include "fileio.h"
@@ -102,6 +103,7 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32
static int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata);
static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
+static int manager_run_environment_generators(Manager *m);
static int manager_run_generators(Manager *m);
static void manager_watch_jobs_in_progress(Manager *m) {
@@ -530,9 +532,9 @@ static int manager_default_environment(Manager *m) {
if (MANAGER_IS_SYSTEM(m)) {
/* The system manager always starts with a clean
* environment for its children. It does not import
- * the kernel or the parents exported variables.
+ * the kernel's or the parents' exported variables.
*
- * The initial passed environ is untouched to keep
+ * The initial passed environment is untouched to keep
* /proc/self/environ valid; it is used for tagging
* the init process inside containers. */
m->environment = strv_new("PATH=" DEFAULT_PATH,
@@ -540,11 +542,10 @@ static int manager_default_environment(Manager *m) {
/* Import locale variables LC_*= from configuration */
locale_setup(&m->environment);
- } else {
+ } else
/* The user manager passes its own environment
* along to its children. */
m->environment = strv_copy(environ);
- }
if (!m->environment)
return -ENOMEM;
@@ -1262,6 +1263,10 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
if (r < 0)
return r;
+ r = manager_run_environment_generators(m);
+ if (r < 0)
+ return r;
+
/* Make sure the transient directory always exists, so that it remains in the search path */
if (!m->test_run) {
r = mkdir_p_label(m->lookup_paths.transient, 0755);
@@ -2437,22 +2442,14 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
}
int manager_open_serialization(Manager *m, FILE **_f) {
- int fd = -1;
+ int fd;
FILE *f;
assert(_f);
- fd = memfd_create("systemd-serialization", MFD_CLOEXEC);
- if (fd < 0) {
- const char *path;
-
- path = MANAGER_IS_SYSTEM(m) ? "/run/systemd" : "/tmp";
- fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
- if (fd < 0)
- return -errno;
- log_debug("Serializing state to %s.", path);
- } else
- log_debug("Serializing state to memfd.");
+ fd = open_serialization_fd("systemd-state");
+ if (fd < 0)
+ return fd;
f = fdopen(fd, "w+");
if (!f) {
@@ -2461,7 +2458,6 @@ int manager_open_serialization(Manager *m, FILE **_f) {
}
*_f = f;
-
return 0;
}
@@ -2469,7 +2465,6 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
Iterator i;
Unit *u;
const char *t;
- char **e;
int r;
assert(m);
@@ -2499,17 +2494,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
}
- if (!switching_root) {
- STRV_FOREACH(e, m->environment) {
- _cleanup_free_ char *ce;
-
- ce = cescape(*e);
- if (!ce)
- return -ENOMEM;
-
- fprintf(f, "env=%s\n", *e);
- }
- }
+ if (!switching_root)
+ (void) serialize_environment(f, m->environment);
if (m->notify_fd >= 0) {
int copy;
@@ -2672,21 +2658,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
else if ((val = startswith(l, "units-load-finish-timestamp=")))
dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
else if (startswith(l, "env=")) {
- _cleanup_free_ char *uce = NULL;
- char **e;
-
- r = cunescape(l + 4, UNESCAPE_RELAX, &uce);
+ r = deserialize_environment(&m->environment, l);
if (r < 0)
- goto finish;
-
- e = strv_env_set(m->environment, uce);
- if (!e) {
- r = -ENOMEM;
- goto finish;
- }
-
- strv_free(m->environment);
- m->environment = e;
+ return r;
} else if ((val = startswith(l, "notify-fd="))) {
int fd;
@@ -2827,6 +2801,10 @@ int manager_reload(Manager *m) {
if (q < 0 && r >= 0)
r = q;
+ q = manager_run_environment_generators(m);
+ if (q < 0 && r >= 0)
+ r = q;
+
/* Find new unit paths */
q = manager_run_generators(m);
if (q < 0 && r >= 0)
@@ -3018,10 +2996,56 @@ void manager_check_finished(Manager *m) {
manager_invalidate_startup_units(m);
}
+static bool generator_path_any(const char* const* paths) {
+ char **path;
+ bool found = false;
+
+ /* Optimize by skipping the whole process by not creating output directories
+ * if no generators are found. */
+ STRV_FOREACH(path, (char**) paths)
+ if (access(*path, F_OK) == 0)
+ found = true;
+ else if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
+
+ return found;
+}
+
+static const char* system_env_generator_binary_paths[] = {
+ "/run/systemd/system-environment-generators",
+ "/etc/systemd/system-environment-generators",
+ "/usr/local/lib/systemd/system-environment-generators",
+ SYSTEM_ENV_GENERATOR_PATH,
+ NULL
+};
+
+static const char* user_env_generator_binary_paths[] = {
+ "/run/systemd/user-environment-generators",
+ "/etc/systemd/user-environment-generators",
+ "/usr/local/lib/systemd/user-environment-generators",
+ USER_ENV_GENERATOR_PATH,
+ NULL
+};
+
+static int manager_run_environment_generators(Manager *m) {
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ const char **paths;
+ void* args[] = {&tmp, &tmp, &m->environment};
+
+ if (m->test_run)
+ return 0;
+
+ paths = MANAGER_IS_SYSTEM(m) ? system_env_generator_binary_paths : user_env_generator_binary_paths;
+
+ if (!generator_path_any(paths))
+ return 0;
+
+ return execute_directories(paths, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
+}
+
static int manager_run_generators(Manager *m) {
_cleanup_strv_free_ char **paths = NULL;
const char *argv[5];
- char **path;
int r;
assert(m);
@@ -3033,18 +3057,9 @@ static int manager_run_generators(Manager *m) {
if (!paths)
return log_oom();
- /* Optimize by skipping the whole process by not creating output directories
- * if no generators are found. */
- STRV_FOREACH(path, paths) {
- if (access(*path, F_OK) >= 0)
- goto found;
- if (errno != ENOENT)
- log_warning_errno(errno, "Failed to open generator directory %s: %m", *path);
- }
-
- return 0;
+ if (!generator_path_any((const char* const*) paths))
+ return 0;
- found:
r = lookup_paths_mkdir_generator(&m->lookup_paths);
if (r < 0)
goto finish;
@@ -3056,7 +3071,8 @@ static int manager_run_generators(Manager *m) {
argv[4] = NULL;
RUN_WITH_UMASK(0022)
- execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv);
+ execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC,
+ NULL, NULL, (char**) argv);
finish:
lookup_paths_trim_generator(&m->lookup_paths);
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index a795d875bb..a2309b7726 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -32,6 +32,7 @@
#include "alloc-util.h"
#include "cgroup-util.h"
#include "def.h"
+#include "exec-util.h"
#include "fileio.h"
#include "killall.h"
#include "log.h"
@@ -321,7 +322,7 @@ int main(int argc, char *argv[]) {
arguments[0] = NULL;
arguments[1] = arg_verb;
arguments[2] = NULL;
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
if (!in_container && !in_initrd() &&
access("/run/initramfs/shutdown", X_OK) == 0) {
diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c
index 6abd99430b..43dba82c3a 100644
--- a/src/coredump/coredumpctl.c
+++ b/src/coredump/coredumpctl.c
@@ -24,10 +24,13 @@
#include <string.h>
#include <unistd.h>
+#include "sd-bus.h"
#include "sd-journal.h"
#include "sd-messages.h"
#include "alloc-util.h"
+#include "bus-error.h"
+#include "bus-util.h"
#include "compress.h"
#include "fd-util.h"
#include "fileio.h"
@@ -871,9 +874,65 @@ finish:
return r;
}
+static int check_units_active(void) {
+ _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ int c = 0, r;
+ const char *state;
+
+ r = sd_bus_default_system(&bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to acquire bus: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "ListUnitsByPatterns");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, NULL);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append_strv(m, STRV_MAKE("systemd-coredump@*.service"));
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, &reply);
+ if (r < 0)
+ return log_error_errno(r, "Failed to check if any systemd-coredump@.service units are running: %s",
+ bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_read(
+ reply, "(ssssssouso)",
+ NULL, NULL, NULL, &state, NULL,
+ NULL, NULL, NULL, NULL, NULL)) > 0)
+ if (!STR_IN_SET(state, "dead", "failed"))
+ c++;
+
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ return c;
+}
+
int main(int argc, char *argv[]) {
_cleanup_(sd_journal_closep) sd_journal*j = NULL;
- int r = 0;
+ int r = 0, units_active;
setlocale(LC_ALL, "");
log_parse_environment();
@@ -913,6 +972,8 @@ int main(int argc, char *argv[]) {
log_debug("Journal filter: %s", filter);
}
+ units_active = check_units_active(); /* error is treated the same as 0 */
+
switch(arg_action) {
case ACTION_LIST:
@@ -933,6 +994,11 @@ int main(int argc, char *argv[]) {
assert_not_reached("Shouldn't be here");
}
+ if (units_active > 0)
+ printf("%s-- Notice: %d systemd-coredump@.service %s, output may be incomplete.%s\n",
+ ansi_highlight_red(),
+ units_active, units_active == 1 ? "unit is running" : "units are running",
+ ansi_normal());
end:
pager_close();
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 59bd7d9e84..06564e94b1 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -208,6 +208,14 @@ int main(int argc, char *argv[]) {
log_error_errno(r, "No root partition for specified root hash found in %s.", arg_image);
goto finish;
}
+ if (r == -ENOTUNIQ) {
+ log_error_errno(r, "Multiple suitable root partitions found in image %s.", arg_image);
+ goto finish;
+ }
+ if (r == -ENXIO) {
+ log_error_errno(r, "No suitable root partition found in image %s.", arg_image);
+ goto finish;
+ }
if (r < 0) {
log_error_errno(r, "Failed to dissect image: %m");
goto finish;
diff --git a/src/environment-d-generator/Makefile b/src/environment-d-generator/Makefile
new file mode 120000
index 0000000000..d0b0e8e008
--- /dev/null
+++ b/src/environment-d-generator/Makefile
@@ -0,0 +1 @@
+../Makefile \ No newline at end of file
diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c
new file mode 100644
index 0000000000..2d4c4235e4
--- /dev/null
+++ b/src/environment-d-generator/environment-d-generator.c
@@ -0,0 +1,107 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-path.h"
+
+#include "conf-files.h"
+#include "def.h"
+#include "escape.h"
+#include "fileio.h"
+#include "log.h"
+#include "path-lookup.h"
+
+static int environment_dirs(char ***ret) {
+ _cleanup_strv_free_ char **dirs = NULL;
+ _cleanup_free_ char *c = NULL;
+ int r;
+
+ dirs = strv_split_nulstr(CONF_PATHS_NULSTR("environment.d"));
+ if (!dirs)
+ return -ENOMEM;
+
+ /* ~/.config/systemd/environment.d */
+ r = sd_path_home(SD_PATH_USER_CONFIGURATION, "environment.d", &c);
+ if (r < 0)
+ return r;
+
+ r = strv_extend_front(&dirs, c);
+ if (r < 0)
+ return r;
+
+ *ret = dirs;
+ dirs = NULL;
+ return 0;
+}
+
+static int load_and_print(void) {
+ _cleanup_strv_free_ char **dirs = NULL, **files = NULL, **env = NULL;
+ char **i;
+ int r;
+
+ r = environment_dirs(&dirs);
+ if (r < 0)
+ return r;
+
+ r = conf_files_list_strv(&files, ".conf", NULL, (const char **) dirs);
+ if (r < 0)
+ return r;
+
+ /* This will mutate the existing environment, based on the presumption
+ * that in case of failure, a partial update is better than none. */
+
+ STRV_FOREACH(i, files) {
+ r = merge_env_file(&env, NULL, *i);
+ if (r == -ENOMEM)
+ return r;
+ }
+
+ STRV_FOREACH(i, env) {
+ char *t;
+ _cleanup_free_ char *q = NULL;
+
+ t = strchr(*i, '=');
+ assert(t);
+
+ q = shell_maybe_quote(t + 1);
+ if (!q)
+ return log_oom();
+
+ printf("%.*s=%s\n", (int) (t - *i), *i, q);
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ if (argc > 1) {
+ log_error("This program takes no arguments.");
+ return EXIT_FAILURE;
+ }
+
+ r = load_and_print();
+ if (r < 0)
+ log_error_errno(r, "Failed to load environment.d: %m");
+
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/src/import/importd.c b/src/import/importd.c
index 9d31a956a5..3d379d6de9 100644
--- a/src/import/importd.c
+++ b/src/import/importd.c
@@ -449,8 +449,11 @@ static int transfer_start(Transfer *t) {
stdio_unset_cloexec();
- setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1);
- setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1);
+ if (setenv("SYSTEMD_LOG_TARGET", "console-prefixed", 1) < 0 ||
+ setenv("NOTIFY_SOCKET", "/run/systemd/import/notify", 1) < 0) {
+ log_error_errno(errno, "setenv() failed: %m");
+ _exit(EXIT_FAILURE);
+ }
if (IN_SET(t->type, TRANSFER_IMPORT_TAR, TRANSFER_IMPORT_RAW))
cmd[k++] = SYSTEMD_IMPORT_PATH;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 22133c51eb..d785b32f1c 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -912,7 +912,7 @@ static int generate_new_id128(void) {
SD_ID128_FORMAT_STR "\n\n"
"As UUID:\n"
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
- "As sd-id128(3) macro:\n"
+ "As man:sd-id128(3) macro:\n"
"#define MESSAGE_XYZ SD_ID128_MAKE(",
SD_ID128_FORMAT_VAL(id),
SD_ID128_FORMAT_VAL(id));
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 451f16483f..6466e46ccc 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -760,7 +760,8 @@ static void dispatch_message_real(
const char *label, size_t label_len,
const char *unit_id,
int priority,
- pid_t object_pid) {
+ pid_t object_pid,
+ char *cgroup) {
char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
@@ -846,7 +847,12 @@ static void dispatch_message_real(
}
#endif
- r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+ r = 0;
+ if (cgroup)
+ c = cgroup;
+ else
+ r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
+
if (r >= 0) {
_cleanup_free_ char *raw_unit = NULL, *raw_slice = NULL;
char *session = NULL;
@@ -904,7 +910,8 @@ static void dispatch_message_real(
}
}
- free(c);
+ if (!cgroup)
+ free(c);
} else if (unit_id) {
x = strjoina("_SYSTEMD_UNIT=", unit_id);
IOVEC_SET_STRING(iovec[n++], x);
@@ -1093,7 +1100,7 @@ void server_driver_message(Server *s, const char *message_id, const char *format
ucred.gid = getgid();
if (r >= 0)
- dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
while (m < n)
free(iovec[m++].iov_base);
@@ -1107,7 +1114,7 @@ void server_driver_message(Server *s, const char *message_id, const char *format
n = 3;
IOVEC_SET_STRING(iovec[n++], "PRIORITY=4");
IOVEC_SET_STRING(iovec[n++], buf);
- dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0, NULL);
}
}
@@ -1124,7 +1131,7 @@ void server_dispatch_message(
int rl, r;
_cleanup_free_ char *path = NULL;
uint64_t available = 0;
- char *c;
+ char *c = NULL;
assert(s);
assert(iovec || n == 0);
@@ -1175,7 +1182,10 @@ void server_dispatch_message(
NULL);
finish:
- dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
+ /* restore cgroup path for logging */
+ if (c)
+ *c = '/';
+ dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid, path);
}
int server_flush_to_var(Server *s, bool require_flag_file) {
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index b4bf75a3dc..7c0317640f 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -825,6 +825,15 @@ static int client_send_request(sd_dhcp_client *client) {
return r;
}
+ if (client->vendor_class_identifier) {
+ r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+ SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER,
+ strlen(client->vendor_class_identifier),
+ client->vendor_class_identifier);
+ if (r < 0)
+ return r;
+ }
+
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index efeadf0cd4..04ead29338 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -1859,8 +1859,7 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
_cleanup_free_ char *value = NULL;
const char *syspath;
char *path;
- struct stat statbuf;
- size_t value_len = 0;
+ size_t len = 0;
ssize_t size;
int r;
@@ -1878,8 +1877,14 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
return r;
path = strjoina(syspath, "/", sysattr);
- r = lstat(path, &statbuf);
- if (r < 0) {
+
+ fd = open(path, O_WRONLY | O_CLOEXEC | O_NOFOLLOW);
+ if (fd < 0) {
+ if (errno == ELOOP)
+ return -EINVAL;
+ if (errno == EISDIR)
+ return -EISDIR;
+
value = strdup("");
if (!value)
return -ENOMEM;
@@ -1891,46 +1896,30 @@ _public_ int sd_device_set_sysattr_value(sd_device *device, const char *sysattr,
return -ENXIO;
}
- if (S_ISLNK(statbuf.st_mode))
- return -EINVAL;
-
- /* skip directories */
- if (S_ISDIR(statbuf.st_mode))
- return -EISDIR;
-
- /* skip non-readable files */
- if ((statbuf.st_mode & S_IRUSR) == 0)
- return -EACCES;
-
- value_len = strlen(_value);
+ len = strlen(_value);
/* drop trailing newlines */
- while (value_len > 0 && _value[value_len - 1] == '\n')
- _value[--value_len] = '\0';
+ while (len > 0 && _value[len - 1] == '\n')
+ len --;
/* value length is limited to 4k */
- if (value_len > 4096)
+ if (len > 4096)
return -EINVAL;
- fd = open(path, O_WRONLY | O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- value = strdup(_value);
+ value = strndup(_value, len);
if (!value)
return -ENOMEM;
- size = write(fd, value, value_len);
+ size = write(fd, value, len);
if (size < 0)
return -errno;
- if ((size_t)size != value_len)
+ if ((size_t)size != len)
return -EIO;
r = device_add_sysattr_value(device, sysattr, value);
if (r < 0)
return r;
-
value = NULL;
return 0;
diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c
index a0fd8a3ac9..129bfd2d80 100644
--- a/src/libsystemd/sd-netlink/netlink-socket.c
+++ b/src/libsystemd/sd-netlink/netlink-socket.c
@@ -281,7 +281,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
else if (errno == EAGAIN)
log_debug("rtnl: no data in socket");
- return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+ return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}
if (sender.nl.nl_pid != 0) {
@@ -292,7 +292,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool
/* drop the message */
r = recvmsg(fd, &msg, 0);
if (r < 0)
- return (errno == EAGAIN || errno == EINTR) ? 0 : -errno;
+ return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}
return 0;
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 43114eb825..68435564de 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -276,6 +276,10 @@ static int dispatch_rqueue(sd_netlink *rtnl, sd_netlink_message **message) {
if (rtnl->rqueue_size <= 0) {
/* Try to read a new message */
r = socket_read_message(rtnl);
+ if (r == -ENOBUFS) { /* FIXME: ignore buffer overruns for now */
+ log_debug_errno(r, "Got ENOBUFS from netlink socket, ignoring.");
+ return 1;
+ }
if (r <= 0)
return r;
}
diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
index e4836fcaab..30dac7997b 100644
--- a/src/login/logind-seat.c
+++ b/src/login/logind-seat.c
@@ -379,7 +379,8 @@ int seat_read_active_vt(Seat *s) {
if (!seat_has_vts(s))
return 0;
- lseek(s->manager->console_active_fd, SEEK_SET, 0);
+ if (lseek(s->manager->console_active_fd, SEEK_SET, 0) < 0)
+ return log_error_errno(errno, "lseek on console_active_fd failed: %m");
k = read(s->manager->console_active_fd, t, sizeof(t)-1);
if (k <= 0) {
@@ -396,10 +397,8 @@ int seat_read_active_vt(Seat *s) {
}
r = safe_atou(t+3, &vtnr);
- if (r < 0) {
- log_error("Failed to parse VT number %s", t+3);
- return r;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse VT number \"%s\": %m", t+3);
if (!vtnr) {
log_error("VT number invalid: %s", t+3);
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 4b3cac8a22..b709166aa9 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -1025,7 +1025,7 @@ static int list_devices(void) {
j = items + n++;
for (c = 0; c < _COLUMN_MAX; c++) {
- const char *x;
+ const char *x = NULL;
size_t k;
switch (c) {
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index 9d0311d76f..e34793e50b 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -85,7 +85,11 @@ int address_new_static(Network *network, const char *filename, unsigned section_
if (filename) {
address->section = n;
- hashmap_put(network->addresses_by_section, n, address);
+ n = NULL;
+
+ r = hashmap_put(network->addresses_by_section, address->section, address);
+ if (r < 0)
+ return r;
}
address->network = network;
@@ -94,7 +98,6 @@ int address_new_static(Network *network, const char *filename, unsigned section_
*ret = address;
address = NULL;
- n = NULL;
return 0;
}
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index a8ba293ae8..570083f180 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -113,7 +113,7 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
route->section = n;
n = NULL;
- r = hashmap_put(network->routes_by_section, n, route);
+ r = hashmap_put(network->routes_by_section, route->section, route);
if (r < 0)
return r;
}
diff --git a/src/resolve/resolved-resolv-conf.c b/src/resolve/resolved-resolv-conf.c
index 13f08f8a6c..3c62550872 100644
--- a/src/resolve/resolved-resolv-conf.c
+++ b/src/resolve/resolved-resolv-conf.c
@@ -203,13 +203,13 @@ static void write_resolv_conf_search(
static int write_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
Iterator i;
- fputs("# This file is managed by systemd-resolved(8). Do not edit.\n#\n"
+ fputs("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n"
"# This is a dynamic resolv.conf file for connecting local clients directly to\n"
"# all known DNS servers.\n#\n"
"# Third party programs must not access this file directly, but only through the\n"
- "# symlink at /etc/resolv.conf. To manage resolv.conf(5) in a different way,\n"
+ "# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
"# replace this symlink by a static file or a different symlink.\n#\n"
- "# See systemd-resolved.service(8) for details about the supported modes of\n"
+ "# See man:systemd-resolved.service(8) for details about the supported modes of\n"
"# operation for /etc/resolv.conf.\n\n", f);
if (ordered_set_isempty(dns))
diff --git a/src/shared/firewall-util.c b/src/shared/firewall-util.c
index 9c29b0afca..952fc48c45 100644
--- a/src/shared/firewall-util.c
+++ b/src/shared/firewall-util.c
@@ -76,8 +76,11 @@ static int entry_fill_basics(
}
if (out_interface) {
+ size_t l = strlen(out_interface);
+ assert(l < sizeof entry->ip.outiface && l < sizeof entry->ip.outiface_mask);
+
strcpy(entry->ip.outiface, out_interface);
- memset(entry->ip.outiface_mask, 0xFF, strlen(out_interface)+1);
+ memset(entry->ip.outiface_mask, 0xFF, l + 1);
}
if (destination) {
entry->ip.dst = destination->in;
diff --git a/src/shared/pager.c b/src/shared/pager.c
index af667a83f4..f00ba9e1e7 100644
--- a/src/shared/pager.c
+++ b/src/shared/pager.c
@@ -104,7 +104,8 @@ int pager_open(bool no_pager, bool jump_to_end) {
less_opts = "FRSXMK";
if (jump_to_end)
less_opts = strjoina(less_opts, " +G");
- setenv("LESS", less_opts, 1);
+ if (setenv("LESS", less_opts, 1) < 0)
+ _exit(EXIT_FAILURE);
/* Initialize a good charset for less. This is
* particularly important if we output UTF-8
@@ -112,8 +113,9 @@ int pager_open(bool no_pager, bool jump_to_end) {
less_charset = getenv("SYSTEMD_LESSCHARSET");
if (!less_charset && is_locale_utf8())
less_charset = "utf-8";
- if (less_charset)
- setenv("LESSCHARSET", less_charset, 1);
+ if (less_charset &&
+ setenv("LESSCHARSET", less_charset, 1) < 0)
+ _exit(EXIT_FAILURE);
/* Make sure the pager goes away when the parent dies */
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
index 09a44534e2..e2b3f8b742 100644
--- a/src/shared/path-lookup.c
+++ b/src/shared/path-lookup.c
@@ -520,8 +520,7 @@ int lookup_paths_init(
append = true;
}
- /* FIXME: empty components in other places should be
- * rejected. */
+ /* FIXME: empty components in other places should be rejected. */
r = path_split_and_make_absolute(e, &paths);
if (r < 0)
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index ea96615222..3bac78b3e4 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -25,6 +25,7 @@
#include "sd-messages.h"
#include "def.h"
+#include "exec-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "log.h"
@@ -106,7 +107,7 @@ static int execute(char **modes, char **states) {
if (r < 0)
return r;
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_SLEEP_START_STR,
@@ -125,7 +126,7 @@ static int execute(char **modes, char **states) {
NULL);
arguments[1] = (char*) "post";
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments);
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, arguments);
return r;
}
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 60f8bc3df5..157a46865f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3482,6 +3482,8 @@ static int set_exit_code(uint8_t code) {
static int start_special(int argc, char *argv[], void *userdata) {
enum action a;
int r;
+ bool termination_action; /* an action that terminates the manager,
+ * can be performed also by signal. */
assert(argv);
@@ -3521,40 +3523,43 @@ static int start_special(int argc, char *argv[], void *userdata) {
return r;
}
- if (arg_force >= 2 &&
- IN_SET(a,
- ACTION_HALT,
- ACTION_POWEROFF,
- ACTION_REBOOT))
+ termination_action = IN_SET(a,
+ ACTION_HALT,
+ ACTION_POWEROFF,
+ ACTION_REBOOT);
+ if (termination_action && arg_force >= 2)
return halt_now(a);
if (arg_force >= 1 &&
- IN_SET(a,
- ACTION_HALT,
- ACTION_POWEROFF,
- ACTION_REBOOT,
- ACTION_KEXEC,
- ACTION_EXIT))
- return trivial_method(argc, argv, userdata);
+ (termination_action || IN_SET(a, ACTION_KEXEC, ACTION_EXIT)))
+ r = trivial_method(argc, argv, userdata);
+ else {
+ /* First try logind, to allow authentication with polkit */
+ if (IN_SET(a,
+ ACTION_POWEROFF,
+ ACTION_REBOOT,
+ ACTION_SUSPEND,
+ ACTION_HIBERNATE,
+ ACTION_HYBRID_SLEEP)) {
+
+ r = logind_reboot(a);
+ if (r >= 0)
+ return r;
+ if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
+ /* requested operation is not supported or already in progress */
+ return r;
- /* First try logind, to allow authentication with polkit */
- if (IN_SET(a,
- ACTION_POWEROFF,
- ACTION_REBOOT,
- ACTION_SUSPEND,
- ACTION_HIBERNATE,
- ACTION_HYBRID_SLEEP)) {
- r = logind_reboot(a);
- if (r >= 0)
- return r;
- if (IN_SET(r, -EOPNOTSUPP, -EINPROGRESS))
- /* requested operation is not supported or already in progress */
- return r;
+ /* On all other errors, try low-level operation */
+ }
- /* On all other errors, try low-level operation */
+ r = start_unit(argc, argv, userdata);
}
- return start_unit(argc, argv, userdata);
+ if (termination_action && arg_force < 2 &&
+ IN_SET(r, -ENOENT, -ETIMEDOUT))
+ log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
+
+ return r;
}
static int start_system_special(int argc, char *argv[], void *userdata) {
@@ -6806,29 +6811,54 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
return r;
STRV_FOREACH(name, names) {
- _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL;
+ _cleanup_free_ char *path = NULL, *new_path = NULL, *tmp_path = NULL, *tmp_name = NULL;
+ const char *unit_name;
r = unit_find_paths(bus, *name, &lp, &path, NULL);
if (r < 0)
return r;
- else if (!arg_force) {
- if (r == 0) {
- log_error("Run 'systemctl edit --force %s' to create a new unit.", *name);
- return -ENOENT;
- } else if (!path) {
- // FIXME: support units with path==NULL (no FragmentPath)
- log_error("No fragment exists for %s.", *name);
+
+ if (r == 0) {
+ assert(!path);
+
+ if (!arg_force) {
+ log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
+ arg_scope == UNIT_FILE_GLOBAL ? " --global" :
+ arg_scope == UNIT_FILE_USER ? " --user" : "",
+ *name);
return -ENOENT;
}
- }
- if (path) {
+ /* Create a new unit from scratch */
+ unit_name = *name;
+ r = unit_file_create_new(&lp, unit_name,
+ arg_full ? NULL : ".d/override.conf",
+ &new_path, &tmp_path);
+ } else {
+ assert(path);
+
+ unit_name = basename(path);
+ /* We follow unit aliases, but we need to propagate the instance */
+ if (unit_name_is_valid(*name, UNIT_NAME_INSTANCE) &&
+ unit_name_is_valid(unit_name, UNIT_NAME_TEMPLATE)) {
+ _cleanup_free_ char *instance = NULL;
+
+ r = unit_name_to_instance(*name, &instance);
+ if (r < 0)
+ return r;
+
+ r = unit_name_replace_instance(unit_name, instance, &tmp_name);
+ if (r < 0)
+ return r;
+
+ unit_name = tmp_name;
+ }
+
if (arg_full)
- r = unit_file_create_copy(&lp, basename(path), path, &new_path, &tmp_path);
+ r = unit_file_create_copy(&lp, unit_name, path, &new_path, &tmp_path);
else
- r = unit_file_create_new(&lp, basename(path), ".d/override.conf", &new_path, &tmp_path);
- } else
- r = unit_file_create_new(&lp, *name, NULL, &new_path, &tmp_path);
+ r = unit_file_create_new(&lp, unit_name, ".d/override.conf", &new_path, &tmp_path);
+ }
if (r < 0)
return r;
@@ -7300,7 +7330,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case 't': {
if (isempty(optarg)) {
- log_error("--type requires arguments.");
+ log_error("--type= requires arguments.");
return -EINVAL;
}
@@ -7540,7 +7570,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case ARG_STATE: {
if (isempty(optarg)) {
- log_error("--signal requires arguments.");
+ log_error("--state= requires arguments.");
return -EINVAL;
}
@@ -7549,7 +7579,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
r = extract_first_word(&p, &s, ",", 0);
if (r < 0)
- return log_error_errno(r, "Failed to parse signal: %s", optarg);
+ return log_error_errno(r, "Failed to parse state: %s", optarg);
if (r == 0)
break;
diff --git a/src/systemd/sd-bus-vtable.h b/src/systemd/sd-bus-vtable.h
index e8f84eb545..3563a2b126 100644
--- a/src/systemd/sd-bus-vtable.h
+++ b/src/systemd/sd-bus-vtable.h
@@ -86,18 +86,26 @@ struct sd_bus_vtable {
{ \
.type = _SD_BUS_VTABLE_START, \
.flags = _flags, \
- .x.start.element_size = sizeof(sd_bus_vtable), \
+ .x = { \
+ .start = { \
+ .element_size = sizeof(sd_bus_vtable) \
+ }, \
+ }, \
}
#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_METHOD, \
.flags = _flags, \
- .x.method.member = _member, \
- .x.method.signature = _signature, \
- .x.method.result = _result, \
- .x.method.handler = _handler, \
- .x.method.offset = _offset, \
+ .x = { \
+ .method = { \
+ .member = _member, \
+ .signature = _signature, \
+ .result = _result, \
+ .handler = _handler, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \
SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, 0, _flags)
@@ -106,29 +114,41 @@ struct sd_bus_vtable {
{ \
.type = _SD_BUS_VTABLE_SIGNAL, \
.flags = _flags, \
- .x.signal.member = _member, \
- .x.signal.signature = _signature, \
+ .x = { \
+ .signal = { \
+ .member = _member, \
+ .signature = _signature, \
+ }, \
+ }, \
}
#define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_PROPERTY, \
.flags = _flags, \
- .x.property.member = _member, \
- .x.property.signature = _signature, \
- .x.property.get = _get, \
- .x.property.offset = _offset, \
+ .x = { \
+ .property = { \
+ .member = _member, \
+ .signature = _signature, \
+ .get = _get, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_WRITABLE_PROPERTY(_member, _signature, _get, _set, _offset, _flags) \
{ \
.type = _SD_BUS_VTABLE_WRITABLE_PROPERTY, \
.flags = _flags, \
- .x.property.member = _member, \
- .x.property.signature = _signature, \
- .x.property.get = _get, \
- .x.property.set = _set, \
- .x.property.offset = _offset, \
+ .x = { \
+ .property = { \
+ .member = _member, \
+ .signature = _signature, \
+ .get = _get, \
+ .set = _set, \
+ .offset = _offset, \
+ }, \
+ }, \
}
#define SD_BUS_VTABLE_END \
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
index 03b3a9fa5c..22b7c61204 100644
--- a/src/test/test-conf-files.c
+++ b/src/test/test-conf-files.c
@@ -47,13 +47,16 @@ static void setup_test_dir(char *tmp_dir, const char *files, ...) {
static void test_conf_files_list(bool use_root) {
char tmp_dir[] = "/tmp/test-conf-files-XXXXXX";
- _cleanup_strv_free_ char **found_files = NULL;
- const char *root_dir, *search_1, *search_2, *expect_a, *expect_b;
+ _cleanup_strv_free_ char **found_files = NULL, **found_files2 = NULL;
+ const char *root_dir, *search_1, *search_2, *expect_a, *expect_b, *expect_c;
+
+ log_debug("/* %s */", __func__);
setup_test_dir(tmp_dir,
"/dir1/a.conf",
"/dir2/a.conf",
"/dir2/b.conf",
+ "/dir2/c.foo",
NULL);
if (use_root) {
@@ -68,6 +71,9 @@ static void test_conf_files_list(bool use_root) {
expect_a = strjoina(tmp_dir, "/dir1/a.conf");
expect_b = strjoina(tmp_dir, "/dir2/b.conf");
+ expect_c = strjoina(tmp_dir, "/dir2/c.foo");
+
+ log_debug("/* Check when filtered by suffix */");
assert_se(conf_files_list(&found_files, ".conf", root_dir, search_1, search_2, NULL) == 0);
strv_print(found_files);
@@ -77,10 +83,24 @@ static void test_conf_files_list(bool use_root) {
assert_se(streq_ptr(found_files[1], expect_b));
assert_se(found_files[2] == NULL);
+ log_debug("/* Check when unfiltered */");
+ assert_se(conf_files_list(&found_files2, NULL, root_dir, search_1, search_2, NULL) == 0);
+ strv_print(found_files2);
+
+ assert_se(found_files2);
+ assert_se(streq_ptr(found_files2[0], expect_a));
+ assert_se(streq_ptr(found_files2[1], expect_b));
+ assert_se(streq_ptr(found_files2[2], expect_c));
+ assert_se(found_files2[3] == NULL);
+
assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
}
int main(int argc, char **argv) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
test_conf_files_list(false);
test_conf_files_list(true);
return 0;
diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c
index 35bb62906e..e5cc2a2df8 100644
--- a/src/test/test-env-util.c
+++ b/src/test/test-env-util.c
@@ -45,6 +45,16 @@ static void test_strv_env_delete(void) {
assert_se(strv_length(d) == 2);
}
+static void test_strv_env_get(void) {
+ char **l;
+
+ l = STRV_MAKE("ONE_OR_TWO=1", "THREE=3", "ONE_OR_TWO=2", "FOUR=4");
+
+ assert_se(streq(strv_env_get(l, "ONE_OR_TWO"), "2"));
+ assert_se(streq(strv_env_get(l, "THREE"), "3"));
+ assert_se(streq(strv_env_get(l, "FOUR"), "4"));
+}
+
static void test_strv_env_unset(void) {
_cleanup_strv_free_ char **l = NULL;
@@ -102,7 +112,90 @@ static void test_strv_env_merge(void) {
assert_se(strv_length(r) == 5);
}
-static void test_replace_env_arg(void) {
+static void test_env_strv_get_n(void) {
+ const char *_env[] = {
+ "FOO=NO NO NO",
+ "FOO=BAR BAR",
+ "BAR=waldo",
+ "PATH=unset",
+ NULL
+ };
+ char **env = (char**) _env;
+
+ assert_se(streq(strv_env_get_n(env, "FOO__", 3, 0), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO__", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO", 3, 0), "BAR BAR"));
+ assert_se(streq(strv_env_get_n(env, "FOO", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
+
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, 0), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, 0), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
+
+ env[3] = NULL; /* kill our $PATH */
+
+ assert_se(!strv_env_get_n(env, "PATH__", 4, 0));
+ assert_se(!strv_env_get_n(env, "PATH", 4, 0));
+ assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT),
+ getenv("PATH")));
+ assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT),
+ getenv("PATH")));
+}
+
+static void test_replace_env(bool braceless) {
+ const char *env[] = {
+ "FOO=BAR BAR",
+ "BAR=waldo",
+ NULL
+ };
+ _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL;
+ unsigned flags = REPLACE_ENV_ALLOW_BRACELESS*braceless;
+
+ t = replace_env("FOO=$FOO=${FOO}", (char**) env, flags);
+ assert_se(streq(t, braceless ? "FOO=BAR BAR=BAR BAR" : "FOO=$FOO=BAR BAR"));
+
+ s = replace_env("BAR=$BAR=${BAR}", (char**) env, flags);
+ assert_se(streq(s, braceless ? "BAR=waldo=waldo" : "BAR=$BAR=waldo"));
+
+ q = replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags);
+ assert_se(streq(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR="));
+
+ r = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
+ assert_se(streq(r, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
+
+ p = replace_env("${BAR}$BAR$BAR", (char**) env, flags);
+ assert_se(streq(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR"));
+}
+
+static void test_replace_env2(bool extended) {
+ const char *env[] = {
+ "FOO=foo",
+ "BAR=bar",
+ NULL
+ };
+ _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL;
+ unsigned flags = REPLACE_ENV_ALLOW_EXTENDED*extended;
+
+ t = replace_env("FOO=${FOO:-${BAR}}", (char**) env, flags);
+ assert_se(streq(t, extended ? "FOO=foo" : "FOO=${FOO:-bar}"));
+
+ s = replace_env("BAR=${XXX:-${BAR}}", (char**) env, flags);
+ assert_se(streq(s, extended ? "BAR=bar" : "BAR=${XXX:-bar}"));
+
+ q = replace_env("XXX=${XXX:+${BAR}}", (char**) env, flags);
+ assert_se(streq(q, extended ? "XXX=" : "XXX=${XXX:+bar}"));
+
+ r = replace_env("FOO=${FOO:+${BAR}}", (char**) env, flags);
+ assert_se(streq(r, extended ? "FOO=bar" : "FOO=${FOO:+bar}"));
+
+ p = replace_env("FOO=${FOO:-${BAR}post}", (char**) env, flags);
+ assert_se(streq(p, extended ? "FOO=foo" : "FOO=${FOO:-barpost}"));
+
+ x = replace_env("XXX=${XXX:+${BAR}post}", (char**) env, flags);
+ assert_se(streq(x, extended ? "XXX=" : "XXX=${XXX:+barpost}"));
+}
+
+static void test_replace_env_argv(void) {
const char *env[] = {
"FOO=BAR BAR",
"BAR=waldo",
@@ -120,6 +213,12 @@ static void test_replace_env_arg(void) {
"${FOO",
"FOO$$${FOO}",
"$$FOO${FOO}",
+ "${FOO:-${BAR}}",
+ "${QUUX:-${FOO}}",
+ "${FOO:+${BAR}}",
+ "${QUUX:+${BAR}}",
+ "${FOO:+|${BAR}|}}",
+ "${FOO:+|${BAR}{|}",
NULL
};
_cleanup_strv_free_ char **r = NULL;
@@ -137,7 +236,13 @@ static void test_replace_env_arg(void) {
assert_se(streq(r[8], "${FOO"));
assert_se(streq(r[9], "FOO$BAR BAR"));
assert_se(streq(r[10], "$FOOBAR BAR"));
- assert_se(strv_length(r) == 11);
+ assert_se(streq(r[11], "${FOO:-waldo}"));
+ assert_se(streq(r[12], "${QUUX:-BAR BAR}"));
+ assert_se(streq(r[13], "${FOO:+waldo}"));
+ assert_se(streq(r[14], "${QUUX:+waldo}"));
+ assert_se(streq(r[15], "${FOO:+|waldo|}}"));
+ assert_se(streq(r[16], "${FOO:+|waldo{|}"));
+ assert_se(strv_length(r) == 17);
}
static void test_env_clean(void) {
@@ -211,10 +316,16 @@ static void test_env_assignment_is_valid(void) {
int main(int argc, char *argv[]) {
test_strv_env_delete();
+ test_strv_env_get();
test_strv_env_unset();
test_strv_env_set();
test_strv_env_merge();
- test_replace_env_arg();
+ test_env_strv_get_n();
+ test_replace_env(false);
+ test_replace_env(true);
+ test_replace_env2(false);
+ test_replace_env2(true);
+ test_replace_env_argv();
test_env_clean();
test_env_name_is_valid();
test_env_value_is_valid();
diff --git a/src/test/test-exec-util.c b/src/test/test-exec-util.c
new file mode 100644
index 0000000000..482b0751b9
--- /dev/null
+++ b/src/test/test-exec-util.c
@@ -0,0 +1,348 @@
+/***
+ This file is part of systemd.
+
+ Copyright 2010 Lennart Poettering
+ Copyright 2013 Thomas H.P. Andersen
+
+ 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.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "copy.h"
+#include "def.h"
+#include "env-util.h"
+#include "exec-util.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "fs-util.h"
+#include "log.h"
+#include "macro.h"
+#include "rm-rf.h"
+#include "string-util.h"
+#include "strv.h"
+
+static int here = 0, here2 = 0, here3 = 0;
+void *ignore_stdout_args[] = {&here, &here2, &here3};
+
+/* noop handlers, just check that arguments are passed correctly */
+static int ignore_stdout_func(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here);
+ safe_close(fd);
+
+ return 0;
+}
+static int ignore_stdout_func2(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here2);
+ safe_close(fd);
+
+ return 0;
+}
+static int ignore_stdout_func3(int fd, void *arg) {
+ assert(fd >= 0);
+ assert(arg == &here3);
+ safe_close(fd);
+
+ return 0;
+}
+
+static const gather_stdout_callback_t ignore_stdout[] = {
+ ignore_stdout_func,
+ ignore_stdout_func2,
+ ignore_stdout_func3,
+};
+
+static void test_execute_directory(bool gather_stdout) {
+ char template_lo[] = "/tmp/test-exec-util.XXXXXXX";
+ char template_hi[] = "/tmp/test-exec-util.XXXXXXX";
+ const char * dirs[] = {template_hi, template_lo, NULL};
+ const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
+
+ log_info("/* %s (%s) */", __func__, gather_stdout ? "gathering stdout" : "asynchronous");
+
+ assert_se(mkdtemp(template_lo));
+ assert_se(mkdtemp(template_hi));
+
+ name = strjoina(template_lo, "/script");
+ name2 = strjoina(template_hi, "/script2");
+ name3 = strjoina(template_lo, "/useless");
+ overridden = strjoina(template_lo, "/overridden");
+ override = strjoina(template_hi, "/overridden");
+ masked = strjoina(template_lo, "/masked");
+ mask = strjoina(template_hi, "/masked");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(overridden,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(override,
+ "#!/bin/sh\necho 'Executing '$0",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(masked,
+ "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(symlink("/dev/null", mask) == 0);
+ assert_se(touch(name3) >= 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(overridden, 0755) == 0);
+ assert_se(chmod(override, 0755) == 0);
+ assert_se(chmod(masked, 0755) == 0);
+
+ if (gather_stdout)
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
+ else
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL);
+
+ assert_se(chdir(template_lo) == 0);
+ assert_se(access("it_works", F_OK) >= 0);
+ assert_se(access("failed", F_OK) < 0);
+
+ assert_se(chdir(template_hi) == 0);
+ assert_se(access("it_works2", F_OK) >= 0);
+ assert_se(access("failed", F_OK) < 0);
+
+ (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
+ (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static void test_execution_order(void) {
+ char template_lo[] = "/tmp/test-exec-util-lo.XXXXXXX";
+ char template_hi[] = "/tmp/test-exec-util-hi.XXXXXXX";
+ const char *dirs[] = {template_hi, template_lo, NULL};
+ const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
+ const char *output, *t;
+ _cleanup_free_ char *contents = NULL;
+
+ assert_se(mkdtemp(template_lo));
+ assert_se(mkdtemp(template_hi));
+
+ output = strjoina(template_hi, "/output");
+
+ log_info("/* %s >>%s */", __func__, output);
+
+ /* write files in "random" order */
+ name2 = strjoina(template_lo, "/90-bar");
+ name = strjoina(template_hi, "/80-foo");
+ name3 = strjoina(template_lo, "/last");
+ overridden = strjoina(template_lo, "/30-override");
+ override = strjoina(template_hi, "/30-override");
+ masked = strjoina(template_lo, "/10-masked");
+ mask = strjoina(template_hi, "/10-masked");
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name2, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(name3, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho OVERRIDDEN >>", output);
+ assert_se(write_string_file(overridden, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho $(basename $0) >>", output);
+ assert_se(write_string_file(override, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ t = strjoina("#!/bin/sh\necho MASKED >>", output);
+ assert_se(write_string_file(masked, t, WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(symlink("/dev/null", mask) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+ assert_se(chmod(overridden, 0755) == 0);
+ assert_se(chmod(override, 0755) == 0);
+ assert_se(chmod(masked, 0755) == 0);
+
+ execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL);
+
+ assert_se(read_full_file(output, &contents, NULL) >= 0);
+ assert_se(streq(contents, "30-override\n80-foo\n90-bar\nlast\n"));
+
+ (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
+ (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
+static int gather_stdout_one(int fd, void *arg) {
+ char ***s = arg, *t;
+ char buf[128] = {};
+
+ assert_se(s);
+ assert_se(read(fd, buf, sizeof buf) >= 0);
+ safe_close(fd);
+
+ assert_se(t = strndup(buf, sizeof buf));
+ assert_se(strv_push(s, t) >= 0);
+
+ return 0;
+}
+static int gather_stdout_two(int fd, void *arg) {
+ char ***s = arg, **t;
+
+ STRV_FOREACH(t, *s)
+ assert_se(write(fd, *t, strlen(*t)) == (ssize_t) strlen(*t));
+ safe_close(fd);
+
+ return 0;
+}
+static int gather_stdout_three(int fd, void *arg) {
+ char **s = arg;
+ char buf[128] = {};
+
+ assert_se(read(fd, buf, sizeof buf - 1) > 0);
+ safe_close(fd);
+ assert_se(*s = strndup(buf, sizeof buf));
+
+ return 0;
+}
+
+const gather_stdout_callback_t const gather_stdout[] = {
+ gather_stdout_one,
+ gather_stdout_two,
+ gather_stdout_three,
+};
+
+
+static void test_stdout_gathering(void) {
+ char template[] = "/tmp/test-exec-util.XXXXXXX";
+ const char *dirs[] = {template, NULL};
+ const char *name, *name2, *name3;
+ int r;
+
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ _cleanup_free_ char *output = NULL;
+
+ void* args[] = {&tmp, &tmp, &output};
+
+ assert_se(mkdtemp(template));
+
+ log_info("/* %s */", __func__);
+
+ /* write files */
+ name = strjoina(template, "/10-foo");
+ name2 = strjoina(template, "/20-bar");
+ name3 = strjoina(template, "/30-last");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\necho a\necho b\necho c\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\necho d\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name3,
+ "#!/bin/sh\nsleep 1",
+ WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+
+ r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL);
+ assert_se(r >= 0);
+
+ log_info("got: %s", output);
+
+ assert_se(streq(output, "a\nb\nc\nd\n"));
+}
+
+static void test_environment_gathering(void) {
+ char template[] = "/tmp/test-exec-util.XXXXXXX", **p;
+ const char *dirs[] = {template, NULL};
+ const char *name, *name2, *name3;
+ int r;
+
+ char **tmp = NULL; /* this is only used in the forked process, no cleanup here */
+ _cleanup_strv_free_ char **env = NULL;
+
+ void* const args[] = { &tmp, &tmp, &env };
+
+ assert_se(mkdtemp(template));
+
+ log_info("/* %s */", __func__);
+
+ /* write files */
+ name = strjoina(template, "/10-foo");
+ name2 = strjoina(template, "/20-bar");
+ name3 = strjoina(template, "/30-last");
+
+ assert_se(write_string_file(name,
+ "#!/bin/sh\n"
+ "echo A=23\n",
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name2,
+ "#!/bin/sh\n"
+ "echo A=22:$A\n\n\n", /* substitution from previous generator */
+ WRITE_STRING_FILE_CREATE) == 0);
+ assert_se(write_string_file(name3,
+ "#!/bin/sh\n"
+ "echo A=$A:24\n"
+ "echo B=12\n"
+ "echo C=000\n"
+ "echo C=001\n" /* variable overwriting */
+ /* various invalid entries */
+ "echo unset A\n"
+ "echo unset A=\n"
+ "echo unset A=B\n"
+ "echo unset \n"
+ "echo A B=C\n"
+ "echo A\n"
+ /* test variable assignment without newline */
+ "echo PATH=$PATH:/no/such/file", /* no newline */
+ WRITE_STRING_FILE_CREATE) == 0);
+
+ assert_se(chmod(name, 0755) == 0);
+ assert_se(chmod(name2, 0755) == 0);
+ assert_se(chmod(name3, 0755) == 0);
+
+ r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL);
+ assert_se(r >= 0);
+
+ STRV_FOREACH(p, env)
+ log_info("got env: \"%s\"", *p);
+
+ assert_se(streq(strv_env_get(env, "A"), "22:23:24"));
+ assert_se(streq(strv_env_get(env, "B"), "12"));
+ assert_se(streq(strv_env_get(env, "C"), "001"));
+ assert_se(endswith(strv_env_get(env, "PATH"), ":/no/such/file"));
+}
+
+int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_execute_directory(true);
+ test_execute_directory(false);
+ test_execution_order();
+ test_stdout_gathering();
+ test_environment_gathering();
+
+ return 0;
+}
diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c
index f555bb976c..4425b5fe5f 100644
--- a/src/test/test-fd-util.c
+++ b/src/test/test-fd-util.c
@@ -94,10 +94,20 @@ static void test_same_fd(void) {
assert_se(same_fd(b, a) == 0);
}
+static void test_open_serialization_fd(void) {
+ _cleanup_close_ int fd = -1;
+
+ fd = open_serialization_fd("test");
+ assert_se(fd >= 0);
+
+ write(fd, "test\n", 5);
+}
+
int main(int argc, char *argv[]) {
test_close_many();
test_close_nointr();
test_same_fd();
+ test_open_serialization_fd();
return 0;
}
diff --git a/src/test/test-fileio.c b/src/test/test-fileio.c
index 56316904a3..b1d688c89e 100644
--- a/src/test/test-fileio.c
+++ b/src/test/test-fileio.c
@@ -71,6 +71,8 @@ static void test_parse_env_file(void) {
"seven=\"sevenval\" #nocomment\n"
"eight=eightval #nocomment\n"
"export nine=nineval\n"
+ "ten=ignored\n"
+ "ten=ignored\n"
"ten=", f);
fflush(f);
@@ -204,6 +206,113 @@ static void test_parse_multiline_env_file(void) {
unlink(p);
}
+static void test_merge_env_file(void) {
+ char t[] = "/tmp/test-fileio-XXXXXX";
+ int fd, r;
+ FILE *f;
+ _cleanup_strv_free_ char **a = NULL;
+ char **i;
+
+ fd = mkostemp_safe(t);
+ assert_se(fd >= 0);
+
+ log_info("/* %s (%s) */", __func__, t);
+
+ f = fdopen(fd, "w");
+ assert_se(f);
+
+ r = write_string_stream(f,
+ "one=1 \n"
+ "twelve=${one}2\n"
+ "twentyone=2${one}\n"
+ "one=2\n"
+ "twentytwo=2${one}\n"
+ "xxx_minus_three=$xxx - 3\n"
+ "xxx=0x$one$one$one\n"
+ "yyy=${one:-fallback}\n"
+ "zzz=${one:+replacement}\n"
+ "zzzz=${foobar:-${nothing}}\n"
+ "zzzzz=${nothing:+${nothing}}\n"
+ , false);
+ assert(r >= 0);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+ strv_sort(a);
+
+ STRV_FOREACH(i, a)
+ log_info("Got: <%s>", *i);
+
+ assert_se(streq(a[0], "one=2"));
+ assert_se(streq(a[1], "twelve=12"));
+ assert_se(streq(a[2], "twentyone=21"));
+ assert_se(streq(a[3], "twentytwo=22"));
+ assert_se(streq(a[4], "xxx=0x222"));
+ assert_se(streq(a[5], "xxx_minus_three= - 3"));
+ assert_se(streq(a[6], "yyy=2"));
+ assert_se(streq(a[7], "zzz=replacement"));
+ assert_se(streq(a[8], "zzzz="));
+ assert_se(streq(a[9], "zzzzz="));
+ assert_se(a[10] == NULL);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+ strv_sort(a);
+
+ STRV_FOREACH(i, a)
+ log_info("Got2: <%s>", *i);
+
+ assert_se(streq(a[0], "one=2"));
+ assert_se(streq(a[1], "twelve=12"));
+ assert_se(streq(a[2], "twentyone=21"));
+ assert_se(streq(a[3], "twentytwo=22"));
+ assert_se(streq(a[4], "xxx=0x222"));
+ assert_se(streq(a[5], "xxx_minus_three=0x222 - 3"));
+ assert_se(streq(a[6], "yyy=2"));
+ assert_se(streq(a[7], "zzz=replacement"));
+ assert_se(streq(a[8], "zzzz="));
+ assert_se(streq(a[9], "zzzzz="));
+ assert_se(a[10] == NULL);
+}
+
+static void test_merge_env_file_invalid(void) {
+ char t[] = "/tmp/test-fileio-XXXXXX";
+ int fd, r;
+ FILE *f;
+ _cleanup_strv_free_ char **a = NULL;
+ char **i;
+
+ fd = mkostemp_safe(t);
+ assert_se(fd >= 0);
+
+ log_info("/* %s (%s) */", __func__, t);
+
+ f = fdopen(fd, "w");
+ assert_se(f);
+
+ r = write_string_stream(f,
+ "unset one \n"
+ "unset one= \n"
+ "unset one=1 \n"
+ "one \n"
+ "one = \n"
+ "one two =\n"
+ "\x20two=\n"
+ "#comment=comment\n"
+ ";comment2=comment2\n"
+ "#\n"
+ "\n\n" /* empty line */
+ , false);
+ assert(r >= 0);
+
+ r = merge_env_file(&a, NULL, t);
+ assert_se(r >= 0);
+
+ STRV_FOREACH(i, a)
+ log_info("Got: <%s>", *i);
+
+ assert_se(strv_isempty(a));
+}
static void test_executable_is_script(void) {
char t[] = "/tmp/test-executable-XXXXXX";
@@ -555,11 +664,14 @@ static void test_tempfn(void) {
}
int main(int argc, char *argv[]) {
+ log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
test_parse_env_file();
test_parse_multiline_env_file();
+ test_merge_env_file();
+ test_merge_env_file_invalid();
test_executable_is_script();
test_status_field();
test_capeff();
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 28ca6bc317..3ff2aadea4 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -82,7 +82,9 @@ static void test_path_check_fstype(void) {
}
static void test_path_is_temporary_fs(void) {
- assert_se(path_is_temporary_fs("/run") > 0);
+ /* run might not be a mount point in build chroots */
+ if (path_is_mount_point("/run", NULL, AT_SYMLINK_FOLLOW) > 0)
+ assert_se(path_is_temporary_fs("/run") > 0);
assert_se(path_is_temporary_fs("/proc") == 0);
assert_se(path_is_temporary_fs("/i-dont-exist") == -ENOENT);
}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 1b5cba86c1..f8bf0cb875 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -195,50 +195,6 @@ static void test_log2i(void) {
assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
}
-static void test_execute_directory(void) {
- char template_lo[] = "/tmp/test-readlink_and_make_absolute-lo.XXXXXXX";
- char template_hi[] = "/tmp/test-readlink_and_make_absolute-hi.XXXXXXX";
- const char * dirs[] = {template_hi, template_lo, NULL};
- const char *name, *name2, *name3, *overridden, *override, *masked, *mask;
-
- assert_se(mkdtemp(template_lo));
- assert_se(mkdtemp(template_hi));
-
- name = strjoina(template_lo, "/script");
- name2 = strjoina(template_hi, "/script2");
- name3 = strjoina(template_lo, "/useless");
- overridden = strjoina(template_lo, "/overridden");
- override = strjoina(template_hi, "/overridden");
- masked = strjoina(template_lo, "/masked");
- mask = strjoina(template_hi, "/masked");
-
- assert_se(write_string_file(name, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(name2, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/it_works2", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(overridden, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(override, "#!/bin/sh\necho 'Executing '$0", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(write_string_file(masked, "#!/bin/sh\necho 'Executing '$0\ntouch $(dirname $0)/failed", WRITE_STRING_FILE_CREATE) == 0);
- assert_se(symlink("/dev/null", mask) == 0);
- assert_se(chmod(name, 0755) == 0);
- assert_se(chmod(name2, 0755) == 0);
- assert_se(chmod(overridden, 0755) == 0);
- assert_se(chmod(override, 0755) == 0);
- assert_se(chmod(masked, 0755) == 0);
- assert_se(touch(name3) >= 0);
-
- execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL);
-
- assert_se(chdir(template_lo) == 0);
- assert_se(access("it_works", F_OK) >= 0);
- assert_se(access("failed", F_OK) < 0);
-
- assert_se(chdir(template_hi) == 0);
- assert_se(access("it_works2", F_OK) >= 0);
- assert_se(access("failed", F_OK) < 0);
-
- (void) rm_rf(template_lo, REMOVE_ROOT|REMOVE_PHYSICAL);
- (void) rm_rf(template_hi, REMOVE_ROOT|REMOVE_PHYSICAL);
-}
-
static void test_raw_clone(void) {
pid_t parent, pid, pid2;
@@ -359,7 +315,6 @@ int main(int argc, char *argv[]) {
test_protect_errno();
test_in_set();
test_log2i();
- test_execute_directory();
test_raw_clone();
test_physical_memory();
test_physical_memory_scale();
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index b5a88c667c..bd7b789cad 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -426,11 +426,10 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
static int names_ccw(struct udev_device *dev, struct netnames *names) {
struct udev_device *cdev;
- const char *bus_id;
+ const char *bus_id, *subsys;
size_t bus_id_len;
size_t bus_id_start;
int rc;
- char *subsys;
assert(dev);
assert(names);
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
index 48c2a3fff4..d466e1b759 100644
--- a/src/update-done/update-done.c
+++ b/src/update-done/update-done.c
@@ -26,7 +26,7 @@
#define MESSAGE \
"# This file was created by systemd-update-done. Its only \n" \
"# purpose is to hold a timestamp of the time this directory\n" \
- "# was updated. See systemd-update-done.service(8).\n"
+ "# was updated. See man:systemd-update-done.service(8).\n"
static int apply_timestamp(const char *path, struct timespec *ts) {
struct timespec twice[2] = {