summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am20
-rw-r--r--hwdb/60-keyboard.hwdb5
-rw-r--r--hwdb/60-sensor.hwdb7
-rw-r--r--hwdb/70-joystick.hwdb50
-rwxr-xr-xhwdb/parse_hwdb.py6
-rw-r--r--man/networkctl.xml33
-rw-r--r--man/sd_bus_error.xml2
-rw-r--r--man/sd_notify.xml52
-rw-r--r--man/systemd-mount.xml12
-rw-r--r--man/systemd-nspawn.xml45
-rw-r--r--man/systemd.link.xml41
-rw-r--r--man/systemd.service.xml40
-rw-r--r--man/systemd.target.xml37
-rw-r--r--man/systemd.unit.xml55
-rw-r--r--meson.build1
-rw-r--r--rules/50-udev-default.rules.in1
-rw-r--r--rules/60-evdev.rules2
-rw-r--r--rules/60-input-id.rules7
-rw-r--r--rules/70-joystick.rules12
-rw-r--r--rules/meson.build1
-rw-r--r--shell-completion/bash/networkctl2
-rw-r--r--shell-completion/zsh/_networkctl1
-rw-r--r--src/basic/missing.h12
-rw-r--r--src/basic/missing_syscall.h4
-rw-r--r--src/basic/process-util.c17
-rw-r--r--src/basic/process-util.h13
-rw-r--r--src/basic/unit-name.c9
-rw-r--r--src/basic/unit-name.h12
-rw-r--r--src/core/automount.c12
-rw-r--r--src/core/dbus-execute.c132
-rw-r--r--src/core/dbus-service.c33
-rw-r--r--src/core/execute.c15
-rw-r--r--src/core/execute.h2
-rw-r--r--src/core/load-fragment.c4
-rw-r--r--src/core/loopback-setup.c6
-rw-r--r--src/core/main.c2
-rw-r--r--src/core/service.c16
-rw-r--r--src/core/service.h12
-rw-r--r--src/core/smack-setup.c64
-rw-r--r--src/core/swap.c72
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c14
-rw-r--r--src/import/pull-raw.c4
-rw-r--r--src/import/pull-tar.c14
-rw-r--r--src/journal/journalctl.c16
-rw-r--r--src/journal/sd-journal.c7
-rw-r--r--src/libsystemd-network/sd-dhcp-server.c46
-rw-r--r--src/libsystemd-network/test-dhcp-server.c2
-rw-r--r--src/libsystemd/sd-bus/bus-control.c268
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h1
-rw-r--r--src/libsystemd/sd-bus/sd-bus.c17
-rw-r--r--src/libsystemd/sd-netlink/netlink-message.c3
-rw-r--r--src/libsystemd/sd-netlink/rtnl-message.c14
-rw-r--r--src/login/70-power-switch.rules9
-rw-r--r--src/login/logind-button.c119
-rw-r--r--src/login/logind-core.c6
-rw-r--r--src/mount/mount-tool.c275
-rw-r--r--src/network/networkctl.c74
-rw-r--r--src/network/networkd-link.c19
-rw-r--r--src/nspawn/nspawn-register.c222
-rw-r--r--src/nspawn/nspawn-register.h2
-rw-r--r--src/nspawn/nspawn.c18
-rw-r--r--src/resolve/meson.build9
-rw-r--r--src/resolve/resolved-dns-packet.c14
-rw-r--r--src/resolve/resolved-dns-packet.h8
-rw-r--r--src/resolve/resolved-dns-server.c5
-rw-r--r--src/resolve/test-resolved-packet.c45
-rw-r--r--src/shared/bus-unit-util.c30
-rw-r--r--src/shared/fstab-util.c33
-rw-r--r--src/shared/fstab-util.h3
-rw-r--r--src/systemctl/systemctl.c22
-rw-r--r--src/systemd/sd-netlink.h1
-rwxr-xr-xsrc/udev/generate-keyboard-gperf.py16
-rwxr-xr-xsrc/udev/generate-keyboard-keys-gperf.sh10
-rwxr-xr-xsrc/udev/generate-keyboard-keys-list.sh6
-rw-r--r--src/udev/meson.build4
-rw-r--r--src/udev/net/ethtool-util.c29
-rw-r--r--src/udev/net/ethtool-util.h24
-rw-r--r--src/udev/net/link-config-gperf.gperf1
-rw-r--r--src/udev/net/link-config.c10
-rw-r--r--src/udev/net/link-config.h1
-rw-r--r--src/udev/udev-builtin-blkid.c13
-rw-r--r--src/udev/udev-builtin-input_id.c28
-rw-r--r--src/udev/udev-event.c10
-rw-r--r--src/udev/udevd.c12
-rw-r--r--units/dev-hugepages.mount2
-rw-r--r--units/dev-mqueue.mount2
-rw-r--r--units/network-online.target2
-rw-r--r--units/network-pre.target2
-rw-r--r--units/network.target2
-rw-r--r--units/org.freedesktop.hostname1.busname2
-rw-r--r--units/org.freedesktop.locale1.busname2
-rw-r--r--units/org.freedesktop.login1.busname4
-rw-r--r--units/org.freedesktop.machine1.busname2
-rw-r--r--units/org.freedesktop.resolve1.busname2
-rw-r--r--units/org.freedesktop.systemd1.busname2
-rw-r--r--units/org.freedesktop.timedate1.busname2
-rw-r--r--units/proc-sys-fs-binfmt_misc.automount4
-rw-r--r--units/proc-sys-fs-binfmt_misc.mount4
-rw-r--r--units/sys-fs-fuse-connections.mount2
-rw-r--r--units/sys-kernel-config.mount2
-rw-r--r--units/sys-kernel-debug.mount2
-rw-r--r--units/syslog.socket4
-rw-r--r--units/systemd-hostnamed.service.in2
-rw-r--r--units/systemd-importd.service.in2
-rw-r--r--units/systemd-localed.service.in2
-rw-r--r--units/systemd-logind.service.in4
-rw-r--r--units/systemd-machined.service.in2
-rw-r--r--units/systemd-remount-fs.service.in2
-rw-r--r--units/systemd-resolved.service.m4.in6
-rw-r--r--units/systemd-timedated.service.in2
-rw-r--r--units/tmp.mount.m42
112 files changed, 1872 insertions, 550 deletions
diff --git a/.gitignore b/.gitignore
index c8c59eba56..8c4331e54f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -272,6 +272,7 @@
/test-replace-var
/test-resolve
/test-resolve-tables
+/test-resolved-packet
/test-ring
/test-rlimit-util
/test-sched-prio
diff --git a/Makefile.am b/Makefile.am
index 56f159b84e..3fb68dd385 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3878,6 +3878,7 @@ dist_udevrules_DATA += \
rules/60-block.rules \
rules/60-drm.rules \
rules/60-evdev.rules \
+ rules/60-input-id.rules \
rules/60-persistent-storage-tape.rules \
rules/60-persistent-input.rules \
rules/60-persistent-alsa.rules \
@@ -3885,6 +3886,7 @@ dist_udevrules_DATA += \
rules/60-sensor.rules \
rules/60-serial.rules \
rules/64-btrfs.rules \
+ rules/70-joystick.rules \
rules/70-mouse.rules \
rules/70-touchpad.rules \
rules/75-net-description.rules \
@@ -3931,10 +3933,10 @@ noinst_LTLIBRARIES += \
src/udev/keyboard-keys-list.txt:
$(AM_V_at)$(MKDIR_P) $(dir $@)
- $(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include linux/input.h - < /dev/null | $(AWK) '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9K]/ { if ($$2 != "KEY_MAX") { print $$2 } }' > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-list.sh "$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)" > $@
src/udev/keyboard-keys-from-name.gperf: src/udev/keyboard-keys-list.txt
- $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct key_name { const char* name; unsigned short id; };"; print "%null-strings"; print "%%";} { print tolower(substr($$1 ,5)) ", " $$1 }' < $< > $@
+ $(AM_V_GEN)$(top_srcdir)/src/udev/generate-keyboard-keys-gperf.sh $< > $@
src/udev/keyboard-keys-from-name.h: src/udev/keyboard-keys-from-name.gperf
$(AM_V_GPERF)$(GPERF) -L ANSI-C -t -N keyboard_lookup_key -H hash_key_name -p -C < $< > $@
@@ -5764,6 +5766,7 @@ dist_zshcompletion_data += \
tests += \
test-dns-packet \
test-resolve-tables \
+ test-resolved-packet \
test-dnssec
manual_tests += \
@@ -5785,6 +5788,19 @@ test_resolve_tables_LDADD = \
$(GCRYPT_LIBS) \
-lm
+test_resolved_packet_SOURCES = \
+ src/resolve/test-resolved-packet.c \
+ $(basic_dns_sources)
+
+test_resolved_packet_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(GCRYPT_CFLAGS)
+
+test_resolved_packet_LDADD = \
+ libsystemd-shared.la \
+ $(GCRYPT_LIBS) \
+ -lm
+
test_dns_packet_SOURCES = \
src/resolve/test-dns-packet.c \
$(basic_dns_sources)
diff --git a/hwdb/60-keyboard.hwdb b/hwdb/60-keyboard.hwdb
index e8be567166..881a531b67 100644
--- a/hwdb/60-keyboard.hwdb
+++ b/hwdb/60-keyboard.hwdb
@@ -58,6 +58,8 @@
# KEYBOARD_KEY_<hex scan code>=<key code identifier>
# The scan code should be expressed in hex lowercase. The key codes
# are retrieved and normalized from the kernel input API header.
+# Keycodes are either KEY_* defines in lowercase with the key_ prefix
+# optionally removed or BTN_ defines in lowercase with btn_ preserved.
#
# An '!' as the first character of the key identifier string
# will add the scan code to the AT keyboard's list of scan codes
@@ -80,7 +82,8 @@
# systemd-hwdb update
# udevadm trigger /dev/input/eventXX
# where /dev/input/eventXX is the keyboard in question. If in
-# doubt, simply use /dev/input/event* to reload all input rules.
+# doubt, simply reload all input rules
+# udevadm trigger --verbose --sysname-match="event*"
#
# If your changes are generally applicable, preferably send them as a pull
# request to
diff --git a/hwdb/60-sensor.hwdb b/hwdb/60-sensor.hwdb
index 2436ca7367..dab22dc643 100644
--- a/hwdb/60-sensor.hwdb
+++ b/hwdb/60-sensor.hwdb
@@ -68,3 +68,10 @@ sensor:modalias:platform:lis3lv02d:dmi:*svn*Hewlett-Packard*:*pn*HPEliteBook8560
#########################################
sensor:modalias:acpi:BMA250*:dmi:*svn*WinBook*:*pn*TW100*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 0
+
+#########################################
+# Cytrix (Mytrix)
+#########################################
+sensor:modalias:acpi:*KIOX000A*:dmi:*svn*CytrixTechnology:*pn*Complex11t*
+ ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, 1, 0; 0, 0, 1
+
diff --git a/hwdb/70-joystick.hwdb b/hwdb/70-joystick.hwdb
new file mode 100644
index 0000000000..9d5c4fc069
--- /dev/null
+++ b/hwdb/70-joystick.hwdb
@@ -0,0 +1,50 @@
+# This file is part of systemd.
+#
+# Database for joystick device information that cannot be queried directly.
+#
+# The lookup keys are composed in:
+# 70-joystick.rules
+#
+# Note: The format of the "joystick:" prefix match key is a
+# contract between the rules file and the hardware data, it might
+# change in later revisions to support more or better matches, it
+# is not necessarily expected to be a stable ABI.
+#
+# Match string format:
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:
+#
+# vid/pid as 4-digit hex lowercase vendor/product
+#
+# To add local entries, create a new file
+# /etc/udev/hwdb.d/71-joystick-local.hwdb
+# and add your rules there. To load the new rules execute (as root):
+# systemd-hwdb update
+# udevadm trigger /dev/input/eventXX
+# where /dev/input/eventXX is the joystick in question. If in
+# doubt, simply use /dev/input/event* to reload all input rules.
+#
+# If your changes are generally applicable, preferably send them as a pull
+# request to
+# https://github.com/systemd/systemd
+# or create a bug report on https://github.com/systemd/systemd/issues and
+# include your new rules, a description of the device, and the output of
+# udevadm info /dev/input/eventXX.
+#
+# Permitted keys:
+# Specify if a joystick is a built-in one or external:
+# ID_INPUT_JOYSTICK_INTEGRATION=internal|external
+#
+# If the property is missing, user-space can assume:
+# ID_INPUT_JOYSTICK_INTEGRATION=external
+
+joystick:bluetooth:*
+ ID_INPUT_JOYSTICK_INTEGRATION=external
+
+###########################################################
+# GPD
+###########################################################
+
+# GPD Win, Classic and XBox 360 compat modes
+joystick:usb:v11c5p5507*
+joystick:usb:v045ep028e*
+ ID_INPUT_JOYSTICK_INTEGRATION=internal
diff --git a/hwdb/parse_hwdb.py b/hwdb/parse_hwdb.py
index adf8a1963e..c7b49b83df 100755
--- a/hwdb/parse_hwdb.py
+++ b/hwdb/parse_hwdb.py
@@ -66,6 +66,7 @@ UDEV_TAG = Word(string.ascii_uppercase, alphanums + '_')
TYPES = {'mouse': ('usb', 'bluetooth', 'ps2', '*'),
'evdev': ('name', 'atkbd', 'input'),
'touchpad': ('i8042', 'rmi', 'bluetooth', 'usb'),
+ 'joystick': ('i8042', 'rmi', 'bluetooth', 'usb'),
'keyboard': ('name', ),
'sensor': ('modalias', ),
}
@@ -109,6 +110,7 @@ def property_grammar():
('MOUSE_WHEEL_TILT_VERTICAL', Literal('1')),
('POINTINGSTICK_SENSITIVITY', INTEGER),
('POINTINGSTICK_CONST_ACCEL', REAL),
+ ('ID_INPUT_JOYSTICK_INTEGRATION', Or(('internal', 'external'))),
('ID_INPUT_TOUCHPAD_INTEGRATION', Or(('internal', 'external'))),
('XKB_FIXED_LAYOUT', STRING),
('XKB_FIXED_VARIANT', STRING),
@@ -170,7 +172,9 @@ def check_one_keycode(prop, value):
if value != '!' and ecodes is not None:
key = 'KEY_' + value.upper()
if key not in ecodes:
- error('Keycode {} unknown', key)
+ key = value.upper()
+ if key not in ecodes:
+ error('Keycode {} unknown', key)
def check_properties(groups):
grammar = property_grammar()
diff --git a/man/networkctl.xml b/man/networkctl.xml
index 809eb7ec6a..d4fa5e9029 100644
--- a/man/networkctl.xml
+++ b/man/networkctl.xml
@@ -172,14 +172,40 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
1 neighbors listed.</programlisting></para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ <command>label</command>
+ </term>
+
+ <listitem><para>Show numerical address labels that can be used for address selection.
+ This is the same information that
+ <citerefentry><refentrytitle>ip-addrlabel</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ shows. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>
+ for a discussion of address labels.</para>
+
+ <para>Produces output similar to:
+ <programlisting>Prefix/Prefixlen Label
+ ::/0 1
+ fc00::/7 5
+ fec0::/10 11
+ 2002::/16 2
+ 3ffe::/16 12
+ 2001:10::/28 7
+ 2001::/32 6
+::ffff:0.0.0.0/96 4
+ ::/96 3
+ ::1/128 0</programlisting></para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
<refsect1>
<title>Exit status</title>
- <para>On success, 0 is returned, a non-zero failure
- code otherwise.</para>
+ <para>On success, 0 is returned, a non-zero failure code otherwise.</para>
</refsect1>
<refsect1>
@@ -187,7 +213,8 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
<para>
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry project='die-net'><refentrytitle>ip</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>
diff --git a/man/sd_bus_error.xml b/man/sd_bus_error.xml
index 3091e1f019..4970ce3c08 100644
--- a/man/sd_bus_error.xml
+++ b/man/sd_bus_error.xml
@@ -265,7 +265,7 @@
<parameter>dst</parameter> using the values in
<parameter>e</parameter>. If the strings in
<parameter>e</parameter> were set using
- <function>sd_bus_set_error_const()</function>, they will be shared.
+ <function>sd_bus_error_set_const()</function>, they will be shared.
Otherwise, they will be copied. Returns a converted
<varname>errno</varname>-like, negative error code.</para>
diff --git a/man/sd_notify.xml b/man/sd_notify.xml
index 4dcefc4baf..e8ddea2f5f 100644
--- a/man/sd_notify.xml
+++ b/man/sd_notify.xml
@@ -205,25 +205,24 @@
<varlistentry>
<term>FDSTORE=1</term>
- <listitem><para>Stores additional file descriptors in the service manager. File
- descriptors sent this way will be maintained per-service by the service manager
- and will be passed again using the usual file descriptor passing logic on the next
- invocation of the service, see
- <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
- This is useful for implementing service restart schemes where services serialize
- their state to <filename>/run</filename>, push their file descriptors to the
- system manager, and are then restarted, retrieving their state again via socket
- passing and <filename>/run</filename>. Note that the service manager will accept
- messages for a service only if <varname>FileDescriptorStoreMax=</varname> is set
- to non-zero for it (defaults to zero, see
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
- File descriptors must be pollable, see
- <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
- Multiple arrays of file descriptors may be sent in separate messages, in which
- case the arrays are combined. Note that the service manager removes duplicate
- file descriptors before passing them to the service. Use
- <function>sd_pid_notify_with_fds()</function> to send messages with
- <literal>FDSTORE=1</literal>, see below.</para></listitem>
+ <listitem><para>Stores additional file descriptors in the service manager. File descriptors sent this way will
+ be maintained per-service by the service manager and will later be handed back using the usual file descriptor
+ passing logic at the next invocation of the service, see
+ <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>. This is
+ useful for implementing services that can restart after an explicit request or a crash without losing
+ state. Any open sockets and other file descriptors which should not be closed during the restart may be stored
+ this way. Application state can either be serialized to a file in <filename>/run</filename>, or better, stored
+ in a <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory
+ file descriptor. Note that the service manager will accept messages for a service only if its
+ <varname>FileDescriptorStoreMax=</varname> setting is non-zero (defaults to zero, see
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If file
+ descriptors sent are pollable (see
+ <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>), then any
+ <constant>EPOLLHUP</constant> or <constant>EPOLLERR</constant> event seen on them will result in their
+ automatic removal from the store. Multiple arrays of file descriptors may be sent in separate messages, in
+ which case the arrays are combined. Note that the service manager removes duplicate (pointing to the same
+ object) file descriptors before passing them to the service. Use <function>sd_pid_notify_with_fds()</function>
+ to send messages with <literal>FDSTORE=1</literal>, see below.</para></listitem>
</varlistentry>
<varlistentry>
@@ -312,13 +311,14 @@
<refsect1>
<title>Return Value</title>
- <para>On failure, these calls return a negative errno-style error
- code. If <varname>$NOTIFY_SOCKET</varname> was not set and hence
- no status data could be sent, 0 is returned. If the status was
- sent, these functions return with a positive return value. In
- order to support both, init systems that implement this scheme and
- those which do not, it is generally recommended to ignore the
- return value of this call.</para>
+ <para>On failure, these calls return a negative errno-style error code. If <varname>$NOTIFY_SOCKET</varname> was
+ not set and hence no status message could be sent, 0 is returned. If the status was sent, these functions return a
+ positive value. In order to support both service managers that implement this scheme and those which do not, it is
+ generally recommended to ignore the return value of this call. Note that the return value simply indicates whether
+ the notification message was enqueued properly, it does not reflect whether the message could be processed
+ successfully. Specifically, no error is returned when a file descriptor is attempted to be stored using
+ <varname>FDSTORE=1</varname> but the service is not actually configured to permit storing of file descriptors (see
+ above).</para>
</refsect1>
<refsect1>
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index 71a4ed5a2b..f3910ca3f7 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -62,9 +62,10 @@
<arg choice="plain"><option>--list</option></arg>
</cmdsynopsis>
<cmdsynopsis>
- <command>systemd-umount</command>
+ <command>systemd-mount</command>
<arg choice="opt" rep="repeat"><replaceable>OPTIONS</replaceable></arg>
- <arg choice="plain" rep="repeat"><replaceable>WHERE</replaceable></arg>
+ <arg choice="plain"><option>--umount</option></arg>
+ <arg choice="plain" rep="repeat"><replaceable>WHAT|WHERE</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
@@ -253,7 +254,12 @@
<term><option>--umount</option></term>
<listitem><para>Stop the mount and automount units corresponding to the specified mount points
- <replaceable>WHERE</replaceable>.</para>
+ <replaceable>WHERE</replaceable> or the devices <replaceable>WHAT</replaceable>.
+ <command>systemd-mount</command> with this option or <command>systemd-umount</command> can take multiple arguments
+ which can be mount points, devices, <filename>/etc/fstab</filename> style node names, or backing files
+ corresponding to loop devices, like
+ <command>systemd-mount --umount /path/to/umount /dev/sda1 UUID=xxxxxx-xxxx LABEL=xxxxx /path/to/disk.img</command>.
+ </para>
</listitem>
</varlistentry>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index ae7082776d..7014443f53 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -398,24 +398,19 @@
<varlistentry>
<term><option>--slice=</option></term>
- <listitem><para>Make the container part of the specified
- slice, instead of the default
- <filename>machine.slice</filename>. This is only applies if
- the machine is run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used.</para>
+ <listitem><para>Make the container part of the specified slice, instead of the default
+ <filename>machine.slice</filename>. This applies only if the machine is run in its own scope unit, i.e. if
+ <option>--keep-unit</option> isn't used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--property=</option></term>
- <listitem><para>Set a unit property on the scope unit to
- register for the machine. This only applies if the machine is
- run in its own scope unit, i.e. if
- <option>--keep-unit</option> is not used. Takes unit property
- assignments in the same format as <command>systemctl
- set-property</command>. This is useful to set memory limits
- and similar for machines.</para>
+ <listitem><para>Set a unit property on the scope unit to register for the machine. This applies only if the
+ machine is run in its own scope unit, i.e. if <option>--keep-unit</option> isn't used. Takes unit property
+ assignments in the same format as <command>systemctl set-property</command>. This is useful to set memory
+ limits and similar for container.</para>
</listitem>
</varlistentry>
@@ -888,18 +883,16 @@
<varlistentry>
<term><option>--register=</option></term>
- <listitem><para>Controls whether the container is registered
- with
- <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
- Takes a boolean argument, which defaults to <literal>yes</literal>.
- This option should be enabled when the container runs a full
- Operating System (more specifically: an init system), and is
- useful to ensure that the container is accessible via
- <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
- and shown by tools such as
- <citerefentry project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
- If the container does not run an init system, it is
- recommended to set this option to <literal>no</literal>.</para></listitem>
+ <listitem><para>Controls whether the container is registered with
+ <citerefentry><refentrytitle>systemd-machined</refentrytitle><manvolnum>8</manvolnum></citerefentry>. Takes a
+ boolean argument, which defaults to <literal>yes</literal>. This option should be enabled when the container
+ runs a full Operating System (more specifically: a system and service manager as PID 1), and is useful to
+ ensure that the container is accessible via
+ <citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry> and shown by
+ tools such as <citerefentry
+ project='man-pages'><refentrytitle>ps</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If the container
+ does not run a service manager, it is recommended to set this option to
+ <literal>no</literal>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -916,7 +909,9 @@
service unit, and the service unit's sole purpose is to run a
single <command>systemd-nspawn</command> container. This
option is not available if run from a user
- session.</para></listitem>
+ session.</para>
+ <para>Note that passing <option>--keep-unit</option> disables the effect of <option>--slice=</option> and
+ <option>--property=</option>.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index 023e24eeb3..1e4a1528db 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -402,6 +402,47 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><varname>Port=</varname></term>
+ <listitem>
+ <para>The port option is used to select the device port. The
+ supported values are:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>tp</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Twisted-Pair cable as the medium.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>aui</literal></term>
+ <listitem>
+ <para>Attachment Unit Interface (AUI). Normally used with hubs.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>bnc</literal></term>
+ <listitem>
+ <para>An Ethernet interface using BNC connectors and co-axial cable.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>mii</literal></term>
+ <listitem>
+ <para>An Ethernet interface using a Media Independent Interface (MII).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>fibre</literal></term>
+ <listitem>
+ <para>An Ethernet interface using Optical Fibre as the medium.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
<para>The TCP Segmentation Offload (TSO) when true enables
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 95c16fded7..0678855945 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -328,14 +328,13 @@
all <varname>ExecStartPre=</varname> commands that were not prefixed
with a <literal>-</literal> exit successfully.</para>
- <para><varname>ExecStartPost=</varname> commands are only run after
- the service has started successfully, as determined by <varname>Type=</varname>
- (i.e. the process has been started for <varname>Type=simple</varname>
- or <varname>Type=idle</varname>, the process exits successfully for
- <varname>Type=oneshot</varname>, the initial process exits successfully
- for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent
- for <varname>Type=notify</varname>, or the <varname>BusName=</varname>
- has been taken for <varname>Type=dbus</varname>).</para>
+ <para><varname>ExecStartPost=</varname> commands are only run after the commands specified in
+ <varname>ExecStart=</varname> have been invoked successfully, as determined by <varname>Type=</varname>
+ (i.e. the process has been started for <varname>Type=simple</varname> or <varname>Type=idle</varname>, the last
+ <varname>ExecStart=</varname> process exited successfully for <varname>Type=oneshot</varname>, the initial
+ process exited successfully for <varname>Type=forking</varname>, <literal>READY=1</literal> is sent for
+ <varname>Type=notify</varname>, or the <varname>BusName=</varname> has been taken for
+ <varname>Type=dbus</varname>).</para>
<para>Note that <varname>ExecStartPre=</varname> may not be
used to start long-running processes. All processes forked
@@ -853,21 +852,18 @@
<varlistentry>
<term><varname>FileDescriptorStoreMax=</varname></term>
- <listitem><para>Configure how many file descriptors may be
- stored in the service manager for the service using
+ <listitem><para>Configure how many file descriptors may be stored in the service manager for the service using
<citerefentry><refentrytitle>sd_pid_notify_with_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
- <literal>FDSTORE=1</literal> messages. This is useful for
- implementing service restart schemes where the state is
- serialized to <filename>/run</filename> and the file
- descriptors passed to the service manager, to allow restarts
- without losing state. Defaults to 0, i.e. no file descriptors
- may be stored in the service manager. All file
- descriptors passed to the service manager from a specific
- service are passed back to the service's main process on the
- next service restart. Any file descriptors passed to the
- service manager are automatically closed when POLLHUP or
- POLLERR is seen on them, or when the service is fully stopped
- and no job is queued or being executed for it.</para></listitem>
+ <literal>FDSTORE=1</literal> messages. This is useful for implementing services that can restart after an
+ explicit request or a crash without losing state. Any open sockets and other file descriptors which should not
+ be closed during the restart may be stored this way. Application state can either be serialized to a file in
+ <filename>/run</filename>, or better, stored in a
+ <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory file
+ descriptor. Defaults to 0, i.e. no file descriptors may be stored in the service manager. All file descriptors
+ passed to the service manager from a specific service are passed back to the service's main process on the next
+ service restart. Any file descriptors passed to the service manager are automatically closed when
+ <constant>POLLHUP</constant> or <constant>POLLERR</constant> is seen on them, or when the service is fully
+ stopped and no job is queued or being executed for it.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index b3cccd4e52..dbe7ff014b 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -99,6 +99,43 @@
</refsect1>
<refsect1>
+ <title>Example</title>
+
+ <example>
+ <title>Simple standalone target</title>
+
+ <programlisting># emergency-net.target
+
+[Unit]
+Description=Emergency Mode with Networking
+Requires=emergency.target systemd-networkd.service
+After=emergency.target systemd-networkd.service
+AllowIsolate=yes</programlisting>
+
+ <para>When adding dependencies to other units, it's important to check if they set
+ <varname>DefaultDependencies=</varname>. Service units, unless they set
+ <varname>DefaultDependencies=no</varname>, automatically get a dependency on
+ <filename>sysinit.target</filename>. In this case, both
+ <filename>emergency.target</filename> and <filename>systemd-networkd.service</filename>
+ have <varname>DefaultDependencies=no</varname>, so they are suitable for use
+ in this target, and do not pull in <filename>sysinit.target</filename>.</para>
+
+ <para>You can now switch into this emergency mode by running <varname>systemctl
+ isolate emergency-net.target</varname> or by passing the option
+ <varname>systemd.unit=emergency-net.target</varname> on the kernel command
+ line.</para>
+
+ <para>Other units can have <varname>WantedBy=emergency-net.target</varname> in the
+ <varname>[Install]</varname> section. After they are enabled using
+ <command>systemctl enable</command>, they will be started before
+ <varname>emergency-net.target</varname> is started. It is also possible to add
+ arbitrary units as dependencies of <filename>emergency.target</filename> without
+ modifying them by using <command>systemctl add-wants</command>.
+ </para>
+ </example>
+ </refsect1>
+
+ <refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 441378936a..dedeb6c6d0 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -546,26 +546,29 @@
<term><varname>Before=</varname></term>
<term><varname>After=</varname></term>
- <listitem><para>A space-separated list of unit names. Configures ordering dependencies between units. If a
- unit <filename>foo.service</filename> contains a setting <option>Before=bar.service</option> and both units are
- being started, <filename>bar.service</filename>'s start-up is delayed until <filename>foo.service</filename> is
- started up. Note that this setting is independent of and orthogonal to the requirement dependencies as
- configured by <varname>Requires=</varname>, <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a
- common pattern to include a unit name in both the <varname>After=</varname> and <varname>Requires=</varname>
- option, in which case the unit listed will be started before the unit that is configured with these
- options. This option may be specified more than once, in which case ordering dependencies for all listed names
- are created. <varname>After=</varname> is the inverse of <varname>Before=</varname>, i.e. while
- <varname>After=</varname> ensures that the configured unit is started after the listed unit finished starting
- up, <varname>Before=</varname> ensures the opposite, i.e. that the configured unit is fully started up before
- the listed unit is started. Note that when two units with an ordering dependency between them are shut down,
- the inverse of the start-up order is applied. i.e. if a unit is configured with <varname>After=</varname> on
- another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering
- dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before
- the start-up. It doesn't matter if the ordering dependency is <varname>After=</varname> or
- <varname>Before=</varname>, in this case. It also doesn't matter which of the two is shut down, as long as one
- is shut down and the other is started up. The shutdown is ordered before the start-up in all cases. If two
- units have no ordering dependencies between them, they are shut down or started up simultaneously, and no
- ordering takes place. </para></listitem>
+ <listitem><para>These two settings expect a space-separated list of unit names. They configure ordering
+ dependencies between units. If a unit <filename>foo.service</filename> contains a setting
+ <option>Before=bar.service</option> and both units are being started, <filename>bar.service</filename>'s
+ start-up is delayed until <filename>foo.service</filename> has finished starting up. Note that this setting is
+ independent of and orthogonal to the requirement dependencies as configured by <varname>Requires=</varname>,
+ <varname>Wants=</varname> or <varname>BindsTo=</varname>. It is a common pattern to include a unit name in both
+ the <varname>After=</varname> and <varname>Requires=</varname> options, in which case the unit listed will be
+ started before the unit that is configured with these options. This option may be specified more than once, in
+ which case ordering dependencies for all listed names are created. <varname>After=</varname> is the inverse of
+ <varname>Before=</varname>, i.e. while <varname>After=</varname> ensures that the configured unit is started
+ after the listed unit finished starting up, <varname>Before=</varname> ensures the opposite, that the
+ configured unit is fully started up before the listed unit is started. Note that when two units with an
+ ordering dependency between them are shut down, the inverse of the start-up order is applied. i.e. if a unit is
+ configured with <varname>After=</varname> on another unit, the former is stopped before the latter if both are
+ shut down. Given two units with any ordering dependency between them, if one unit is shut down and the other is
+ started up, the shutdown is ordered before the start-up. It doesn't matter if the ordering dependency is
+ <varname>After=</varname> or <varname>Before=</varname>, in this case. It also doesn't matter which of the two
+ is shut down, as long as one is shut down and the other is started up. The shutdown is ordered before the
+ start-up in all cases. If two units have no ordering dependencies between them, they are shut down or started
+ up simultaneously, and no ordering takes place. It depends on the unit type when precisely a unit has finished
+ starting up. Most importantly, for service units start-up is considered completed for the purpose of
+ <varname>Before=</varname>/<varname>After=</varname> when all its configured start-up commands have been
+ invoked and they either failed or reported start-up success.</para></listitem>
</varlistentry>
<varlistentry>
@@ -980,13 +983,11 @@
to make sure they run before the stamp file's modification
time gets reset indicating a completed update.</para>
- <para><varname>ConditionFirstBoot=</varname> takes a boolean
- argument. This condition may be used to conditionalize units
- on whether the system is booting up with an unpopulated
- <filename>/etc</filename> directory. This may be used to
- populate <filename>/etc</filename> on the first boot after
- factory reset, or when a new system instances boots up for the
- first time.</para>
+ <para><varname>ConditionFirstBoot=</varname> takes a boolean argument. This condition may be used to
+ conditionalize units on whether the system is booting up with an unpopulated <filename>/etc</filename>
+ directory (specifically: an <filename>/etc</filename> with no <filename>/etc/machine-id</filename>). This may
+ be used to populate <filename>/etc</filename> on the first boot after factory reset, or when a new system
+ instance boots up for the first time.</para>
<para>With <varname>ConditionPathExists=</varname> a file
existence condition is checked before a unit is started. If
diff --git a/meson.build b/meson.build
index be33ea10dc..af68a2ff83 100644
--- a/meson.build
+++ b/meson.build
@@ -312,7 +312,6 @@ link_test_c = files('tools/meson-link-test.c')
foreach arg : ['-Wl,-z,relro',
'-Wl,-z,now',
'-pie',
- '-Wl,-fuse-ld=gold',
]
have = run_command(check_compilation_sh,
diff --git a/rules/50-udev-default.rules.in b/rules/50-udev-default.rules.in
index e556533020..898148c064 100644
--- a/rules/50-udev-default.rules.in
+++ b/rules/50-udev-default.rules.in
@@ -11,7 +11,6 @@ SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc"
SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
-SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"
ACTION!="add", GOTO="default_end"
diff --git a/rules/60-evdev.rules b/rules/60-evdev.rules
index f5d5ba6a5f..e5e608acd3 100644
--- a/rules/60-evdev.rules
+++ b/rules/60-evdev.rules
@@ -8,7 +8,7 @@ IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=evdev:", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
# AT keyboard matching by the machine's DMI data
-ENV{ID_INPUT_KEY}=="?*", DRIVERS=="atkbd", \
+DRIVERS=="atkbd", \
IMPORT{builtin}="hwdb 'evdev:atkbd:$attr{[dmi/id]modalias}'", \
RUN{builtin}+="keyboard", GOTO="evdev_end"
diff --git a/rules/60-input-id.rules b/rules/60-input-id.rules
new file mode 100644
index 0000000000..dee42199b6
--- /dev/null
+++ b/rules/60-input-id.rules
@@ -0,0 +1,7 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="id_input_end"
+
+SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
+
+LABEL="id_input_end"
diff --git a/rules/70-joystick.rules b/rules/70-joystick.rules
new file mode 100644
index 0000000000..b80d203670
--- /dev/null
+++ b/rules/70-joystick.rules
@@ -0,0 +1,12 @@
+# do not edit this file, it will be overwritten on update
+
+ACTION=="remove", GOTO="joystick_end"
+ENV{ID_INPUT_JOYSTICK}=="", GOTO="joystick_end"
+KERNEL!="event*", GOTO="joystick_end"
+
+# joystick:<bustype>:v<vid>p<pid>:name:<name>:*
+KERNELS=="input*", ENV{ID_BUS}!="", \
+ IMPORT{builtin}="hwdb 'joystick:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \
+ GOTO="joystick_end"
+
+LABEL="joystick_end"
diff --git a/rules/meson.build b/rules/meson.build
index 1cd37f3cf3..0f818a506f 100644
--- a/rules/meson.build
+++ b/rules/meson.build
@@ -3,6 +3,7 @@ rules = files('''
60-cdrom_id.rules
60-drm.rules
60-evdev.rules
+ 60-input-id.rules
60-persistent-alsa.rules
60-persistent-input.rules
60-persistent-storage.rules
diff --git a/shell-completion/bash/networkctl b/shell-completion/bash/networkctl
index 942c7e1c00..68e3338471 100644
--- a/shell-completion/bash/networkctl
+++ b/shell-completion/bash/networkctl
@@ -36,7 +36,7 @@ _networkctl() {
)
local -A VERBS=(
- [STANDALONE]='list lldp'
+ [STANDALONE]='list lldp label'
[LINKS]='status'
)
diff --git a/shell-completion/zsh/_networkctl b/shell-completion/zsh/_networkctl
index 61f173b78e..acf7463edb 100644
--- a/shell-completion/zsh/_networkctl
+++ b/shell-completion/zsh/_networkctl
@@ -6,6 +6,7 @@ _networkctl_command(){
'list:List existing links'
'status:Show information about the specified links'
'lldp:Show Link Layer Discovery Protocol status'
+ 'label:Show address labels'
)
if (( CURRENT == 1 )); then
_describe -t commands 'networkctl command' _networkctl_cmds
diff --git a/src/basic/missing.h b/src/basic/missing.h
index 55028754cd..7c323c61cf 100644
--- a/src/basic/missing.h
+++ b/src/basic/missing.h
@@ -23,6 +23,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <linux/audit.h>
#include <linux/capability.h>
#include <linux/if_link.h>
@@ -569,6 +570,17 @@ struct btrfs_ioctl_quota_ctl_args {
# define EVIOCREVOKE _IOW('E', 0x91, int)
#endif
+#ifndef EVIOCSMASK
+
+struct input_mask {
+ uint32_t type;
+ uint32_t codes_size;
+ uint64_t codes_ptr;
+};
+
+#define EVIOCSMASK _IOW('E', 0x93, struct input_mask)
+#endif
+
#ifndef DRM_IOCTL_SET_MASTER
# define DRM_IOCTL_SET_MASTER _IO('d', 0x1e)
#endif
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
index d4096b8cae..898116c7b3 100644
--- a/src/basic/missing_syscall.h
+++ b/src/basic/missing_syscall.h
@@ -216,6 +216,10 @@ static inline pid_t raw_getpid(void) {
# endif
# elif defined __i386__
# define __NR_renameat2 353
+# elif defined __powerpc64__
+# define __NR_renameat2 357
+# elif defined __s390__ || defined __s390x__
+# define __NR_renameat2 347
# elif defined __arc__
# define __NR_renameat2 276
# else
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index a21dc35baa..b80cacaa42 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -905,6 +905,23 @@ int pid_compare_func(const void *a, const void *b) {
return 0;
}
+int ioprio_parse_priority(const char *s, int *ret) {
+ int i, r;
+
+ assert(s);
+ assert(ret);
+
+ r = safe_atoi(s, &i);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_priority_is_valid(i))
+ return -EINVAL;
+
+ *ret = i;
+ return 0;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
index d378901399..28d8d7499a 100644
--- a/src/basic/process-util.h
+++ b/src/basic/process-util.h
@@ -25,10 +25,11 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/resource.h>
+#include <sys/types.h>
#include "format-util.h"
+#include "ioprio.h"
#include "macro.h"
#define procfs_file_alloca(pid, field) \
@@ -108,3 +109,13 @@ int pid_compare_func(const void *a, const void *b);
static inline bool nice_is_valid(int n) {
return n >= PRIO_MIN && n < PRIO_MAX;
}
+
+static inline bool ioprio_class_is_valid(int i) {
+ return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
+}
+
+static inline bool ioprio_priority_is_valid(int i) {
+ return i >= 0 && i < IOPRIO_BE_NR;
+}
+
+int ioprio_parse_priority(const char *s, int *ret);
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index 0a6efa449a..920ca0d9f5 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -1047,3 +1047,12 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);
+
+static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
+ [NOTIFY_NONE] = "none",
+ [NOTIFY_MAIN] = "main",
+ [NOTIFY_EXEC] = "exec",
+ [NOTIFY_ALL] = "all"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h
index 44eadf0347..0f164a6aa9 100644
--- a/src/basic/unit-name.h
+++ b/src/basic/unit-name.h
@@ -257,6 +257,15 @@ typedef enum UnitDependency {
_UNIT_DEPENDENCY_INVALID = -1
} UnitDependency;
+typedef enum NotifyAccess {
+ NOTIFY_NONE,
+ NOTIFY_ALL,
+ NOTIFY_MAIN,
+ NOTIFY_EXEC,
+ _NOTIFY_ACCESS_MAX,
+ _NOTIFY_ACCESS_INVALID = -1
+} NotifyAccess;
+
typedef enum UnitNameFlags {
UNIT_NAME_PLAIN = 1, /* Allow foo.service */
UNIT_NAME_INSTANCE = 2, /* Allow foo@bar.service */
@@ -365,3 +374,6 @@ TimerState timer_state_from_string(const char *s) _pure_;
const char *unit_dependency_to_string(UnitDependency i) _const_;
UnitDependency unit_dependency_from_string(const char *s) _pure_;
+
+const char* notify_access_to_string(NotifyAccess i) _const_;
+NotifyAccess notify_access_from_string(const char *s) _pure_;
diff --git a/src/core/automount.c b/src/core/automount.c
index c040efa931..6a5612a769 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -474,10 +474,10 @@ static int automount_send_ready(Automount *a, Set *tokens, int status) {
while ((token = PTR_TO_UINT(set_steal_first(tokens)))) {
int k;
- /* Autofs fun fact II:
+ /* Autofs fun fact:
*
- * if you pass a positive status code here, the kernel will
- * freeze! Yay! */
+ * if you pass a positive status code here, kernels
+ * prior to 4.12 will freeze! Yay! */
k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
ioctl_fd,
@@ -619,12 +619,6 @@ static void automount_enter_waiting(Automount *a) {
if (r < 0)
goto fail;
- /* Autofs fun fact:
- *
- * Unless we close the ioctl fd here, for some weird reason
- * the direct mount will not receive events from the
- * kernel. */
-
r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
if (r < 0)
goto fail;
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 0454a28e12..c041a7d94c 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -45,6 +45,7 @@
#endif
#include "strv.h"
#include "syslog-util.h"
+#include "unit-printf.h"
#include "user-util.h"
#include "utf8.h"
@@ -159,21 +160,50 @@ static int property_get_ioprio(
ExecContext *c = userdata;
- int32_t n;
assert(bus);
assert(reply);
assert(c);
- if (c->ioprio_set)
- n = c->ioprio;
- else {
- n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
- if (n < 0)
- n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
- }
+ return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
+}
- return sd_bus_message_append(reply, "i", n);
+static int property_get_ioprio_class(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ ExecContext *c = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
+}
+
+static int property_get_ioprio_priority(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+
+ ExecContext *c = userdata;
+
+ assert(bus);
+ assert(reply);
+ assert(c);
+
+ return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
}
static int property_get_cpu_sched_policy(
@@ -761,7 +791,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -783,7 +814,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
@@ -793,9 +823,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
- SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -830,6 +857,14 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
+
+ /* Obsolete/redundant properties: */
+ SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+ SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
+
SD_BUS_VTABLE_END
};
@@ -1001,7 +1036,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "SyslogLevel")) {
- int level;
+ int32_t level;
r = sd_bus_message_read(message, "i", &level);
if (r < 0)
@@ -1017,7 +1052,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "SyslogFacility")) {
- int facility;
+ int32_t facility;
r = sd_bus_message_read(message, "i", &facility);
if (r < 0)
@@ -1033,7 +1068,7 @@ int bus_exec_context_set_transient_property(
return 1;
} else if (streq(name, "Nice")) {
- int n;
+ int32_t n;
r = sd_bus_message_read(message, "i", &n);
if (r < 0)
@@ -1049,6 +1084,50 @@ int bus_exec_context_set_transient_property(
return 1;
+ } else if (streq(name, "IOSchedulingClass")) {
+ int32_t q;
+
+ r = sd_bus_message_read(message, "i", &q);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_class_is_valid(q))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
+
+ if (mode != UNIT_CHECK) {
+ _cleanup_free_ char *s = NULL;
+
+ r = ioprio_class_to_string_alloc(q, &s);
+ if (r < 0)
+ return r;
+
+ c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
+ c->ioprio_set = true;
+
+ unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
+ }
+
+ return 1;
+
+ } else if (streq(name, "IOSchedulingPriority")) {
+ int32_t p;
+
+ r = sd_bus_message_read(message, "i", &p);
+ if (r < 0)
+ return r;
+
+ if (!ioprio_priority_is_valid(p))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
+
+ if (mode != UNIT_CHECK) {
+ c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
+ c->ioprio_set = true;
+
+ unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
+ }
+
+ return 1;
+
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
const char *s;
@@ -1317,7 +1396,7 @@ int bus_exec_context_set_transient_property(
} else if (streq(name, "Environment")) {
- _cleanup_strv_free_ char **l = NULL;
+ _cleanup_strv_free_ char **l = NULL, **q = NULL;
r = sd_bus_message_read_strv(message, &l);
if (r < 0)
@@ -1326,22 +1405,27 @@ int bus_exec_context_set_transient_property(
if (!strv_env_is_valid(l))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
- if (mode != UNIT_CHECK) {
- _cleanup_free_ char *joined = NULL;
- char **e;
+ r = unit_full_printf_strv(u, l, &q);
+ if (r < 0)
+ return r;
- if (strv_length(l) == 0) {
+ if (mode != UNIT_CHECK) {
+ if (strv_length(q) == 0) {
c->environment = strv_free(c->environment);
unit_write_drop_in_private_format(u, mode, name, "Environment=");
} else {
- e = strv_env_merge(2, c->environment, l);
+ _cleanup_free_ char *joined = NULL;
+ char **e;
+
+ e = strv_env_merge(2, c->environment, q);
if (!e)
return -ENOMEM;
strv_free(c->environment);
c->environment = e;
- joined = strv_join_quoted(c->environment);
+ /* We write just the new settings out to file, with unresolved specifiers */
+ joined = strv_join_quoted(q);
if (!joined)
return -ENOMEM;
diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c
index 85b67318ed..6458ee5c12 100644
--- a/src/core/dbus-service.c
+++ b/src/core/dbus-service.c
@@ -199,6 +199,39 @@ static int bus_service_set_transient_property(
return 1;
+ } else if (streq(name, "FileDescriptorStoreMax")) {
+ uint32_t u;
+
+ r = sd_bus_message_read(message, "u", &u);
+ if (r < 0)
+ return r;
+
+ if (mode != UNIT_CHECK) {
+ s->n_fd_store_max = (unsigned) u;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "FileDescriptorStoreMax=%" PRIu32, u);
+ }
+
+ return 1;
+
+ } else if (streq(name, "NotifyAccess")) {
+ const char *t;
+ NotifyAccess k;
+
+ r = sd_bus_message_read(message, "s", &t);
+ if (r < 0)
+ return r;
+
+ k = notify_access_from_string(t);
+ if (k < 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t);
+
+ if (mode != UNIT_CHECK) {
+ s->notify_access = k;
+ unit_write_drop_in_private_format(UNIT(s), mode, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
+ }
+
+ return 1;
+
} else if (streq(name, "ExecStart")) {
unsigned n = 0;
diff --git a/src/core/execute.c b/src/core/execute.c
index 340939d98a..d72e5bf08c 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -3701,6 +3701,21 @@ bool exec_context_maintains_privileges(ExecContext *c) {
return false;
}
+int exec_context_get_effective_ioprio(ExecContext *c) {
+ int p;
+
+ assert(c);
+
+ if (c->ioprio_set)
+ return c->ioprio;
+
+ p = ioprio_get(IOPRIO_WHO_PROCESS, 0);
+ if (p < 0)
+ return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
+
+ return p;
+}
+
void exec_status_start(ExecStatus *s, pid_t pid) {
assert(s);
diff --git a/src/core/execute.h b/src/core/execute.h
index 136319359c..9f07aa4aef 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -307,6 +307,8 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index);
bool exec_context_may_touch_console(ExecContext *c);
bool exec_context_maintains_privileges(ExecContext *c);
+int exec_context_get_effective_ioprio(ExecContext *c);
+
void exec_status_start(ExecStatus *s, pid_t pid);
void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index af3c6a4606..8d7153f1b9 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -940,8 +940,8 @@ int config_parse_exec_io_priority(const char *unit,
assert(rvalue);
assert(data);
- r = safe_atoi(rvalue, &i);
- if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) {
+ r = ioprio_parse_priority(rvalue, &i);
+ if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue);
return 0;
}
diff --git a/src/core/loopback-setup.c b/src/core/loopback-setup.c
index 82addfdde6..a7b801c47d 100644
--- a/src/core/loopback-setup.c
+++ b/src/core/loopback-setup.c
@@ -26,6 +26,8 @@
#include "missing.h"
#include "netlink-util.h"
+#define LOOPBACK_SETUP_TIMEOUT_USEC (5 * USEC_PER_SEC)
+
struct state {
unsigned n_messages;
int rcode;
@@ -61,7 +63,7 @@ static int start_loopback(sd_netlink *rtnl, struct state *s) {
if (r < 0)
return r;
- r = sd_netlink_call_async(rtnl, req, start_loopback_handler, s, USEC_INFINITY, NULL);
+ r = sd_netlink_call_async(rtnl, req, start_loopback_handler, s, LOOPBACK_SETUP_TIMEOUT_USEC, NULL);
if (r < 0)
return r;
@@ -201,7 +203,7 @@ int loopback_setup(void) {
return log_error_errno(r, "Failed to enqueue loopback interface start request: %m");
while (state.n_messages > 0) {
- r = sd_netlink_wait(rtnl, USEC_INFINITY);
+ r = sd_netlink_wait(rtnl, LOOPBACK_SETUP_TIMEOUT_USEC);
if (r < 0)
return log_error_errno(r, "Failed to wait for netlink event: %m");
diff --git a/src/core/main.c b/src/core/main.c
index c2439ed185..88e2c92504 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1780,7 +1780,7 @@ int main(int argc, char *argv[]) {
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_error_errno(errno, "Failed to adjust timer slack: %m");
- if (!cap_test_all(arg_capability_bounding_set)) {
+ if (arg_system && !cap_test_all(arg_capability_bounding_set)) {
r = capability_bounding_set_drop_usermode(arg_capability_bounding_set);
if (r < 0) {
log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m");
diff --git a/src/core/service.c b/src/core/service.c
index df7f1f3053..4c577db8d7 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -413,13 +413,12 @@ static int service_add_fd_store(Service *s, int fd, const char *name) {
}
r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
- if (r < 0) {
+ if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
free(fs->fdname);
free(fs);
return r;
- }
-
- (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
+ } else if (r >= 0)
+ (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
LIST_PREPEND(fd_store, s->fd_store, fs);
s->n_fd_store++;
@@ -3584,15 +3583,6 @@ static const char* const service_exec_command_table[_SERVICE_EXEC_COMMAND_MAX] =
DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
-static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
- [NOTIFY_NONE] = "none",
- [NOTIFY_MAIN] = "main",
- [NOTIFY_EXEC] = "exec",
- [NOTIFY_ALL] = "all"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(notify_access, NotifyAccess);
-
static const char* const notify_state_table[_NOTIFY_STATE_MAX] = {
[NOTIFY_UNKNOWN] = "unknown",
[NOTIFY_READY] = "ready",
diff --git a/src/core/service.h b/src/core/service.h
index ff9cfaeb88..f4ba604f69 100644
--- a/src/core/service.h
+++ b/src/core/service.h
@@ -61,15 +61,6 @@ typedef enum ServiceExecCommand {
_SERVICE_EXEC_COMMAND_INVALID = -1
} ServiceExecCommand;
-typedef enum NotifyAccess {
- NOTIFY_NONE,
- NOTIFY_ALL,
- NOTIFY_MAIN,
- NOTIFY_EXEC,
- _NOTIFY_ACCESS_MAX,
- _NOTIFY_ACCESS_INVALID = -1
-} NotifyAccess;
-
typedef enum NotifyState {
NOTIFY_UNKNOWN,
NOTIFY_READY,
@@ -218,9 +209,6 @@ ServiceType service_type_from_string(const char *s) _pure_;
const char* service_exec_command_to_string(ServiceExecCommand i) _const_;
ServiceExecCommand service_exec_command_from_string(const char *s) _pure_;
-const char* notify_access_to_string(NotifyAccess i) _const_;
-NotifyAccess notify_access_from_string(const char *s) _pure_;
-
const char* notify_state_to_string(NotifyState i) _const_;
NotifyState notify_state_from_string(const char *s) _pure_;
diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c
index 5a6d11cfa1..adf2293142 100644
--- a/src/core/smack-setup.c
+++ b/src/core/smack-setup.c
@@ -264,6 +264,54 @@ static int write_netlabel_rules(const char* srcdir) {
return r;
}
+static int write_onlycap_list(void) {
+ _cleanup_close_ int onlycap_fd = -1;
+ _cleanup_free_ char *list = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
+ size_t len = 0, allocated = 0;
+ char buf[LINE_MAX];
+ int r;
+
+ f = fopen("/etc/smack/onlycap", "re");
+ if (!f) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to read '/etc/smack/onlycap'");
+ return errno == ENOENT ? ENOENT : -errno;
+ }
+
+ FOREACH_LINE(buf, f, return -errno) {
+ size_t l;
+
+ if (isempty(truncate_nl(buf)) || strchr(COMMENTS, *buf))
+ continue;
+
+ l = strlen(buf);
+ if (!GREEDY_REALLOC(list, allocated, len + l + 1))
+ return log_oom();
+
+ stpcpy(list + len, buf)[0] = ' ';
+ len += l + 1;
+ }
+
+ if (!len)
+ return 0;
+
+ list[len - 1] = 0;
+
+ onlycap_fd = open("/sys/fs/smackfs/onlycap", O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+ if (onlycap_fd < 0) {
+ if (errno != ENOENT)
+ log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/onlycap'");
+ return -errno; /* negative error */
+ }
+
+ r = write(onlycap_fd, list, len);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to write onlycap list(%s) to '/sys/fs/smackfs/onlycap'", list);
+
+ return 0;
+}
+
#endif
int mac_smack_setup(bool *loaded_policy) {
@@ -338,6 +386,22 @@ int mac_smack_setup(bool *loaded_policy) {
break;
}
+ r = write_onlycap_list();
+ switch(r) {
+ case -ENOENT:
+ log_debug("Smack is not enabled in the kernel.");
+ break;
+ case ENOENT:
+ log_debug("Smack onlycap list file '/etc/smack/onlycap' not found");
+ break;
+ case 0:
+ log_info("Successfully wrote Smack onlycap list.");
+ break;
+ default:
+ log_emergency_errno(r, "Failed to write Smack onlycap list.");
+ return r;
+ }
+
*loaded_policy = true;
#endif
diff --git a/src/core/swap.c b/src/core/swap.c
index e9468e105c..4c3a74ce00 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -487,13 +487,14 @@ static void swap_set_state(Swap *s, SwapState state) {
old_state = s->state;
s->state = state;
- if (state != SWAP_ACTIVATING &&
- state != SWAP_ACTIVATING_SIGTERM &&
- state != SWAP_ACTIVATING_SIGKILL &&
- state != SWAP_ACTIVATING_DONE &&
- state != SWAP_DEACTIVATING &&
- state != SWAP_DEACTIVATING_SIGTERM &&
- state != SWAP_DEACTIVATING_SIGKILL) {
+ if (!IN_SET(state,
+ SWAP_ACTIVATING,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_DONE,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL)) {
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
swap_unwatch_control_pid(s);
s->control_command = NULL;
@@ -695,20 +696,19 @@ static void swap_enter_active(Swap *s, SwapResult f) {
static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) {
int r;
+ KillOperation kop;
assert(s);
if (s->result == SWAP_SUCCESS)
s->result = f;
- r = unit_kill_context(
- UNIT(s),
- &s->kill_context,
- (state != SWAP_ACTIVATING_SIGTERM && state != SWAP_DEACTIVATING_SIGTERM) ?
- KILL_KILL : KILL_TERMINATE,
- -1,
- s->control_pid,
- false);
+ if (IN_SET(state, SWAP_ACTIVATING_SIGTERM, SWAP_DEACTIVATING_SIGTERM))
+ kop = KILL_TERMINATE;
+ else
+ kop = KILL_KILL;
+
+ r = unit_kill_context(UNIT(s), &s->kill_context, kop, -1, s->control_pid, false);
if (r < 0)
goto fail;
@@ -829,17 +829,18 @@ static int swap_start(Unit *u) {
/* We cannot fulfill this request right now, try again later
* please! */
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return -EAGAIN;
if (s->state == SWAP_ACTIVATING)
return 0;
- assert(s->state == SWAP_DEAD || s->state == SWAP_FAILED);
+ assert(IN_SET(s->state, SWAP_DEAD, SWAP_FAILED));
if (detect_container() > 0)
return -EPERM;
@@ -873,16 +874,15 @@ static int swap_stop(Unit *u) {
assert(s);
- if (s->state == SWAP_DEACTIVATING ||
- s->state == SWAP_DEACTIVATING_SIGTERM ||
- s->state == SWAP_DEACTIVATING_SIGKILL ||
- s->state == SWAP_ACTIVATING_SIGTERM ||
- s->state == SWAP_ACTIVATING_SIGKILL)
+ if (IN_SET(s->state,
+ SWAP_DEACTIVATING,
+ SWAP_DEACTIVATING_SIGTERM,
+ SWAP_DEACTIVATING_SIGKILL,
+ SWAP_ACTIVATING_SIGTERM,
+ SWAP_ACTIVATING_SIGKILL))
return 0;
- assert(s->state == SWAP_ACTIVATING ||
- s->state == SWAP_ACTIVATING_DONE ||
- s->state == SWAP_ACTIVE);
+ assert(IN_SET(s->state, SWAP_ACTIVATING, SWAP_ACTIVATING_DONE, SWAP_ACTIVE));
if (detect_container() > 0)
return -EPERM;
@@ -1340,7 +1340,7 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
struct udev_list_entry *item = NULL, *first = NULL;
_cleanup_free_ char *e = NULL;
const char *dn;
- Swap *s;
+ Unit *u;
int r = 0;
assert(m);
@@ -1354,9 +1354,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
if (r < 0)
return r;
- s = hashmap_get(m->units, e);
- if (s)
- r = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, e);
+ if (u)
+ r = swap_set_devnode(SWAP(u), dn);
first = udev_device_get_devlinks_list_entry(dev);
udev_list_entry_foreach(item, first) {
@@ -1367,9 +1367,9 @@ int swap_process_device_new(Manager *m, struct udev_device *dev) {
if (q < 0)
return q;
- s = hashmap_get(m->units, n);
- if (s) {
- q = swap_set_devnode(s, dn);
+ u = manager_get_unit(m, n);
+ if (u) {
+ q = swap_set_devnode(SWAP(u), dn);
if (q < 0)
r = q;
}
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 3578e2513c..c5319169b3 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -305,6 +305,15 @@ static int add_swap(const char *path) {
assert(path);
+ /* Disable the swap auto logic if at least one swap is defined in /etc/fstab, see #6192. */
+ r = fstab_has_fstype("swap");
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r == 0) {
+ log_debug("swap specified in fstab, ignoring.");
+ return 0;
+ }
+
log_debug("Adding swap: %s", path);
r = unit_name_from_path(path, ".swap", &name);
@@ -435,7 +444,10 @@ static int add_esp(DissectedPartition *p) {
esp = access("/efi/", F_OK) >= 0 ? "/efi" : "/boot";
/* We create an .automount which is not overridden by the .mount from the fstab generator. */
- if (fstab_is_mount_point(esp)) {
+ r = fstab_is_mount_point(esp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse fstab: %m");
+ if (r == 0) {
log_debug("%s specified in fstab, ignoring.", esp);
return 0;
}
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 974e42d7ce..b45ac814a9 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -444,7 +444,7 @@ static int raw_pull_rename_auxiliary_file(
assert(suffix);
assert(path);
- /* Regenerate final name for this auxiliary file, we might know the etag of the raw file now, and we shoud
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and we should
* incorporate it in the file name if we can */
*path = mfree(*path);
r = raw_pull_determine_path(i, suffix, path);
@@ -538,7 +538,7 @@ static void raw_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to move RAW file into place: %m");
+ log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
goto finish;
}
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 16ce901650..12211a6fc6 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -114,6 +114,7 @@ TarPull* tar_pull_unref(TarPull *i) {
free(i->settings_path);
free(i->image_root);
free(i->local);
+
return mfree(i);
}
@@ -358,7 +359,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename to final image name: %m");
+ log_error_errno(r, "Failed to rename to final image name to %s: %m", i->final_path);
goto finish;
}
@@ -367,13 +368,14 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (i->settings_job &&
i->settings_job->error == 0) {
- assert(i->settings_temp_path);
- assert(i->settings_path);
-
- /* Also move the settings file into place, if it exist. Note that we do so only if we also
+ /* Also move the settings file into place, if it exists. Note that we do so only if we also
* moved the tar file in place, to keep things strictly in sync. */
+ assert(i->settings_temp_path);
+ /* Regenerate final name for this auxiliary file, we might know the etag of the file now, and
+ * we should incorporate it in the file name if we can */
i->settings_path = mfree(i->settings_path);
+
r = tar_pull_determine_path(i, ".nspawn", &i->settings_path);
if (r < 0)
goto finish;
@@ -384,7 +386,7 @@ static void tar_pull_job_on_finished(PullJob *j) {
r = rename_noreplace(AT_FDCWD, i->settings_temp_path, AT_FDCWD, i->settings_path);
if (r < 0) {
- log_error_errno(r, "Failed to rename settings file: %m");
+ log_error_errno(r, "Failed to rename settings file to %s: %m", i->settings_path);
goto finish;
}
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index f990ac9303..698a5a9dc8 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -2365,20 +2365,13 @@ int main(int argc, char *argv[]) {
log_error_errno(r, "Failed to iterate through journal: %m");
goto finish;
}
- if (r == 0) {
- if (arg_follow)
- need_seek = true;
- else {
- if (!arg_quiet)
- printf("-- No entries --\n");
- goto finish;
- }
- }
+ if (r == 0)
+ need_seek = true;
if (!arg_follow)
pager_open(arg_no_pager, arg_pager_end);
- if (!arg_quiet) {
+ if (!arg_quiet && (arg_lines != 0 || arg_follow)) {
usec_t start, end;
char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
@@ -2474,6 +2467,9 @@ int main(int argc, char *argv[]) {
}
if (!arg_follow) {
+ if (n_shown == 0 && !arg_quiet)
+ printf("-- No entries --\n");
+
if (arg_show_cursor) {
_cleanup_free_ char *cursor = NULL;
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
index 86afb4985d..cd56470a33 100644
--- a/src/journal/sd-journal.c
+++ b/src/journal/sd-journal.c
@@ -882,8 +882,11 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t
if (skip == 0) {
/* If this is not a discrete skip, then at least
* resolve the current location */
- if (j->current_location.type != LOCATION_DISCRETE)
- return real_journal_next(j, direction);
+ if (j->current_location.type != LOCATION_DISCRETE) {
+ r = real_journal_next(j, direction);
+ if (r < 0)
+ return r;
+ }
return 0;
}
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 315cbf1ac5..5a59c377f8 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -34,6 +34,14 @@
#define DHCP_DEFAULT_LEASE_TIME_USEC USEC_PER_HOUR
#define DHCP_MAX_LEASE_TIME_USEC (USEC_PER_HOUR*12)
+static void dhcp_lease_free(DHCPLease *lease) {
+ if (!lease)
+ return;
+
+ free(lease->client_id.data);
+ free(lease);
+}
+
/* configures the server's address and subnet, and optionally the pool's size and offset into the subnet
* the whole pool must fit into the subnet, and may not contain the first (any) nor last (broadcast) address
* moreover, the server's own address may be in the pool, and is in that case reserved in order not to
@@ -47,7 +55,6 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
assert_return(address, -EINVAL);
assert_return(address->s_addr != INADDR_ANY, -EINVAL);
assert_return(prefixlen <= 32, -ERANGE);
- assert_return(server->address == INADDR_ANY, -EBUSY);
assert_se(in_addr_prefixlen_to_netmask(&netmask_addr, prefixlen));
netmask = netmask_addr.s_addr;
@@ -78,19 +85,28 @@ int sd_dhcp_server_configure_pool(sd_dhcp_server *server, struct in_addr *addres
else
size = size_max;
- server->bound_leases = new0(DHCPLease*, size);
- if (!server->bound_leases)
- return -ENOMEM;
+ if (server->address != address->s_addr || server->netmask != netmask || server->pool_size != size || server->pool_offset != offset) {
+ DHCPLease *lease;
+
+ free(server->bound_leases);
+ server->bound_leases = new0(DHCPLease*, size);
+ if (!server->bound_leases)
+ return -ENOMEM;
- server->pool_offset = offset;
- server->pool_size = size;
+ server->pool_offset = offset;
+ server->pool_size = size;
- server->address = address->s_addr;
- server->netmask = netmask;
- server->subnet = address->s_addr & netmask;
+ server->address = address->s_addr;
+ server->netmask = netmask;
+ server->subnet = address->s_addr & netmask;
- if (server_off >= offset && server_off - offset < size)
- server->bound_leases[server_off - offset] = &server->invalid_lease;
+ if (server_off >= offset && server_off - offset < size)
+ server->bound_leases[server_off - offset] = &server->invalid_lease;
+
+ /* Drop any leases associated with the old address range */
+ while ((lease = hashmap_steal_first(server->leases_by_client_id)))
+ dhcp_lease_free(lease);
+ }
return 0;
}
@@ -143,14 +159,6 @@ static const struct hash_ops client_id_hash_ops = {
.compare = client_id_compare_func
};
-static void dhcp_lease_free(DHCPLease *lease) {
- if (!lease)
- return;
-
- free(lease->client_id.data);
- free(lease);
-}
-
sd_dhcp_server *sd_dhcp_server_unref(sd_dhcp_server *server) {
DHCPLease *lease;
diff --git a/src/libsystemd-network/test-dhcp-server.c b/src/libsystemd-network/test-dhcp-server.c
index e81c508c7f..26f217835f 100644
--- a/src/libsystemd-network/test-dhcp-server.c
+++ b/src/libsystemd-network/test-dhcp-server.c
@@ -63,7 +63,7 @@ static int test_basic(sd_event *event) {
assert_se(sd_dhcp_server_configure_pool(server, &address_any, 28, 0, 0) == -EINVAL);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 38, 0, 0) == -ERANGE);
assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
- assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) == -EBUSY);
+ assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
test_pool(&address_any, 1, -EINVAL);
test_pool(&address_lo, 1, 0);
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index 303ae0f230..b56bb07713 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -786,6 +786,8 @@ static int bus_get_name_creds_dbus1(
}
if (mask != 0) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ bool need_pid, need_uid, need_selinux, need_separate_calls;
c = bus_creds_new();
if (!c)
return -ENOMEM;
@@ -798,99 +800,216 @@ static int bus_get_name_creds_dbus1(
c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
}
- if ((mask & SD_BUS_CREDS_PID) ||
- ((mask & SD_BUS_CREDS_AUGMENT) &&
- (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
- SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
- SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
- SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
- SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
- SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
- SD_BUS_CREDS_SELINUX_CONTEXT|
- SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))) {
+ need_pid = (mask & SD_BUS_CREDS_PID) ||
+ ((mask & SD_BUS_CREDS_AUGMENT) &&
+ (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+ SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
+ SD_BUS_CREDS_SUPPLEMENTARY_GIDS|
+ SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
+ SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
+ SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
+ SD_BUS_CREDS_SELINUX_CONTEXT|
+ SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
+ need_uid = mask & SD_BUS_CREDS_EUID;
+ need_selinux = mask & SD_BUS_CREDS_SELINUX_CONTEXT;
- uint32_t u;
+ if (need_pid + need_uid + need_selinux > 1) {
+
+ /* If we need more than one of the credentials, then use GetConnectionCredentials() */
r = sd_bus_call_method(
bus,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus",
- "GetConnectionUnixProcessID",
- NULL,
+ "GetConnectionCredentials",
+ &error,
&reply,
"s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ unique ?: name);
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ if (r < 0) {
- pid = u;
- if (mask & SD_BUS_CREDS_PID) {
- c->pid = u;
- c->mask |= SD_BUS_CREDS_PID;
- }
+ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+ return r;
- reply = sd_bus_message_unref(reply);
- }
+ /* If we got an unknown method error, fall back to the invidual calls... */
+ need_separate_calls = true;
+ sd_bus_error_free(&error);
- if (mask & SD_BUS_CREDS_EUID) {
- uint32_t u;
+ } else {
+ need_separate_calls = false;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionUnixUser",
- NULL,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0)
- return r;
+ r = sd_bus_message_enter_container(reply, 'a', "{sv}");
+ if (r < 0)
+ return r;
- r = sd_bus_message_read(reply, "u", &u);
- if (r < 0)
- return r;
+ for (;;) {
+ const char *m;
- c->euid = u;
- c->mask |= SD_BUS_CREDS_EUID;
+ r = sd_bus_message_enter_container(reply, 'e', "sv");
+ if (r < 0)
+ return r;
+ if (r == 0)
+ break;
- reply = sd_bus_message_unref(reply);
- }
+ r = sd_bus_message_read(reply, "s", &m);
+ if (r < 0)
+ return r;
- if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- const void *p = NULL;
- size_t sz = 0;
+ if (need_uid && streq(m, "UnixUserID")) {
+ uint32_t u;
- r = sd_bus_call_method(
- bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "GetConnectionSELinuxSecurityContext",
- &error,
- &reply,
- "s",
- unique ? unique : name);
- if (r < 0) {
- if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ r = sd_bus_message_read(reply, "v", "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ } else if (need_pid && streq(m, "ProcessID")) {
+ uint32_t p;
+
+ r = sd_bus_message_read(reply, "v", "u", &p);
+ if (r < 0)
+ return r;
+
+ pid = p;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = p;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ } else if (need_selinux && streq(m, "LinuxSecurityLabel")) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_message_enter_container(reply, 'v', "ay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ free(c->label);
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ } else {
+ r = sd_bus_message_skip(reply, "v");
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
return r;
- } else {
- r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+
+ if (need_pid && pid == 0)
+ return -EPROTO;
+ }
+
+ } else /* When we only need a single field, then let's use separate calls */
+ need_separate_calls = true;
+
+ if (need_separate_calls) {
+ if (need_pid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixProcessID",
+ NULL,
+ &reply,
+ "s",
+ unique ?: name);
if (r < 0)
return r;
- c->label = strndup(p, sz);
- if (!c->label)
- return -ENOMEM;
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
- c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ pid = u;
+ if (mask & SD_BUS_CREDS_PID) {
+ c->pid = u;
+ c->mask |= SD_BUS_CREDS_PID;
+ }
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_uid) {
+ uint32_t u;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser",
+ NULL,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_read(reply, "u", &u);
+ if (r < 0)
+ return r;
+
+ c->euid = u;
+ c->mask |= SD_BUS_CREDS_EUID;
+
+ reply = sd_bus_message_unref(reply);
+ }
+
+ if (need_selinux) {
+ const void *p = NULL;
+ size_t sz = 0;
+
+ r = sd_bus_call_method(
+ bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionSELinuxSecurityContext",
+ &error,
+ &reply,
+ "s",
+ unique ? unique : name);
+ if (r < 0) {
+ if (!sd_bus_error_has_name(&error, "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown"))
+ return r;
+
+ /* no data is fine */
+ } else {
+ r = sd_bus_message_read_array(reply, 'y', &p, &sz);
+ if (r < 0)
+ return r;
+
+ c->label = strndup(p, sz);
+ if (!c->label)
+ return -ENOMEM;
+
+ c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+ }
}
}
@@ -923,9 +1042,17 @@ _public_ int sd_bus_get_name_creds(
if (!bus->bus_client)
return -EINVAL;
+ /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not
+ * going to match. */
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (streq(name, "org.freedesktop.DBus.Local"))
return -EINVAL;
+ if (streq(name, "org.freedesktop.DBus"))
+ return sd_bus_get_owner_creds(bus, mask, creds);
+
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
@@ -1046,6 +1173,9 @@ _public_ int sd_bus_get_owner_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **r
if (!BUS_IS_OPEN(bus->state))
return -ENOTCONN;
+ if (!bus->is_local)
+ mask &= ~SD_BUS_CREDS_AUGMENT;
+
if (bus->is_kernel)
return bus_get_owner_creds_kdbus(bus, mask, ret);
else
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index bb0414c4d6..3575ea8cde 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -212,6 +212,7 @@ struct sd_bus {
bool exit_on_disconnect:1;
bool exited:1;
bool exit_triggered:1;
+ bool is_local:1;
int use_memfd;
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
index e809942278..2f065c2657 100644
--- a/src/libsystemd/sd-bus/sd-bus.c
+++ b/src/libsystemd/sd-bus/sd-bus.c
@@ -588,6 +588,8 @@ static int parse_unix_address(sd_bus *b, const char **p, char **guid) {
b->sockaddr_size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
}
+ b->is_local = true;
+
return 0;
}
@@ -655,6 +657,8 @@ static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
freeaddrinfo(result);
+ b->is_local = false;
+
return 0;
}
@@ -737,6 +741,9 @@ static int parse_exec_address(sd_bus *b, const char **p, char **guid) {
b->exec_path = path;
b->exec_argv = argv;
+
+ b->is_local = false;
+
return 0;
fail:
@@ -780,6 +787,8 @@ static int parse_kernel_address(sd_bus *b, const char **p, char **guid) {
b->kernel = path;
path = NULL;
+ b->is_local = true;
+
return 0;
}
@@ -838,6 +847,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
b->sockaddr.un.sun_family = AF_UNIX;
strncpy(b->sockaddr.un.sun_path, "/var/run/dbus/system_bus_socket", sizeof(b->sockaddr.un.sun_path));
b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
+ b->is_local = false;
return 0;
}
@@ -898,6 +908,8 @@ static int parse_container_kernel_address(sd_bus *b, const char **p, char **guid
if (r < 0)
return r;
+ b->is_local = false;
+
return 0;
}
@@ -1179,6 +1191,7 @@ _public_ int sd_bus_open(sd_bus **ret) {
/* We don't know whether the bus is trusted or not, so better
* be safe, and authenticate everything */
b->trusted = false;
+ b->is_local = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
@@ -1227,6 +1240,7 @@ _public_ int sd_bus_open_system(sd_bus **ret) {
b->trusted = false;
b->attach_flags |= KDBUS_ATTACH_CAPS | KDBUS_ATTACH_CREDS;
b->creds_mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_EFFECTIVE_CAPS;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
@@ -1293,6 +1307,7 @@ _public_ int sd_bus_open_user(sd_bus **ret) {
/* We don't do any per-method access control on the user
* bus. */
b->trusted = true;
+ b->is_local = true;
r = sd_bus_start(b);
if (r < 0)
@@ -1364,6 +1379,7 @@ _public_ int sd_bus_open_system_remote(sd_bus **ret, const char *host) {
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
@@ -1413,6 +1429,7 @@ _public_ int sd_bus_open_system_machine(sd_bus **ret, const char *machine) {
bus->bus_client = true;
bus->trusted = false;
bus->is_system = true;
+ bus->is_local = false;
r = sd_bus_start(bus);
if (r < 0)
diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c
index 654a22fe3b..e8c8abac2a 100644
--- a/src/libsystemd/sd-netlink/netlink-message.c
+++ b/src/libsystemd/sd-netlink/netlink-message.c
@@ -104,7 +104,8 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
assert_return(m->hdr->nlmsg_type == RTM_GETLINK ||
m->hdr->nlmsg_type == RTM_GETADDR ||
m->hdr->nlmsg_type == RTM_GETROUTE ||
- m->hdr->nlmsg_type == RTM_GETNEIGH,
+ m->hdr->nlmsg_type == RTM_GETNEIGH ||
+ m->hdr->nlmsg_type == RTM_GETADDRLABEL ,
-EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
diff --git a/src/libsystemd/sd-netlink/rtnl-message.c b/src/libsystemd/sd-netlink/rtnl-message.c
index d5f8b7d15e..12c51ffe2e 100644
--- a/src/libsystemd/sd-netlink/rtnl-message.c
+++ b/src/libsystemd/sd-netlink/rtnl-message.c
@@ -740,3 +740,17 @@ int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char
return 0;
}
+
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
+ struct ifaddrlblmsg *addrlabel;
+
+ assert_return(m, -EINVAL);
+ assert_return(m->hdr, -EINVAL);
+ assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
+
+ addrlabel = NLMSG_DATA(m->hdr);
+
+ *prefixlen = addrlabel->ifal_prefixlen;
+
+ return 0;
+}
diff --git a/src/login/70-power-switch.rules b/src/login/70-power-switch.rules
index e2855b50f7..394a80f1f8 100644
--- a/src/login/70-power-switch.rules
+++ b/src/login/70-power-switch.rules
@@ -7,12 +7,7 @@
ACTION=="remove", GOTO="power_switch_end"
-SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", KERNELS=="thinkpad_acpi", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="twl4030_pwrbutton", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="tps65217_pwr_but", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="* WMI hotkeys", TAG+="power-switch"
-SUBSYSTEM=="input", KERNEL=="event*", \
- SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", ATTRS{keys}=="*,116|116,*|116|*,116,*", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_SWITCH}=="1", TAG+="power-switch"
+SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_KEY}=="1", TAG+="power-switch"
LABEL="power_switch_end"
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index d739af8ea2..e53dd63c29 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -32,6 +32,18 @@
#include "string-util.h"
#include "util.h"
+#define CONST_MAX4(a, b, c, d) CONST_MAX(CONST_MAX(a, b), CONST_MAX(c, d))
+
+#define ULONG_BITS (sizeof(unsigned long)*8)
+
+static bool bitset_get(const unsigned long *bits, unsigned i) {
+ return (bits[i / ULONG_BITS] >> (i % ULONG_BITS)) & 1UL;
+}
+
+static void bitset_put(unsigned long *bits, unsigned i) {
+ bits[i / ULONG_BITS] |= (unsigned long) 1 << (i % ULONG_BITS);
+}
+
Button* button_new(Manager *m, const char *name) {
Button *b;
@@ -231,6 +243,95 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
return 0;
}
+static int button_suitable(Button *b) {
+ unsigned long types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1];
+
+ assert(b);
+ assert(b->fd);
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SYN, sizeof(types)), types) < 0)
+ return -errno;
+
+ if (bitset_get(types, EV_KEY)) {
+ unsigned long keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_KEY, sizeof(keys)), keys) < 0)
+ return -errno;
+
+ if (bitset_get(keys, KEY_POWER) ||
+ bitset_get(keys, KEY_POWER2) ||
+ bitset_get(keys, KEY_SLEEP) ||
+ bitset_get(keys, KEY_SUSPEND))
+ return true;
+ }
+
+ if (bitset_get(types, EV_SW)) {
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1];
+
+ if (ioctl(b->fd, EVIOCGBIT(EV_SW, sizeof(switches)), switches) < 0)
+ return -errno;
+
+ if (bitset_get(switches, SW_LID) ||
+ bitset_get(switches, SW_DOCK))
+ return true;
+ }
+
+ return false;
+}
+
+static int button_set_mask(Button *b) {
+ unsigned long
+ types[CONST_MAX(EV_KEY, EV_SW)/ULONG_BITS+1] = {},
+ keys[CONST_MAX4(KEY_POWER, KEY_POWER2, KEY_SLEEP, KEY_SUSPEND)/ULONG_BITS+1] = {},
+ switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
+ struct input_mask mask;
+
+ assert(b);
+ assert(b->fd >= 0);
+
+ bitset_put(types, EV_KEY);
+ bitset_put(types, EV_SW);
+
+ mask = (struct input_mask) {
+ .type = EV_SYN,
+ .codes_size = sizeof(types),
+ .codes_ptr = PTR_TO_UINT64(types),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ /* Log only at debug level if the kernel doesn't do EVIOCSMASK yet */
+ return log_full_errno(IN_SET(errno, ENOTTY, EOPNOTSUPP, EINVAL) ? LOG_DEBUG : LOG_WARNING,
+ errno, "Failed to set EV_SYN event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(keys, KEY_POWER);
+ bitset_put(keys, KEY_POWER2);
+ bitset_put(keys, KEY_SLEEP);
+ bitset_put(keys, KEY_SUSPEND);
+
+ mask = (struct input_mask) {
+ .type = EV_KEY,
+ .codes_size = sizeof(keys),
+ .codes_ptr = PTR_TO_UINT64(keys),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_KEY event mask on /dev/input/%s: %m", b->name);
+
+ bitset_put(switches, SW_LID);
+ bitset_put(switches, SW_DOCK);
+
+ mask = (struct input_mask) {
+ .type = EV_SW,
+ .codes_size = sizeof(switches),
+ .codes_ptr = PTR_TO_UINT64(switches),
+ };
+
+ if (ioctl(b->fd, EVIOCSMASK, &mask) < 0)
+ return log_warning_errno(errno, "Failed to set EV_SW event mask on /dev/input/%s: %m", b->name);
+
+ return 0;
+}
+
int button_open(Button *b) {
char *p, name[256];
int r;
@@ -243,13 +344,23 @@ int button_open(Button *b) {
b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (b->fd < 0)
- return log_warning_errno(errno, "Failed to open %s: %m", b->name);
+ return log_warning_errno(errno, "Failed to open %s: %m", p);
+
+ r = button_suitable(b);
+ if (r < 0)
+ return log_warning_errno(r, "Failed to determine whether input device is relevant to us: %m");
+ if (r == 0) {
+ log_debug("Device %s does not expose keys or switches relevant to us, ignoring.", p);
+ return -EADDRNOTAVAIL;
+ }
if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
r = log_error_errno(errno, "Failed to get input name: %m");
goto fail;
}
+ (void) button_set_mask(b);
+
r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
if (r < 0) {
log_error_errno(r, "Failed to add button event: %m");
@@ -266,7 +377,7 @@ fail:
}
int button_check_switches(Button *b) {
- uint8_t switches[SW_MAX/8+1] = {};
+ unsigned long switches[CONST_MAX(SW_LID, SW_DOCK)/ULONG_BITS+1] = {};
assert(b);
if (b->fd < 0)
@@ -275,8 +386,8 @@ int button_check_switches(Button *b) {
if (ioctl(b->fd, EVIOCGSW(sizeof(switches)), switches) < 0)
return -errno;
- b->lid_closed = (switches[SW_LID/8] >> (SW_LID % 8)) & 1;
- b->docked = (switches[SW_DOCK/8] >> (SW_DOCK % 8)) & 1;
+ b->lid_closed = bitset_get(switches, SW_LID);
+ b->docked = bitset_get(switches, SW_DOCK);
if (b->lid_closed)
button_install_check_event_source(b);
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index eff5a4a36f..ebe1d68634 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -269,7 +269,11 @@ int manager_process_button_device(Manager *m, struct udev_device *d) {
sn = "seat0";
button_set_seat(b, sn);
- button_open(b);
+
+ r = button_open(b);
+ if (r < 0) /* event device doesn't have any keys or switches relevant to us? (or any other error
+ * opening the device?) let's close the button again. */
+ button_free(b);
}
return 0;
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index b709166aa9..65d57d86b3 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -25,12 +25,16 @@
#include "bus-error.h"
#include "bus-unit-util.h"
#include "bus-util.h"
+#include "dirent-util.h"
#include "escape.h"
+#include "fd-util.h"
+#include "fileio.h"
#include "fstab-util.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "spawn-polkit-agent.h"
+#include "stat-util.h"
#include "strv.h"
#include "udev-util.h"
#include "unit-name.h"
@@ -77,7 +81,9 @@ static void polkit_agent_open_if_enabled(void) {
}
static void help(void) {
- printf("%s [OPTIONS...] WHAT [WHERE]\n\n"
+ printf("systemd-mount [OPTIONS...] WHAT [WHERE]\n"
+ "systemd-mount [OPTIONS...] --list\n"
+ "%s [OPTIONS...] %sWHAT|WHERE...\n\n"
"Establish a mount or auto-mount point transiently.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
@@ -100,8 +106,9 @@ static void help(void) {
" Set automount unit property\n"
" --bind-device Bind automount unit to device\n"
" --list List mountable block devices\n"
- " -u --umount Unmount mount points\n"
- , program_invocation_short_name);
+ " -u --umount Unmount mount points\n",
+ program_invocation_short_name,
+ streq(program_invocation_short_name, "systemd-umount") ? "" : "--umount ");
}
static int parse_argv(int argc, char *argv[]) {
@@ -297,6 +304,16 @@ static int parse_argv(int argc, char *argv[]) {
log_error("Listing devices only supported locally.");
return -EOPNOTSUPP;
}
+ } else if (arg_action == ACTION_UMOUNT) {
+ if (optind >= argc) {
+ log_error("At least one argument required.");
+ return -EINVAL;
+ }
+
+ if (arg_transport != BUS_TRANSPORT_LOCAL) {
+ log_error("Unmounting devices only supported locally.");
+ return -EOPNOTSUPP;
+ }
} else {
if (optind >= argc) {
log_error("At least one argument required.");
@@ -621,7 +638,7 @@ static int start_transient_automount(
static int stop_mount(
sd_bus *bus,
- char **argv,
+ const char *where,
const char *suffix) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
@@ -636,9 +653,9 @@ static int stop_mount(
return log_error_errno(r, "Could not watch jobs: %m");
}
- r = unit_name_from_path(arg_mount_where, suffix, &mount_unit);
+ r = unit_name_from_path(where, suffix, &mount_unit);
if (r < 0)
- return log_error_errno(r, "Failed to make mount unit name: %m");
+ return log_error_errno(r, "Failed to make mount unit name from path %s: %m", where);
r = sd_bus_message_new_method_call(
bus,
@@ -680,28 +697,241 @@ static int stop_mount(
if (!arg_quiet)
log_info("Stopped unit %s%s%s for mount point: %s%s%s",
ansi_highlight(), mount_unit, ansi_normal(),
- ansi_highlight(), arg_mount_where, ansi_normal());
+ ansi_highlight(), where, ansi_normal());
return 0;
}
static int stop_mounts(
sd_bus *bus,
- char **argv) {
+ const char *where) {
int r;
- r = stop_mount(bus, argv + optind, ".mount");
+ if (path_equal(where, "/")) {
+ log_error("Refusing to operate on root directory: %s", where);
+ return -EINVAL;
+ }
+
+ if (!path_is_safe(where)) {
+ log_error("Path contains unsafe components: %s", where);
+ return -EINVAL;
+ }
+
+ r = stop_mount(bus, where, ".mount");
if (r < 0)
return r;
- r = stop_mount(bus, argv + optind, ".automount");
+ r = stop_mount(bus, where, ".automount");
if (r < 0)
return r;
return 0;
}
+static int umount_by_mountinfo(sd_bus *bus, const char *what) {
+ _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+ int r, r2 = 0;
+
+ proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
+ if (!proc_self_mountinfo)
+ return -errno;
+
+ for (;;) {
+ _cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL;
+ int k;
+
+ k = fscanf(proc_self_mountinfo,
+ "%*s " /* (1) mount id */
+ "%*s " /* (2) parent id */
+ "%*s " /* (3) major:minor */
+ "%*s " /* (4) root */
+ "%ms " /* (5) mount point */
+ "%*s" /* (6) mount options */
+ "%*[^-]" /* (7) optional fields */
+ "- " /* (8) separator */
+ "%*s " /* (9) file system type */
+ "%ms" /* (10) mount source */
+ "%*s" /* (11) mount options 2 */
+ "%*[^\n]", /* some rubbish at the end */
+ &path, &dev);
+ if (k != 2) {
+ if (k == EOF)
+ break;
+
+ continue;
+ }
+
+ if (!streq(what, dev))
+ continue;
+
+ r = cunescape(path, UNESCAPE_RELAX, &where);
+ if (r < 0) {
+ r2 = r;
+ continue;
+ }
+
+ r = stop_mounts(bus, where);
+ if (r < 0) {
+ r2 = r;
+ continue;
+ }
+ }
+
+ return r2;
+}
+
+static int umount_by_device(sd_bus *bus, const char *what) {
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ _cleanup_free_ char *where = NULL;
+ struct stat st;
+ const char *v;
+ int r, r2 = 0;
+
+ assert(what);
+
+ if (stat(what, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", what);
+
+ if (!S_ISBLK(st.st_mode)) {
+ log_error("Not a block device: %s", what);
+ return -ENOTBLK;
+ }
+
+ udev = udev_new();
+ if (!udev)
+ return log_oom();
+
+ d = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
+ if (!d)
+ return log_oom();
+
+ v = udev_device_get_property_value(d, "ID_FS_USAGE");
+ if (!streq_ptr(v, "filesystem")) {
+ log_error("%s does not contain a known file system.", what);
+ return -EINVAL;
+ }
+
+ v = udev_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE");
+ if (!isempty(v)) {
+ where = strdup(v);
+ if (!where)
+ return log_oom();
+ r2 = stop_mounts(bus, where);
+ }
+
+ v = udev_device_get_devnode(d);
+ if (!isempty(v)) {
+ r = umount_by_mountinfo(bus, v);
+ if (r < 0)
+ return r;
+ }
+
+ return r2;
+}
+
+static int umount_loop(sd_bus *bus, const char *backing_file) {
+ _cleanup_closedir_ DIR *d = NULL;
+ struct dirent *de;
+ int r, r2 = 0;
+ bool found = false;
+
+ assert(backing_file);
+
+ d = opendir("/sys/devices/virtual/block");
+ if (!d) {
+ if (errno == ENOENT)
+ return log_error_errno(errno, "File %s is not mounted.", backing_file);
+ return log_error_errno(errno, "Can't open directory /sys/devices/virtual/block: %m");
+ }
+
+ FOREACH_DIRENT(de, d, return -errno) {
+ _cleanup_free_ char *sys = NULL, *what = NULL, *fname = NULL;
+
+ dirent_ensure_type(d, de);
+
+ if (de->d_type != DT_DIR)
+ continue;
+
+ if (!startswith(de->d_name, "loop"))
+ continue;
+
+ sys = strjoin("/sys/devices/virtual/block/", de->d_name, "/loop/backing_file");
+ if (!sys)
+ return log_oom();
+
+ r = read_one_line_file(sys, &fname);
+ if (r < 0) {
+ if (r != -ENOENT)
+ r2 = log_error_errno(r, "Can't read %s: %m", sys);
+ continue;
+ }
+
+ if (!files_same(fname, backing_file, 0))
+ continue;
+
+ found = true;
+
+ what = strjoin("/dev/", de->d_name);
+ if (!what)
+ return log_oom();
+
+ r = umount_by_device(bus, what);
+ if (r < 0)
+ r2 = r;
+ }
+
+ if (!found)
+ return log_error_errno(ENOENT, "File %s is not mounted.", backing_file);
+
+ return r2;
+}
+
+static int action_umount(
+ sd_bus *bus,
+ int argc,
+ char **argv) {
+
+ int i, r, r2 = 0;
+
+ for (i = optind; i < argc; i++) {
+ _cleanup_free_ char *u = NULL, *p = NULL;
+ struct stat st;
+
+ u = fstab_node_to_udev_node(argv[i]);
+ if (!u)
+ return log_oom();
+
+ r = path_make_absolute_cwd(u, &p);
+ if (r < 0) {
+ r2 = log_error_errno(r, "Failed to make path absolute: %m");
+ continue;
+ }
+
+ path_kill_slashes(p);
+
+ if (stat(p, &st) < 0)
+ return log_error_errno(errno, "Can't stat %s: %m", p);
+
+ if (S_ISBLK(st.st_mode))
+ r = umount_by_device(bus, p);
+ else if (S_ISREG(st.st_mode))
+ r = umount_loop(bus, p);
+ else if (S_ISDIR(st.st_mode))
+ r = stop_mounts(bus, p);
+ else {
+ log_error("Invalid file type: %s", p);
+ r = -EINVAL;
+ }
+
+ if (r < 0)
+ r2 = r;
+ }
+
+ return r2;
+}
+
static int acquire_mount_type(struct udev_device *d) {
const char *v;
@@ -907,7 +1137,7 @@ static int discover_device(void) {
v = udev_device_get_property_value(d, "ID_FS_USAGE");
if (!streq_ptr(v, "filesystem")) {
- log_error("%s does not contain a file system.", arg_mount_what);
+ log_error("%s does not contain a known file system.", arg_mount_what);
return -EINVAL;
}
@@ -1130,6 +1360,17 @@ int main(int argc, char* argv[]) {
goto finish;
}
+ r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
+ if (r < 0) {
+ log_error_errno(r, "Failed to create bus connection: %m");
+ goto finish;
+ }
+
+ if (arg_action == ACTION_UMOUNT) {
+ r = action_umount(bus, argc, argv);
+ goto finish;
+ }
+
r = discover_device();
if (r < 0)
goto finish;
@@ -1148,7 +1389,7 @@ int main(int argc, char* argv[]) {
}
if (!path_is_safe(arg_mount_where)) {
- log_error("Path is contains unsafe components.");
+ log_error("Path contains unsafe components.");
r = -EINVAL;
goto finish;
}
@@ -1171,12 +1412,6 @@ int main(int argc, char* argv[]) {
}
}
- r = bus_connect_transport_systemd(arg_transport, arg_host, arg_user, &bus);
- if (r < 0) {
- log_error_errno(r, "Failed to create bus connection: %m");
- goto finish;
- }
-
switch (arg_action) {
case ACTION_MOUNT:
@@ -1188,10 +1423,6 @@ int main(int argc, char* argv[]) {
r = start_transient_automount(bus, argv + optind);
break;
- case ACTION_UMOUNT:
- r = stop_mounts(bus, argv + optind);
- break;
-
default:
assert_not_reached("Unexpected action.");
}
diff --git a/src/network/networkctl.c b/src/network/networkctl.c
index 6f7f41bf7d..54d54c8fd5 100644
--- a/src/network/networkctl.c
+++ b/src/network/networkctl.c
@@ -18,6 +18,7 @@
***/
#include <getopt.h>
+#include <linux/if_addrlabel.h>
#include <net/if.h>
#include <stdbool.h>
@@ -35,6 +36,7 @@
#include "hwdb-util.h"
#include "local-addresses.h"
#include "locale-util.h"
+#include "macro.h"
#include "netlink-util.h"
#include "pager.h"
#include "parse-util.h"
@@ -569,6 +571,76 @@ static int dump_addresses(
return 0;
}
+static int dump_address_labels(sd_netlink *rtnl) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
+ sd_netlink_message *m;
+ int r;
+
+ assert(rtnl);
+
+ r = sd_rtnl_message_new_addrlabel(rtnl, &req, RTM_GETADDRLABEL, 0, AF_INET6);
+ if (r < 0)
+ return log_error_errno(r, "Could not allocate RTM_GETADDRLABEL message: %m");
+
+ r = sd_netlink_message_request_dump(req, true);
+ if (r < 0)
+ return r;
+
+ r = sd_netlink_call(rtnl, req, 0, &reply);
+ if (r < 0)
+ return r;
+
+ printf("%10s/%s %30s\n", "Prefix", "Prefixlen", "Label");
+
+ for (m = reply; m; m = sd_netlink_message_next(m)) {
+ _cleanup_free_ char *pretty = NULL;
+ union in_addr_union prefix = {};
+ uint8_t prefixlen;
+ uint32_t label;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0) {
+ log_error_errno(r, "got error: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_u32(m, IFAL_LABEL, &label);
+ if (r < 0 && r != -ENODATA) {
+ log_error_errno(r, "Could not read IFAL_LABEL, ignoring: %m");
+ continue;
+ }
+
+ r = sd_netlink_message_read_in6_addr(m, IFAL_ADDRESS, &prefix.in6);
+ if (r < 0)
+ continue;
+
+ r = in_addr_to_string(AF_INET6, &prefix, &pretty);
+ if (r < 0)
+ continue;
+
+ r = sd_rtnl_message_addrlabel_get_prefixlen(m, &prefixlen);
+ if (r < 0)
+ continue;
+
+ printf("%10s/%-5u %30u\n", pretty, prefixlen, label);
+ }
+
+ return 0;
+}
+
+static int list_address_labels(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ int r;
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ dump_address_labels(rtnl);
+
+ return 0;
+}
+
static int open_lldp_neighbors(int ifindex, FILE **ret) {
_cleanup_free_ char *p = NULL;
FILE *f;
@@ -1043,6 +1115,7 @@ static void help(void) {
" list [LINK...] List links\n"
" status [LINK...] Show link status\n"
" lldp [LINK...] Show LLDP neighbors\n"
+ " label Show current address label entries in the kernel\n"
, program_invocation_short_name);
}
@@ -1107,6 +1180,7 @@ static int networkctl_main(int argc, char *argv[]) {
{ "list", VERB_ANY, VERB_ANY, VERB_DEFAULT, list_links },
{ "status", VERB_ANY, VERB_ANY, 0, link_status },
{ "lldp", VERB_ANY, VERB_ANY, 0, link_lldp_status },
+ { "label", VERB_ANY, VERB_ANY, 0, list_address_labels},
{}
};
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 69f3e1212a..4c57fa1793 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2135,6 +2135,12 @@ static int link_joined(Link *link) {
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
}
+ /* Skip setting up addresses until it gets carrier,
+ or it would try to set addresses twice,
+ which is bad for non-idempotent steps. */
+ if (!link_has_carrier(link))
+ return 0;
+
return link_enter_set_addresses(link);
}
@@ -2443,7 +2449,7 @@ static int link_drop_foreign_config(Link *link) {
}
static int link_drop_config(Link *link) {
- Address *address;
+ Address *address, *pool_address;
Route *route;
Iterator i;
int r;
@@ -2456,6 +2462,15 @@ static int link_drop_config(Link *link) {
r = address_remove(address, link, link_address_remove_handler);
if (r < 0)
return r;
+
+ /* If this address came from an address pool, clean up the pool */
+ LIST_FOREACH(addresses, pool_address, link->pool_addresses) {
+ if (address_equal(address, pool_address)) {
+ LIST_REMOVE(addresses, link->pool_addresses, pool_address);
+ address_free(pool_address);
+ break;
+ }
+ }
}
SET_FOREACH(route, link->routes, i) {
@@ -3045,6 +3060,8 @@ static int link_carrier_lost(Link *link) {
return r;
}
+ (void) sd_dhcp_server_stop(link->dhcp_server);
+
r = link_drop_config(link);
if (r < 0)
return r;
diff --git a/src/nspawn/nspawn-register.c b/src/nspawn/nspawn-register.c
index e3ab39faea..ffdf1239fa 100644
--- a/src/nspawn/nspawn-register.c
+++ b/src/nspawn/nspawn-register.c
@@ -27,6 +27,77 @@
#include "strv.h"
#include "util.h"
+static int append_machine_properties(
+ sd_bus_message *m,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ unsigned j;
+ int r;
+
+ assert(m);
+
+ r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* If you make changes here, also make sure to update systemd-nspawn@.service, to keep the device policies in
+ * sync regardless if we are run with or without the --keep-unit switch. */
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
+ /* Allow the container to
+ * access and create the API
+ * device nodes, so that
+ * PrivateDevices= in the
+ * container can work
+ * fine */
+ "/dev/net/tun", "rwm",
+ /* Allow the container
+ * access to ptys. However,
+ * do not permit the
+ * container to ever create
+ * these device nodes. */
+ "char-pts", "rw");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ for (j = 0; j < n_mounts; j++) {
+ CustomMount *cm = mounts + j;
+
+ if (cm->type != CUSTOM_MOUNT_BIND)
+ continue;
+
+ r = is_device_node(cm->source);
+ if (r == -ENOENT) {
+ /* The bind source might only appear as the image is put together, hence don't complain */
+ log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
+ continue;
+ }
+ if (r < 0)
+ return log_error_errno(r, "Failed to stat %s: %m", cm->source);
+
+ if (r) {
+ r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
+ cm->source, cm->read_only ? "r" : "rw");
+ if (r < 0)
+ return log_error_errno(r, "Failed to append message arguments: %m");
+ }
+ }
+
+ if (kill_signal != 0) {
+ r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
+ return 0;
+}
+
int register_machine(
const char *machine_name,
pid_t pid,
@@ -68,7 +139,6 @@ int register_machine(
local_ifindex > 0 ? 1 : 0, local_ifindex);
} else {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- unsigned j;
r = sd_bus_message_new_method_call(
bus,
@@ -103,63 +173,14 @@ int register_machine(
return bus_log_create_error(r);
}
- r = sd_bus_message_append(m, "(sv)", "DevicePolicy", "s", "closed");
- if (r < 0)
- return bus_log_create_error(r);
-
- /* If you make changes here, also make sure to update
- * systemd-nspawn@.service, to keep the device
- * policies in sync regardless if we are run with or
- * without the --keep-unit switch. */
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 2,
- /* Allow the container to
- * access and create the API
- * device nodes, so that
- * PrivateDevices= in the
- * container can work
- * fine */
- "/dev/net/tun", "rwm",
- /* Allow the container
- * access to ptys. However,
- * do not permit the
- * container to ever create
- * these device nodes. */
- "char-pts", "rw");
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
if (r < 0)
- return bus_log_create_error(r);
-
- for (j = 0; j < n_mounts; j++) {
- CustomMount *cm = mounts + j;
-
- if (cm->type != CUSTOM_MOUNT_BIND)
- continue;
-
- r = is_device_node(cm->source);
- if (r == -ENOENT) {
- /* The bind source might only appear as the image is put together, hence don't complain */
- log_debug_errno(r, "Bind mount source %s not found, ignoring: %m", cm->source);
- continue;
- }
- if (r < 0)
- return log_error_errno(r, "Failed to stat %s: %m", cm->source);
-
- if (r) {
- r = sd_bus_message_append(m, "(sv)", "DeviceAllow", "a(ss)", 1,
- cm->source, cm->read_only ? "r" : "rw");
- if (r < 0)
- return log_error_errno(r, "Failed to append message arguments: %m");
- }
- }
-
- if (kill_signal != 0) {
- r = sd_bus_message_append(m, "(sv)", "KillSignal", "i", kill_signal);
- if (r < 0)
- return bus_log_create_error(r);
-
- r = sd_bus_message_append(m, "(sv)", "KillMode", "s", "mixed");
- if (r < 0)
- return bus_log_create_error(r);
- }
+ return r;
r = bus_append_unit_property_assignment_many(m, properties);
if (r < 0)
@@ -229,3 +250,90 @@ int terminate_machine(pid_t pid) {
return 0;
}
+
+int allocate_scope(
+ const char *machine_name,
+ pid_t pid,
+ const char *slice,
+ CustomMount *mounts,
+ unsigned n_mounts,
+ int kill_signal,
+ char **properties) {
+
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ _cleanup_free_ char *scope = NULL;
+ const char *description;
+ int r;
+
+ r = sd_bus_default_system(&bus);
+ if (r < 0)
+ return log_error_errno(r, "Failed to open system bus: %m");
+
+ r = unit_name_mangle_with_suffix(machine_name, UNIT_NAME_NOGLOB, ".scope", &scope);
+ if (r < 0)
+ return log_error_errno(r, "Failed to mangle scope name: %m");
+
+ r = sd_bus_message_new_method_call(
+ bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_message_append(m, "ss", scope, "fail");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* Properties */
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ description = strjoina("Container ", machine_name);
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
+ "PIDs", "au", 1, pid,
+ "Description", "s", description,
+ "Delegate", "b", 1,
+ "Slice", "s", isempty(slice) ? "machine.slice" : slice);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = append_machine_properties(
+ m,
+ mounts,
+ n_mounts,
+ kill_signal,
+ properties);
+ if (r < 0)
+ return r;
+
+ r = bus_append_unit_property_assignment_many(m, properties);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ /* No auxiliary units */
+ r = sd_bus_message_append(
+ m,
+ "a(sa(sv))",
+ 0);
+ if (r < 0)
+ return bus_log_create_error(r);
+
+ r = sd_bus_call(bus, m, 0, &error, NULL);
+ if (r < 0) {
+ log_error("Failed to allocate scope: %s", bus_error_message(&error, r));
+ return r;
+ }
+
+ return 0;
+}
diff --git a/src/nspawn/nspawn-register.h b/src/nspawn/nspawn-register.h
index 304c5a485b..6694b3f6b1 100644
--- a/src/nspawn/nspawn-register.h
+++ b/src/nspawn/nspawn-register.h
@@ -27,3 +27,5 @@
int register_machine(const char *machine_name, pid_t pid, const char *directory, sd_id128_t uuid, int local_ifindex, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties, bool keep_unit, const char *service);
int terminate_machine(pid_t pid);
+
+int allocate_scope(const char *machine_name, pid_t pid, const char *slice, CustomMount *mounts, unsigned n_mounts, int kill_signal, char **properties);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 767d99201c..8a5fedd4b0 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1083,8 +1083,8 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_userns_mode == USER_NAMESPACE_PICK)
arg_userns_chown = true;
- if (arg_keep_unit && cg_pid_get_owner_uid(0, NULL) >= 0) {
- log_error("--keep-unit may not be used when invoked from a user session.");
+ if (arg_keep_unit && arg_register && cg_pid_get_owner_uid(0, NULL) >= 0) {
+ log_error("--keep-unit --register=yes may not be used when invoked from a user session.");
return -EINVAL;
}
@@ -3387,7 +3387,19 @@ static int run(int master,
arg_container_service_name);
if (r < 0)
return r;
- }
+ } else if (!arg_keep_unit) {
+ r = allocate_scope(
+ arg_machine,
+ *pid,
+ arg_slice,
+ arg_custom_mounts, arg_n_custom_mounts,
+ arg_kill_signal,
+ arg_property);
+ if (r < 0)
+ return r;
+
+ } else if (arg_slice || arg_property)
+ log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect.");
r = sync_cgroup(*pid, arg_unified_cgroup_hierarchy, arg_uid_shift);
if (r < 0)
diff --git a/src/resolve/meson.build b/src/resolve/meson.build
index f3c411ffee..fe228784fa 100644
--- a/src/resolve/meson.build
+++ b/src/resolve/meson.build
@@ -160,6 +160,15 @@ tests += [
libm],
'ENABLE_RESOLVED'],
+ [['src/resolve/test-resolved-packet.c',
+ basic_dns_sources,
+ dns_type_headers],
+ [],
+ [libgcrypt,
+ libgpg_error,
+ libm],
+ 'ENABLE_RESOLVED'],
+
[['src/resolve/test-dnssec.c',
basic_dns_sources,
dns_type_headers],
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 240ee448f4..a486216d68 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -28,6 +28,9 @@
#define EDNS0_OPT_DO (1<<15)
+#define DNS_PACKET_SIZE_START 512u
+assert_cc(DNS_PACKET_SIZE_START > UDP_PACKET_HEADER_SIZE)
+
typedef struct DnsPacketRewinder {
DnsPacket *packet;
size_t saved_rindex;
@@ -47,13 +50,14 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
assert(ret);
- if (mtu <= UDP_PACKET_HEADER_SIZE)
+ /* When dns_packet_new() is called with mtu == 0, allocate more than the
+ * absolute minimum (which is the dns packet header size), to avoid
+ * resizing immediately again after appending the first data to the packet.
+ */
+ if (mtu < UDP_PACKET_HEADER_SIZE)
a = DNS_PACKET_SIZE_START;
else
- a = mtu - UDP_PACKET_HEADER_SIZE;
-
- if (a < DNS_PACKET_HEADER_SIZE)
- a = DNS_PACKET_HEADER_SIZE;
+ a = MAX(mtu, DNS_PACKET_HEADER_SIZE);
/* round up to next page size */
a = PAGE_ALIGN(ALIGN(sizeof(DnsPacket)) + a) - ALIGN(sizeof(DnsPacket));
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 2c92392e4d..5dff272fd9 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -58,15 +58,13 @@ struct DnsPacketHeader {
/* The various DNS protocols deviate in how large a packet can grow,
but the TCP transport has a 16bit size field, hence that appears to
be the absolute maximum. */
-#define DNS_PACKET_SIZE_MAX 0xFFFF
+#define DNS_PACKET_SIZE_MAX 0xFFFFu
/* RFC 1035 say 512 is the maximum, for classic unicast DNS */
-#define DNS_PACKET_UNICAST_SIZE_MAX 512
+#define DNS_PACKET_UNICAST_SIZE_MAX 512u
/* With EDNS0 we can use larger packets, default to 4096, which is what is commonly used */
-#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096
-
-#define DNS_PACKET_SIZE_START 512
+#define DNS_PACKET_UNICAST_SIZE_LARGE_MAX 4096u
struct DnsPacket {
int n_ref;
diff --git a/src/resolve/resolved-dns-server.c b/src/resolve/resolved-dns-server.c
index 63cb6a5bda..9c3ee0136c 100644
--- a/src/resolve/resolved-dns-server.c
+++ b/src/resolve/resolved-dns-server.c
@@ -304,7 +304,10 @@ void dns_server_packet_received(DnsServer *s, int protocol, DnsServerFeatureLeve
if (s->max_rtt < rtt) {
s->max_rtt = rtt;
s->resend_timeout = CLAMP(s->max_rtt * 2, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
- }
+ } else if (s->resend_timeout > rtt)
+ /* If we received the packet faster than the resend_timeout, bias
+ * the resend_timeout back to the rtt. */
+ s->resend_timeout = CLAMP((2 * s->resend_timeout + rtt) / 3, DNS_TIMEOUT_MIN_USEC, DNS_TIMEOUT_MAX_USEC);
}
void dns_server_packet_lost(DnsServer *s, int protocol, DnsServerFeatureLevel level, usec_t usec) {
diff --git a/src/resolve/test-resolved-packet.c b/src/resolve/test-resolved-packet.c
new file mode 100644
index 0000000000..8b7da1408d
--- /dev/null
+++ b/src/resolve/test-resolved-packet.c
@@ -0,0 +1,45 @@
+/***
+ This file is part of systemd
+
+ Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "log.h"
+#include "resolved-dns-packet.h"
+
+static void test_dns_packet_new(void) {
+ size_t i;
+
+ for (i = 0; i < DNS_PACKET_SIZE_MAX + 2; i++) {
+ _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
+
+ assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, i) == 0);
+
+ log_debug("dns_packet_new: %zu → %zu", i, p->allocated);
+ assert_se(p->allocated >= MIN(DNS_PACKET_SIZE_MAX, i));
+ }
+}
+
+int main(int argc, char **argv) {
+
+ log_set_max_level(LOG_DEBUG);
+ log_parse_environment();
+ log_open();
+
+ test_dns_packet_new();
+
+ return 0;
+}
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
index 7b0bc8255c..5cbe663fa8 100644
--- a/src/shared/bus-unit-util.c
+++ b/src/shared/bus-unit-util.c
@@ -266,7 +266,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
"StandardInput", "StandardOutput", "StandardError",
"Description", "Slice", "Type", "WorkingDirectory",
"RootDirectory", "SyslogIdentifier", "ProtectSystem",
- "ProtectHome", "SELinuxContext", "Restart", "RootImage"))
+ "ProtectHome", "SELinuxContext", "Restart", "RootImage",
+ "NotifyAccess"))
r = sd_bus_message_append(m, "v", "s", eq);
else if (streq(field, "SyslogLevel")) {
@@ -389,6 +390,33 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
r = sd_bus_message_append(m, "v", "i", (int32_t) n);
+ } else if (streq(field, "FileDescriptorStoreMax")) {
+ unsigned u;
+
+ r = safe_atou(eq, &u);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse file descriptor store limit: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "u", (uint32_t) u);
+
+ } else if (streq(field, "IOSchedulingClass")) {
+ int c;
+
+ c = ioprio_class_from_string(eq);
+ if (c < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling class: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) c);
+
+ } else if (streq(field, "IOSchedulingPriority")) {
+ int q;
+
+ r = ioprio_parse_priority(eq, &q);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse IO scheduling priority: %s", eq);
+
+ r = sd_bus_message_append(m, "v", "i", (int32_t) q);
+
} else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
const char *p;
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
index c3106f1ae9..ec2e868ca8 100644
--- a/src/shared/fstab-util.c
+++ b/src/shared/fstab-util.c
@@ -34,18 +34,43 @@
#include "strv.h"
#include "util.h"
-bool fstab_is_mount_point(const char *mount) {
+int fstab_has_fstype(const char *fstype) {
_cleanup_endmntent_ FILE *f = NULL;
struct mntent *m;
f = setmntent("/etc/fstab", "re");
if (!f)
- return false;
+ return errno == ENOENT ? false : -errno;
- while ((m = getmntent(f)))
- if (path_equal(m->mnt_dir, mount))
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (streq(m->mnt_type, fstype))
return true;
+ }
+ return false;
+}
+
+int fstab_is_mount_point(const char *mount) {
+ _cleanup_endmntent_ FILE *f = NULL;
+ struct mntent *m;
+ f = setmntent("/etc/fstab", "re");
+ if (!f)
+ return errno == ENOENT ? false : -errno;
+
+ for (;;) {
+ errno = 0;
+ m = getmntent(f);
+ if (!m)
+ return errno != 0 ? -errno : false;
+
+ if (path_equal(m->mnt_dir, mount))
+ return true;
+ }
return false;
}
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
index 679f6902f7..bbf0441351 100644
--- a/src/shared/fstab-util.h
+++ b/src/shared/fstab-util.h
@@ -24,7 +24,8 @@
#include "macro.h"
-bool fstab_is_mount_point(const char *mount);
+int fstab_is_mount_point(const char *mount);
+int fstab_has_fstype(const char *fstype);
int fstab_filter_options(const char *opts, const char *names, const char **namefound, char **value, char **filtered);
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index a61d46d7fc..4c5b14bca5 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -5912,7 +5912,8 @@ static int enable_sysv_units(const char *verb, char **args) {
if (!l)
return log_oom();
- log_info("Executing: %s", l);
+ if (!arg_quiet)
+ log_info("Executing: %s", l);
pid = fork();
if (pid < 0)
@@ -8268,12 +8269,14 @@ static int halt_now(enum action a) {
switch (a) {
case ACTION_HALT:
- log_info("Halting.");
+ if (!arg_quiet)
+ log_info("Halting.");
(void) reboot(RB_HALT_SYSTEM);
return -errno;
case ACTION_POWEROFF:
- log_info("Powering off.");
+ if (!arg_quiet)
+ log_info("Powering off.");
(void) reboot(RB_POWER_OFF);
return -errno;
@@ -8286,12 +8289,14 @@ static int halt_now(enum action a) {
log_warning_errno(r, "Failed to read reboot parameter file: %m");
if (!isempty(param)) {
- log_info("Rebooting with argument '%s'.", param);
+ if (!arg_quiet)
+ log_info("Rebooting with argument '%s'.", param);
(void) syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m");
}
- log_info("Rebooting.");
+ if (!arg_quiet)
+ log_info("Rebooting.");
(void) reboot(RB_AUTOBOOT);
return -errno;
}
@@ -8352,7 +8357,8 @@ static int logind_schedule_shutdown(void) {
if (r < 0)
return log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error, r));
- log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
+ if (!arg_quiet)
+ log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date, sizeof(date), arg_when));
return 0;
#else
log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
@@ -8480,7 +8486,9 @@ int main(int argc, char*argv[]) {
goto finish;
if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) {
- log_info("Running in chroot, ignoring request.");
+
+ if (!arg_quiet)
+ log_info("Running in chroot, ignoring request.");
r = 0;
goto finish;
}
diff --git a/src/systemd/sd-netlink.h b/src/systemd/sd-netlink.h
index aa39e0a0db..3f5a6673cf 100644
--- a/src/systemd/sd-netlink.h
+++ b/src/systemd/sd-netlink.h
@@ -157,6 +157,7 @@ int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags);
int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family);
int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
+int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink_message, sd_netlink_message_unref);
diff --git a/src/udev/generate-keyboard-gperf.py b/src/udev/generate-keyboard-gperf.py
deleted file mode 100755
index 03d3bba7d3..0000000000
--- a/src/udev/generate-keyboard-gperf.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python3
-
-"""Generate keyboard-keys-from-name.gperf from keyboard-keys-list.txt
-"""
-
-import sys
-
-input = sys.argv[1]
-
-print("""\
-struct key_name { const char* name; unsigned short id; };
-%null-strings
-%%""")
-
-for line in open(input):
- print("{0}, {1}".format(line.rstrip()[4:].lower(), line.rstrip()))
diff --git a/src/udev/generate-keyboard-keys-gperf.sh b/src/udev/generate-keyboard-keys-gperf.sh
new file mode 100755
index 0000000000..5724e4e3dc
--- /dev/null
+++ b/src/udev/generate-keyboard-keys-gperf.sh
@@ -0,0 +1,10 @@
+#!/bin/sh -eu
+awk ' BEGIN {
+ print "struct key_name { const char* name; unsigned short id; };"
+ print "%null-strings"
+ print "%%"
+ }
+
+ /^KEY_/ { print tolower(substr($1 ,5)) ", " $1 }
+ { print tolower($1) ", " $1 }
+' < "$1"
diff --git a/src/udev/generate-keyboard-keys-list.sh b/src/udev/generate-keyboard-keys-list.sh
index 479e493182..7a74e0dae1 100755
--- a/src/udev/generate-keyboard-keys-list.sh
+++ b/src/udev/generate-keyboard-keys-list.sh
@@ -1,4 +1,6 @@
#!/bin/sh -eu
-$1 -dM -include linux/input.h - </dev/null | \
- awk '/^#define[ \t]+KEY_[^ ]+[ \t]+[0-9K]/ { if ($2 != "KEY_MAX") { print $2 } }'
+$1 -dM -include linux/input.h - </dev/null | awk '
+ /\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next }
+ /^#define[ \t]+(KEY|BTN)_[^ ]+[ \t]+[0-9BK]/ { print $2 }
+'
diff --git a/src/udev/meson.build b/src/udev/meson.build
index 9c81bce545..eeb341f8d1 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -59,13 +59,13 @@ keyboard_keys_list_txt = custom_target(
command : [generate_keyboard_keys_list, cpp],
capture : true)
-generate_keyboard_gperf = find_program('generate-keyboard-gperf.py')
+generate_keyboard_keys_gperf = find_program('generate-keyboard-keys-gperf.sh')
fname = 'keyboard-keys-from-name.gperf'
gperf_file = custom_target(
fname,
input : keyboard_keys_list_txt,
output : fname,
- command : [generate_keyboard_gperf, '@INPUT@'],
+ command : [generate_keyboard_keys_gperf, '@INPUT@'],
capture : true)
fname = 'keyboard-keys-from-name.h'
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index d7edbb396b..201fc23437 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -25,6 +25,7 @@
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "link-config.h"
#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
@@ -48,6 +49,17 @@ static const char* const wol_table[_WOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
+static const char* const port_table[_NET_DEV_PORT_MAX] = {
+ [NET_DEV_PORT_TP] = "tp",
+ [NET_DEV_PORT_AUI] = "aui",
+ [NET_DEV_PORT_MII] = "mii",
+ [NET_DEV_PORT_FIBRE] = "fibre",
+ [NET_DEV_PORT_BNC] = "bnc"
+};
+
+DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
+
static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
[NET_DEV_FEAT_GSO] = "tx-generic-segmentation",
[NET_DEV_FEAT_GRO] = "rx-gro",
@@ -488,12 +500,12 @@ static int set_sset(int *fd, struct ifreq *ifr, const struct ethtool_link_usetti
* enabled speed and @duplex is %DUPLEX_UNKNOWN or the best enabled duplex mode.
*/
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autonegotiation) {
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link) {
_cleanup_free_ struct ethtool_link_usettings *u = NULL;
struct ifreq ifr = {};
int r;
- if (autonegotiation != 0) {
+ if (link->autonegotiation != 0) {
log_info("link_config: autonegotiation is unset or enabled, the speed and duplex are not writable.");
return 0;
}
@@ -514,13 +526,16 @@ int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, D
return log_warning_errno(r, "link_config: Cannot get device settings for %s : %m", ifname);
}
- if (speed)
- u->base.speed = speed;
+ if (link->speed)
+ u->base.speed = DIV_ROUND_UP(link->speed, 1000000);
+
+ if (link->duplex != _DUP_INVALID)
+ u->base.duplex = link->duplex;
- if (duplex != _DUP_INVALID)
- u->base.duplex = duplex;
+ if (link->port != _NET_DEV_PORT_INVALID)
+ u->base.port = link->port;
- u->base.autoneg = autonegotiation;
+ u->base.autoneg = link->autonegotiation;
if (u->base.cmd == ETHTOOL_GLINKSETTINGS)
r = set_slinksettings(fd, &ifr, u);
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 75d6af396b..27ce0e0aba 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -24,11 +24,13 @@
#include "missing.h"
+struct link_config;
+
/* we can't use DUPLEX_ prefix, as it
* clashes with <linux/ethtool.h> */
typedef enum Duplex {
- DUP_FULL,
- DUP_HALF,
+ DUP_HALF = DUPLEX_HALF,
+ DUP_FULL = DUPLEX_FULL,
_DUP_MAX,
_DUP_INVALID = -1
} Duplex;
@@ -51,6 +53,18 @@ typedef enum NetDevFeature {
_NET_DEV_FEAT_INVALID = -1
} NetDevFeature;
+typedef enum NetDevPort {
+ NET_DEV_PORT_TP = 0x00,
+ NET_DEV_PORT_AUI = 0x01,
+ NET_DEV_PORT_MII = 0x02,
+ NET_DEV_PORT_FIBRE = 0x03,
+ NET_DEV_PORT_BNC = 0x04,
+ NET_DEV_PORT_DA = 0x05,
+ NET_DEV_PORT_NONE = 0xef,
+ NET_DEV_PORT_OTHER = 0xff,
+ _NET_DEV_PORT_MAX,
+ _NET_DEV_PORT_INVALID = -1
+} NetDevPort;
#define ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NU32 (SCHAR_MAX)
@@ -71,7 +85,7 @@ int ethtool_get_driver(int *fd, const char *ifname, char **ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
-int ethtool_set_glinksettings(int *fd, const char *ifname, unsigned int speed, Duplex duplex, int autoneg);
+int ethtool_set_glinksettings(int *fd, const char *ifname, struct link_config *link);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
@@ -79,5 +93,9 @@ Duplex duplex_from_string(const char *d) _pure_;
const char *wol_to_string(WakeOnLan wol) _const_;
WakeOnLan wol_from_string(const char *wol) _pure_;
+const char *port_to_string(NetDevPort port) _const_;
+NetDevPort port_from_string(const char *port) _pure_;
+
int config_parse_duplex(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_wol(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_port(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);
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index 78e551df22..5488867ba7 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -36,6 +36,7 @@ Link.BitsPerSecond, config_parse_si_size, 0,
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Link.Port, config_parse_port, 0, offsetof(link_config, port)
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO])
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 3af87f1388..05a186357c 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -167,6 +167,7 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
link->mac_policy = _MACPOLICY_INVALID;
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ link->port = _NET_DEV_PORT_INVALID;
link->autonegotiation = -1;
memset(&link->features, -1, sizeof(link->features));
@@ -377,12 +378,13 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (!old_name)
return -EINVAL;
-
- speed = DIV_ROUND_UP(config->speed, 1000000);
-
- r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, speed, config->duplex, config->autonegotiation);
+ r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, config);
if (r < 0) {
+ if (config->port != _NET_DEV_PORT_INVALID)
+ log_warning_errno(r, "Could not set port (%s) of %s: %m", port_to_string(config->port), old_name);
+
+ speed = DIV_ROUND_UP(config->speed, 1000000);
if (r == -EOPNOTSUPP)
r = ethtool_set_speed(&ctx->ethtool_fd, old_name, speed, config->duplex);
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 5a25cec6fd..ff91a65135 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -71,6 +71,7 @@ struct link_config {
Duplex duplex;
int autonegotiation;
WakeOnLan wol;
+ NetDevPort port;
NetDevFeature features[_NET_DEV_FEAT_MAX];
LIST_FIELDS(link_config, links);
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 4171bbd3ce..11d7085153 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -229,7 +229,6 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
_cleanup_blkid_free_probe_ blkid_probe pr = NULL;
const char *data;
const char *name;
- const char *prtype = NULL;
int nvals;
int i;
int err = 0;
@@ -265,8 +264,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
- BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
- BLKID_SUBLKS_BADCSUM);
+ BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
if (noraid)
blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
@@ -288,15 +286,6 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
err = probe_superblocks(pr);
if (err < 0)
goto out;
- if (blkid_probe_has_value(pr, "SBBADCSUM")) {
- if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL))
- log_warning("incorrect %s checksum on %s",
- prtype, udev_device_get_devnode(dev));
- else
- log_warning("incorrect checksum on %s",
- udev_device_get_devnode(dev));
- goto out;
- }
/* If we are a partition then our parent passed on the root
* partition UUID to us */
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 47f41a6607..01e56b26f3 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -158,6 +158,7 @@ static bool test_pointers(struct udev_device *dev,
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
+ int button, axis;
bool has_abs_coordinates = false;
bool has_rel_coordinates = false;
bool has_mt_coordinates = false;
@@ -193,7 +194,8 @@ static bool test_pointers(struct udev_device *dev,
is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
- has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
+ for (button = BTN_MOUSE; button < BTN_JOYSTICK && !has_mouse_button; button++)
+ has_mouse_button = test_bit(button, bitmask_key);
has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
@@ -205,18 +207,14 @@ static bool test_pointers(struct udev_device *dev,
/* joysticks don't necessarily have buttons; e. g.
* rudders/pedals are joystick-like, but buttonless; they have
* other fancy axes. Others have buttons only but no axes. */
- has_joystick_axes_or_buttons = test_bit(BTN_TRIGGER, bitmask_key) ||
- test_bit(BTN_TRIGGER_HAPPY, bitmask_key) ||
- test_bit(BTN_A, bitmask_key) ||
- test_bit(BTN_1, bitmask_key) ||
- test_bit(ABS_RX, bitmask_abs) ||
- test_bit(ABS_RY, bitmask_abs) ||
- test_bit(ABS_RZ, bitmask_abs) ||
- test_bit(ABS_THROTTLE, bitmask_abs) ||
- test_bit(ABS_RUDDER, bitmask_abs) ||
- test_bit(ABS_WHEEL, bitmask_abs) ||
- test_bit(ABS_GAS, bitmask_abs) ||
- test_bit(ABS_BRAKE, bitmask_abs);
+ for (button = BTN_JOYSTICK; button < BTN_DIGI && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_TRIGGER_HAPPY1; button <= BTN_TRIGGER_HAPPY40 && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (button = BTN_DPAD_UP; button <= BTN_DPAD_RIGHT && !has_joystick_axes_or_buttons; button++)
+ has_joystick_axes_or_buttons = test_bit(button, bitmask_key);
+ for (axis = ABS_RX; axis < ABS_PRESSURE && !has_joystick_axes_or_buttons; axis++)
+ has_joystick_axes_or_buttons = test_bit(axis, bitmask_abs);
if (has_abs_coordinates) {
if (stylus_or_pen)
@@ -244,7 +242,9 @@ static bool test_pointers(struct udev_device *dev,
is_touchscreen = true;
}
- if (has_rel_coordinates && has_mouse_button)
+ if (has_mouse_button &&
+ (has_rel_coordinates ||
+ !has_abs_coordinates)) /* mouse buttons and no axis */
is_mouse = true;
if (is_pointing_stick)
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 3f9c3ed0cf..601f0ee13d 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -58,7 +58,7 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
event->udev = udev;
udev_list_init(udev, &event->run_list, false);
udev_list_init(udev, &event->seclabel_list, false);
- event->birth_usec = clock_boottime_or_monotonic();
+ event->birth_usec = now(CLOCK_MONOTONIC);
return event;
}
@@ -520,7 +520,7 @@ static void spawn_read(struct udev_event *event,
if (timeout_usec > 0) {
usec_t age_usec;
- age_usec = clock_boottime_or_monotonic() - event->birth_usec;
+ age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= timeout_usec) {
log_error("timeout '%s'", cmd);
return;
@@ -671,13 +671,13 @@ static int spawn_wait(struct udev_event *event,
if (timeout_usec > 0) {
usec_t usec, age_usec;
- usec = now(clock_boottime_or_monotonic());
+ usec = now(CLOCK_MONOTONIC);
age_usec = usec - event->birth_usec;
if (age_usec < timeout_usec) {
if (timeout_warn_usec > 0 && timeout_warn_usec < timeout_usec && age_usec < timeout_warn_usec) {
spawn.timeout_warn = timeout_warn_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout_warn, USEC_PER_SEC,
on_spawn_timeout_warning, &spawn);
if (r < 0)
@@ -686,7 +686,7 @@ static int spawn_wait(struct udev_event *event,
spawn.timeout = timeout_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
usec + spawn.timeout, USEC_PER_SEC, on_spawn_timeout, &spawn);
if (r < 0)
return r;
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 3af06c68b2..acbddd4180 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -284,12 +284,12 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
e = worker->manager->event;
- assert_se(sd_event_now(e, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(e, CLOCK_MONOTONIC, &usec) >= 0);
- (void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout_warning, CLOCK_MONOTONIC,
usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
- (void) sd_event_add_time(e, &event->timeout, clock_boottime_or_monotonic(),
+ (void) sd_event_add_time(e, &event->timeout, CLOCK_MONOTONIC,
usec + arg_event_timeout_usec, USEC_PER_SEC, on_event_timeout, event);
}
@@ -755,9 +755,9 @@ static void manager_exit(Manager *manager) {
event_queue_cleanup(manager, EVENT_QUEUED);
manager_kill_workers(manager);
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
- r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
+ r = sd_event_add_time(manager->event, NULL, CLOCK_MONOTONIC,
usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
if (r < 0)
return;
@@ -791,7 +791,7 @@ static void event_queue_start(Manager *manager) {
manager->exit || manager->stop_exec_queue)
return;
- assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ assert_se(sd_event_now(manager->event, CLOCK_MONOTONIC, &usec) >= 0);
/* check for changed config, every 3 seconds at most */
if (manager->last_usec == 0 ||
(usec - manager->last_usec) > 3 * USEC_PER_SEC) {
diff --git a/units/dev-hugepages.mount b/units/dev-hugepages.mount
index 489cc777e4..86ad7ac2c9 100644
--- a/units/dev-hugepages.mount
+++ b/units/dev-hugepages.mount
@@ -8,7 +8,7 @@
[Unit]
Description=Huge Pages File System
Documentation=https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/sys/kernel/mm/hugepages
diff --git a/units/dev-mqueue.mount b/units/dev-mqueue.mount
index 8d29f96ca6..b2adfeb835 100644
--- a/units/dev-mqueue.mount
+++ b/units/dev-mqueue.mount
@@ -8,7 +8,7 @@
[Unit]
Description=POSIX Message Queue File System
Documentation=man:mq_overview(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/mqueue
diff --git a/units/network-online.target b/units/network-online.target
index 67bc4fa471..5130d8c5e3 100644
--- a/units/network-online.target
+++ b/units/network-online.target
@@ -8,5 +8,5 @@
[Unit]
Description=Network is Online
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network.target
diff --git a/units/network-pre.target b/units/network-pre.target
index 0ea4bc739a..0d54a4cff8 100644
--- a/units/network-pre.target
+++ b/units/network-pre.target
@@ -8,5 +8,5 @@
[Unit]
Description=Network (Pre)
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
RefuseManualStart=yes
diff --git a/units/network.target b/units/network.target
index 61ebdcadd0..f8331b6124 100644
--- a/units/network.target
+++ b/units/network.target
@@ -8,6 +8,6 @@
[Unit]
Description=Network
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget
After=network-pre.target
RefuseManualStart=yes
diff --git a/units/org.freedesktop.hostname1.busname b/units/org.freedesktop.hostname1.busname
index d64c36486d..f7b41331bf 100644
--- a/units/org.freedesktop.hostname1.busname
+++ b/units/org.freedesktop.hostname1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Hostname Service Bus Name
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[BusName]
Service=systemd-hostnamed.service
diff --git a/units/org.freedesktop.locale1.busname b/units/org.freedesktop.locale1.busname
index 3cd201180b..e0c498e8ff 100644
--- a/units/org.freedesktop.locale1.busname
+++ b/units/org.freedesktop.locale1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Locale Service Bus Name
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[BusName]
Service=systemd-localed.service
diff --git a/units/org.freedesktop.login1.busname b/units/org.freedesktop.login1.busname
index d0686b17e0..b169720f8e 100644
--- a/units/org.freedesktop.login1.busname
+++ b/units/org.freedesktop.login1.busname
@@ -8,8 +8,8 @@
[Unit]
Description=Login Service Bus Name
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
[BusName]
Service=systemd-logind.service
diff --git a/units/org.freedesktop.machine1.busname b/units/org.freedesktop.machine1.busname
index 7df8e9e732..a1f0154778 100644
--- a/units/org.freedesktop.machine1.busname
+++ b/units/org.freedesktop.machine1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Virtual Machine and Container Registration Service Bus Name
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
[BusName]
Service=systemd-machined.service
diff --git a/units/org.freedesktop.resolve1.busname b/units/org.freedesktop.resolve1.busname
index 5b7a7fed3f..28c8f97037 100644
--- a/units/org.freedesktop.resolve1.busname
+++ b/units/org.freedesktop.resolve1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Network Name Resolution Service Bus Name
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
# This is pulled in by systemd-resolved.service, since it cannot run
# without its policy set. However, let's conditionalize this unit on
diff --git a/units/org.freedesktop.systemd1.busname b/units/org.freedesktop.systemd1.busname
index 9ec055e3f2..f9f41cbaf0 100644
--- a/units/org.freedesktop.systemd1.busname
+++ b/units/org.freedesktop.systemd1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=System and Service Manager Bus Name
Documentation=man:systemd(1)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd
[BusName]
Activating=no
diff --git a/units/org.freedesktop.timedate1.busname b/units/org.freedesktop.timedate1.busname
index eae4e536b8..1c962b5f8a 100644
--- a/units/org.freedesktop.timedate1.busname
+++ b/units/org.freedesktop.timedate1.busname
@@ -8,7 +8,7 @@
[Unit]
Description=Time & Date Service Bus Name
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[BusName]
Service=systemd-timedated.service
diff --git a/units/proc-sys-fs-binfmt_misc.automount b/units/proc-sys-fs-binfmt_misc.automount
index 6be38937b1..1067bcd839 100644
--- a/units/proc-sys-fs-binfmt_misc.automount
+++ b/units/proc-sys-fs-binfmt_misc.automount
@@ -7,8 +7,8 @@
[Unit]
Description=Arbitrary Executable File Formats File System Automount Point
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Before=sysinit.target
ConditionPathExists=/proc/sys/fs/binfmt_misc/
diff --git a/units/proc-sys-fs-binfmt_misc.mount b/units/proc-sys-fs-binfmt_misc.mount
index 8c7c386318..27773cd4ea 100644
--- a/units/proc-sys-fs-binfmt_misc.mount
+++ b/units/proc-sys-fs-binfmt_misc.mount
@@ -7,8 +7,8 @@
[Unit]
Description=Arbitrary Executable File Formats File System
-Documentation=https://www.kernel.org/doc/Documentation/binfmt_misc.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
[Mount]
diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount
index 336b5f6277..492ceb16f3 100644
--- a/units/sys-fs-fuse-connections.mount
+++ b/units/sys-fs-fuse-connections.mount
@@ -8,7 +8,7 @@
[Unit]
Description=FUSE Control File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/fs/fuse/connections
ConditionCapability=CAP_SYS_ADMIN
diff --git a/units/sys-kernel-config.mount b/units/sys-kernel-config.mount
index 7f2e1d92f3..b585f32561 100644
--- a/units/sys-kernel-config.mount
+++ b/units/sys-kernel-config.mount
@@ -8,7 +8,7 @@
[Unit]
Description=Kernel Configuration File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/config
ConditionCapability=CAP_SYS_RAWIO
diff --git a/units/sys-kernel-debug.mount b/units/sys-kernel-debug.mount
index d5c50ea142..808dbf08f4 100644
--- a/units/sys-kernel-debug.mount
+++ b/units/sys-kernel-debug.mount
@@ -8,7 +8,7 @@
[Unit]
Description=Kernel Debug File System
Documentation=https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
ConditionPathExists=/sys/kernel/debug
ConditionCapability=CAP_SYS_RAWIO
diff --git a/units/syslog.socket b/units/syslog.socket
index e6e9cf8525..d3987cb9a8 100644
--- a/units/syslog.socket
+++ b/units/syslog.socket
@@ -8,7 +8,7 @@
[Unit]
Description=Syslog Socket
Documentation=man:systemd.special(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/syslog
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/syslog
DefaultDependencies=no
Before=sockets.target shutdown.target
@@ -37,4 +37,4 @@ ReceiveBuffer=8M
# [Install]
# Alias=syslog.service
#
-# See http://www.freedesktop.org/wiki/Software/systemd/syslog for details.
+# See https://www.freedesktop.org/wiki/Software/systemd/syslog for details.
diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in
index 01a8ec9f57..d29e9ff81b 100644
--- a/units/systemd-hostnamed.service.in
+++ b/units/systemd-hostnamed.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Hostname Service
Documentation=man:systemd-hostnamed.service(8) man:hostname(5) man:machine-info(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/hostnamed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/hostnamed
[Service]
ExecStart=@rootlibexecdir@/systemd-hostnamed
diff --git a/units/systemd-importd.service.in b/units/systemd-importd.service.in
index 75585d5dbc..58762055eb 100644
--- a/units/systemd-importd.service.in
+++ b/units/systemd-importd.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Virtual Machine and Container Download Service
Documentation=man:systemd-importd.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/importd
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/importd
[Service]
ExecStart=@rootlibexecdir@/systemd-importd
diff --git a/units/systemd-localed.service.in b/units/systemd-localed.service.in
index f76012a34c..90a913881a 100644
--- a/units/systemd-localed.service.in
+++ b/units/systemd-localed.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Locale Service
Documentation=man:systemd-localed.service(8) man:locale.conf(5) man:vconsole.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/localed
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/localed
[Service]
ExecStart=@rootlibexecdir@/systemd-localed
diff --git a/units/systemd-logind.service.in b/units/systemd-logind.service.in
index 22d74f51d9..bb4a23ec83 100644
--- a/units/systemd-logind.service.in
+++ b/units/systemd-logind.service.in
@@ -8,8 +8,8 @@
[Unit]
Description=Login Service
Documentation=man:systemd-logind.service(8) man:logind.conf(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/logind
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/multiseat
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/logind
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/multiseat
Wants=user.slice
After=nss-user-lookup.target user.slice
diff --git a/units/systemd-machined.service.in b/units/systemd-machined.service.in
index 0fbb302888..a4f86aa7c8 100644
--- a/units/systemd-machined.service.in
+++ b/units/systemd-machined.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Virtual Machine and Container Registration Service
Documentation=man:systemd-machined.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/machined
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/machined
Wants=machine.slice
After=machine.slice
RequiresMountsFor=/var/lib/machines
diff --git a/units/systemd-remount-fs.service.in b/units/systemd-remount-fs.service.in
index 8d9daacaa5..29d0674ab3 100644
--- a/units/systemd-remount-fs.service.in
+++ b/units/systemd-remount-fs.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Remount Root and Kernel File Systems
Documentation=man:systemd-remount-fs.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-fsck-root.service
diff --git a/units/systemd-resolved.service.m4.in b/units/systemd-resolved.service.m4.in
index 6c22893ed7..931156a861 100644
--- a/units/systemd-resolved.service.m4.in
+++ b/units/systemd-resolved.service.m4.in
@@ -8,9 +8,9 @@
[Unit]
Description=Network Name Resolution
Documentation=man:systemd-resolved.service(8)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/resolved
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/resolved
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
After=systemd-networkd.service network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
diff --git a/units/systemd-timedated.service.in b/units/systemd-timedated.service.in
index f691f47517..2b5f0744c9 100644
--- a/units/systemd-timedated.service.in
+++ b/units/systemd-timedated.service.in
@@ -8,7 +8,7 @@
[Unit]
Description=Time & Date Service
Documentation=man:systemd-timedated.service(8) man:localtime(5)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/timedated
[Service]
ExecStart=@rootlibexecdir@/systemd-timedated
diff --git a/units/tmp.mount.m4 b/units/tmp.mount.m4
index 854c7ae614..3a333d22ec 100644
--- a/units/tmp.mount.m4
+++ b/units/tmp.mount.m4
@@ -8,7 +8,7 @@
[Unit]
Description=Temporary Directory (/tmp)
Documentation=man:hier(7)
-Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
+Documentation=https://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
ConditionPathIsSymbolicLink=!/tmp
DefaultDependencies=no
Conflicts=umount.target