diff options
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 |