; A list of (major-mode . ((var1 . value1) (var2 . value2)))
; Mode can be nil, which gives default values.
+; Note that we set a line width of 119 for .c and XML files, but for everything
+; else (such as journal catalog files, unit files, README files) we stick to a
+; more conservative 79 characters.
+
+; NOTE: If you update this file make sure to update .vimrc and .editorconfig,
+; too.
+
((nil . ((indent-tabs-mode . nil)
(tab-width . 8)
- (fill-column . 119)))
- (c-mode . ((c-basic-offset . 8)
+ (fill-column . 79)))
+ (c-mode . ((fill-column . 119)
+ (c-basic-offset . 8)
(eval . (c-set-offset 'substatement-open 0))
(eval . (c-set-offset 'statement-case-open 0))
(eval . (c-set-offset 'case-label 0))
(eval . (c-set-offset 'arglist-intro '++))
(eval . (c-set-offset 'arglist-close 0))))
- (nxml-mode . ((nxml-child-indent . 2))))
+ (nxml-mode . ((nxml-child-indent . 2)
+ (fill-column . 119))))
# EditorConfig configuration for systemd
# http://EditorConfig.org
-# top-most EditorConfig file
+# NOTE: If you update this file make sure to update .dir-locals.el and .vimrc,
+# too.
+
+# Top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file, utf-8 charset
trim_trailing_whitespace = true
charset = utf-8
-# match config files, set indent to spaces with width of eight
+# Match config files, set indent to spaces with width of eight
[*.{c,h}]
indent_style = space
indent_size = 8
" vimrc configuration file, including write operations and shell execution.
" You should consider setting 'set secure' as well, which is highly
" recommended!
+
+" Note that we set a line width of 119 for .c and XML files, but for everything
+" else (such as journal catalog files, unit files, README files) we stick to a
+" more conservative 79 characters.
+
+" NOTE: If you update this file make sure to update .dir-locals.el and
+" .editorconfig, too.
+
set tabstop=8
set shiftwidth=8
set expandtab
set makeprg=GCC_COLORS=\ make
-set tw=119
+set tw=79
+au FileType xml set tw=119
+au FileType c set tw=119
noinst_PROGRAMS =
TESTS =
endif
+if ENABLE_BASH_COMPLETION
+dist_bashcompletion_DATA = $(dist_bashcompletion_data)
+nodist_bashcompletion_DATA = $(nodist_bashcompletion_data)
+endif
+if ENABLE_ZSH_COMPLETION
+dist_zshcompletion_DATA = $(dist_zshcompletion_data)
+nodist_zshcompletion_DATA = $(nodist_zshcompletion_data)
+endif
udevlibexec_PROGRAMS =
gperf_gperf_sources =
CLEANFILES = $(BUILT_SOURCES) \
$(pkgconfigdata_DATA) \
$(pkgconfiglib_DATA) \
+ $(nodist_bashcompletion_data) \
+ $(nodist_zshcompletion_data) \
$(in_files:.in=) $(in_in_files:.in.in=) \
$(m4_files:.m4=)
systemd-system-update-generator \
systemd-debug-generator
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA = \
+dist_bashcompletion_data = \
shell-completion/bash/busctl \
shell-completion/bash/journalctl \
shell-completion/bash/systemd-analyze \
shell-completion/bash/udevadm \
shell-completion/bash/kernel-install
-nodist_bashcompletion_DATA = \
+nodist_bashcompletion_data = \
shell-completion/bash/systemctl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA = \
+dist_zshcompletion_data = \
shell-completion/zsh/_busctl \
shell-completion/zsh/_journalctl \
shell-completion/zsh/_udevadm \
shell-completion/zsh/_systemd-delta \
shell-completion/zsh/_systemd
-nodist_zshcompletion_DATA = \
+nodist_zshcompletion_data = \
shell-completion/zsh/_systemctl
-endif
EXTRA_DIST += \
shell-completion/bash/systemctl.in \
shell-completion/zsh/_systemctl.in
-CLEANFILES += \
- $(nodist_bashcompletion_DATA) \
- $(nodist_zshcompletion_DATA)
-
dist_sysctl_DATA = \
sysctl.d/50-default.conf
systemd-tmpfiles-setup-dev.service \
systemd-tmpfiles-setup.service
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_systemd-tmpfiles
-endif
TIMERS_TARGET_WANTS += \
systemd-tmpfiles-clean.timer
bin_PROGRAMS += \
bootctl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/bootctl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_bootctl
endif
-endif
# ------------------------------------------------------------------------------
if HAVE_GNUEFI
EXTRA_DIST += $(systemd_boot_sources) $(systemd_boot_headers)
-if ENABLE_EFI
-if HAVE_GNUEFI
systemd_boot_objects = $(addprefix $(top_builddir)/,$(systemd_boot_sources:.c=.o))
systemd_boot_solib = $(top_builddir)/src/boot/efi/systemd_boot.so
systemd_boot = systemd-boot$(EFI_MACHINE_TYPE_NAME).efi
+if ENABLE_EFI
+if HAVE_GNUEFI
bootlib_DATA = $(systemd_boot)
-CLEANFILES += $(systemd_boot_objects) $(systemd_boot_solib) $(systemd_boot)
$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(systemd_boot_headers))
@$(MKDIR_P) $(top_builddir)/src/boot/efi/
endif
endif
+CLEANFILES += $(systemd_boot_objects) $(systemd_boot_solib) $(systemd_boot)
+
# ------------------------------------------------------------------------------
stub_headers = \
src/boot/efi/util.h \
$(stub_headers) \
test/splash.bmp
-if ENABLE_EFI
-if HAVE_GNUEFI
stub_objects = $(addprefix $(top_builddir)/,$(stub_sources:.c=.o))
stub_solib = $(top_builddir)/src/boot/efi/stub.so
stub = linux$(EFI_MACHINE_TYPE_NAME).efi.stub
+if ENABLE_EFI
+if HAVE_GNUEFI
bootlib_DATA += $(stub)
-CLEANFILES += $(stub_objects) $(stub_solib) $(stub)
$(top_builddir)/src/boot/efi/%.o: $(top_srcdir)/src/boot/efi/%.c $(addprefix $(top_srcdir)/,$(stub_headers))
@$(MKDIR_P) $(top_builddir)/src/boot/efi/
$(stub): $(stub_solib)
$(AM_V_GEN)$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel -j .rela -j .reloc $(EFI_FORMAT) $< $@
+endif
+endif
+
+CLEANFILES += $(stub_objects) $(stub_solib) $(stub)
+
# ------------------------------------------------------------------------------
CLEANFILES += test-efi-disk.img
test-efi: test-efi-disk.img
$(QEMU) -machine accel=kvm -m 1024 -bios $(QEMU_BIOS) -snapshot test-efi-disk.img
-endif
-endif
EXTRA_DIST += test/test-efi-create-disk.sh
src/nspawn/nspawn-register.h \
src/nspawn/nspawn-setuid.c \
src/nspawn/nspawn-setuid.h \
+ src/nspawn/nspawn-stub-pid1.c \
+ src/nspawn/nspawn-stub-pid1.h \
src/core/mount-setup.c \
src/core/mount-setup.h \
src/core/loopback-setup.c \
# ------------------------------------------------------------------------------
if ENABLE_COREDUMP
systemd_coredump_SOURCES = \
- src/journal/coredump.c \
- src/journal/coredump-vacuum.c \
- src/journal/coredump-vacuum.h
+ src/coredump/coredump.c \
+ src/coredump/coredump-vacuum.c \
+ src/coredump/coredump-vacuum.h
systemd_coredump_LDADD = \
libshared.la
if HAVE_ELFUTILS
systemd_coredump_SOURCES += \
- src/journal/stacktrace.c \
- src/journal/stacktrace.h
+ src/coredump/stacktrace.c \
+ src/coredump/stacktrace.h
systemd_coredump_LDADD += \
$(ELFUTILS_LIBS)
endif
+nodist_systemunit_DATA += \
+ units/systemd-coredump@.service
+
+dist_systemunit_DATA += \
+ units/systemd-coredump.socket
+
+SOCKETS_TARGET_WANTS += \
+ systemd-coredump.socket
+
rootlibexec_PROGRAMS += \
systemd-coredump
dist_pkgsysconf_DATA += \
- src/journal/coredump.conf
+ src/coredump/coredump.conf
coredumpctl_SOURCES = \
- src/journal/coredumpctl.c
+ src/coredump/coredumpctl.c
coredumpctl_LDADD = \
libshared.la
test-coredump-vacuum
test_coredump_vacuum_SOURCES = \
- src/journal/test-coredump-vacuum.c \
- src/journal/coredump-vacuum.c \
- src/journal/coredump-vacuum.h
+ src/coredump/test-coredump-vacuum.c \
+ src/coredump/coredump-vacuum.c \
+ src/coredump/coredump-vacuum.h
test_coredump_vacuum_LDADD = \
libshared.la
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/coredumpctl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_coredumpctl
-endif
nodist_sysctl_DATA = \
sysctl.d/50-coredump.conf
endif
EXTRA_DIST += \
- sysctl.d/50-coredump.conf.in
+ sysctl.d/50-coredump.conf.in \
+ units/systemd-coredump@.service.in
# ------------------------------------------------------------------------------
if ENABLE_BINFMT
bin_PROGRAMS += \
hostnamectl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/hostnamectl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_hostnamectl
endif
-endif
polkitpolicy_in_files += \
src/hostname/org.freedesktop.hostname1.policy.in
bin_PROGRAMS += \
localectl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/localectl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_localectl
endif
-endif
.PHONY: update-kbd-model-map
bin_PROGRAMS += \
timedatectl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/timedatectl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_timedatectl
endif
-endif
polkitpolicy_in_files += \
src/timedate/org.freedesktop.timedate1.policy.in
GENERAL_ALIASES += \
$(systemunitdir)/systemd-timesyncd.service $(pkgsysconfdir)/system/sysinit.target.wants/systemd-timesyncd.service
-
nodist_pkgsysconf_DATA += \
src/timesync/timesyncd.conf
rootbin_PROGRAMS += \
machinectl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
- shell-completion/bash/machinectl
-endif
-
test_machine_tables_SOURCES = \
src/machine/test-machine-tables.c
polkitpolicy_files += \
src/machine/org.freedesktop.machine1.policy
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_bashcompletion_data += \
+ shell-completion/bash/machinectl
+
+dist_zshcompletion_data += \
shell-completion/zsh/_machinectl \
shell-completion/zsh/_sd_machines
-endif
SYSTEM_UNIT_ALIASES += \
systemd-machined.service dbus-org.freedesktop.machine1.service
libshared.la \
libsystemd-network.la
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/networkctl
-endif
test_network_SOURCES = \
src/network/test-network.c
rootbin_PROGRAMS += \
loginctl
-if ENABLE_BASH_COMPLETION
-dist_bashcompletion_DATA += \
+dist_bashcompletion_data += \
shell-completion/bash/loginctl
-endif
-if ENABLE_ZSH_COMPLETION
-dist_zshcompletion_DATA += \
+dist_zshcompletion_data += \
shell-completion/zsh/_loginctl \
shell-completion/zsh/_systemd-inhibit
-endif
systemd_inhibit_SOURCES = \
src/login/inhibit.c
doc-sync: all
rsync -rlv --delete-excluded --include="*.html" --exclude="*" --omit-dir-times man/ $(www_target)/man/
-.PHONY: gardel
-gardel:
- scp man/*.html gardel:public/systemd-man/
-
-.PHONY: lennart-fedora
-lennart-fedora:
- cp -v systemd-$(VERSION).tar.xz /home/lennart/git.fedora/systemd/
-
.PHONY: install-tree
install-tree: all
rm -rf $(abs_srcdir)/install-tree
CHANGES WITH 229:
- * Creation of the legacy /run/lock/lockdev/ directory was
- dropped from tmpfiles.d/legacy.conf. Hardly any software uses
- that any more, and better locking mechanisms like flock() have
+ * The systemd-resolved DNS resolver service has gained a substantial
+ set of new features, most prominently it may now act as a DNSSEC
+ validating stub resolver. DNSSEC mode is currently turned off by
+ default, but it is expected that this is turned on by default in one
+ of the next releases. For now, we invite everybody to test the DNSSEC
+ logic by setting DNSSEC=allow-downgrade in
+ /etc/systemd/resolved.conf. The service also gained a full set of
+ D-Bus interfaces, including calls to configure DNS and DNSSEC
+ settings per link (for consumption by external network management
+ software). systemd-resolved (and systemd-networkd along with it) now
+ know to distinguish between "search" and "routing" domains. The
+ former are used to qualify single-label names, the latter are purely
+ used for routing lookups within certain domains to specific
+ links. resolved will now also synthesize RRs for all entries from
+ /etc/hosts.
+
+ * The systemd-resolve tool (which is a client utility for
+ systemd-resolved, and previously experimental) has been improved
+ considerably and is now fully supported and documented. Hence it has
+ moved from /usr/lib/systemd to /usr/bin.
+
+ * /dev/disk/by-path/ symlink support has been (re-)added for virtio
+ devices.
+
+ * The coredump collection logic has been reworked: when a coredump is
+ collected it is now written to disk, compressed and processed
+ (including stacktrace extraction) from a new instantiated service
+ systemd-coredump@.service, instead of directly from the
+ /proc/sys/kernel/core_pattern hook we provide. This is beneficial as
+ processing large coredumps can take up a substantial amount of
+ resources and time, and this previously happened entirely outside of
+ systemd's service supervision. With the new logic the core_pattern
+ hook only does minimal metadata collection before passing off control
+ to the new instantiated service, which is configured with a time
+ limit, a nice level and other settings to minimize negative impact on
+ the rest of the system. Also note that the new logic will honour the
+ RLIMIT_CORE setting of the crashed process, which now allows users
+ and processes to turn off coredumping for their processes by setting
+ this limit.
+
+ * The RLIMIT_CORE resource limit now defaults to "unlimited" for PID 1
+ and all forked processes by default. Previously, PID 1 would leave
+ the setting at "0" for all processes, as set by the kernel. Note that
+ the resource limit traditionally has no effect on the generated
+ coredumps on the system if the /proc/sys/kernel/core_pattern hook
+ logic is used. Since the limit is now honoured (see above) its
+ default has been changed so that the coredumping logic is enabled by
+ default for all processes, while allowing specific opt-out.
+
+ * When the stacktrace is extracted from processes of system users, this
+ is now done as "systemd-coredump" user, in order to sandbox this
+ potentially security sensitive parsing operation. (Note that when
+ processing coredumps of normal users this is done under the user ID
+ of process that crashed, as before.) Packagers should take notice
+ that it is now necessary to create the "systemd-coredump" system user
+ and group at package installation time.
+
+ * The systemd-activate socket activation testing tool gained support
+ for SOCK_DGRAM and SOCK_SEQPACKET sockets using the new --datagram
+ and --seqpacket switches. It also has been extended to support both
+ new-style and inetd-style file descriptor passing. Use the new
+ --inetd switch to request inetd-style file descriptor passing.
+
+ * Most systemd tools now honor a new $SYSTEMD_COLORS environment
+ variable, which takes a boolean value. If set to false, ANSI color
+ output is disabled in the tools even when run on a terminal that
+ supports it.
+
+ * The VXLAN support in networkd now supports two new settings
+ DestinationPort= and PortRange=.
+
+ * A new systemd.machine_id= kernel command line switch has been added,
+ that may be used to set the machine ID in /etc/machine-id if it is
+ not initialized yet. This command line option has no effect if the
+ file is already initialized.
+
+ * systemd-nspawn gained a new --as-pid2 switch that invokes any
+ specified command line as PID 2 rather than PID 1 in the
+ container. In this mode PID 1 will be a minimal stub init process
+ that implements the special POSIX and Linux semantics of PID 1
+ regarding signal and child process management. Note that this stub
+ init process is implemented in nspawn itself and requires no support
+ from the container image. This new logic is useful to support running
+ arbitrary command lines in the container, as normal processes are
+ generally not prepared to run as PID 1.
+
+ * systemd-nspawn gained a new --chdir= switch for setting the current
+ working directory for the process started in the container.
+
+ * "journalctl /dev/sda" will now output all kernel log messages from
+ the specified device, in addition to all devices that are parents of
+ it. This should make log output about devices pretty useful, as long
+ as kernel drivers attach enough metadata to the log messages. (The
+ usual SATA drivers do.)
+
+ * The sd-journal API gained two new calls
+ sd_journal_has_runtime_files() and sd_journal_has_persistent_files()
+ that report whether log data from /run or /var has been found.
+
+ * journalctl gained a new switch "--fields" that prints all journal
+ record field names currently in use in the journal. This is backed
+ by two new sd-journal API calls sd_journal_enumerate_fields() and
+ sd_journal_restart_fields().
+
+ * Most configurable timeouts in systemd now expect an argument of
+ "infinity" to turn them off, instead of "0" as before. The semantics
+ from now on is that a timeout of "0" means "now", and "infinity"
+ means "never". To maintain backwards compatibility, "0" continues to
+ turn off previously existing timeout settings.
+
+ * "systemctl reload-or-try-restart" has been renamed to "systemctl
+ try-reload-or-restart" to clarify what it actually does: the "try"
+ logic applies to both reloading and restarting, not just restarting.
+ The old name continues to be accepted for compatibility.
+
+ * On boot-up, when PID 1 detects that the system clock is behind the
+ release date of the systemd version in use, the clock is now set
+ to the latter. Previously, this was already done in timesyncd, in order
+ to avoid running with clocks set to the various clock epochs such as
+ 1902, 1938 or 1970. With this change the logic is now done in PID 1
+ in addition to timesyncd during early boot-up, so that it is enforced
+ before the first process is spawned by systemd. Note that the logic
+ in timesyncd remains, as it is more comprehensive and ensures
+ montonic clocks by maintaining a persistant timestamp file in
+ /var. Since /var is generally not available in earliest boot or the
+ initrd, this part of the logic remains in timesyncd, and is not done
+ by PID 1.
+
+ * A new service setting RuntimeMaxSec= has been added that may be used
+ to specify a maximum runtime for a service. If the timeout is hit, the
+ service is terminated and put into a failure state.
+
+ * A new service setting AmbientCapabilities= has been added. It allows
+ configuration of additional Linux process capabilities that are
+ passed to the activated processes. This is only available on very
+ recent kernels.
+
+ * The process resource limit settings in service units may now be used
+ to configure hard and soft limits individually.
+
+ * The various libsystemd APIs such as sd-bus or sd-event now publicly
+ expose support for gcc's __attribute__((cleanup())) C
+ extension. Specifically, for many object destructor functions
+ alternative versions whose names are suffixed with "p" have been
+ added, which take a pointer to a pointer to the object to destroy,
+ instead of just a pointer to the object itself. This is useful because
+ these destructor functions may be used directly as parameters to the
+ cleanup construct. Internally, systemd has been a heavy user of the
+ GCC extension since a long time, and with this change similar support
+ is now available to consumers of the library outside of systemd. Note
+ that by using this extension in your sources compatibility with old
+ and strictly ANSI compatible C compilers is lost. However, any gcc or
+ LLVM version of recent years have supported this extension.
+
+ * Timer units gained support for a new setting RandomizedDelaySec= that
+ allows configuring some additional randomized delay to the configured
+ time. This is useful to spread out timer events to avoid load peaks in
+ clusters or larger setups.
+
+ * Calendar time specifications now support sub-second accuracy.
+
+ * Socket units now support listening on SCTP and UDP-lite protocol
+ sockets.
+
+ * The sd-event API now comes with a full set of man pages.
+
+ * Older versions of systemd contained experimental support for
+ compressing journal files and coredumps with the LZ4 compressor that
+ was not compatible with the lz4 binary (due to API limitations of the
+ lz4 library). This support has been removed; only support for files
+ compatible with the lz4 binary remains. This LZ4 logic is now
+ officially supported and no longer considered experimental.
+
+ * The dkr image import logic has been removed again from importd. dkr's
+ micro-services focus doesn't fit into the machine image focus of
+ importd, and quickly got out of date with the upstream dkr API.
+
+ * Creation of the /run/lock/lockdev/ directory was dropped from
+ tmpfiles.d/legacy.conf. Better locking mechanisms like flock() have
been available for many years. If you still need this, you need to
create your own tmpfiles.d config file with:
- d /run/lock/lockdev 0775 root lock -
+
+ d /run/lock/lockdev 0775 root lock -
Contributions from: ...
Similarly, the kdbus dbus1 proxy daemon requires the
"systemd-bus-proxy" system user and group to exist.
+ Similarly, the coredump support requires the
+ "systemd-coredump" system user and group to exist.
+
NSS:
systemd ships with three NSS modules:
Features:
-* rework coredump tool to move actual processing into a socket activated service
-
* cache sd_event_now() result from before the first iteration...
* remove Capabilities=, after all AmbientCapabilities= and CapabilityBoundingSet= should be enough.
* add systemctl stop --job-mode=triggering that follows TRIGGERED_BY deps and adds them to the same transaction
-* coredump logic should use prlimit() to query RLIMIT_CORE of the dumpee and honour it
-
-* Add a MaxRuntimeSec= setting for service units (or units in general) to terminate units after they ran for a certain
- amount of time
-
* Maybe add a way how users can "pin" units into memory, so that they are not subject to automatic GC?
* PID1: find a way how we can reload unit file configuration for
* coredump:
- save coredump in Windows/Mozilla minidump format
- move PID 1 segfaults to /var/lib/systemd/coredump?
- - make the handler check /proc/$PID/rlimits for RLIMIT_CORE,
- and supress coredump if turned off. Then change RLIMIT_CORE to
- infinity by default for all services. This then allows per-service
- control of coredumping.
* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)
-# -*- fill-column: 79; indent-tabs-mode: nil -*-
# This file is part of systemd.
#
# Copyright 2012 Lennart Poettering
# ------------------------------------------------------------------------------
have_bzip2=no
-AC_ARG_ENABLE(bzip2, AS_HELP_STRING([--enable-bzip2], [Disable optional BZIP2 support]))
+AC_ARG_ENABLE(bzip2, AS_HELP_STRING([--enable-bzip2], [Enable optional BZIP2 support]))
AS_IF([test "x$enable_bzip2" != "xno"], [
AC_CHECK_HEADERS(bzlib.h,
[AC_DEFINE(HAVE_BZIP2, 1, [Define if BZIP2 is available])
AC_ARG_ENABLE(coredump, AS_HELP_STRING([--disable-coredump], [disable coredump hook]))
if test "x$enable_coredump" != "xno"; then
have_coredump=yes
+ M4_DEFINES="$M4_DEFINES -DENABLE_COREDUMP"
fi
AM_CONDITIONAL(ENABLE_COREDUMP, [test "$have_coredump" = "yes"])
AC_SUBST([EFI_MACHINE_TYPE_NAME])
have_gnuefi=no
-AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [Disable optional gnuefi support]))
+AC_ARG_ENABLE(gnuefi, AS_HELP_STRING([--enable-gnuefi], [Enable optional gnuefi support]))
AS_IF([test "x$enable_gnuefi" != "xno"], [
AC_CHECK_HEADERS(efi/${EFI_ARCH}/efibind.h,
[AC_DEFINE(HAVE_GNUEFI, 1, [Define if gnuefi is available])
EVDEV_ABS_35=::10
EVDEV_ABS_36=::10
+#########################################
+# HP
+#########################################
+
+# HP Pavilion dm4
+evdev:name:SynPS/2 Synaptics TouchPad*:dmi:*svnHewlett-Packard:pnHPPaviliondm4*
+ EVDEV_ABS_00=1360:5563:47
+ EVDEV_ABS_01=1269:4618:61
+ EVDEV_ABS_35=1360:5563:47
+ EVDEV_ABS_36=1269:4618:61
+
#########################################
# Lenovo
#########################################
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeD620*:pvr*
POINTINGSTICK_CONST_ACCEL=0.5
+# Latitude E6320
+evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6320*:pvr*
+ POINTINGSTICK_CONST_ACCEL=2.0
+
# Latitude E6400
evdev:name:*DualPoint Stick:dmi:bvn*:bvr*:bd*:svnDellInc.:pnLatitudeE6400*:pvr*
POINTINGSTICK_CONST_ACCEL=1.5
AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2],
AS_TR_SH([cc_cv_$2_$3]),
[eval "AS_TR_SH([cc_save_$2])='${$2}'"
- eval "AS_TR_SH([$2])='-Werror `echo "$3" | sed 's/^-Wno-/-W/'`'"
+ eval "AS_TR_SH([$2])='${cc_save_$2} -Werror `echo "$3" | sed 's/^-Wno-/-W/'`'"
AC_LINK_IFELSE([AC_LANG_SOURCE(ifelse([$4], [],
[int main(void) { return 0; } ],
[$4]))],
for DNS domain name labels, even though this is not a strict
requirement.</para>
- <para>Depending on the operating system, other configuration files
- might be checked for configuration of the hostname as well,
- however only as fallback.</para>
-
<para>You may use
<citerefentry><refentrytitle>hostnamectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
to change the value of this file during runtime from the command
high-level "pretty" hostname which might include all kinds of
special characters (e.g. "Lennart's Laptop"), the static hostname
which is used to initialize the kernel hostname at boot (e.g.
- "lennarts-laptop"), and the transient hostname which is a default
- received from network configuration. If a static hostname is set,
- and is valid (something other than localhost), then the transient
- hostname is not used.</para>
+ "lennarts-laptop"), and the transient hostname which is a fallback
+ value received from network configuration. If a static hostname is
+ set, and is valid (something other than localhost), then the
+ transient hostname is not used.</para>
<para>Note that the pretty hostname has little restrictions on the
characters used, while the static and transient hostnames are
<refsect1>
<title>Description</title>
- <para><command>systemd-activate</command> can be used to
- launch a socket-activated daemon from the command line for
- testing purposes. It can also be used to launch single instances
- of the daemon per connection (inetd-style).
+ <para><command>systemd-activate</command> may be used to launch a socket-activated service binary from the command
+ line for testing purposes. It may also be used to launch individual instances of the service binary per connection.
</para>
<para>The daemon to launch and its options should be specified
after options intended for <command>systemd-activate</command>.
</para>
- <para>If the <option>-a</option> option is given, file descriptor
- of the connection will be used as the standard input and output of
- the launched process. Otherwise, standard input and output will be
- inherited, and sockets will be passed through file descriptors 3
- and higher. Sockets passed through <varname>$LISTEN_FDS</varname>
- to <command>systemd-activate</command> will be passed through to
- the daemon, in the original positions. Other sockets specified
- with <option>--listen</option> will use consecutive descriptors.
- By default, <command>systemd-activate</command> listens on a
- stream socket, use <option>--datagram</option> to listen on
- a datagram socket instead (see below).
+ <para>If the <option>--inetd</option> option is given, the socket file descriptor will be used as the standard
+ input and output of the launched process. Otherwise, standard input and output will be inherited, and sockets will
+ be passed through file descriptors 3 and higher. Sockets passed through <varname>$LISTEN_FDS</varname> to
+ <command>systemd-activate</command> will be passed through to the daemon, in the original positions. Other sockets
+ specified with <option>--listen=</option> will use consecutive descriptors. By default,
+ <command>systemd-activate</command> listens on a stream socket, use <option>--datagram</option> and
+ <option>--seqpacket</option> to listen on datagram or sequential packet sockets instead (see below).
</para>
</refsect1>
<term><option>-a</option></term>
<term><option>--accept</option></term>
- <listitem><para>Launch a separate instance of daemon per
- connection and pass the connection socket as standard input
- and standard output.</para></listitem>
+ <listitem><para>Launch an instance of the service binary for each connection and pass the connection
+ socket.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>-d</option></term>
<term><option>--datagram</option></term>
- <listitem><para>Listen on a datagram socket, instead of a stream socket.</para></listitem>
+ <listitem><para>Listen on a datagram socket (<constant>SOCK_DGRAM</constant>), instead of a stream socket
+ (<constant>SOCK_STREAM</constant>). May not be combined with <option>--seqpacket</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--seqpacket</option></term>
+
+ <listitem><para>Listen on a sequential packet socket (<constant>SOCK_SEQPACKET</constant>), instead of a stream
+ socket (<constant>SOCK_STREAM</constant>). May not be combined with
+ <option>--datagram</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--inetd</option></term>
+
+ <listitem><para>Use the inetd protocol for passing file descriptors, i.e. as standard input and standard
+ output, instead of the new-style protocol for passing file descriptors using <varname>$LISTEN_FDS</varname>
+ (see above).</para></listitem>
</varlistentry>
<varlistentry>
<example>
<title>Run an echo server on port 2000</title>
- <programlisting>$ /usr/lib/systemd/systemd-activate -l 2000 -a cat</programlisting>
+ <programlisting>$ /usr/lib/systemd/systemd-activate -l 2000 --inetd -a cat</programlisting>
</example>
<example>
<option>--ephemeral</option>.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--as-pid2</option></term>
+
+ <listitem><para>Invoke the shell or specified program as process ID (PID) 2 instead of PID 1 (init). By
+ default, if neither this option nor <option>--boot</option> is used, the selected binary is run as process with
+ PID 1, a mode only suitable for programs that are aware of the special semantics that the process with PID 1
+ has on UNIX. For example, it needs to reap all processes reparented to it, and should implement
+ <command>sysvinit</command> compatible signal handling (specifically: it needs to reboot on SIGINT, reexecute
+ on SIGTERM, reload configuration on SIGHUP, and so on). With <option>--as-pid2</option> a minimal stub init
+ process is run as PID 1 and the selected binary is executed as PID 2 (and hence does not need to implement any
+ special semantics). The stub init process will reap processes as necessary and react appropriately to
+ signals. It is recommended to use this mode to invoke arbitrary commands in containers, unless they have been
+ modified to run correctly as PID 1. Or in other words: this switch should be used for pretty much all commands,
+ except when the command refers to an init or shell implementation, as these are generally capable of running
+ correctly as PID 1). This option may not be combined with <option>--boot</option> or
+ <option>--share-system</option>.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>-b</option></term>
<term><option>--boot</option></term>
- <listitem><para>Automatically search for an init binary and
- invoke it instead of a shell or a user supplied program. If
- this option is used, arguments specified on the command line
- are used as arguments for the init binary. This option may not
- be combined with <option>--share-system</option>.
- </para></listitem>
+ <listitem><para>Automatically search for an init binary and invoke it as PID 1, instead of a shell or a user
+ supplied program. If this option is used, arguments specified on the command line are used as arguments for the
+ init binary. This option may not be combined with <option>--as-pid2</option> or
+ <option>--share-system</option>.</para>
+
+ <para>The following table explains the different modes of invocation and relationship to
+ <option>--as-pid2</option> (see above):</para>
+
+ <table>
+ <title>Invocation Mode</title>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
+ <colspec colname="switch" />
+ <colspec colname="explanation" />
+ <thead>
+ <row>
+ <entry>Switch</entry>
+ <entry>Explanation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Neither <option>--as-pid2</option> nor <option>--boot</option> specified</entry>
+ <entry>The passed parameters are interpreted as command line, which is executed as PID 1 in the container.</entry>
+ </row>
+
+ <row>
+ <entry><option>--as-pid2</option> specified</entry>
+ <entry>The passed parameters are interpreted as command line, which are executed as PID 2 in the container. A stub init process is run as PID 1.</entry>
+ </row>
+
+ <row>
+ <entry><option>--boot</option> specified</entry>
+ <entry>An init binary as automatically searched and run as PID 1 in the container. The passed parameters are used as invocation parameters for this process.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--chdir=</option></term>
+
+ <listitem><para>Change to the specified working directory before invoking the process in the container. Expects
+ an absolute path in the container's file system namespace.</para></listitem>
</varlistentry>
<varlistentry>
<para>Note that <filename>/run/systemd/resolve/resolv.conf</filename> should not be used directly by applications,
but only through a symlink from <filename>/etc/resolv.conf</filename>.</para>
+
+ <para>See the <ulink url="http://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>
<refsect1>
Generators are run very early at boot and cannot rely on
any external services. They may not talk to any other
process. That includes simple things such as logging to
- <citerefentry
- project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ <citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
or <command>systemd</command> itself (this means: no
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>!). They
- can however rely on the most basic kernel functionality to
- be available, including a mounted <filename>/sys</filename>,
- <filename>/proc</filename>, <filename>/dev</filename>.
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>)!.
+ Non-essential file systems like
+ <filename>/var</filename> and <filename>/home</filename>
+ are mounted after generators have run. Generators
+ can however rely on the most basic kernel functionality to be
+ available, including a mounted <filename>/sys</filename>,
+ <filename>/proc</filename>, <filename>/dev</filename>,
+ <filename>/usr</filename>.
</para>
</listitem>
<varlistentry>
<term><varname>Boot=</varname></term>
- <listitem><para>Takes a boolean argument, which defaults to off. If
- enabled, <command>systemd-nspawn</command> will automatically
- search for an <filename>init</filename> executable and invoke
- it. In this case, the specified parameters using
- <varname>Parameters=</varname> are passed as additional
- arguments to the <filename>init</filename> process. This
- setting corresponds to the <option>--boot</option> switch on
- the <command>systemd-nspawn</command> command
- line. </para></listitem>
+ <listitem><para>Takes a boolean argument, which defaults to off. If enabled, <command>systemd-nspawn</command>
+ will automatically search for an <filename>init</filename> executable and invoke it. In this case, the
+ specified parameters using <varname>Parameters=</varname> are passed as additional arguments to the
+ <filename>init</filename> process. This setting corresponds to the <option>--boot</option> switch on the
+ <command>systemd-nspawn</command> command line. This option may not be combined with
+ <varname>ProcessTwo=yes</varname>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ProcessTwo=</varname></term>
+
+ <listitem><para>Takes a boolean argument, which defaults to off. If enabled, the specified program is run as
+ PID 2. A stub init process is run as PID 1. This setting corresponds to the <option>--as-pid2</option> switch
+ on the <command>systemd-nspawn</command> command line. This option may not be combined with
+ <varname>Boot=yes</varname>.</para></listitem>
</varlistentry>
<varlistentry>
switch.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>WorkingDirectory=</varname></term>
+
+ <listitem><para>Selects the working directory for the process invoked in the container. Expects an absolute
+ path in the container's file system namespace. This corresponds to the <option>--chdir=</option> command line
+ switch.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>Capability=</varname></term>
<term><varname>DropCapability=</varname></term>
used to start long-running processes. All processes forked
off by processes invoked via <varname>ExecStartPre=</varname> will
be killed before the next service process is run.</para>
+
+ <para>Note that if any of the commands specified in <varname>ExecStartPre=</varname>,
+ <varname>ExecStart=</varname>, or <varname>ExecStartPost=</varname> fail (and are not prefixed with
+ <literal>-</literal>, see above) or time out before the service is fully up, execution continues with commands
+ specified in <varname>ExecStopPost=</varname>, the commands in <varname>ExecStop=</varname> are skipped.</para>
</listitem>
</varlistentry>
<constant>SIGKILL</constant> immediately after the command
exited, this would not result in a clean stop. The specified
command should hence be a synchronous operation, not an
- asynchronous one.</para></listitem>
+ asynchronous one.</para>
+
+ <para>Note that the commands specified in <varname>ExecStop=</varname> are only executed when the service
+ started successfuly first. They are not invoked if the service was never started at all, or in case its
+ start-up failed, for example because any of the commands specified in <varname>ExecStart=</varname>,
+ <varname>ExecStartPre=</varname> or <varname>ExecStartPost=</varname> failed (and weren't prefixed with
+ <literal>-</literal>, see above) or timed out. Use <varname>ExecStopPost=</varname> to invoke commands when a
+ service failed to start up correctly and is shut down again.</para>
+
+ <para>It is recommended to use this setting for commands that communicate with the service requesting clean
+ termination. When the commands specified with this option are executed it should be assumed that the service is
+ still fully up and is able to react correctly to all commands. For post-mortem clean-up steps use
+ <varname>ExecStopPost=</varname> instead.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ExecStopPost=</varname></term>
- <listitem><para>Additional commands that are executed after
- the service was stopped. This includes cases where the
- commands configured in <varname>ExecStop=</varname> were used,
- where the service does not have any
- <varname>ExecStop=</varname> defined, or where the service
- exited unexpectedly. This argument takes multiple command
- lines, following the same scheme as described for
- <varname>ExecStart=</varname>. Use of these settings is
- optional. Specifier and environment variable substitution is
- supported.</para></listitem>
+ <listitem><para>Additional commands that are executed after the service is stopped. This includes cases where
+ the commands configured in <varname>ExecStop=</varname> were used, where the service does not have any
+ <varname>ExecStop=</varname> defined, or where the service exited unexpectedly. This argument takes multiple
+ command lines, following the same scheme as described for <varname>ExecStart=</varname>. Use of these settings
+ is optional. Specifier and environment variable substitution is supported. Note that – unlike
+ <varname>ExecStop=</varname> – commands specified with this setting are invoked when a service failed to start
+ up correctly and is shut down again.</para>
+
+ <para>It is recommended to use this setting for clean-up operations that shall be executed even when the
+ service failed to start up correctly. Commands configured with this setting need to be able to operate even if
+ the service failed starting up half-way and left incompletely initialized data around. As the service's
+ processes have been terminated already when the commands specified with this setting are executed they should
+ not attempt to communicate with them.</para></listitem>
</varlistentry>
<varlistentry>
effect.</para></listitem>
</varlistentry>
- <varlistentry>
- <term><varname>StartLimitInterval=</varname></term>
- <term><varname>StartLimitBurst=</varname></term>
-
- <listitem><para>Configure service start rate limiting. By
- default, services which are started more than 5 times within
- 10 seconds are not permitted to start any more times until the
- 10 second interval ends. With these two options, this rate
- limiting may be modified. Use
- <varname>StartLimitInterval=</varname> to configure the
- checking interval (defaults to
- <varname>DefaultStartLimitInterval=</varname> in manager
- configuration file, set to 0 to disable any kind of rate
- limiting). Use <varname>StartLimitBurst=</varname> to
- configure how many starts per interval are allowed (defaults
- to <varname>DefaultStartLimitBurst=</varname> in manager
- configuration file). These configuration options are
- particularly useful in conjunction with
- <varname>Restart=</varname>; however, they apply to all kinds
- of starts (including manual), not just those triggered by the
- <varname>Restart=</varname> logic. Note that units which are
- configured for <varname>Restart=</varname> and which reach the
- start limit are not attempted to be restarted anymore;
- however, they may still be restarted manually at a later
- point, from which point on, the restart logic is again
- activated. Note that <command>systemctl reset-failed</command>
- will cause the restart rate counter for a service to be
- flushed, which is useful if the administrator wants to
- manually start a service and the start limit interferes with
- that.</para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>StartLimitAction=</varname></term>
-
- <listitem><para>Configure the action to take if the rate limit
- configured with <varname>StartLimitInterval=</varname> and
- <varname>StartLimitBurst=</varname> is hit. Takes one of
- <option>none</option>,
- <option>reboot</option>,
- <option>reboot-force</option>,
- <option>reboot-immediate</option>,
- <option>poweroff</option>,
- <option>poweroff-force</option> or
- <option>poweroff-immediate</option>. If
- <option>none</option> is set, hitting the rate limit will
- trigger no action besides that the start will not be
- permitted. <option>reboot</option> causes a reboot following
- the normal shutdown procedure (i.e. equivalent to
- <command>systemctl reboot</command>).
- <option>reboot-force</option> causes a forced reboot which
- will terminate all processes forcibly but should cause no
- dirty file systems on reboot (i.e. equivalent to
- <command>systemctl reboot -f</command>) and
- <option>reboot-immediate</option> causes immediate execution
- of the
- <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system call, which might result in data loss. Similarly,
- <option>poweroff</option>, <option>poweroff-force</option>,
- <option>poweroff-immediate</option> have the effect of
- powering down the system with similar semantics. Defaults to
- <option>none</option>.</para></listitem>
- </varlistentry>
-
<varlistentry>
<term><varname>FailureAction=</varname></term>
- <listitem><para>Configure the action to take when the service
- enters a failed state. Takes the same values as
- <varname>StartLimitAction=</varname> and executes the same
- actions. Defaults to <option>none</option>. </para></listitem>
- </varlistentry>
-
- <varlistentry>
- <term><varname>RebootArgument=</varname></term>
- <listitem><para>Configure the optional argument for the
- <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
- system call if <varname>StartLimitAction=</varname> or
- <varname>FailureAction=</varname> is a reboot action. This
- works just like the optional argument to <command>systemctl
- reboot</command> command.</para></listitem>
+ <listitem><para>Configure the action to take when the service enters a failed state. Takes the same values as
+ the unit setting <varname>StartLimitAction=</varname> and executes the same actions (see
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). Defaults to
+ <option>none</option>. </para></listitem>
</varlistentry>
<varlistentry>
<term><varname>JobTimeoutAction=</varname></term>
<term><varname>JobTimeoutRebootArgument=</varname></term>
- <listitem><para>When a job for this unit is queued, a time-out
- may be configured. If this time limit is reached, the job will
- be cancelled, the unit however will not change state or even
- enter the <literal>failed</literal> mode. This value defaults
- to 0 (job timeouts disabled), except for device units. NB:
- this timeout is independent from any unit-specific timeout
- (for example, the timeout set with
- <varname>TimeoutStartSec=</varname> in service units) as the
- job timeout has no effect on the unit itself, only on the job
- that might be pending for it. Or in other words: unit-specific
- timeouts are useful to abort unit state changes, and revert
- them. The job timeout set with this option however is useful
- to abort only the job waiting for the unit state to
- change.</para>
+ <listitem><para>When a job for this unit is queued, a time-out may be configured. If this time limit is
+ reached, the job will be cancelled, the unit however will not change state or even enter the
+ <literal>failed</literal> mode. This value defaults to <literal>infinity</literal> (job timeouts disabled),
+ except for device units. NB: this timeout is independent from any unit-specific timeout (for example, the
+ timeout set with <varname>TimeoutStartSec=</varname> in service units) as the job timeout has no effect on the
+ unit itself, only on the job that might be pending for it. Or in other words: unit-specific timeouts are useful
+ to abort unit state changes, and revert them. The job timeout set with this option however is useful to abort
+ only the job waiting for the unit state to change.</para>
<para><varname>JobTimeoutAction=</varname>
optionally configures an additional
system call.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>StartLimitInterval=</varname></term>
+ <term><varname>StartLimitBurst=</varname></term>
+
+ <listitem><para>Configure unit start rate limiting. By default, units which are started more than 5 times
+ within 10 seconds are not permitted to start any more times until the 10 second interval ends. With these two
+ options, this rate limiting may be modified. Use <varname>StartLimitInterval=</varname> to configure the
+ checking interval (defaults to <varname>DefaultStartLimitInterval=</varname> in manager configuration file, set
+ to 0 to disable any kind of rate limiting). Use <varname>StartLimitBurst=</varname> to configure how many
+ starts per interval are allowed (defaults to <varname>DefaultStartLimitBurst=</varname> in manager
+ configuration file). These configuration options are particularly useful in conjunction with the service
+ setting <varname>Restart=</varname> (see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>); however,
+ they apply to all kinds of starts (including manual), not just those triggered by the
+ <varname>Restart=</varname> logic. Note that units which are configured for <varname>Restart=</varname> and
+ which reach the start limit are not attempted to be restarted anymore; however, they may still be restarted
+ manually at a later point, from which point on, the restart logic is again activated. Note that
+ <command>systemctl reset-failed</command> will cause the restart rate counter for a service to be flushed,
+ which is useful if the administrator wants to manually start a unit and the start limit interferes with
+ that.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>StartLimitAction=</varname></term>
+
+ <listitem><para>Configure the action to take if the rate limit configured with
+ <varname>StartLimitInterval=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes one of
+ <option>none</option>, <option>reboot</option>, <option>reboot-force</option>,
+ <option>reboot-immediate</option>, <option>poweroff</option>, <option>poweroff-force</option> or
+ <option>poweroff-immediate</option>. If <option>none</option> is set, hitting the rate limit will trigger no
+ action besides that the start will not be permitted. <option>reboot</option> causes a reboot following the
+ normal shutdown procedure (i.e. equivalent to <command>systemctl reboot</command>).
+ <option>reboot-force</option> causes a forced reboot which will terminate all processes forcibly but should
+ cause no dirty file systems on reboot (i.e. equivalent to <command>systemctl reboot -f</command>) and
+ <option>reboot-immediate</option> causes immediate execution of the
+ <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call, which
+ might result in data loss. Similarly, <option>poweroff</option>, <option>poweroff-force</option>,
+ <option>poweroff-immediate</option> have the effect of powering down the system with similar
+ semantics. Defaults to <option>none</option>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>RebootArgument=</varname></term>
+ <listitem><para>Configure the optional argument for the
+ <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call if
+ <varname>StartLimitAction=</varname> or a service's <varname>FailureAction=</varname> is a reboot action. This
+ works just like the optional argument to <command>systemctl reboot</command> command.</para></listitem>
+ </varlistentry>
+
<varlistentry>
<term><varname>ConditionArchitecture=</varname></term>
<term><varname>ConditionVirtualization=</varname></term>
done
}
+__get_machines() {
+ local a b
+ (machinectl list-images --no-legend --no-pager; machinectl list --no-legend --no-pager; echo ".host") | \
+ { while read a b; do echo " $a"; done; } | sort -u;
+}
+
__journal_fields=(MESSAGE{,_ID} PRIORITY CODE_{FILE,LINE,FUNC}
ERRNO SYSLOG_{FACILITY,IDENTIFIER,PID} COREDUMP_EXE
_{P,U,G}ID _COMM _EXE _CMDLINE
--utc -x --catalog --no-full --force --dump-catalog
--flush --rotate --sync'
[ARG]='-b --boot --this-boot -D --directory --file -F --field
- -o --output -u --unit --user-unit -p --priority
+ -M --machine -o --output -u --unit --user-unit -p --priority
--vacuum-size --vacuum-time'
[ARGUNKNOWN]='-c --cursor --interval -n --lines -S --since -U --until
--after-cursor --verify-key -t --identifier
- --root -M --machine'
+ --root'
)
if __contains_word "$prev" ${OPTS[ARG]} ${OPTS[ARGUNKNOWN]}; then
;;
--field|-F)
comps=${__journal_fields[*]}
+ ;;
+ --machine|-M)
+ comps=$( __get_machines )
;;
--priority|-p)
comps=${__syslog_priorities[*]}
#compdef busctl
-# hostnamectl(1) completion -*- shell-script -*-
+# busctl(1) completion -*- shell-script -*-
#
# This file is part of systemd.
#
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
static char** arg_listen = NULL;
static bool arg_accept = false;
-static bool arg_datagram = false;
+static int arg_socket_type = SOCK_STREAM;
static char** arg_args = NULL;
static char** arg_setenv = NULL;
static const char *arg_fdname = NULL;
+static bool arg_inetd = false;
static int add_epoll(int epoll_fd, int fd) {
struct epoll_event ev = {
*/
STRV_FOREACH(address, arg_listen) {
-
- if (arg_datagram)
- fd = make_socket_fd(LOG_DEBUG, *address, SOCK_DGRAM, SOCK_CLOEXEC);
- else
- fd = make_socket_fd(LOG_DEBUG, *address, SOCK_STREAM, (arg_accept*SOCK_CLOEXEC));
-
+ fd = make_socket_fd(LOG_DEBUG, *address, arg_socket_type, (arg_accept*SOCK_CLOEXEC));
if (fd < 0) {
log_open();
return log_error_errno(fd, "Failed to open '%s': %m", *address);
return count;
}
-static int launch(char* name, char **argv, char **env, int fds) {
+static int exec_process(const char* name, char **argv, char **env, int start_fd, int n_fds) {
- static const char* tocopy[] = {"TERM=", "PATH=", "USER=", "HOME="};
_cleanup_strv_free_ char **envp = NULL;
- _cleanup_free_ char *tmp = NULL;
+ _cleanup_free_ char *joined = NULL;
unsigned n_env = 0, length;
- char **s;
+ const char *tocopy;
unsigned i;
+ char **s;
+ int r;
+
+ if (arg_inetd && n_fds != 1) {
+ log_error("--inetd only supported for single file descriptors.");
+ return -EINVAL;
+ }
length = strv_length(arg_setenv);
return log_oom();
STRV_FOREACH(s, arg_setenv) {
+
if (strchr(*s, '=')) {
char *k;
envp[n_env] = strdup(n);
if (!envp[n_env])
return log_oom();
+
+ n_env ++;
}
}
- for (i = 0; i < ELEMENTSOF(tocopy); i++) {
+ FOREACH_STRING(tocopy, "TERM=", "PATH=", "USER=", "HOME=") {
const char *n;
- n = strv_find_prefix(env, tocopy[i]);
+ n = strv_find_prefix(env, tocopy);
if (!n)
continue;
n_env ++;
}
- if ((asprintf((char**)(envp + n_env++), "LISTEN_FDS=%d", fds) < 0) ||
- (asprintf((char**)(envp + n_env++), "LISTEN_PID=%d", getpid()) < 0))
- return log_oom();
+ if (arg_inetd) {
+ assert(n_fds == 1);
+
+ r = dup2(start_fd, STDIN_FILENO);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to dup connection to stdin: %m");
+
+ r = dup2(start_fd, STDOUT_FILENO);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to dup connection to stdout: %m");
+
+ start_fd = safe_close(start_fd);
+ } else {
+ if (start_fd != SD_LISTEN_FDS_START) {
+ assert(n_fds == 1);
+
+ r = dup2(start_fd, SD_LISTEN_FDS_START);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to dup connection: %m");
- if (arg_fdname) {
- char *e;
+ safe_close(start_fd);
+ start_fd = SD_LISTEN_FDS_START;
+ }
+
+ if (asprintf((char**)(envp + n_env++), "LISTEN_FDS=%i", n_fds) < 0)
+ return log_oom();
- e = strappend("LISTEN_FDNAMES=", arg_fdname);
- if (!e)
+ if (asprintf((char**)(envp + n_env++), "LISTEN_PID=" PID_FMT, getpid()) < 0)
return log_oom();
- for (i = 1; i < (unsigned) fds; i++) {
- char *c;
+ if (arg_fdname) {
+ char *e;
- c = strjoin(e, ":", arg_fdname, NULL);
- if (!c) {
- free(e);
+ e = strappend("LISTEN_FDNAMES=", arg_fdname);
+ if (!e)
return log_oom();
+
+ for (i = 1; i < (unsigned) n_fds; i++) {
+ char *c;
+
+ c = strjoin(e, ":", arg_fdname, NULL);
+ if (!c) {
+ free(e);
+ return log_oom();
+ }
+
+ free(e);
+ e = c;
}
- free(e);
- e = c;
+ envp[n_env++] = e;
}
-
- envp[n_env++] = e;
}
- tmp = strv_join(argv, " ");
- if (!tmp)
+ joined = strv_join(argv, " ");
+ if (!joined)
return log_oom();
- log_info("Execing %s (%s)", name, tmp);
+ log_info("Execing %s (%s)", name, joined);
execvpe(name, argv, envp);
- return log_error_errno(errno, "Failed to execp %s (%s): %m", name, tmp);
+ return log_error_errno(errno, "Failed to execp %s (%s): %m", name, joined);
}
-static int launch1(const char* child, char** argv, char **env, int fd) {
- _cleanup_free_ char *tmp = NULL;
+static int fork_and_exec_process(const char* child, char** argv, char **env, int fd) {
+ _cleanup_free_ char *joined = NULL;
pid_t parent_pid, child_pid;
- int r;
- tmp = strv_join(argv, " ");
- if (!tmp)
+ joined = strv_join(argv, " ");
+ if (!joined)
return log_oom();
parent_pid = getpid();
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
- r = dup2(fd, STDIN_FILENO);
- if (r < 0) {
- log_error_errno(errno, "Failed to dup connection to stdin: %m");
- _exit(EXIT_FAILURE);
- }
-
- r = dup2(fd, STDOUT_FILENO);
- if (r < 0) {
- log_error_errno(errno, "Failed to dup connection to stdout: %m");
- _exit(EXIT_FAILURE);
- }
-
- r = close(fd);
- if (r < 0) {
- log_error_errno(errno, "Failed to close dupped connection: %m");
- _exit(EXIT_FAILURE);
- }
-
/* Make sure the child goes away when the parent dies */
if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
_exit(EXIT_FAILURE);
if (getppid() != parent_pid)
_exit(EXIT_SUCCESS);
- execvp(child, argv);
- log_error_errno(errno, "Failed to exec child %s: %m", child);
+ exec_process(child, argv, env, fd, 1);
_exit(EXIT_FAILURE);
}
- log_info("Spawned %s (%s) as PID %d", child, tmp, child_pid);
-
+ log_info("Spawned %s (%s) as PID %d", child, joined, child_pid);
return 0;
}
static int do_accept(const char* name, char **argv, char **envp, int fd) {
_cleanup_free_ char *local = NULL, *peer = NULL;
- _cleanup_close_ int fd2 = -1;
+ _cleanup_close_ int fd_accepted = -1;
- fd2 = accept(fd, NULL, NULL);
- if (fd2 < 0) {
- log_error_errno(errno, "Failed to accept connection on fd:%d: %m", fd);
- return fd2;
- }
+ fd_accepted = accept4(fd, NULL, NULL, 0);
+ if (fd_accepted < 0)
+ return log_error_errno(errno, "Failed to accept connection on fd:%d: %m", fd);
- getsockname_pretty(fd2, &local);
- getpeername_pretty(fd2, true, &peer);
+ getsockname_pretty(fd_accepted, &local);
+ getpeername_pretty(fd_accepted, true, &peer);
log_info("Connection from %s to %s", strna(peer), strna(local));
- return launch1(name, argv, envp, fd2);
+ return fork_and_exec_process(name, argv, envp, fd_accepted);
}
/* SIGCHLD handler. */
PROTECT_ERRNO;
log_info("Child %d died with code %d", t->si_pid, t->si_status);
+
/* Wait for a dead child. */
- waitpid(t->si_pid, NULL, 0);
+ (void) waitpid(t->si_pid, NULL, 0);
}
static int install_chld_handler(void) {
- int r;
- struct sigaction act = {
+ static const struct sigaction act = {
.sa_flags = SA_SIGINFO,
.sa_sigaction = sigchld_hdl,
};
+ int r;
+
r = sigaction(SIGCHLD, &act, 0);
if (r < 0)
- log_error_errno(errno, "Failed to install SIGCHLD handler: %m");
- return r;
+ return log_error_errno(errno, "Failed to install SIGCHLD handler: %m");
+
+ return 0;
}
static void help(void) {
" --version Print version string and exit\n"
" -l --listen=ADDR Listen for raw connections at ADDR\n"
" -d --datagram Listen on datagram instead of stream socket\n"
+ " --seqpacket Listen on SOCK_SEQPACKET instead of stream socket\n"
" -a --accept Spawn separate child for each connection\n"
" -E --setenv=NAME[=VALUE] Pass an environment variable to children\n"
+ " --inetd Enable inetd file descriptor passing protocol\n"
"\n"
"Note: file descriptors from sd_listen_fds() will be passed through.\n"
, program_invocation_short_name);
enum {
ARG_VERSION = 0x100,
ARG_FDNAME,
+ ARG_SEQPACKET,
+ ARG_INETD,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "datagram", no_argument, NULL, 'd' },
+ { "seqpacket", no_argument, NULL, ARG_SEQPACKET },
{ "listen", required_argument, NULL, 'l' },
{ "accept", no_argument, NULL, 'a' },
{ "setenv", required_argument, NULL, 'E' },
{ "environment", required_argument, NULL, 'E' }, /* legacy alias */
{ "fdname", required_argument, NULL, ARG_FDNAME },
+ { "inetd", no_argument, NULL, ARG_INETD },
{}
};
break;
case 'd':
- arg_datagram = true;
+ if (arg_socket_type == SOCK_SEQPACKET) {
+ log_error("--datagram may not be combined with --seqpacket.");
+ return -EINVAL;
+ }
+
+ arg_socket_type = SOCK_DGRAM;
+ break;
+
+ case ARG_SEQPACKET:
+ if (arg_socket_type == SOCK_DGRAM) {
+ log_error("--seqpacket may not be combined with --datagram.");
+ return -EINVAL;
+ }
+
+ arg_socket_type = SOCK_SEQPACKET;
break;
case 'a':
arg_fdname = optarg;
break;
+ case ARG_INETD:
+ arg_inetd = true;
+ break;
+
case '?':
return -EINVAL;
return -EINVAL;
}
- if (arg_datagram && arg_accept) {
+ if (arg_socket_type == SOCK_DGRAM && arg_accept) {
log_error("Datagram sockets do not accept connections. "
"The --datagram and --accept options may not be combined.");
return -EINVAL;
log_info("Communication attempt on fd %i.", event.data.fd);
if (arg_accept) {
- r = do_accept(argv[optind], argv + optind, envp,
- event.data.fd);
+ r = do_accept(argv[optind], argv + optind, envp, event.data.fd);
if (r < 0)
return EXIT_FAILURE;
} else
break;
}
- launch(argv[optind], argv + optind, envp, n);
+ exec_process(argv[optind], argv + optind, envp, SD_LISTEN_FDS_START, n);
return EXIT_SUCCESS;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
#include "macro.h"
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
return 0;
}
+
+#define TIME_EPOCH_USEC ((usec_t) TIME_EPOCH * USEC_PER_SEC)
+
+int clock_apply_epoch(void) {
+ struct timespec ts;
+
+ if (now(CLOCK_REALTIME) >= TIME_EPOCH_USEC)
+ return 0;
+
+ if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, TIME_EPOCH_USEC)) < 0)
+ return -errno;
+
+ return 1;
+}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
int clock_reset_timewarp(void);
int clock_get_hwclock(struct tm *tm);
int clock_set_hwclock(const struct tm *tm);
+int clock_apply_epoch(void);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
struct cmsghdr cmsghdr;
uint8_t buf[CMSG_SPACE(sizeof(int))];
} control = {};
- struct cmsghdr *cmsg;
-
struct msghdr mh = {
.msg_name = (struct sockaddr*) sa,
.msg_namelen = len,
.msg_control = &control,
.msg_controllen = sizeof(control),
};
+ struct cmsghdr *cmsg;
assert(transport_fd >= 0);
assert(fd >= 0);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
#include "strv.h"
#include "time-util.h"
+static nsec_t timespec_load_nsec(const struct timespec *ts);
+
usec_t now(clockid_t clock_id) {
struct timespec ts;
ts->realtime = u;
delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
- ts->monotonic = now(CLOCK_MONOTONIC);
-
- if ((int64_t) ts->monotonic > delta)
- ts->monotonic -= delta;
- else
- ts->monotonic = 0;
+ ts->monotonic = usec_sub(now(CLOCK_MONOTONIC), delta);
return ts;
}
ts->monotonic = u;
delta = (int64_t) now(CLOCK_MONOTONIC) - (int64_t) u;
-
- ts->realtime = now(CLOCK_REALTIME);
- if ((int64_t) ts->realtime > delta)
- ts->realtime -= delta;
- else
- ts->realtime = 0;
+ ts->realtime = usec_sub(now(CLOCK_REALTIME), delta);
return ts;
}
ts->realtime = ts->monotonic = USEC_INFINITY;
return ts;
}
- ts->realtime = now(CLOCK_REALTIME);
- ts->monotonic = now(CLOCK_MONOTONIC);
+ dual_timestamp_get(ts);
delta = (int64_t) now(clock_boottime_or_monotonic()) - (int64_t) u;
-
- if ((int64_t) ts->realtime > delta)
- ts->realtime -= delta;
- else
- ts->realtime = 0;
-
- if ((int64_t) ts->monotonic > delta)
- ts->monotonic -= delta;
- else
- ts->monotonic = 0;
+ ts->realtime = usec_sub(ts->realtime, delta);
+ ts->monotonic = usec_sub(ts->monotonic, delta);
return ts;
}
-
usec_t timespec_load(const struct timespec *ts) {
assert(ts);
(usec_t) ts->tv_nsec / NSEC_PER_USEC;
}
-nsec_t timespec_load_nsec(const struct timespec *ts) {
+static nsec_t timespec_load_nsec(const struct timespec *ts) {
assert(ts);
if (ts->tv_sec == (time_t) -1 &&
return tv;
}
-static char *format_timestamp_internal(char *buf, size_t l, usec_t t, bool utc) {
+static char *format_timestamp_internal(char *buf, size_t l, usec_t t,
+ bool utc, bool us) {
struct tm tm;
time_t sec;
+ int k;
assert(buf);
assert(l > 0);
sec = (time_t) (t / USEC_PER_SEC);
localtime_or_gmtime_r(&sec, &tm, utc);
- if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm) <= 0)
+ if (us)
+ k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm);
+ else
+ k = strftime(buf, l, "%a %Y-%m-%d %H:%M:%S %Z", &tm);
+
+ if (k <= 0)
return NULL;
+ if (us) {
+ snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
+ if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
+ return NULL;
+ }
return buf;
}
char *format_timestamp(char *buf, size_t l, usec_t t) {
- return format_timestamp_internal(buf, l, t, false);
+ return format_timestamp_internal(buf, l, t, false, false);
}
char *format_timestamp_utc(char *buf, size_t l, usec_t t) {
- return format_timestamp_internal(buf, l, t, true);
-}
-
-static char *format_timestamp_internal_us(char *buf, size_t l, usec_t t, bool utc) {
- struct tm tm;
- time_t sec;
-
- assert(buf);
- assert(l > 0);
-
- if (t <= 0 || t == USEC_INFINITY)
- return NULL;
-
- sec = (time_t) (t / USEC_PER_SEC);
- localtime_or_gmtime_r(&sec, &tm, utc);
-
- if (strftime(buf, l, "%a %Y-%m-%d %H:%M:%S", &tm) <= 0)
- return NULL;
- snprintf(buf + strlen(buf), l - strlen(buf), ".%06llu", (unsigned long long) (t % USEC_PER_SEC));
- if (strftime(buf + strlen(buf), l - strlen(buf), " %Z", &tm) <= 0)
- return NULL;
-
- return buf;
+ return format_timestamp_internal(buf, l, t, true, false);
}
char *format_timestamp_us(char *buf, size_t l, usec_t t) {
- return format_timestamp_internal_us(buf, l, t, false);
+ return format_timestamp_internal(buf, l, t, false, true);
}
char *format_timestamp_us_utc(char *buf, size_t l, usec_t t) {
- return format_timestamp_internal_us(buf, l, t, true);
+ return format_timestamp_internal(buf, l, t, true, true);
}
char *format_timestamp_relative(char *buf, size_t l, usec_t t) {
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
#define FORMAT_TIMESTAMP_RELATIVE_MAX 256
#define FORMAT_TIMESPAN_MAX 64
-#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+#define TIME_T_MAX (time_t)((UINTMAX_C(1) << ((sizeof(time_t) << 3) - 1)) - 1)
#define DUAL_TIMESTAMP_NULL ((struct dual_timestamp) { 0ULL, 0ULL })
usec_t timeval_load(const struct timeval *tv) _pure_;
struct timeval *timeval_store(struct timeval *tv, usec_t u);
-nsec_t timespec_load_nsec(const struct timespec *ts) _pure_;
-
char *format_timestamp(char *buf, size_t l, usec_t t);
char *format_timestamp_utc(char *buf, size_t l, usec_t t);
char *format_timestamp_us(char *buf, size_t l, usec_t t);
return c;
}
+
+static inline usec_t usec_sub(usec_t timestamp, int64_t delta) {
+ if (delta < 0)
+ return usec_add(timestamp, (usec_t) (-delta));
+
+ if (timestamp == USEC_INFINITY) /* Make sure infinity doesn't degrade */
+ return USEC_INFINITY;
+
+ if (timestamp < (usec_t) delta)
+ return 0;
+
+ return timestamp - delta;
+}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/* This program 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
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
static void busname_trigger_notify(Unit *u, Unit *other) {
BusName *n = BUSNAME(u);
- Service *s;
assert(n);
assert(other);
if (!IN_SET(n->state, BUSNAME_RUNNING, BUSNAME_LISTENING))
return;
- if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
+ if (other->start_limit_hit) {
+ busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT);
return;
+ }
- s = SERVICE(other);
+ if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
+ return;
- if (s->state == SERVICE_FAILED && s->result == SERVICE_FAILURE_START_LIMIT)
- busname_enter_dead(n, BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT);
- else if (IN_SET(s->state,
- SERVICE_DEAD, SERVICE_FAILED,
- SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
- SERVICE_STOP_POST, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
- SERVICE_AUTO_RESTART))
+ if (IN_SET(SERVICE(other)->state,
+ SERVICE_DEAD, SERVICE_FAILED,
+ SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
+ SERVICE_AUTO_RESTART))
busname_enter_listening(n);
+
+ if (SERVICE(other)->state == SERVICE_RUNNING)
+ busname_set_state(n, BUSNAME_RUNNING);
}
static int busname_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
return unit_kill_common(u, who, signo, -1, BUSNAME(u)->control_pid, error);
}
-static int busname_get_timeout(Unit *u, uint64_t *timeout) {
+static int busname_get_timeout(Unit *u, usec_t *timeout) {
BusName *n = BUSNAME(u);
+ usec_t t;
int r;
if (!n->timer_event_source)
return 0;
- r = sd_event_source_get_time(n->timer_event_source, timeout);
+ r = sd_event_source_get_time(n->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
[BUSNAME_FAILURE_EXIT_CODE] = "exit-code",
[BUSNAME_FAILURE_SIGNAL] = "signal",
[BUSNAME_FAILURE_CORE_DUMP] = "core-dump",
- [BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent",
+ [BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit",
};
DEFINE_STRING_TABLE_LOOKUP(busname_result, BusNameResult);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
BUSNAME_FAILURE_EXIT_CODE,
BUSNAME_FAILURE_SIGNAL,
BUSNAME_FAILURE_CORE_DUMP,
- BUSNAME_FAILURE_SERVICE_FAILED_PERMANENT,
+ BUSNAME_FAILURE_SERVICE_START_LIMIT_HIT,
_BUSNAME_RESULT_MAX,
_BUSNAME_RESULT_INVALID = -1
} BusNameResult;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec, offsetof(Service, runtime_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), SD_BUS_VTABLE_PROPERTY_CONST),
BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
- SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
+ /* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
+ SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("FailureAction", "s", property_get_failure_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NetClass", "u", NULL, offsetof(Unit, cgroup_netclass_id), 0),
+ SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
* possible. Note that in the case of UNIT_MASKED, load_error
* is not set. */
if (u->load_state == UNIT_MASKED)
- return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit is masked.");
+ return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", u->id);
if (u->load_state == UNIT_NOT_FOUND)
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit not found.");
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not found.", u->id);
- return sd_bus_error_set_errnof(error, u->load_error, "Unit is not loaded properly: %m.");
+ return sd_bus_error_set_errnof(error, u->load_error, "Unit %s is not loaded properly: %m.", u->id);
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
asynchronous_sync();
}
-int job_get_timeout(Job *j, uint64_t *timeout) {
+int job_get_timeout(Job *j, usec_t *timeout) {
+ usec_t x = USEC_INFINITY, y = USEC_INFINITY;
Unit *u = j->unit;
- uint64_t x = -1, y = -1;
- int r = 0, q = 0;
+ int r;
assert(u);
r = sd_event_source_get_time(j->timer_event_source, &x);
if (r < 0)
return r;
- r = 1;
}
if (UNIT_VTABLE(u)->get_timeout) {
- q = UNIT_VTABLE(u)->get_timeout(u, &y);
- if (q < 0)
- return q;
+ r = UNIT_VTABLE(u)->get_timeout(u, &y);
+ if (r < 0)
+ return r;
}
- if (r == 0 && q == 0)
+ if (x == USEC_INFINITY && y == USEC_INFINITY)
return 0;
*timeout = MIN(x, y);
-
return 1;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
void job_shutdown_magic(Job *j);
+int job_get_timeout(Job *j, usec_t *timeout) _pure_;
+
const char* job_type_to_string(JobType t) _const_;
JobType job_type_from_string(const char *s) _pure_;
const char* job_result_to_string(JobResult t) _const_;
JobResult job_result_from_string(const char *s) _pure_;
-int job_get_timeout(Job *j, uint64_t *timeout) _pure_;
-
const char* job_type_to_access_method(JobType t);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0, offsetof(Unit, on_failure_job_mode)
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
-Unit.JobTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_timeout)
+Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
Unit.JobTimeoutAction, config_parse_failure_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_string, 0, offsetof(Unit, job_timeout_reboot_arg)
+Unit.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
+Unit.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
+Unit.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
+Unit.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
Unit.ConditionPathExists, config_parse_unit_condition_path, CONDITION_PATH_EXISTS, offsetof(Unit, conditions)
Unit.ConditionPathExistsGlob, config_parse_unit_condition_path, CONDITION_PATH_EXISTS_GLOB, offsetof(Unit, conditions)
Unit.ConditionPathIsDirectory, config_parse_unit_condition_path, CONDITION_PATH_IS_DIRECTORY, offsetof(Unit, conditions)
Service.ExecStop, config_parse_exec, SERVICE_EXEC_STOP, offsetof(Service, exec_command)
Service.ExecStopPost, config_parse_exec, SERVICE_EXEC_STOP_POST, offsetof(Service, exec_command)
Service.RestartSec, config_parse_sec, 0, offsetof(Service, restart_usec)
-Service.TimeoutSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec)
-Service.TimeoutStartSec, config_parse_service_timeout, 0, offsetof(Service, timeout_start_usec)
-Service.TimeoutStopSec, config_parse_service_timeout, 0, offsetof(Service, timeout_stop_usec)
+Service.TimeoutSec, config_parse_service_timeout, 0, 0
+Service.TimeoutStartSec, config_parse_service_timeout, 0, 0
+Service.TimeoutStopSec, config_parse_service_timeout, 0, 0
Service.RuntimeMaxSec, config_parse_sec, 0, offsetof(Service, runtime_max_usec)
Service.WatchdogSec, config_parse_sec, 0, offsetof(Service, watchdog_usec)
-Service.StartLimitInterval, config_parse_sec, 0, offsetof(Service, start_limit.interval)
-Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Service, start_limit.burst)
-Service.StartLimitAction, config_parse_failure_action, 0, offsetof(Service, start_limit_action)
-Service.RebootArgument, config_parse_string, 0, offsetof(Service, reboot_arg)
+Service.StartLimitInterval, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
+Service.StartLimitBurst, config_parse_unsigned, 0, offsetof(Unit, start_limit.burst)
+Service.StartLimitAction, config_parse_failure_action, 0, offsetof(Unit, start_limit_action)
+Service.RebootArgument, config_parse_string, 0, offsetof(Unit, reboot_arg)
Service.FailureAction, config_parse_failure_action, 0, offsetof(Service, failure_action)
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
return config_parse_string(unit, filename, line, section, section_line, lvalue, ltype, k, data, userdata);
}
-int config_parse_service_timeout(const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
+int config_parse_service_timeout(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
Service *s = userdata;
+ usec_t usec;
int r;
assert(filename);
assert(rvalue);
assert(s);
- r = config_parse_sec(unit, filename, line, section, section_line, lvalue, ltype,
- rvalue, data, userdata);
- if (r < 0)
- return r;
+ /* This is called for three cases: TimeoutSec=, TimeoutStopSec= and TimeoutStartSec=. */
- if (streq(lvalue, "TimeoutSec")) {
- s->start_timeout_defined = true;
- s->timeout_stop_usec = s->timeout_start_usec;
- } else if (streq(lvalue, "TimeoutStartSec"))
- s->start_timeout_defined = true;
+ r = parse_sec(rvalue, &usec);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
+ return 0;
+ }
/* Traditionally, these options accepted 0 to disable the timeouts. However, a timeout of 0 suggests it happens
* immediately, hence fix this to become USEC_INFINITY instead. This is in-line with how we internally handle
* all other timeouts. */
+ if (usec <= 0)
+ usec = USEC_INFINITY;
+
+ if (!streq(lvalue, "TimeoutStopSec")) {
+ s->start_timeout_defined = true;
+ s->timeout_start_usec = usec;
+ }
+
+ if (!streq(lvalue, "TimeoutStartSec"))
+ s->timeout_stop_usec = usec;
+
+ return 0;
+}
+
+int config_parse_sec_fix_0(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ usec_t *usec = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(usec);
+
+ /* This is pretty much like config_parse_sec(), except that this treats a time of 0 as infinity, for
+ * compatibility with older versions of systemd where 0 instead of infinity was used as indicator to turn off a
+ * timeout. */
+
+ r = parse_sec(rvalue, usec);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
+ return 0;
+ }
- if (s->timeout_start_usec <= 0)
- s->timeout_start_usec = USEC_INFINITY;
- if (s->timeout_stop_usec <= 0)
- s->timeout_stop_usec = USEC_INFINITY;
+ if (*usec <= 0)
+ *usec = USEC_INFINITY;
return 0;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
int config_parse_exec_utmp_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_working_directory(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_fdname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_sec_fix_0(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
if (pid < 0)
log_emergency_errno(errno, "Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
else if (pid == 0) {
- struct rlimit rl = {
- .rlim_cur = RLIM_INFINITY,
- .rlim_max = RLIM_INFINITY,
- };
-
/* Enable default signal handler for core dump */
+
sa = (struct sigaction) {
.sa_handler = SIG_DFL,
};
(void) sigaction(sig, &sa, NULL);
- /* Don't limit the core dump size */
- (void) setrlimit(RLIMIT_CORE, &rl);
+ /* Don't limit the coredump size */
+ (void) setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY));
/* Just to be sure... */
(void) chdir("/");
* saving time change. All kernel local time concepts will be treated
* as UTC that way.
*/
- clock_reset_timewarp();
+ (void) clock_reset_timewarp();
}
+
+ r = clock_apply_epoch();
+ if (r < 0)
+ log_error_errno(r, "Current system time is before build time, but cannot correct: %m");
+ else if (r > 0)
+ log_info("System time before build time, advancing clock.");
}
/* Set the default for later on, but don't actually
kernel_timestamp = DUAL_TIMESTAMP_NULL;
}
+ if (getpid() == 1) {
+ /* Don't limit the core dump size, so that coredump handlers such as systemd-coredump (which honour the limit)
+ * will process core dumps for system services by default. */
+ (void) setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY));
+
+ /* But at the same time, turn off the core_pattern logic by default, so that no coredumps are stored
+ * until the systemd-coredump tool is enabled via sysctl. */
+ if (!skip_setup)
+ (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+ }
+
/* Initialize default unit */
r = free_and_strdup(&arg_default_unit, SPECIAL_DEFAULT_TARGET);
if (r < 0) {
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
/* Relabel first, just in case */
if (relabel)
- label_fix(p->where, true, true);
+ (void) label_fix(p->where, true, true);
r = path_is_mount_point(p->where, AT_SYMLINK_FOLLOW);
- if (r < 0 && r != -ENOENT)
- return r;
+ if (r < 0 && r != -ENOENT) {
+ log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, r, "Failed to determine whether %s is a mount point: %m", p->where);
+ return (p->mode & MNT_FATAL) ? r : 0;
+ }
if (r > 0)
return 0;
/* The access mode here doesn't really matter too much, since
* the mounted file system will take precedence anyway. */
if (relabel)
- mkdir_p_label(p->where, 0755);
+ (void) mkdir_p_label(p->where, 0755);
else
- mkdir_p(p->where, 0755);
+ (void) mkdir_p(p->where, 0755);
log_debug("Mounting %s to %s of type %s with options %s.",
p->what,
p->type,
p->flags,
p->options) < 0) {
- log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s at %s: %m", p->type, p->where);
+ log_full_errno((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, errno, "Failed to mount %s at %s: %m", p->type, p->where);
return (p->mode & MNT_FATAL) ? -errno : 0;
}
/* Relabel again, since we now mounted something fresh here */
if (relabel)
- label_fix(p->where, false, false);
+ (void) label_fix(p->where, false, false);
return 1;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
m->mount_monitor = NULL;
}
-static int mount_get_timeout(Unit *u, uint64_t *timeout) {
+static int mount_get_timeout(Unit *u, usec_t *timeout) {
Mount *m = MOUNT(u);
+ usec_t t;
int r;
if (!m->timer_event_source)
return 0;
- r = sd_event_source_get_time(m->timer_event_source, timeout);
+ r = sd_event_source_get_time(m->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
return unit_kill_common(u, who, signo, -1, -1, error);
}
-static int scope_get_timeout(Unit *u, uint64_t *timeout) {
+static int scope_get_timeout(Unit *u, usec_t *timeout) {
Scope *s = SCOPE(u);
+ usec_t t;
int r;
if (!s->timer_event_source)
return 0;
- r = sd_event_source_get_time(s->timer_event_source, timeout);
+ r = sd_event_source_get_time(s->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
s->stdin_fd = s->stdout_fd = s->stderr_fd = -1;
s->guess_main_pid = true;
- RATELIMIT_INIT(s->start_limit, u->manager->default_start_limit_interval, u->manager->default_start_limit_burst);
-
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
}
s->pid_file = mfree(s->pid_file);
s->status_text = mfree(s->status_text);
- s->reboot_arg = mfree(s->reboot_arg);
s->exec_runtime = exec_runtime_unref(s->exec_runtime);
exec_command_free_array(s->exec_command, _SERVICE_EXEC_COMMAND_MAX);
if (s->result != SERVICE_SUCCESS) {
log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
- failure_action(UNIT(s)->manager, s->failure_action, s->reboot_arg);
+ failure_action(UNIT(s)->manager, s->failure_action, UNIT(s)->reboot_arg);
}
if (allow_restart && service_shall_restart(s)) {
if (f != SERVICE_SUCCESS)
s->result = f;
+ service_unwatch_control_pid(s);
+
if (service_good(s)) {
/* If there are any queued up sd_notify()
service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
}
-static int service_start_limit_test(Service *s) {
- assert(s);
-
- if (ratelimit_test(&s->start_limit))
- return 0;
-
- log_unit_warning(UNIT(s), "Start request repeated too quickly.");
-
- return failure_action(UNIT(s)->manager, s->start_limit_action, s->reboot_arg);
-}
-
static int service_start(Unit *u) {
Service *s = SERVICE(u);
- int r;
assert(s);
assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
- /* Make sure we don't enter a busy loop of some kind. */
- r = service_start_limit_test(s);
- if (r < 0) {
- service_enter_dead(s, SERVICE_FAILURE_START_LIMIT, false);
- return r;
- }
-
s->result = SERVICE_SUCCESS;
s->reload_result = SERVICE_SUCCESS;
s->main_pid_known = false;
case SERVICE_START_POST:
if (f != SERVICE_SUCCESS) {
- service_enter_stop(s, f);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
break;
}
case SERVICE_START_POST:
log_unit_warning(UNIT(s), "Start-post operation timed out. Stopping.");
- service_enter_stop(s, SERVICE_FAILURE_TIMEOUT);
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
break;
case SERVICE_RUNNING:
break;
case SERVICE_RELOAD:
- log_unit_warning(UNIT(s), "Reload operation timed out. Stopping.");
- service_unwatch_control_pid(s);
+ log_unit_warning(UNIT(s), "Reload operation timed out. Killing reload process.");
service_kill_control_processes(s);
s->reload_result = SERVICE_FAILURE_TIMEOUT;
service_enter_running(s, SERVICE_SUCCESS);
unit_add_to_dbus_queue(u);
}
-static int service_get_timeout(Unit *u, uint64_t *timeout) {
+static int service_get_timeout(Unit *u, usec_t *timeout) {
Service *s = SERVICE(u);
+ uint64_t t;
int r;
if (!s->timer_event_source)
return 0;
- r = sd_event_source_get_time(s->timer_event_source, timeout);
+ r = sd_event_source_get_time(s->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
s->result = SERVICE_SUCCESS;
s->reload_result = SERVICE_SUCCESS;
-
- RATELIMIT_RESET(s->start_limit);
}
static int service_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
[SERVICE_FAILURE_SIGNAL] = "signal",
[SERVICE_FAILURE_CORE_DUMP] = "core-dump",
[SERVICE_FAILURE_WATCHDOG] = "watchdog",
- [SERVICE_FAILURE_START_LIMIT] = "start-limit"
};
DEFINE_STRING_TABLE_LOOKUP(service_result, ServiceResult);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
SERVICE_FAILURE_SIGNAL,
SERVICE_FAILURE_CORE_DUMP,
SERVICE_FAILURE_WATCHDOG,
- SERVICE_FAILURE_START_LIMIT,
_SERVICE_RESULT_MAX,
_SERVICE_RESULT_INVALID = -1
} ServiceResult;
char *status_text;
int status_errno;
- RateLimit start_limit;
- FailureAction start_limit_action;
FailureAction failure_action;
- char *reboot_arg;
UnitRef accept_socket;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
s->result = SOCKET_SUCCESS;
}
-static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
- assert(s);
-
- /* The service is dead. Dang!
- *
- * This is strictly for one-instance-for-all-connections
- * services. */
-
- if (s->state == SOCKET_RUNNING) {
- log_unit_debug(UNIT(s), "Got notified about service death (failed permanently: %s)", yes_no(failed_permanent));
- if (failed_permanent)
- socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
- else
- socket_enter_listening(s);
- }
-}
-
void socket_connection_unref(Socket *s) {
assert(s);
static void socket_trigger_notify(Unit *u, Unit *other) {
Socket *s = SOCKET(u);
- Service *se;
assert(u);
assert(other);
/* Don't propagate state changes from the service if we are
already down or accepting connections */
- if ((s->state != SOCKET_RUNNING &&
- s->state != SOCKET_LISTENING) ||
- s->accept)
+ if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING) || s->accept)
return;
- if (other->load_state != UNIT_LOADED ||
- other->type != UNIT_SERVICE)
+ if (other->start_limit_hit) {
+ socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_START_LIMIT_HIT);
return;
+ }
- se = SERVICE(other);
-
- if (se->state == SERVICE_FAILED)
- socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
+ if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
+ return;
- if (se->state == SERVICE_DEAD ||
- se->state == SERVICE_FINAL_SIGTERM ||
- se->state == SERVICE_FINAL_SIGKILL ||
- se->state == SERVICE_AUTO_RESTART)
- socket_notify_service_dead(s, false);
+ if (IN_SET(SERVICE(other)->state,
+ SERVICE_DEAD, SERVICE_FAILED,
+ SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
+ SERVICE_AUTO_RESTART))
+ socket_enter_listening(s);
- if (se->state == SERVICE_RUNNING)
+ if (SERVICE(other)->state == SERVICE_RUNNING)
socket_set_state(s, SOCKET_RUNNING);
}
return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
}
-static int socket_get_timeout(Unit *u, uint64_t *timeout) {
+static int socket_get_timeout(Unit *u, usec_t *timeout) {
Socket *s = SOCKET(u);
+ usec_t t;
int r;
if (!s->timer_event_source)
return 0;
- r = sd_event_source_get_time(s->timer_event_source, timeout);
+ r = sd_event_source_get_time(s->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
[SOCKET_FAILURE_EXIT_CODE] = "exit-code",
[SOCKET_FAILURE_SIGNAL] = "signal",
[SOCKET_FAILURE_CORE_DUMP] = "core-dump",
- [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
+ [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
};
DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
SOCKET_FAILURE_EXIT_CODE,
SOCKET_FAILURE_SIGNAL,
SOCKET_FAILURE_CORE_DUMP,
- SOCKET_FAILURE_SERVICE_FAILED_PERMANENT,
+ SOCKET_FAILURE_SERVICE_START_LIMIT_HIT,
_SOCKET_RESULT_MAX,
_SOCKET_RESULT_INVALID = -1
} SocketResult;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
return unit_kill_common(u, who, signo, -1, SWAP(u)->control_pid, error);
}
-static int swap_get_timeout(Unit *u, uint64_t *timeout) {
+static int swap_get_timeout(Unit *u, usec_t *timeout) {
Swap *s = SWAP(u);
+ usec_t t;
int r;
if (!s->timer_event_source)
return 0;
- r = sd_event_source_get_time(s->timer_event_source, timeout);
+ r = sd_event_source_get_time(s->timer_event_source, &t);
if (r < 0)
return r;
+ if (t == USEC_INFINITY)
+ return 0;
+ *timeout = t;
return 1;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUIRES], i) {
r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, false, false, ignore_order, e);
if (r < 0) {
- if (r != -EBADR)
+ if (r != -EBADR) /* job type not applicable */
goto fail;
sd_bus_error_free(e);
SET_FOREACH(dep, ret->unit->dependencies[UNIT_BINDS_TO], i) {
r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, true, false, false, ignore_order, e);
if (r < 0) {
- if (r != -EBADR)
+ if (r != -EBADR) /* job type not applicable */
goto fail;
sd_bus_error_free(e);
SET_FOREACH(dep, ret->unit->dependencies[UNIT_WANTS], i) {
r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, ignore_order, e);
if (r < 0) {
- /* unit masked and unit not found are not considered as errors. */
+ /* unit masked, job type not applicable and unit not found are not considered as errors. */
log_unit_full(dep,
- r == -EBADR || r == -ENOENT ? LOG_DEBUG : LOG_WARNING,
+ IN_SET(r, -ESHUTDOWN, -EBADR, -ENOENT) ? LOG_DEBUG : LOG_WARNING,
r, "Cannot add dependency job, ignoring: %s",
bus_error_message(e, r));
sd_bus_error_free(e);
SET_FOREACH(dep, ret->unit->dependencies[UNIT_REQUISITE], i) {
r = transaction_add_job_and_dependencies(tr, JOB_VERIFY_ACTIVE, dep, ret, true, false, false, ignore_order, e);
if (r < 0) {
- if (r != -EBADR)
+ if (r != -EBADR) /* job type not applicable */
goto fail;
sd_bus_error_free(e);
SET_FOREACH(dep, ret->unit->dependencies[UNIT_CONFLICTS], i) {
r = transaction_add_job_and_dependencies(tr, JOB_STOP, dep, ret, true, true, false, ignore_order, e);
if (r < 0) {
- if (r != -EBADR)
+ if (r != -EBADR) /* job type not applicable */
goto fail;
sd_bus_error_free(e);
r = transaction_add_job_and_dependencies(tr, nt, dep, ret, true, false, false, ignore_order, e);
if (r < 0) {
- if (r != -EBADR)
+ if (r != -EBADR) /* job type not applicable */
goto fail;
sd_bus_error_free(e);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
u->cgroup_inotify_wd = -1;
u->job_timeout = USEC_INFINITY;
+ RATELIMIT_INIT(u->start_limit, m->default_start_limit_interval, m->default_start_limit_burst);
RATELIMIT_INIT(u->auto_stop_ratelimit, 10 * USEC_PER_SEC, 16);
return u;
condition_free_list(u->conditions);
condition_free_list(u->asserts);
+ free(u->reboot_arg);
+
unit_ref_unset(&u->slice);
while (u->refs)
unit_status_print_starting_stopping(u, t);
}
+static int unit_start_limit_test(Unit *u) {
+ assert(u);
+
+ if (ratelimit_test(&u->start_limit)) {
+ u->start_limit_hit = false;
+ return 0;
+ }
+
+ log_unit_warning(u, "Start request repeated too quickly.");
+ u->start_limit_hit = true;
+
+ return failure_action(u->manager, u->start_limit_action, u->reboot_arg);
+}
+
/* Errors:
- * -EBADR: This unit type does not support starting.
- * -EALREADY: Unit is already started.
- * -EAGAIN: An operation is already in progress. Retry later.
- * -ECANCELED: Too many requests for now.
- * -EPROTO: Assert failed
+ * -EBADR: This unit type does not support starting.
+ * -EALREADY: Unit is already started.
+ * -EAGAIN: An operation is already in progress. Retry later.
+ * -ECANCELED: Too many requests for now.
+ * -EPROTO: Assert failed
+ * -EINVAL: Unit not loaded
+ * -EOPNOTSUPP: Unit type not supported
*/
int unit_start(Unit *u) {
UnitActiveState state;
Unit *following;
+ int r;
assert(u);
- /* Units that aren't loaded cannot be started */
- if (u->load_state != UNIT_LOADED)
- return -EINVAL;
-
/* If this is already started, then this will succeed. Note
* that this will even succeed if this unit is not startable
* by the user. This is relied on to detect when we need to
if (UNIT_IS_ACTIVE_OR_RELOADING(state))
return -EALREADY;
+ /* Make sure we don't enter a busy loop of some kind. */
+ r = unit_start_limit_test(u);
+ if (r < 0)
+ return r;
+
+ /* Units that aren't loaded cannot be started */
+ if (u->load_state != UNIT_LOADED)
+ return -EINVAL;
+
/* If the conditions failed, don't do anything at all. If we
* already are activating this call might still be useful to
* speed up activation in case there is some hold-off time,
/* Versions before 228 did not carry a state change timestamp. In this case, take the current time. This is
* useful, so that timeouts based on this timestamp don't trigger too early, and is in-line with the logic from
- * before 228 where the base for timeouts was not peristet across reboots. */
+ * before 228 where the base for timeouts was not persistent across reboots. */
if (!dual_timestamp_is_set(&u->state_change_timestamp))
dual_timestamp_get(&u->state_change_timestamp);
if (UNIT_VTABLE(u)->reset_failed)
UNIT_VTABLE(u)->reset_failed(u);
+
+ RATELIMIT_RESET(u->start_limit);
+ u->start_limit_hit = false;
}
Unit *unit_following(Unit *u) {
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
/* Error code when we didn't manage to load the unit (negative) */
int load_error;
+ /* Put a ratelimit on unit starting */
+ RateLimit start_limit;
+ FailureAction start_limit_action;
+ char *reboot_arg;
+
/* Make sure we never enter endless loops with the check unneeded logic, or the BindsTo= logic */
RateLimit auto_stop_ratelimit;
bool cgroup_members_mask_valid:1;
bool cgroup_subtree_mask_valid:1;
+ bool start_limit_hit:1;
+
/* Did we already invoke unit_coldplug() for this unit? */
bool coldplugged:1;
};
/* Called whenever CLOCK_REALTIME made a jump */
void (*time_change)(Unit *u);
- int (*get_timeout)(Unit *u, uint64_t *timeout);
+ /* Returns the next timeout of a unit */
+ int (*get_timeout)(Unit *u, usec_t *timeout);
/* This is called for each unit type and should be used to
* enumerate existing devices and load them. However,
--- /dev/null
+../Makefile
\ No newline at end of file
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
#include <unistd.h>
#ifdef HAVE_ELFUTILS
-# include <dwarf.h>
-# include <elfutils/libdwfl.h>
+#include <dwarf.h>
+#include <elfutils/libdwfl.h>
#endif
#include "sd-journal.h"
#include "sd-login.h"
+#include "sd-daemon.h"
#include "acl-util.h"
#include "alloc-util.h"
#include "mkdir.h"
#include "parse-util.h"
#include "process-util.h"
+#include "socket-util.h"
#include "special.h"
#include "stacktrace.h"
#include "string-table.h"
/* The maximum size up to which we process coredumps */
#define PROCESS_SIZE_MAX ((uint64_t) (2LLU*1024LLU*1024LLU*1024LLU))
-/* The maximum size up to which we leave the coredump around on
- * disk */
+/* The maximum size up to which we leave the coredump around on disk */
#define EXTERNAL_SIZE_MAX PROCESS_SIZE_MAX
-/* The maximum size up to which we store the coredump in the
- * journal */
+/* The maximum size up to which we store the coredump in the journal */
#define JOURNAL_SIZE_MAX ((size_t) (767LU*1024LU*1024LU))
/* Make sure to not make this larger than the maximum journal entry
assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
enum {
- INFO_PID,
- INFO_UID,
- INFO_GID,
- INFO_SIGNAL,
- INFO_TIMESTAMP,
- INFO_COMM,
- INFO_EXE,
- _INFO_LEN
+ /* We use this as array indexes for a couple of special fields we use for naming coredumping files, and
+ * attaching xattrs */
+ CONTEXT_PID,
+ CONTEXT_UID,
+ CONTEXT_GID,
+ CONTEXT_SIGNAL,
+ CONTEXT_TIMESTAMP,
+ CONTEXT_RLIMIT,
+ CONTEXT_COMM,
+ CONTEXT_EXE,
+ _CONTEXT_MAX
};
typedef enum CoredumpStorage {
return 0;
}
-static int fix_xattr(int fd, const char *info[_INFO_LEN]) {
+static int fix_xattr(int fd, const char *context[_CONTEXT_MAX]) {
- static const char * const xattrs[_INFO_LEN] = {
- [INFO_PID] = "user.coredump.pid",
- [INFO_UID] = "user.coredump.uid",
- [INFO_GID] = "user.coredump.gid",
- [INFO_SIGNAL] = "user.coredump.signal",
- [INFO_TIMESTAMP] = "user.coredump.timestamp",
- [INFO_COMM] = "user.coredump.comm",
- [INFO_EXE] = "user.coredump.exe",
+ static const char * const xattrs[_CONTEXT_MAX] = {
+ [CONTEXT_PID] = "user.coredump.pid",
+ [CONTEXT_UID] = "user.coredump.uid",
+ [CONTEXT_GID] = "user.coredump.gid",
+ [CONTEXT_SIGNAL] = "user.coredump.signal",
+ [CONTEXT_TIMESTAMP] = "user.coredump.timestamp",
+ [CONTEXT_COMM] = "user.coredump.comm",
+ [CONTEXT_EXE] = "user.coredump.exe",
};
int r = 0;
/* Attach some metadata to coredumps via extended
* attributes. Just because we can. */
- for (i = 0; i < _INFO_LEN; i++) {
+ for (i = 0; i < _CONTEXT_MAX; i++) {
int k;
- if (isempty(info[i]) || !xattrs[i])
+ if (isempty(context[i]) || !xattrs[i])
continue;
- k = fsetxattr(fd, xattrs[i], info[i], strlen(info[i]), XATTR_CREATE);
+ k = fsetxattr(fd, xattrs[i], context[i], strlen(context[i]), XATTR_CREATE);
if (k < 0 && r == 0)
r = -errno;
}
int fd,
const char *filename,
const char *target,
- const char *info[_INFO_LEN],
+ const char *context[_CONTEXT_MAX],
uid_t uid) {
assert(fd >= 0);
assert(filename);
assert(target);
- assert(info);
+ assert(context);
/* Ignore errors on these */
- fchmod(fd, 0640);
- fix_acl(fd, uid);
- fix_xattr(fd, info);
+ (void) fchmod(fd, 0640);
+ (void) fix_acl(fd, uid);
+ (void) fix_xattr(fd, context);
if (fsync(fd) < 0)
return log_error_errno(errno, "Failed to sync coredump %s: %m", filename);
return 1;
}
-static int make_filename(const char *info[_INFO_LEN], char **ret) {
+static int make_filename(const char *context[_CONTEXT_MAX], char **ret) {
_cleanup_free_ char *c = NULL, *u = NULL, *p = NULL, *t = NULL;
sd_id128_t boot = {};
int r;
- assert(info);
+ assert(context);
- c = filename_escape(info[INFO_COMM]);
+ c = filename_escape(context[CONTEXT_COMM]);
if (!c)
return -ENOMEM;
- u = filename_escape(info[INFO_UID]);
+ u = filename_escape(context[CONTEXT_UID]);
if (!u)
return -ENOMEM;
if (r < 0)
return r;
- p = filename_escape(info[INFO_PID]);
+ p = filename_escape(context[CONTEXT_PID]);
if (!p)
return -ENOMEM;
- t = filename_escape(info[INFO_TIMESTAMP]);
+ t = filename_escape(context[CONTEXT_TIMESTAMP]);
if (!t)
return -ENOMEM;
}
static int save_external_coredump(
- const char *info[_INFO_LEN],
- uid_t uid,
+ const char *context[_CONTEXT_MAX],
+ int input_fd,
char **ret_filename,
int *ret_node_fd,
int *ret_data_fd,
_cleanup_free_ char *fn = NULL, *tmp = NULL;
_cleanup_close_ int fd = -1;
+ uint64_t rlimit, max_size;
struct stat st;
+ uid_t uid;
int r;
- assert(info);
+ assert(context);
assert(ret_filename);
assert(ret_node_fd);
assert(ret_data_fd);
assert(ret_size);
- r = make_filename(info, &fn);
+ r = parse_uid(context[CONTEXT_UID], &uid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse UID: %m");
+
+ r = safe_atou64(context[CONTEXT_RLIMIT], &rlimit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse resource limit: %s", context[CONTEXT_RLIMIT]);
+ if (rlimit <= 0) {
+ /* Is coredumping disabled? Then don't bother saving/processing the coredump */
+ log_info("Core Dumping has been disabled for process %s (%s).", context[CONTEXT_PID], context[CONTEXT_COMM]);
+ return -EBADSLT;
+ }
+
+ /* Never store more than the process configured, or than we actually shall keep or process */
+ max_size = MIN(rlimit, MAX(arg_process_size_max, arg_external_size_max));
+
+ r = make_filename(context, &fn);
if (r < 0)
return log_error_errno(r, "Failed to determine coredump file name: %m");
if (fd < 0)
return log_error_errno(errno, "Failed to create coredump file %s: %m", tmp);
- r = copy_bytes(STDIN_FILENO, fd, arg_process_size_max, false);
+ r = copy_bytes(input_fd, fd, max_size, false);
if (r == -EFBIG) {
- log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", info[INFO_PID], info[INFO_COMM]);
+ log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", context[CONTEXT_PID], context[CONTEXT_COMM]);
goto fail;
} else if (IN_SET(r, -EDQUOT, -ENOSPC)) {
- log_error("Not enough disk space for coredump of %s (%s), refusing.", info[INFO_PID], info[INFO_COMM]);
+ log_error("Not enough disk space for coredump of %s (%s), refusing.", context[CONTEXT_PID], context[CONTEXT_COMM]);
goto fail;
} else if (r < 0) {
log_error_errno(r, "Failed to dump coredump to file: %m");
goto fail_compressed;
}
- r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, info, uid);
+ r = fix_permissions(fd_compressed, tmp_compressed, fn_compressed, context, uid);
if (r < 0)
goto fail_compressed;
return 0;
fail_compressed:
- unlink_noerrno(tmp_compressed);
+ (void) unlink(tmp_compressed);
}
uncompressed:
#endif
- r = fix_permissions(fd, tmp, fn, info, uid);
+ r = fix_permissions(fd, tmp, fn, context, uid);
if (r < 0)
goto fail;
return 0;
fail:
- unlink_noerrno(tmp);
+ (void) unlink(tmp);
return r;
}
return 0;
}
-int main(int argc, char* argv[]) {
+static int change_uid_gid(const char *context[]) {
+ uid_t uid;
+ gid_t gid;
+ int r;
- /* The small core field we allocate on the stack, to keep things simple */
- char
- *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
- *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL,
- *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL,
- *core_slice = NULL;
+ r = parse_uid(context[CONTEXT_UID], &uid);
+ if (r < 0)
+ return r;
- /* The larger ones we allocate on the heap */
- _cleanup_free_ char
- *core_timestamp = NULL, *core_message = NULL, *coredump_data = NULL, *core_owner_uid = NULL,
- *core_open_fds = NULL, *core_proc_status = NULL, *core_proc_maps = NULL, *core_proc_limits = NULL,
- *core_proc_cgroup = NULL, *core_environ = NULL;
+ if (uid <= SYSTEM_UID_MAX) {
+ const char *user = "systemd-coredump";
- _cleanup_free_ char *exe = NULL, *comm = NULL, *filename = NULL;
- const char *info[_INFO_LEN];
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ if (r < 0) {
+ log_warning_errno(r, "Cannot resolve %s user. Proceeding to dump core as root: %m", user);
+ uid = gid = 0;
+ }
+ } else {
+ r = parse_gid(context[CONTEXT_GID], &gid);
+ if (r < 0)
+ return r;
+ }
- _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
+ return drop_privileges(uid, gid, 0);
+}
- struct iovec iovec[26];
+static int submit_coredump(
+ const char *context[_CONTEXT_MAX],
+ struct iovec *iovec,
+ size_t n_iovec_allocated,
+ size_t n_iovec,
+ int input_fd) {
+
+ _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
+ _cleanup_free_ char *core_message = NULL, *filename = NULL, *coredump_data = NULL;
uint64_t coredump_size;
- int r, j = 0;
- uid_t uid, owner_uid;
- gid_t gid;
- pid_t pid;
- char *t;
- const char *p;
+ int r;
- /* Make sure we never enter a loop */
- prctl(PR_SET_DUMPABLE, 0);
+ assert(context);
+ assert(iovec);
+ assert(n_iovec_allocated >= n_iovec + 3);
+ assert(input_fd >= 0);
- /* First, log to a safe place, since we don't know what
- * crashed and it might be journald which we'd rather not log
- * to then. */
- log_set_target(LOG_TARGET_KMSG);
- log_open();
+ /* Vacuum before we write anything again */
+ (void) coredump_vacuum(-1, arg_keep_free, arg_max_use);
- if (argc < INFO_COMM + 1) {
- log_error("Not enough arguments passed from kernel (%d, expected %d).",
- argc - 1, INFO_COMM + 1 - 1);
- r = -EINVAL;
- goto finish;
+ /* Always stream the coredump to disk, if that's possible */
+ r = save_external_coredump(context, input_fd, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
+ if (r < 0)
+ /* Skip whole core dumping part */
+ goto log;
+
+ /* If we don't want to keep the coredump on disk, remove it now, as later on we will lack the privileges for
+ * it. However, we keep the fd to it, so that we can still process it and log it. */
+ r = maybe_remove_external_coredump(filename, coredump_size);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ const char *coredump_filename;
+
+ coredump_filename = strjoina("COREDUMP_FILENAME=", filename);
+ IOVEC_SET_STRING(iovec[n_iovec++], coredump_filename);
}
- /* Ignore all parse errors */
- parse_config();
+ /* Vacuum again, but exclude the coredump we just created */
+ (void) coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
- log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage));
- log_debug("Selected compression %s.", yes_no(arg_compress));
+ /* Now, let's drop privileges to become the user who owns the segfaulted process and allocate the coredump
+ * memory under the user's uid. This also ensures that the credentials journald will see are the ones of the
+ * coredumping user, thus making sure the user gets access to the core dump. Let's also get rid of all
+ * capabilities, if we run as root, we won't need them anymore. */
+ r = change_uid_gid(context);
+ if (r < 0)
+ return log_error_errno(r, "Failed to drop privileges: %m");
- r = parse_uid(argv[INFO_UID + 1], &uid);
- if (r < 0) {
- log_error("Failed to parse UID.");
- goto finish;
+#ifdef HAVE_ELFUTILS
+ /* Try to get a strack trace if we can */
+ if (coredump_size <= arg_process_size_max) {
+ _cleanup_free_ char *stacktrace = NULL;
+
+ r = coredump_make_stack_trace(coredump_fd, context[CONTEXT_EXE], &stacktrace);
+ if (r >= 0)
+ core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], " (", context[CONTEXT_COMM], ") of user ", context[CONTEXT_UID], " dumped core.\n\n", stacktrace, NULL);
+ else if (r == -EINVAL)
+ log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
+ else
+ log_warning_errno(r, "Failed to generate stack trace: %m");
}
- r = parse_pid(argv[INFO_PID + 1], &pid);
- if (r < 0) {
- log_error("Failed to parse PID.");
- goto finish;
+ if (!core_message)
+#endif
+log:
+ core_message = strjoin("MESSAGE=Process ", context[CONTEXT_PID], " (", context[CONTEXT_COMM], ") of user ", context[CONTEXT_UID], " dumped core.", NULL);
+ if (core_message)
+ IOVEC_SET_STRING(iovec[n_iovec++], core_message);
+
+ /* Optionally store the entire coredump in the journal */
+ if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
+ coredump_size <= arg_journal_size_max) {
+ size_t sz = 0;
+
+ /* Store the coredump itself in the journal */
+
+ r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
+ if (r >= 0) {
+ iovec[n_iovec].iov_base = coredump_data;
+ iovec[n_iovec].iov_len = sz;
+ n_iovec++;
+ }
}
- r = parse_gid(argv[INFO_GID + 1], &gid);
- if (r < 0) {
- log_error("Failed to parse GID.");
+ assert(n_iovec <= n_iovec_allocated);
+
+ r = sd_journal_sendv(iovec, n_iovec);
+ if (r < 0)
+ return log_error_errno(r, "Failed to log coredump: %m");
+
+ return 0;
+}
+
+static void map_context_fields(const struct iovec *iovec, const char *context[]) {
+
+ static const char * const context_field_names[_CONTEXT_MAX] = {
+ [CONTEXT_PID] = "COREDUMP_PID=",
+ [CONTEXT_UID] = "COREDUMP_UID=",
+ [CONTEXT_GID] = "COREDUMP_GID=",
+ [CONTEXT_SIGNAL] = "COREDUMP_SIGNAL=",
+ [CONTEXT_TIMESTAMP] = "COREDUMP_TIMESTAMP=",
+ [CONTEXT_COMM] = "COREDUMP_COMM=",
+ [CONTEXT_EXE] = "COREDUMP_EXE=",
+ [CONTEXT_RLIMIT] = "COREDUMP_RLIMIT=",
+ };
+
+ unsigned i;
+
+ assert(iovec);
+ assert(context);
+
+ for (i = 0; i < _CONTEXT_MAX; i++) {
+ size_t l;
+
+ l = strlen(context_field_names[i]);
+ if (iovec->iov_len < l)
+ continue;
+
+ if (memcmp(iovec->iov_base, context_field_names[i], l) != 0)
+ continue;
+
+ /* Note that these strings are NUL terminated, because we made sure that a trailing NUL byte is in the
+ * buffer, though not included in the iov_len count. (see below) */
+ context[i] = (char*) iovec->iov_base + l;
+ break;
+ }
+}
+
+static int process_socket(int fd) {
+ _cleanup_close_ int coredump_fd = -1;
+ struct iovec *iovec = NULL;
+ size_t n_iovec = 0, n_iovec_allocated = 0, i;
+ const char *context[_CONTEXT_MAX] = {};
+ int r;
+
+ assert(fd >= 0);
+
+ log_set_target(LOG_TARGET_AUTO);
+ log_parse_environment();
+ log_open();
+
+ for (;;) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+ struct msghdr mh = {
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ .msg_iovlen = 1,
+ };
+ ssize_t n;
+ int l;
+
+ if (!GREEDY_REALLOC(iovec, n_iovec_allocated, n_iovec + 3)) {
+ r = log_oom();
+ goto finish;
+ }
+
+ if (ioctl(fd, FIONREAD, &l) < 0) {
+ r = log_error_errno(errno, "FIONREAD failed: %m");
+ goto finish;
+ }
+
+ assert(l >= 0);
+
+ iovec[n_iovec].iov_len = l;
+ iovec[n_iovec].iov_base = malloc(l + 1);
+
+ if (!iovec[n_iovec].iov_base) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mh.msg_iov = iovec + n_iovec;
+
+ n = recvmsg(fd, &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC);
+ if (n < 0) {
+ free(iovec[n_iovec].iov_base);
+ r = log_error_errno(errno, "Failed to receive datagram: %m");
+ goto finish;
+ }
+
+ if (n == 0) {
+ struct cmsghdr *cmsg, *found = NULL;
+ /* The final zero-length datagram carries the file descriptor and tells us that we're done. */
+
+ free(iovec[n_iovec].iov_base);
+
+ CMSG_FOREACH(cmsg, &mh) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ assert(!found);
+ found = cmsg;
+ }
+ }
+
+ if (!found) {
+ log_error("Coredump file descriptor missing.");
+ r = -EBADMSG;
+ goto finish;
+ }
+
+ assert(coredump_fd < 0);
+ coredump_fd = *(int*) CMSG_DATA(found);
+ break;
+ }
+
+ /* Add trailing NUL byte, in case these are strings */
+ ((char*) iovec[n_iovec].iov_base)[n] = 0;
+ iovec[n_iovec].iov_len = (size_t) n;
+
+ cmsg_close_all(&mh);
+ map_context_fields(iovec + n_iovec, context);
+ n_iovec++;
+ }
+
+ if (!GREEDY_REALLOC(iovec, n_iovec_allocated, n_iovec + 3)) {
+ r = log_oom();
goto finish;
}
- if (get_process_comm(pid, &comm) < 0) {
- log_warning("Failed to get COMM, falling back to the command line.");
- comm = strv_join(argv + INFO_COMM + 1, " ");
+ /* Make sure we we got all data we really need */
+ assert(context[CONTEXT_PID]);
+ assert(context[CONTEXT_UID]);
+ assert(context[CONTEXT_GID]);
+ assert(context[CONTEXT_SIGNAL]);
+ assert(context[CONTEXT_TIMESTAMP]);
+ assert(context[CONTEXT_RLIMIT]);
+ assert(context[CONTEXT_COMM]);
+ assert(coredump_fd >= 0);
+
+ r = submit_coredump(context, iovec, n_iovec_allocated, n_iovec, coredump_fd);
+
+finish:
+ for (i = 0; i < n_iovec; i++)
+ free(iovec[i].iov_base);
+ free(iovec);
+
+ return r;
+}
+
+static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd) {
+
+ static const union sockaddr_union sa = {
+ .un.sun_family = AF_UNIX,
+ .un.sun_path = "/run/systemd/coredump",
+ };
+ _cleanup_close_ int fd = -1;
+ size_t i;
+ int r;
+
+ assert(iovec || n_iovec <= 0);
+ assert(input_fd >= 0);
+
+ fd = socket(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ return log_error_errno(errno, "Failed to create coredump socket: %m");
+
+ if (connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)) < 0)
+ return log_error_errno(errno, "Failed to connect to coredump service: %m");
+
+ for (i = 0; i < n_iovec; i++) {
+ ssize_t n;
+ assert(iovec[i].iov_len > 0);
+
+ n = send(fd, iovec[i].iov_base, iovec[i].iov_len, MSG_NOSIGNAL);
+ if (n < 0)
+ return log_error_errno(errno, "Failed to send coredump datagram: %m");
}
- if (get_process_exe(pid, &exe) < 0)
- log_warning("Failed to get EXE.");
+ r = send_one_fd(fd, input_fd, 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to send coredump fd: %m");
- info[INFO_PID] = argv[INFO_PID + 1];
- info[INFO_UID] = argv[INFO_UID + 1];
- info[INFO_GID] = argv[INFO_GID + 1];
- info[INFO_SIGNAL] = argv[INFO_SIGNAL + 1];
- info[INFO_TIMESTAMP] = argv[INFO_TIMESTAMP + 1];
- info[INFO_COMM] = comm;
- info[INFO_EXE] = exe;
+ return 0;
+}
- if (cg_pid_get_unit(pid, &t) >= 0) {
+static int process_journald_crash(const char *context[], int input_fd) {
+ _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
+ _cleanup_free_ char *filename = NULL;
+ uint64_t coredump_size;
+ int r;
- if (streq(t, SPECIAL_JOURNALD_SERVICE)) {
- free(t);
+ assert(context);
+ assert(input_fd >= 0);
- /* If we are journald, we cut things short,
- * don't write to the journal, but still
- * create a coredump. */
+ /* If we are journald, we cut things short, don't write to the journal, but still create a coredump. */
- if (arg_storage != COREDUMP_STORAGE_NONE)
- arg_storage = COREDUMP_STORAGE_EXTERNAL;
+ if (arg_storage != COREDUMP_STORAGE_NONE)
+ arg_storage = COREDUMP_STORAGE_EXTERNAL;
- r = save_external_coredump(info, uid, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
- if (r < 0)
- goto finish;
+ r = save_external_coredump(context, input_fd, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
+ if (r < 0)
+ return r;
- r = maybe_remove_external_coredump(filename, coredump_size);
- if (r < 0)
- goto finish;
+ r = maybe_remove_external_coredump(filename, coredump_size);
+ if (r < 0)
+ return r;
- log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename);
- goto finish;
+ log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename);
+ return 0;
+}
+
+static int process_kernel(int argc, char* argv[]) {
+
+ /* The small core field we allocate on the stack, to keep things simple */
+ char
+ *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL,
+ *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL,
+ *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL,
+ *core_user_unit = NULL, *core_slice = NULL, *core_timestamp = NULL, *core_rlimit = NULL;
+
+ /* The larger ones we allocate on the heap */
+ _cleanup_free_ char
+ *core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL,
+ *core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL;
+
+ _cleanup_free_ char *exe = NULL, *comm = NULL;
+ const char *context[_CONTEXT_MAX];
+ struct iovec iovec[25];
+ size_t n_iovec = 0;
+ uid_t owner_uid;
+ const char *p;
+ pid_t pid;
+ char *t;
+ int r;
+
+ if (argc < CONTEXT_COMM + 1) {
+ log_error("Not enough arguments passed from kernel (%i, expected %i).", argc - 1, CONTEXT_COMM + 1 - 1);
+ return -EINVAL;
+ }
+
+ r = parse_pid(argv[CONTEXT_PID + 1], &pid);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse PID.");
+
+ r = get_process_comm(pid, &comm);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get COMM, falling back to the command line: %m");
+ comm = strv_join(argv + CONTEXT_COMM + 1, " ");
+ if (!comm)
+ return log_oom();
+ }
+
+ r = get_process_exe(pid, &exe);
+ if (r < 0)
+ log_warning_errno(r, "Failed to get EXE, ignoring: %m");
+
+ context[CONTEXT_PID] = argv[CONTEXT_PID + 1];
+ context[CONTEXT_UID] = argv[CONTEXT_UID + 1];
+ context[CONTEXT_GID] = argv[CONTEXT_GID + 1];
+ context[CONTEXT_SIGNAL] = argv[CONTEXT_SIGNAL + 1];
+ context[CONTEXT_TIMESTAMP] = argv[CONTEXT_TIMESTAMP + 1];
+ context[CONTEXT_RLIMIT] = argv[CONTEXT_RLIMIT + 1];
+ context[CONTEXT_COMM] = comm;
+ context[CONTEXT_EXE] = exe;
+
+ if (cg_pid_get_unit(pid, &t) >= 0) {
+
+ if (streq(t, SPECIAL_JOURNALD_SERVICE)) {
+ free(t);
+ return process_journald_crash(context, STDIN_FILENO);
}
core_unit = strjoina("COREDUMP_UNIT=", t);
free(t);
- } else if (cg_pid_get_user_unit(pid, &t) >= 0) {
- core_unit = strjoina("COREDUMP_USER_UNIT=", t);
- free(t);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_unit);
}
- if (core_unit)
- IOVEC_SET_STRING(iovec[j++], core_unit);
-
- /* OK, now we know it's not the journal, hence we can make use
- * of it now. */
+ /* OK, now we know it's not the journal, hence we can make use of it now. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
log_open();
- core_pid = strjoina("COREDUMP_PID=", info[INFO_PID]);
- IOVEC_SET_STRING(iovec[j++], core_pid);
+ if (cg_pid_get_user_unit(pid, &t) >= 0) {
+ core_user_unit = strjoina("COREDUMP_USER_UNIT=", t);
+ free(t);
+
+ IOVEC_SET_STRING(iovec[n_iovec++], core_user_unit);
+ }
+
+ core_pid = strjoina("COREDUMP_PID=", context[CONTEXT_PID]);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_pid);
+
+ core_uid = strjoina("COREDUMP_UID=", context[CONTEXT_UID]);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_uid);
- core_uid = strjoina("COREDUMP_UID=", info[INFO_UID]);
- IOVEC_SET_STRING(iovec[j++], core_uid);
+ core_gid = strjoina("COREDUMP_GID=", context[CONTEXT_GID]);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_gid);
- core_gid = strjoina("COREDUMP_GID=", info[INFO_GID]);
- IOVEC_SET_STRING(iovec[j++], core_gid);
+ core_signal = strjoina("COREDUMP_SIGNAL=", context[CONTEXT_SIGNAL]);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_signal);
- core_signal = strjoina("COREDUMP_SIGNAL=", info[INFO_SIGNAL]);
- IOVEC_SET_STRING(iovec[j++], core_signal);
+ core_rlimit = strjoina("COREDUMP_RLIMIT=", context[CONTEXT_RLIMIT]);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_rlimit);
if (sd_pid_get_session(pid, &t) >= 0) {
core_session = strjoina("COREDUMP_SESSION=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_session);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_session);
}
if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
- r = asprintf(&core_owner_uid,
- "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
+ r = asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
if (r > 0)
- IOVEC_SET_STRING(iovec[j++], core_owner_uid);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_owner_uid);
}
if (sd_pid_get_slice(pid, &t) >= 0) {
core_slice = strjoina("COREDUMP_SLICE=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_slice);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_slice);
}
if (comm) {
core_comm = strjoina("COREDUMP_COMM=", comm);
- IOVEC_SET_STRING(iovec[j++], core_comm);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_comm);
}
if (exe) {
core_exe = strjoina("COREDUMP_EXE=", exe);
- IOVEC_SET_STRING(iovec[j++], core_exe);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_exe);
}
if (get_process_cmdline(pid, 0, false, &t) >= 0) {
core_cmdline = strjoina("COREDUMP_CMDLINE=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_cmdline);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_cmdline);
}
if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) {
core_cgroup = strjoina("COREDUMP_CGROUP=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_cgroup);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_cgroup);
}
if (compose_open_fds(pid, &t) >= 0) {
free(t);
if (core_open_fds)
- IOVEC_SET_STRING(iovec[j++], core_open_fds);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_open_fds);
}
p = procfs_file_alloca(pid, "status");
free(t);
if (core_proc_status)
- IOVEC_SET_STRING(iovec[j++], core_proc_status);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_proc_status);
}
p = procfs_file_alloca(pid, "maps");
free(t);
if (core_proc_maps)
- IOVEC_SET_STRING(iovec[j++], core_proc_maps);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_proc_maps);
}
p = procfs_file_alloca(pid, "limits");
free(t);
if (core_proc_limits)
- IOVEC_SET_STRING(iovec[j++], core_proc_limits);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_proc_limits);
}
p = procfs_file_alloca(pid, "cgroup");
free(t);
if (core_proc_cgroup)
- IOVEC_SET_STRING(iovec[j++], core_proc_cgroup);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_proc_cgroup);
}
if (get_process_cwd(pid, &t) >= 0) {
core_cwd = strjoina("COREDUMP_CWD=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_cwd);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_cwd);
}
if (get_process_root(pid, &t) >= 0) {
core_root = strjoina("COREDUMP_ROOT=", t);
free(t);
- IOVEC_SET_STRING(iovec[j++], core_root);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_root);
}
if (get_process_environ(pid, &t) >= 0) {
free(t);
if (core_environ)
- IOVEC_SET_STRING(iovec[j++], core_environ);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_environ);
}
- core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL);
- if (core_timestamp)
- IOVEC_SET_STRING(iovec[j++], core_timestamp);
+ core_timestamp = strjoina("COREDUMP_TIMESTAMP=", context[CONTEXT_TIMESTAMP], "000000", NULL);
+ IOVEC_SET_STRING(iovec[n_iovec++], core_timestamp);
- IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
+ IOVEC_SET_STRING(iovec[n_iovec++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
assert_cc(2 == LOG_CRIT);
- IOVEC_SET_STRING(iovec[j++], "PRIORITY=2");
-
- /* Vacuum before we write anything again */
- coredump_vacuum(-1, arg_keep_free, arg_max_use);
-
- /* Always stream the coredump to disk, if that's possible */
- r = save_external_coredump(info, uid, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
- if (r < 0)
- /* skip whole core dumping part */
- goto log;
+ IOVEC_SET_STRING(iovec[n_iovec++], "PRIORITY=2");
- /* If we don't want to keep the coredump on disk, remove it
- * now, as later on we will lack the privileges for
- * it. However, we keep the fd to it, so that we can still
- * process it and log it. */
- r = maybe_remove_external_coredump(filename, coredump_size);
- if (r < 0)
- goto finish;
- if (r == 0) {
- const char *coredump_filename;
+ assert(n_iovec <= ELEMENTSOF(iovec));
- coredump_filename = strjoina("COREDUMP_FILENAME=", filename);
- IOVEC_SET_STRING(iovec[j++], coredump_filename);
- }
+ return send_iovec(iovec, n_iovec, STDIN_FILENO);
+}
- /* Vacuum again, but exclude the coredump we just created */
- coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
-
- /* Now, let's drop privileges to become the user who owns the
- * segfaulted process and allocate the coredump memory under
- * the user's uid. This also ensures that the credentials
- * journald will see are the ones of the coredumping user,
- * thus making sure the user gets access to the core
- * dump. Let's also get rid of all capabilities, if we run as
- * root, we won't need them anymore. */
- r = drop_privileges(uid, gid, 0);
- if (r < 0) {
- log_error_errno(r, "Failed to drop privileges: %m");
- goto finish;
- }
+int main(int argc, char *argv[]) {
+ int r;
-#ifdef HAVE_ELFUTILS
- /* Try to get a strack trace if we can */
- if (coredump_size <= arg_process_size_max) {
- _cleanup_free_ char *stacktrace = NULL;
+ /* First, log to a safe place, since we don't know what crashed and it might be journald which we'd rather not
+ * log to then. */
- r = coredump_make_stack_trace(coredump_fd, exe, &stacktrace);
- if (r >= 0)
- core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.\n\n", stacktrace, NULL);
- else if (r == -EINVAL)
- log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
- else
- log_warning_errno(r, "Failed to generate stack trace: %m");
- }
+ log_set_target(LOG_TARGET_KMSG);
+ log_open();
- if (!core_message)
-#endif
-log:
- core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.", NULL);
- if (core_message)
- IOVEC_SET_STRING(iovec[j++], core_message);
+ /* Make sure we never enter a loop */
+ (void) prctl(PR_SET_DUMPABLE, 0);
- /* Optionally store the entire coredump in the journal */
- if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
- coredump_size <= arg_journal_size_max) {
- size_t sz = 0;
+ /* Ignore all parse errors */
+ (void) parse_config();
- /* Store the coredump itself in the journal */
+ log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage));
+ log_debug("Selected compression %s.", yes_no(arg_compress));
- r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
- if (r >= 0) {
- iovec[j].iov_base = coredump_data;
- iovec[j].iov_len = sz;
- j++;
- }
+ r = sd_listen_fds(false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to determine number of file descriptor: %m");
+ goto finish;
}
- r = sd_journal_sendv(iovec, j);
- if (r < 0)
- log_error_errno(r, "Failed to log coredump: %m");
+ /* If we got an fd passed, we are running in coredumpd mode. Otherwise we are invoked from the kernel as
+ * coredump handler */
+ if (r == 0)
+ r = process_kernel(argc, argv);
+ else if (r == 1)
+ r = process_socket(SD_LISTEN_FDS_START);
+ else {
+ log_error("Received unexpected number of file descriptors.");
+ r = -EINVAL;
+ }
finish:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);
(void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
- if (!streq(fstype, "vfat")) {
+ if (!streq_ptr(fstype, "vfat")) {
log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
return 0;
}
+ errno = 0;
r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
if (r != 0) {
- log_debug_errno(r, "Partition for /boot does not have a UUID, ignoring. %m");
+ log_debug_errno(errno, "Partition for /boot does not have a UUID, ignoring.");
return 0;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
{ MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free},
{ MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger},
{ MHD_OPTION_LISTEN_SOCKET, fd},
- { MHD_OPTION_CONNECTION_MEMORY_LIMIT, DATA_SIZE_MAX},
+ { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
{ MHD_OPTION_END},
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
.compare = catalog_compare_func
};
+static bool next_header(const char **s) {
+ const char *e;
+
+ e = strchr(*s, '\n');
+
+ /* Unexpected end */
+ if (!e)
+ return false;
+
+ /* End of headers */
+ if (e == *s)
+ return false;
+
+ *s = e + 1;
+ return true;
+}
+
+static const char *skip_header(const char *s) {
+ while (next_header(&s))
+ ;
+ return s;
+}
+
+static char *combine_entries(const char *one, const char *two) {
+ const char *b1, *b2;
+ size_t l1, l2, n;
+ char *dest, *p;
+
+ /* Find split point of headers to body */
+ b1 = skip_header(one);
+ b2 = skip_header(two);
+
+ l1 = strlen(one);
+ l2 = strlen(two);
+ dest = new(char, l1 + l2 + 1);
+ if (!dest) {
+ log_oom();
+ return NULL;
+ }
+
+ p = dest;
+
+ /* Headers from @one */
+ n = b1 - one;
+ p = mempcpy(p, one, n);
+
+ /* Headers from @two, these will only be found if not present above */
+ n = b2 - two;
+ p = mempcpy(p, two, n);
+
+ /* Body from @one */
+ n = l1 - (b1 - one);
+ if (n > 0) {
+ memcpy(p, b1, n);
+ p += n;
+
+ /* Body from @two */
+ } else {
+ n = l2 - (b2 - two);
+ memcpy(p, b2, n);
+ p += n;
+ }
+
+ assert(p - dest <= (ptrdiff_t)(l1 + l2));
+ p[0] = '\0';
+ return dest;
+}
+
static int finish_item(
Hashmap *h,
- struct strbuf *sb,
sd_id128_t id,
const char *language,
- const char *payload) {
+ char *payload) {
- ssize_t offset;
_cleanup_free_ CatalogItem *i = NULL;
+ _cleanup_free_ char *combined = NULL, *prev = NULL;
int r;
assert(h);
- assert(sb);
assert(payload);
- offset = strbuf_add_string(sb, payload, strlen(payload));
- if (offset < 0)
- return log_oom();
-
i = new0(CatalogItem, 1);
if (!i)
return log_oom();
assert(strlen(language) > 1 && strlen(language) < 32);
strcpy(i->language, language);
}
- i->offset = htole64((uint64_t) offset);
- r = hashmap_put(h, i, i);
- if (r == -EEXIST) {
- log_warning("Duplicate entry for " SD_ID128_FORMAT_STR ".%s, ignoring.",
- SD_ID128_FORMAT_VAL(id), language ? language : "C");
- return 0;
- } else if (r < 0)
- return r;
+ prev = hashmap_get(h, i);
+
+ /* Already have such an item, combine them */
+ if (prev) {
+ combined = combine_entries(payload, prev);
+ if (!combined)
+ return log_oom();
+ r = hashmap_update(h, i, combined);
+ if (r < 0)
+ return r;
+ combined = NULL;
+
+ /* A new item */
+ } else {
+ r = hashmap_put(h, i, payload);
+ if (r < 0)
+ return r;
+ i = NULL;
+ }
- i = NULL;
return 0;
}
return 0;
}
-int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path) {
+int catalog_import_file(Hashmap *h, const char *path) {
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *payload = NULL;
unsigned n = 0;
int r;
assert(h);
- assert(sb);
assert(path);
f = fopen(path, "re");
if (sd_id128_from_string(line + 2 + 1, &jd) >= 0) {
if (got_id) {
- r = finish_item(h, sb, id, lang ?: deflang, payload);
+ r = finish_item(h, id, lang ?: deflang, payload);
if (r < 0)
return r;
+ payload = NULL;
lang = mfree(lang);
}
}
if (got_id) {
- r = finish_item(h, sb, id, lang ?: deflang, payload);
+ r = finish_item(h, id, lang ?: deflang, payload);
if (r < 0)
return r;
+ payload = NULL;
}
return 0;
_cleanup_strv_free_ char **files = NULL;
char **f;
struct strbuf *sb = NULL;
- _cleanup_hashmap_free_free_ Hashmap *h = NULL;
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
_cleanup_free_ CatalogItem *items = NULL;
+ ssize_t offset;
+ char *payload;
CatalogItem *i;
Iterator j;
unsigned n;
STRV_FOREACH(f, files) {
log_debug("Reading file '%s'", *f);
- r = catalog_import_file(h, sb, *f);
+ r = catalog_import_file(h, *f);
if (r < 0) {
log_error_errno(r, "Failed to import file '%s': %m", *f);
goto finish;
} else
log_debug("Found %u items in catalog.", hashmap_size(h));
- strbuf_complete(sb);
-
items = new(CatalogItem, hashmap_size(h));
if (!items) {
r = log_oom();
}
n = 0;
- HASHMAP_FOREACH(i, h, j) {
+ HASHMAP_FOREACH_KEY(payload, i, h, j) {
log_debug("Found " SD_ID128_FORMAT_STR ", language %s",
SD_ID128_FORMAT_VAL(i->id),
isempty(i->language) ? "C" : i->language);
+
+ offset = strbuf_add_string(sb, payload, strlen(payload));
+ if (offset < 0) {
+ r = log_oom();
+ goto finish;
+ }
+ i->offset = htole64((uint64_t) offset);
items[n++] = *i;
}
assert(n == hashmap_size(h));
qsort_safe(items, n, sizeof(CatalogItem), catalog_compare_func);
+ strbuf_complete(sb);
+
sz = write_catalog(database, sb, items, n);
if (sz < 0)
r = log_error_errno(sz, "Failed to write %s: %m", database);
static char *find_header(const char *s, const char *header) {
for (;;) {
- const char *v, *e;
+ const char *v;
v = startswith(s, header);
if (v) {
return strndup(v, strcspn(v, NEWLINE));
}
- /* End of text */
- e = strchr(s, '\n');
- if (!e)
+ if (!next_header(&s))
return NULL;
-
- /* End of header */
- if (e == s)
- return NULL;
-
- s = e + 1;
}
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
#include "hashmap.h"
#include "strbuf.h"
-int catalog_import_file(Hashmap *h, struct strbuf *sb, const char *path);
+int catalog_import_file(Hashmap *h, const char *path);
int catalog_update(const char* database, const char* root, const char* const* dirs);
int catalog_get(const char* database, sd_id128_t id, char **data);
int catalog_list(FILE *f, const char* database, bool oneline);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* fsprg v0.1 - (seekable) forward-secure pseudorandom generator
* Copyright (C) 2012 B. Poettering
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef __fsprgh__
#define __fsprgh__
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
if (mmap_cache_got_sigbus(f->mmap, f->fd))
return -EIO;
- switch(f->header->state) {
+ switch (f->header->state) {
case STATE_ONLINE:
return 0;
int r;
assert(f);
+ assert(f->header);
r = sd_id128_get_machine(&f->header->machine_id);
if (r < 0)
uint32_t flags;
assert(f);
+ assert(f->header);
if (memcmp(f->header->signature, HEADER_SIGNATURE, 8))
return -EBADMSG;
int r;
assert(f);
+ assert(f->header);
/* We assume that this file is not sparse, and we know that
* for sure, since we always call posix_fallocate()
uint64_t r;
assert(f);
+ assert(f->header);
r = le64toh(f->header->tail_entry_seqnum) + 1;
void *t;
assert(f);
+ assert(f->header);
assert(type > OBJECT_UNUSED && type < _OBJECT_TYPE_MAX);
assert(size >= sizeof(ObjectHeader));
assert(offset);
int r;
assert(f);
+ assert(f->header);
/* We estimate that we need 1 hash table entry per 768 bytes
of journal file and we want to make sure we never get
int r;
assert(f);
+ assert(f->header);
/* We use a fixed size hash table for the fields as this
* number should grow very slowly only */
int r;
assert(f);
+ assert(f->header);
if (f->data_hash_table)
return 0;
int r;
assert(f);
+ assert(f->header);
if (f->field_hash_table)
return 0;
int r;
assert(f);
+ assert(f->header);
+ assert(f->field_hash_table);
assert(o);
assert(offset > 0);
int r;
assert(f);
+ assert(f->header);
+ assert(f->data_hash_table);
assert(o);
assert(offset > 0);
int r;
assert(f);
+ assert(f->header);
assert(field && size > 0);
/* If the field hash table is empty, we can't find anything */
int r;
assert(f);
+ assert(f->header);
assert(data || size == 0);
/* If there's no data hash table, then there's no entry. */
Object *o;
assert(f);
+ assert(f->header);
assert(first);
assert(idx);
assert(p > 0);
int r;
assert(f);
+ assert(f->header);
assert(o);
assert(offset > 0);
int r;
assert(f);
+ assert(f->header);
assert(items || n_items == 0);
assert(ts);
struct dual_timestamp _ts;
assert(f);
+ assert(f->header);
assert(iovec || n_iovec == 0);
if (!ts) {
ts = &_ts;
}
- if (f->tail_entry_monotonic_valid &&
- ts->monotonic < le64toh(f->header->tail_entry_monotonic))
- return -EINVAL;
-
#ifdef HAVE_GCRYPT
r = journal_file_maybe_append_tag(f, ts->realtime);
if (r < 0)
direction_t direction,
Object **ret,
uint64_t *offset) {
+ assert(f);
+ assert(f->header);
return generic_array_bisect(f,
le64toh(f->header->entry_array_offset),
direction_t direction,
Object **ret,
uint64_t *offset) {
+ assert(f);
+ assert(f->header);
return generic_array_bisect(f,
le64toh(f->header->entry_array_offset),
int journal_file_compare_locations(JournalFile *af, JournalFile *bf) {
assert(af);
+ assert(af->header);
assert(bf);
+ assert(bf->header);
assert(af->location_type == LOCATION_SEEK);
assert(bf->location_type == LOCATION_SEEK);
int r;
assert(f);
+ assert(f->header);
n = le64toh(f->header->n_entries);
if (n <= 0)
uint64_t p;
assert(f);
+ assert(f->header);
journal_file_print_header(f);
char bytes[FORMAT_BYTES_MAX];
assert(f);
+ assert(f->header);
printf("File Path: %s\n"
"File ID: %s\n"
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
assert(f);
+ assert(f->header);
assert(from || to);
if (from) {
bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec) {
assert(f);
+ assert(f->header);
/* If we gained new header fields we gained new features,
* hence suggest a rotation */
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
int flags,
bool seal,
JournalMetrics *metrics,
- JournalFile *template,
JournalFile **ret) {
int r;
JournalFile *f;
assert(ret);
if (reliably)
- r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
else
- r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
if (r < 0)
return r;
journal_file_close(f);
}
- r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &f);
+ r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
if (r < 0)
return s->system_journal;
(void) mkdir(fn, 0755);
fn = strjoina(fn, "/system.journal");
- r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &s->system_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &s->system_journal);
if (r >= 0) {
server_add_acls(s->system_journal, 0);
(void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
* if it already exists, so that we can flush
* it into the system journal */
- r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, &s->runtime_journal);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to open runtime journal: %m");
(void) mkdir("/run/log/journal", 0755);
(void) mkdir_parents(fn, 0750);
- r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, &s->runtime_journal);
if (r < 0)
return log_error_errno(r, "Failed to open runtime journal: %m");
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
#include <inttypes.h>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
struct Window {
MMapCache *cache;
- bool invalidated;
- bool keep_always;
- bool in_unused;
+ bool invalidated:1;
+ bool keep_always:1;
+ bool in_unused:1;
int prot;
void *ptr;
unsigned n_hit, n_missed;
-
Hashmap *fds;
Context *contexts[MMAP_CACHE_MAX_CONTEXTS];
offset + size <= w->offset + w->size;
}
-static Window *window_add(MMapCache *m) {
+static Window *window_add(MMapCache *m, FileDescriptor *fd, int prot, bool keep_always, uint64_t offset, size_t size, void *ptr) {
Window *w;
assert(m);
+ assert(fd);
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
}
w->cache = m;
+ w->fd = fd;
+ w->prot = prot;
+ w->keep_always = keep_always;
+ w->offset = offset;
+ w->size = size;
+ w->ptr = ptr;
+
+ LIST_PREPEND(by_fd, fd->windows, w);
+
return w;
}
if (c->window->fd->sigbus)
return -EIO;
- c->window->keep_always |= keep_always;
+ c->window->keep_always = c->window->keep_always || keep_always;
*ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
return 1;
return -ENOMEM;
context_attach_window(c, w);
- w->keep_always += keep_always;
+ w->keep_always = w->keep_always || keep_always;
*ret = (uint8_t*) w->ptr + (offset - w->offset);
return 1;
}
+static int mmap_try_harder(MMapCache *m, void *addr, int fd, int prot, int flags, uint64_t offset, size_t size, void **res) {
+ void *ptr;
+
+ assert(m);
+ assert(fd >= 0);
+ assert(res);
+
+ for (;;) {
+ int r;
+
+ ptr = mmap(addr, size, prot, flags, fd, offset);
+ if (ptr != MAP_FAILED)
+ break;
+ if (errno != ENOMEM)
+ return -errno;
+
+ r = make_room(m);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENOMEM;
+ }
+
+ *res = ptr;
+ return 0;
+}
+
static int add_mmap(
MMapCache *m,
int fd,
wsize = PAGE_ALIGN(st->st_size - woffset);
}
- for (;;) {
- d = mmap(NULL, wsize, prot, MAP_SHARED, fd, woffset);
- if (d != MAP_FAILED)
- break;
- if (errno != ENOMEM)
- return -errno;
-
- r = make_room(m);
- if (r < 0)
- return r;
- if (r == 0)
- return -ENOMEM;
- }
+ r = mmap_try_harder(m, NULL, fd, prot, MAP_SHARED, woffset, wsize, &d);
+ if (r < 0)
+ return r;
c = context_add(m, context);
if (!c)
if (!f)
goto outofmem;
- w = window_add(m);
+ w = window_add(m, f, prot, keep_always, woffset, wsize, d);
if (!w)
goto outofmem;
- w->keep_always = keep_always;
- w->ptr = d;
- w->offset = woffset;
- w->prot = prot;
- w->size = wsize;
- w->fd = f;
-
- LIST_PREPEND(by_fd, f->windows, w);
-
context_detach_window(c);
c->window = w;
LIST_PREPEND(by_window, w->contexts, c);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
}
}
- /* We use OBJECT_UNUSED here, so that the iteator below doesn't remove our mmap window */
+ /* We use OBJECT_UNUSED here, so that the iterator below doesn't remove our mmap window */
r = journal_file_move_to_object(f, OBJECT_UNUSED, j->fields_offset, &o);
if (r < 0)
return r;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
NULL
};
-static void test_import(Hashmap *h, struct strbuf *sb,
- const char* contents, ssize_t size, int code) {
+static Hashmap * test_import(const char* contents, ssize_t size, int code) {
int r;
char name[] = "/tmp/test-catalog.XXXXXX";
_cleanup_close_ int fd;
+ Hashmap *h;
+
+ if (size < 0)
+ size = strlen(contents);
+
+ assert_se(h = hashmap_new(&catalog_hash_ops));
fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
assert_se(write(fd, contents, size) == size);
- r = catalog_import_file(h, sb, name);
+ r = catalog_import_file(h, name);
assert_se(r == code);
unlink(name);
+
+ return h;
}
-static void test_catalog_importing(void) {
- Hashmap *h;
- struct strbuf *sb;
+static void test_catalog_import_invalid(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
- assert_se(h = hashmap_new(&catalog_hash_ops));
- assert_se(sb = strbuf_new());
-
-#define BUF "xxx"
- test_import(h, sb, BUF, sizeof(BUF), -EINVAL);
-#undef BUF
+ h = test_import("xxx", -1, -EINVAL);
assert_se(hashmap_isempty(h));
- log_debug("----------------------------------------");
+}
-#define BUF \
+static void test_catalog_import_badid(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ const char *input =
"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \
"Subject: message\n" \
"\n" \
-"payload\n"
- test_import(h, sb, BUF, sizeof(BUF), -EINVAL);
-#undef BUF
+"payload\n";
+ h = test_import(input, -1, -EINVAL);
+}
- log_debug("----------------------------------------");
+static void test_catalog_import_one(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
-#define BUF \
+ const char *input =
"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
"Subject: message\n" \
"\n" \
-"payload\n"
- test_import(h, sb, BUF, sizeof(BUF), 0);
-#undef BUF
+"payload\n";
+ const char *expect =
+"Subject: message\n" \
+"\n" \
+"payload\n";
+ h = test_import(input, -1, 0);
assert_se(hashmap_size(h) == 1);
- log_debug("----------------------------------------");
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(expect, payload));
+ }
+}
+
+static void test_catalog_import_merge(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
+
+ const char *input =
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n" \
+"\n" \
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"\n" \
+"override payload\n";
+
+ const char *combined =
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"override payload\n";
+
+ h = test_import(input, -1, 0);
+ assert_se(hashmap_size(h) == 1);
- hashmap_free_free(h);
- strbuf_cleanup(sb);
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(combined, payload));
+ }
}
+static void test_catalog_import_merge_no_body(void) {
+ _cleanup_hashmap_free_free_free_ Hashmap *h = NULL;
+ char *payload;
+ Iterator j;
+
+ const char *input =
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n" \
+"\n" \
+"-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"\n";
+
+ const char *combined =
+"Subject: override subject\n" \
+"X-Header: hello\n" \
+"Subject: message\n" \
+"Defined-By: me\n" \
+"\n" \
+"payload\n";
+
+ h = test_import(input, -1, 0);
+ assert_se(hashmap_size(h) == 1);
+
+ HASHMAP_FOREACH(payload, h, j) {
+ assert_se(streq(combined, payload));
+ }
+}
static const char* database = NULL;
test_catalog_file_lang();
- test_catalog_importing();
+ test_catalog_import_invalid();
+ test_catalog_import_badid();
+ test_catalog_import_one();
+ test_catalog_import_merge();
+ test_catalog_import_merge_no_body();
test_catalog_update();
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, EDEADLK),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, EDEADLK),
- SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, EBADR),
+ SD_BUS_ERROR_MAP(BUS_ERROR_UNIT_MASKED, ESHUTDOWN),
SD_BUS_ERROR_MAP(BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, EBADR),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_ISOLATION, EPERM),
SD_BUS_ERROR_MAP(BUS_ERROR_SHUTTING_DOWN, ECANCELED),
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
%struct-type
%includes
%%
-Exec.Boot, config_parse_tristate, 0, offsetof(Settings, boot)
+Exec.Boot, config_parse_boot, 0, 0
+Exec.ProcessTwo, config_parse_pid2, 0, 0,
Exec.Parameters, config_parse_strv, 0, offsetof(Settings, parameters)
Exec.Environment, config_parse_strv, 0, offsetof(Settings, environment)
Exec.User, config_parse_string, 0, offsetof(Settings, user)
Exec.KillSignal, config_parse_signal, 0, offsetof(Settings, kill_signal)
Exec.Personality, config_parse_personality, 0, offsetof(Settings, personality)
Exec.MachineID, config_parse_id128, 0, offsetof(Settings, machine_id)
+Exec.WorkingDirectory, config_parse_path, 0, offsetof(Settings, working_directory)
Files.ReadOnly, config_parse_tristate, 0, offsetof(Settings, read_only)
Files.Volatile, config_parse_volatile_mode, 0, offsetof(Settings, volatile_mode)
Files.Bind, config_parse_bind, 0, 0
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
#include "conf-parser.h"
#include "nspawn-network.h"
#include "nspawn-settings.h"
+#include "parse-util.h"
#include "process-util.h"
#include "strv.h"
#include "util.h"
if (!s)
return -ENOMEM;
- s->boot = -1;
+ s->start_mode = _START_MODE_INVALID;
s->personality = PERSONALITY_INVALID;
s->read_only = -1;
strv_free(s->parameters);
strv_free(s->environment);
free(s->user);
+ free(s->working_directory);
strv_free(s->network_interfaces);
strv_free(s->network_macvlan);
return 0;
}
+
+int config_parse_boot(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Settings *settings = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Boot= parameter %s, ignoring: %m", rvalue);
+ return 0;
+ }
+
+ if (r > 0) {
+ if (settings->start_mode == START_PID2)
+ goto conflict;
+
+ settings->start_mode = START_BOOT;
+ } else {
+ if (settings->start_mode == START_BOOT)
+ goto conflict;
+
+ if (settings->start_mode < 0)
+ settings->start_mode = START_PID1;
+ }
+
+ return 0;
+
+conflict:
+ log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
+ return 0;
+}
+
+int config_parse_pid2(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Settings *settings = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse ProcessTwo= parameter %s, ignoring: %m", rvalue);
+ return 0;
+ }
+
+ if (r > 0) {
+ if (settings->start_mode == START_BOOT)
+ goto conflict;
+
+ settings->start_mode = START_PID2;
+ } else {
+ if (settings->start_mode == START_PID2)
+ goto conflict;
+
+ if (settings->start_mode < 0)
+ settings->start_mode = START_PID1;
+ }
+
+ return 0;
+
+conflict:
+ log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
+ return 0;
+}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
#include "nspawn-expose-ports.h"
#include "nspawn-mount.h"
+typedef enum StartMode {
+ START_PID1, /* Run parameters as command line as process 1 */
+ START_PID2, /* Use stub init process as PID 1, run parameters as command line as process 2 */
+ START_BOOT, /* Search for init system, pass arguments as parameters */
+ _START_MODE_MAX,
+ _START_MODE_INVALID = -1
+} StartMode;
+
typedef enum SettingsMask {
- SETTING_BOOT = 1 << 0,
- SETTING_ENVIRONMENT = 1 << 1,
- SETTING_USER = 1 << 2,
- SETTING_CAPABILITY = 1 << 3,
- SETTING_KILL_SIGNAL = 1 << 4,
- SETTING_PERSONALITY = 1 << 5,
- SETTING_MACHINE_ID = 1 << 6,
- SETTING_NETWORK = 1 << 7,
- SETTING_EXPOSE_PORTS = 1 << 8,
- SETTING_READ_ONLY = 1 << 9,
- SETTING_VOLATILE_MODE = 1 << 10,
- SETTING_CUSTOM_MOUNTS = 1 << 11,
- _SETTINGS_MASK_ALL = (1 << 12) -1
+ SETTING_START_MODE = 1 << 0,
+ SETTING_ENVIRONMENT = 1 << 1,
+ SETTING_USER = 1 << 2,
+ SETTING_CAPABILITY = 1 << 3,
+ SETTING_KILL_SIGNAL = 1 << 4,
+ SETTING_PERSONALITY = 1 << 5,
+ SETTING_MACHINE_ID = 1 << 6,
+ SETTING_NETWORK = 1 << 7,
+ SETTING_EXPOSE_PORTS = 1 << 8,
+ SETTING_READ_ONLY = 1 << 9,
+ SETTING_VOLATILE_MODE = 1 << 10,
+ SETTING_CUSTOM_MOUNTS = 1 << 11,
+ SETTING_WORKING_DIRECTORY = 1 << 12,
+ _SETTINGS_MASK_ALL = (1 << 13) -1
} SettingsMask;
typedef struct Settings {
/* [Run] */
- int boot;
+ StartMode start_mode;
char **parameters;
char **environment;
char *user;
int kill_signal;
unsigned long personality;
sd_id128_t machine_id;
+ char *working_directory;
/* [Image] */
int read_only;
int config_parse_bind(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_tmpfs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_veth_extra(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_boot(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_pid2(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
--- /dev/null
+/***
+ This file is part of systemd.
+
+ Copyright 2016 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 <sys/reboot.h>
+#include <sys/unistd.h>
+#include <sys/wait.h>
+
+#include "fd-util.h"
+#include "log.h"
+#include "nspawn-stub-pid1.h"
+#include "process-util.h"
+#include "signal-util.h"
+#include "time-util.h"
+#include "def.h"
+
+int stub_pid1(void) {
+ enum {
+ STATE_RUNNING,
+ STATE_REBOOT,
+ STATE_POWEROFF,
+ } state = STATE_RUNNING;
+
+ sigset_t fullmask, oldmask, waitmask;
+ usec_t quit_usec = USEC_INFINITY;
+ pid_t pid;
+ int r;
+
+ /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
+ * for allowing arbitrary processes run in a container, and still have all zombies reaped. */
+
+ assert_se(sigfillset(&fullmask) >= 0);
+ assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);
+
+ pid = fork();
+ if (pid < 0)
+ return log_error_errno(errno, "Failed to fork child pid: %m");
+
+ if (pid == 0) {
+ /* Return in the child */
+ assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0);
+ setsid();
+ return 0;
+ }
+
+ reset_all_signal_handlers();
+
+ log_close();
+ close_all_fds(NULL, 0);
+ log_open();
+
+ rename_process("STUBINIT");
+
+ assert_se(sigemptyset(&waitmask) >= 0);
+ assert_se(sigset_add_many(&waitmask,
+ SIGCHLD, /* posix: process died */
+ SIGINT, /* sysv: ctrl-alt-del */
+ SIGRTMIN+3, /* systemd: halt */
+ SIGRTMIN+4, /* systemd: poweroff */
+ SIGRTMIN+5, /* systemd: reboot */
+ SIGRTMIN+6, /* systemd: kexec */
+ SIGRTMIN+13, /* systemd: halt */
+ SIGRTMIN+14, /* systemd: poweroff */
+ SIGRTMIN+15, /* systemd: reboot */
+ SIGRTMIN+16, /* systemd: kexec */
+ -1) >= 0);
+
+ /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't
+ * support reexec/reloading in this stub process. */
+
+ for (;;) {
+ siginfo_t si;
+ usec_t current_usec;
+
+ si.si_pid = 0;
+ r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
+ if (r < 0) {
+ r = log_error_errno(errno, "Failed to reap children: %m");
+ goto finish;
+ }
+
+ current_usec = now(CLOCK_MONOTONIC);
+
+ if (si.si_pid == pid || current_usec >= quit_usec) {
+
+ /* The child we started ourselves died or we reached a timeout. */
+
+ if (state == STATE_REBOOT) { /* dispatch a queued reboot */
+ (void) reboot(RB_AUTOBOOT);
+ r = log_error_errno(errno, "Failed to reboot: %m");
+ goto finish;
+
+ } else if (state == STATE_POWEROFF)
+ (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */
+
+ if (si.si_pid == pid && si.si_code == CLD_EXITED)
+ r = si.si_status; /* pass on exit code */
+ else
+ r = 255; /* signal, coredump, timeout, … */
+
+ goto finish;
+ }
+ if (si.si_pid != 0)
+ /* We reaped something. Retry until there's nothing more to reap. */
+ continue;
+
+ if (quit_usec == USEC_INFINITY)
+ r = sigwaitinfo(&waitmask, &si);
+ else {
+ struct timespec ts;
+ r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec));
+ }
+ if (r < 0) {
+ if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */
+ continue;
+ if (errno == EAGAIN) /* timeout reached */
+ continue;
+
+ r = log_error_errno(errno, "Failed to wait for signal: %m");
+ goto finish;
+ }
+
+ if (si.si_signo == SIGCHLD)
+ continue; /* Let's reap this */
+
+ if (state != STATE_RUNNING)
+ continue;
+
+ /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a
+ * constant… */
+
+ if (si.si_signo == SIGRTMIN+3 ||
+ si.si_signo == SIGRTMIN+4 ||
+ si.si_signo == SIGRTMIN+13 ||
+ si.si_signo == SIGRTMIN+14)
+
+ state = STATE_POWEROFF;
+
+ else if (si.si_signo == SIGINT ||
+ si.si_signo == SIGRTMIN+5 ||
+ si.si_signo == SIGRTMIN+6 ||
+ si.si_signo == SIGRTMIN+15 ||
+ si.si_signo == SIGRTMIN+16)
+
+ state = STATE_REBOOT;
+ else
+ assert_not_reached("Got unexpected signal");
+
+ /* (void) kill_and_sigcont(pid, SIGTERM); */
+ quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
+ }
+
+finish:
+ _exit(r < 0 ? EXIT_FAILURE : r);
+}
--- /dev/null
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2016 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/>.
+***/
+
+int stub_pid1(void);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
#include "nspawn-register.h"
#include "nspawn-settings.h"
#include "nspawn-setuid.h"
+#include "nspawn-stub-pid1.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
static char *arg_directory = NULL;
static char *arg_template = NULL;
+static char *arg_chdir = NULL;
static char *arg_user = NULL;
static sd_id128_t arg_uuid = {};
static char *arg_machine = NULL;
static const char *arg_slice = NULL;
static bool arg_private_network = false;
static bool arg_read_only = false;
-static bool arg_boot = false;
+static StartMode arg_start_mode = START_PID1;
static bool arg_ephemeral = false;
static LinkJournal arg_link_journal = LINK_AUTO;
static bool arg_link_journal_try = false;
" -x --ephemeral Run container with snapshot of root directory, and\n"
" remove it after exit\n"
" -i --image=PATH File system device or disk image for the container\n"
+ " -a --as-pid2 Maintain a stub init as PID1, invoke binary as PID2\n"
" -b --boot Boot up full system (i.e. invoke init)\n"
+ " --chdir=PATH Set working directory in the container\n"
" -u --user=USER Run the command under specified user or uid\n"
" -M --machine=NAME Set the machine name for the container\n"
" --uuid=UUID Set a specific machine UUID for the container\n"
" capability\n"
" --drop-capability=CAP Drop the specified capability from the default set\n"
" --kill-signal=SIGNAL Select signal to use for shutting down PID 1\n"
- " --link-journal=MODE Link up guest journal, one of no, auto, guest, host,\n"
- " try-guest, try-host\n"
+ " --link-journal=MODE Link up guest journal, one of no, auto, guest, \n"
+ " host, try-guest, try-host\n"
" -j Equivalent to --link-journal=try-guest\n"
" --read-only Mount the root directory read-only\n"
" --bind=PATH[:PATH[:OPTIONS]]\n"
ARG_PRIVATE_USERS,
ARG_KILL_SIGNAL,
ARG_SETTINGS,
+ ARG_CHDIR,
};
static const struct option options[] = {
{ "ephemeral", no_argument, NULL, 'x' },
{ "user", required_argument, NULL, 'u' },
{ "private-network", no_argument, NULL, ARG_PRIVATE_NETWORK },
+ { "as-pid2", no_argument, NULL, 'a' },
{ "boot", no_argument, NULL, 'b' },
{ "uuid", required_argument, NULL, ARG_UUID },
{ "read-only", no_argument, NULL, ARG_READ_ONLY },
{ "private-users", optional_argument, NULL, ARG_PRIVATE_USERS },
{ "kill-signal", required_argument, NULL, ARG_KILL_SIGNAL },
{ "settings", required_argument, NULL, ARG_SETTINGS },
+ { "chdir", required_argument, NULL, ARG_CHDIR },
{}
};
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:xp:n", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hD:u:abL:M:jS:Z:qi:xp:n", options, NULL)) >= 0)
switch (c) {
break;
case 'b':
- arg_boot = true;
- arg_settings_mask |= SETTING_BOOT;
+ if (arg_start_mode == START_PID2) {
+ log_error("--boot and --as-pid2 may not be combined.");
+ return -EINVAL;
+ }
+
+ arg_start_mode = START_BOOT;
+ arg_settings_mask |= SETTING_START_MODE;
+ break;
+
+ case 'a':
+ if (arg_start_mode == START_BOOT) {
+ log_error("--boot and --as-pid2 may not be combined.");
+ return -EINVAL;
+ }
+
+ arg_start_mode = START_PID2;
+ arg_settings_mask |= SETTING_START_MODE;
break;
case ARG_UUID:
break;
+ case ARG_CHDIR:
+ if (!path_is_absolute(optarg)) {
+ log_error("Working directory %s is not an absolute path.", optarg);
+ return -EINVAL;
+ }
+
+ r = free_and_strdup(&arg_chdir, optarg);
+ if (r < 0)
+ return log_oom();
+
+ arg_settings_mask |= SETTING_WORKING_DIRECTORY;
+ break;
+
case '?':
return -EINVAL;
if (arg_share_system)
arg_register = false;
- if (arg_boot && arg_share_system) {
+ if (arg_start_mode != START_PID1 && arg_share_system) {
log_error("--boot and --share-system may not be combined.");
return -EINVAL;
}
if (!arg_parameters)
return log_oom();
- arg_settings_mask |= SETTING_BOOT;
+ arg_settings_mask |= SETTING_START_MODE;
}
/* Load all settings from .nspawn files */
return -EINVAL;
}
- if (arg_boot && arg_kill_signal <= 0)
+ if (arg_start_mode == START_BOOT && arg_kill_signal <= 0)
arg_kill_signal = SIGRTMIN+3;
return 0;
return -ESRCH;
}
+ if (arg_chdir)
+ if (chdir(arg_chdir) < 0)
+ return log_error_errno(errno, "Failed to change to specified working directory %s: %m", arg_chdir);
+
+ if (arg_start_mode == START_PID2) {
+ r = stub_pid1();
+ if (r < 0)
+ return r;
+ }
+
/* Now, explicitly close the log, so that we
* then can close all remaining fds. Closing
* the log explicitly first has the benefit
log_close();
(void) fdset_close_others(fds);
- if (arg_boot) {
+ if (arg_start_mode == START_BOOT) {
char **a;
size_t m;
} else if (!strv_isempty(arg_parameters))
execvpe(arg_parameters[0], arg_parameters, env_use);
else {
- chdir(home ?: "/root");
+ if (!arg_chdir)
+ chdir(home ?: "/root");
+
execle("/bin/bash", "-bash", NULL, env_use);
execle("/bin/sh", "-sh", NULL, env_use);
}
/* Copy over bits from the settings, unless they have been
* explicitly masked by command line switches. */
- if ((arg_settings_mask & SETTING_BOOT) == 0 &&
- settings->boot >= 0) {
- arg_boot = settings->boot;
+ if ((arg_settings_mask & SETTING_START_MODE) == 0 &&
+ settings->start_mode >= 0) {
+ arg_start_mode = settings->start_mode;
strv_free(arg_parameters);
arg_parameters = settings->parameters;
settings->parameters = NULL;
}
+ if ((arg_settings_mask & SETTING_WORKING_DIRECTORY) == 0 &&
+ settings->working_directory) {
+ free(arg_chdir);
+ arg_chdir = settings->working_directory;
+ settings->working_directory = NULL;
+ }
+
if ((arg_settings_mask & SETTING_ENVIRONMENT) == 0 &&
settings->environment) {
strv_free(arg_setenv);
log_parse_environment();
log_open();
+ /* Make sure rename_process() in the stub init process can work */
+ saved_argv = argv;
+ saved_argc = argc;
+
r = parse_argv(argc, argv);
if (r <= 0)
goto finish;
}
}
- if (arg_boot) {
+ if (arg_start_mode == START_BOOT) {
if (path_is_os_tree(arg_directory) <= 0) {
log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", arg_directory);
r = -EINVAL;
free(arg_image);
free(arg_machine);
free(arg_user);
+ free(arg_chdir);
strv_free(arg_setenv);
free(arg_network_bridge);
strv_free(arg_network_interfaces);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
_cleanup_free_ void* buf = NULL;
size_t buf_size = 0;
ssize_t k;
- int r;
+ int r, open_rw_error;
FILE *f;
bool refresh_seed_file = true;
if (streq(argv[1], "load")) {
seed_fd = open(RANDOM_SEED, O_RDWR|O_CLOEXEC|O_NOCTTY|O_CREAT, 0600);
+ open_rw_error = -errno;
if (seed_fd < 0) {
+ refresh_seed_file = false;
+
seed_fd = open(RANDOM_SEED, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (seed_fd < 0) {
- r = log_error_errno(errno, "Failed to open " RANDOM_SEED ": %m");
+ bool missing = errno == ENOENT;
+
+ log_full_errno(missing ? LOG_DEBUG : LOG_ERR,
+ open_rw_error, "Failed to open " RANDOM_SEED " for writing: %m");
+ r = log_full_errno(missing ? LOG_DEBUG : LOG_ERR,
+ errno, "Failed to open " RANDOM_SEED " for reading: %m");
+ if (missing)
+ r = 0;
+
goto finish;
}
-
- refresh_seed_file = false;
}
random_fd = open("/dev/urandom", O_RDWR|O_CLOEXEC|O_NOCTTY, 0600);
k = loop_read(seed_fd, buf, buf_size, false);
if (k < 0)
r = log_error_errno(k, "Failed to read seed from " RANDOM_SEED ": %m");
- else if (k == 0)
+ else if (k == 0) {
+ r = 0;
log_debug("Seed file " RANDOM_SEED " not yet initialized, proceeding.");
- else {
+ } else {
(void) lseek(seed_fd, 0, SEEK_SET);
r = loop_write(random_fd, buf, (size_t) k, false);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <inttypes.h>
+
#define SD_RESOLVED_DNS (UINT64_C(1) << 0)
#define SD_RESOLVED_LLMNR_IPV4 (UINT64_C(1) << 1)
#define SD_RESOLVED_LLMNR_IPV6 (UINT64_C(1) << 2)
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
bool authenticated:1;
bool shared_owner:1;
+ int ifindex;
int owner_family;
union in_addr_union owner_address;
bool authenticated,
bool shared_owner,
usec_t timestamp,
+ int ifindex,
int owner_family,
const union in_addr_union *owner_address) {
i->authenticated = authenticated;
i->shared_owner = shared_owner;
+ i->ifindex = ifindex;
+
i->owner_family = owner_family;
i->owner_address = *owner_address;
bool authenticated,
bool shared_owner,
usec_t timestamp,
+ int ifindex,
int owner_family,
const union in_addr_union *owner_address) {
authenticated,
shared_owner,
timestamp,
+ ifindex,
owner_family,
owner_address);
return 0;
i->until = calculate_until(rr, (uint32_t) -1, timestamp, false);
i->authenticated = authenticated;
i->shared_owner = shared_owner;
+ i->ifindex = ifindex;
i->owner_family = owner_family;
i->owner_address = *owner_address;
i->prioq_idx = PRIOQ_IDX_NULL;
DnsResourceRecord *soa = NULL, *rr;
DnsAnswerFlags flags;
unsigned cache_keys;
- int r;
+ int r, ifindex;
assert(c);
assert(owner_address);
timestamp = now(clock_boottime_or_monotonic());
/* Second, add in positive entries for all contained RRs */
- DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
+ DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, answer) {
if ((flags & DNS_ANSWER_CACHEABLE) == 0)
continue;
flags & DNS_ANSWER_AUTHENTICATED,
flags & DNS_ANSWER_SHARED_OWNER,
timestamp,
+ ifindex,
owner_family, owner_address);
if (r < 0)
goto fail;
if (!j->rr)
continue;
- r = dns_answer_add(answer, j->rr, 0, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0);
+ r = dns_answer_add(answer, j->rr, j->ifindex, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0);
if (r < 0)
return r;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
if (rr->key->type != DNS_TYPE_NSEC3)
return 0;
- /* RFC 5155, Section 8.2 says we MUST ignore NSEC3 RRs with flags != 0 or 1 */
+ /* RFC 5155, Section 8.2 says we MUST ignore NSEC3 RRs with flags != 0 or 1 */
if (!IN_SET(rr->nsec3.flags, 0, 1))
return 0;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
}
if (!dns_name_is_root(DNS_RESOURCE_KEY_NAME(rr->key))) {
- /* If the OPT RR qis not owned by the root domain, then it is bad, let's ignore
+ /* If the OPT RR is not owned by the root domain, then it is bad, let's ignore
* it. */
log_debug("OPT RR is not owned by root domain, ignoring.");
bad_opt = true;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
if (r == 0 && k == 0) /* No actual cname happened? */
return -ELOOP;
+ if (q->answer_protocol == DNS_PROTOCOL_DNS) {
+ /* Don't permit CNAME redirects from unicast DNS to LLMNR or MulticastDNS, so that global resources
+ * cannot invade the local namespace. The opposite way we permit: local names may redirect to global
+ * ones. */
+
+ q->flags &= ~(SD_RESOLVED_LLMNR|SD_RESOLVED_MDNS); /* mask away the local protocols */
+ }
+
+ /* Turn off searching for the new name */
+ q->flags |= SD_RESOLVED_NO_SEARCH;
+
dns_question_unref(q->question_idna);
q->question_idna = nq_idna;
nq_idna = NULL;
dns_query_free_candidates(q);
dns_query_reset_answer(q);
- q->state = DNS_TRANSACTION_NULL;
- /* Turn off searching for the new name */
- q->flags |= SD_RESOLVED_NO_SEARCH;
+ q->state = DNS_TRANSACTION_NULL;
return 0;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
if (dns_resource_record_equal(x, y))
return 0;
- /* This is a bit dirty, we don't implement proper odering, but
+ /* This is a bit dirty, we don't implement proper ordering, but
* the hashtable doesn't need ordering anyway, hence we don't
* care. */
return x < y ? -1 : 1;
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
s->family = family;
s->resend_timeout = MULTICAST_RESEND_TIMEOUT_MIN_USEC;
- s->dnssec_mode = _DNSSEC_MODE_INVALID;
-
if (protocol == DNS_PROTOCOL_DNS) {
/* Copy DNSSEC mode from the link if it is set there,
* otherwise take the manager's DNSSEC mode. Note that
s->dnssec_mode = link_get_dnssec_mode(l);
else
s->dnssec_mode = manager_get_dnssec_mode(m);
- }
+ } else
+ s->dnssec_mode = DNSSEC_NO;
LIST_PREPEND(scopes, m->dns_scopes, s);
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
#include <stdbool.h>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdcommonhfoo
#define foosdcommonhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdbusprotocolhfoo
#define foosdbusprotocolhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdbusvtablehfoo
#define foosdbusvtablehfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdbushfoo
#define foosdbushfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddaemonhfoo
#define foosddaemonhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddevicehfoo
#define foosddevicehfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddhcpclienthfoo
#define foosddhcpclienthfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddhcpleasehfoo
#define foosddhcpleasehfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddhcpserverhfoo
#define foosddhcpserverhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddhcp6clienthfoo
#define foosddhcp6clienthfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosddhcp6leasehfoo
#define foosddhcp6leasehfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdeventhfoo
#define foosdeventhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdhwdbhfoo
#define foosdhwdbhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdid128hfoo
#define foosdid128hfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdipv4acdfoo
#define foosdipv4acdfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdipv4llfoo
#define foosdipv4llfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdjournalhfoo
#define foosdjournalhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdlldphfoo
#define foosdlldphfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdloginhfoo
#define foosdloginhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdmessageshfoo
#define foosdmessageshfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdndiscfoo
#define foosdndiscfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdnetlinkhfoo
#define foosdnetlinkhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdnetworkhfoo
#define foosdnetworkhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdpathhfoo
#define foosdpathhfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdresolvehfoo
#define foosdresolvehfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#ifndef foosdutf8hfoo
#define foosdutf8hfoo
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
assert_se(usec_add(USEC_INFINITY, 2) == USEC_INFINITY);
}
+static void test_usec_sub(void) {
+ assert_se(usec_sub(0, 0) == 0);
+ assert_se(usec_sub(4, 1) == 3);
+ assert_se(usec_sub(4, 4) == 0);
+ assert_se(usec_sub(4, 5) == 0);
+ assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub(USEC_INFINITY-3, -3) == USEC_INFINITY);
+ assert_se(usec_sub(USEC_INFINITY-3, -4) == USEC_INFINITY);
+ assert_se(usec_sub(USEC_INFINITY-3, -5) == USEC_INFINITY);
+ assert_se(usec_sub(USEC_INFINITY, 5) == USEC_INFINITY);
+}
+
int main(int argc, char *argv[]) {
+ uintmax_t x;
+
test_parse_sec();
test_parse_time();
test_parse_nsec();
test_timezone_is_valid();
test_get_timezones();
test_usec_add();
+ test_usec_sub();
+
+ /* Ensure time_t is signed */
+ assert_cc((time_t) -1 < (time_t) 1);
+
+ /* Ensure TIME_T_MAX works correctly */
+ x = (uintmax_t) TIME_T_MAX;
+ x ++;
+ assert((time_t) x < 0);
return 0;
}
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
#pragma once
/***
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* scsi.h
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) IBM Corp. 2003
* Copyright (C) SUSE Linux Products GmbH, 2006
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) IBM Corp. 2003
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) IBM Corp. 2003
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* probe disks for filesystems and partitions
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* expose input properties via udev
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* load kernel modules
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* compose persistent device path
*
path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "xen");
supported_parent = true;
+ } else if (streq(subsys, "virtio")) {
+ while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
+ parent = udev_device_get_parent(parent);
+ path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
+ supported_transport = true;
+ supported_parent = true;
} else if (streq(subsys, "scm")) {
path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "scm");
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* manage device node user ACL
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* USB device properties and persistent device path
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* libudev - interface to udev device information
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2003-2013 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2003-2012 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2009 Canonical Ltd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2005-2011 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2004-2009 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2004-2010 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2009 Canonical Ltd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2004-2008 Kay Sievers <kay@vrfy.org>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2014 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
*
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2004-2012 Kay Sievers <kay@vrfy.org>
* Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/*
* Copyright (C) 2009 Kay Sievers <kay@vrfy.org>
* Copyright (c) 2009 Filippo Argiolas <filippo.argiolas@gmail.com>
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
# and systemd-coredump(8) and core(5) for the explanation of the
# setting below.
-kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t %e
+kernel.core_pattern=|@rootlibexecdir@/systemd-coredump %P %u %g %s %t %c %e
m4_ifdef(`ENABLE_TIMESYNCD',
u systemd-timesync - "systemd Time Synchronization"
)m4_dnl
+m4_ifdef(`ENABLE_COREDUMP',
+u systemd-coredump - "systemd Core Dumper"
+)m4_dnl
systemctl start unstoppable.service || exit 1
touch /testok
-exit 0
[[ ! -f "/i-lose-my-logs" ]]
touch /testok
-exit 0
[[ "$(ulimit -n -H)" = "16384" ]]
touch /testok
-exit 0
runcon -t systemd_test_stop_t systemctl stop hola
touch /testok
-exit 0
desc => "big major number test",
devpath => "/devices/virtual/misc/misc-fake1",
exp_name => "node",
- exp_majorminor => "4095:1",
+ exp_majorminor => "511:1",
rules => <<EOF
KERNEL=="misc-fake1", SYMLINK+="node"
EOF
desc => "big major and big minor number test",
devpath => "/devices/virtual/misc/misc-fake89999",
exp_name => "node",
- exp_majorminor => "4095:89999",
+ exp_majorminor => "511:89999",
rules => <<EOF
KERNEL=="misc-fake89999", SYMLINK+="node"
EOF
/systemd-binfmt.service
/systemd-bootchart.service
/systemd-bus-proxyd.service
+/systemd-coredump@.service
/systemd-firstboot.service
/systemd-fsck-root.service
/systemd-fsck@.service
Documentation=man:systemd.special(7)
Requires=sysinit.target
Wants=sockets.target timers.target paths.target slices.target
-After=sysinit.target sockets.target paths.target slices.target
+After=sysinit.target sockets.target paths.target slices.target tmp.mount
# We support /var, /tmp, /var/tmp, being on NFS, but we don't pull in
-# remote-fs.target by default, hence explicitly pull /var in here.
-RequiresMountsFor=/var /tmp /var/tmp
+# remote-fs.target by default, hence pull them in explicitly here. Note that we
+# require /var and /var/tmp, but only add a Wants= type dependency on /tmp, as
+# we support that unit being masked, and this should not be considered an error.
+RequiresMountsFor=/var /var/tmp
+Wants=tmp.mount
Environment=HOME=/root
WorkingDirectory=-/root
ExecStartPre=-/bin/plymouth quit
-ExecStartPre=-/bin/echo -e 'Welcome to emergency mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\nboot into default mode.'
+ExecStartPre=-/bin/echo -e 'Welcome to rescue mode! After logging in, type "journalctl -xb" to view\\nsystem logs, "systemctl reboot" to reboot, "systemctl default" or ^D to\\nboot into default mode.'
ExecStart=-/bin/sh -c "@SULOGIN@; @SYSTEMCTL@ --job-mode=fail --no-block default"
Type=idle
StandardInput=tty-force
--- /dev/null
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Process Core Dump Socket
+Documentation=man:systemd-coredump(8)
+DefaultDependencies=no
+
+[Socket]
+ListenSequentialPacket=/run/systemd/coredump
+SocketMode=0600
+Accept=yes
+MaxConnections=16
--- /dev/null
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Process Core Dump
+Documentation=man:systemd-coredump(8)
+DefaultDependencies=no
+RequiresMountsFor=/var/lib/systemd/coredump
+Conflicts=shutdown.target
+After=systemd-remount-fs.service systemd-journald.socket
+Requires=systemd-journald.socket
+Before=shutdown.target
+
+[Service]
+ExecStart=-@rootlibexecdir@/systemd-coredump
+Nice=9
+OOMScoreAdjust=500
+PrivateNetwork=yes
+ProtectSystem=full
+RuntimeMaxSec=5min