Compare commits
No commits in common. "2e22a54f4e085496088b77085f38b66532da59fb" and "7477451b691d288dad67b4c8ce9e519e9b75770d" have entirely different histories.
2e22a54f4e
...
7477451b69
1
TODO
1
TODO
|
@ -701,6 +701,7 @@ Features:
|
||||||
- allow multiple signal handlers per signal?
|
- allow multiple signal handlers per signal?
|
||||||
- document chaining of signal handler for SIGCHLD and child handlers
|
- document chaining of signal handler for SIGCHLD and child handlers
|
||||||
- define more intervals where we will shift wakeup intervals around in, 1h, 6h, 24h, ...
|
- define more intervals where we will shift wakeup intervals around in, 1h, 6h, 24h, ...
|
||||||
|
- generate a failure of a default event loop is executed out-of-thread
|
||||||
|
|
||||||
* investigate endianness issues of UUID vs. GUID
|
* investigate endianness issues of UUID vs. GUID
|
||||||
|
|
||||||
|
|
|
@ -207,10 +207,6 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pn*:pvr*
|
||||||
KEYBOARD_KEY_c1=!prog2 #graphics amplifier, undock-button event
|
KEYBOARD_KEY_c1=!prog2 #graphics amplifier, undock-button event
|
||||||
KEYBOARD_KEY_c2=!power #graphics amplifier, surprise undock event
|
KEYBOARD_KEY_c2=!power #graphics amplifier, surprise undock event
|
||||||
|
|
||||||
# Alienware M17xR3 laptops
|
|
||||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnAlienware*:pnM17xR3:*
|
|
||||||
KEYBOARD_KEY_89=ejectcd
|
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
# Asus
|
# Asus
|
||||||
###########################################################
|
###########################################################
|
||||||
|
|
|
@ -471,7 +471,7 @@ mouse:usb:v046dp4069:name:Logitech MX Master 2s:
|
||||||
# Logitech MX Master 2S (via Bluetooth)
|
# Logitech MX Master 2S (via Bluetooth)
|
||||||
# Horiz wheel has 14 stops, angle is rounded up
|
# Horiz wheel has 14 stops, angle is rounded up
|
||||||
mouse:bluetooth:v046dpb019:name:MX Master 2S Mouse:
|
mouse:bluetooth:v046dpb019:name:MX Master 2S Mouse:
|
||||||
MOUSE_DPI=1000@2000
|
MOUSE_DPI=2000@2000
|
||||||
MOUSE_WHEEL_CLICK_ANGLE=15
|
MOUSE_WHEEL_CLICK_ANGLE=15
|
||||||
MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26
|
MOUSE_WHEEL_CLICK_ANGLE_HORIZONTAL=26
|
||||||
MOUSE_WHEEL_CLICK_COUNT=24
|
MOUSE_WHEEL_CLICK_COUNT=24
|
||||||
|
|
|
@ -139,51 +139,6 @@
|
||||||
<literal>us</literal>. To turn off any kind of rate limiting,
|
<literal>us</literal>. To turn off any kind of rate limiting,
|
||||||
set either value to 0.</para>
|
set either value to 0.</para>
|
||||||
|
|
||||||
<para>Note that the effective rate limit is multiplied with a
|
|
||||||
factor derived from the available free disk space for the journal.
|
|
||||||
Currently, this factor is calculated using the base 2 logarithm.</para>
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<title>Example <varname>RateLimitBurst=</varname> rate
|
|
||||||
modifications by the available disk space</title>
|
|
||||||
<tgroup cols='2'>
|
|
||||||
<colspec colname='freespace' />
|
|
||||||
<colspec colname='multiplier' />
|
|
||||||
<thead>
|
|
||||||
<row>
|
|
||||||
<entry>Available Disk Space</entry>
|
|
||||||
<entry>Burst Multiplier</entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<row>
|
|
||||||
<entry><= 1MB</entry>
|
|
||||||
<entry>1</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry><= 16MB</entry>
|
|
||||||
<entry>2</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry><= 256MB</entry>
|
|
||||||
<entry>3</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry><= 4GB</entry>
|
|
||||||
<entry>4</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry><= 64GB</entry>
|
|
||||||
<entry>5</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry><= 1TB</entry>
|
|
||||||
<entry>6</entry>
|
|
||||||
</row>
|
|
||||||
</tbody>
|
|
||||||
</tgroup>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<para>If a service provides rate limits for itself through
|
<para>If a service provides rate limits for itself through
|
||||||
<varname>LogRateLimitIntervalSec=</varname> and/or <varname>LogRateLimitBurst=</varname>
|
<varname>LogRateLimitIntervalSec=</varname> and/or <varname>LogRateLimitBurst=</varname>
|
||||||
in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
|
|
@ -393,17 +393,6 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><varname>systemd.cpu_affinity=</varname></term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>Overrides the CPU affinity mask for the service manager and the default for all child
|
|
||||||
processes it forks. This takes precedence over <varname>CPUAffinity=</varname>, see
|
|
||||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
|
||||||
for details.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>modules_load=</varname></term>
|
<term><varname>modules_load=</varname></term>
|
||||||
<term><varname>rd.modules_load=</varname></term>
|
<term><varname>rd.modules_load=</varname></term>
|
||||||
|
|
|
@ -214,9 +214,6 @@
|
||||||
resolver is not capable of authenticating the server, so it is
|
resolver is not capable of authenticating the server, so it is
|
||||||
vulnerable to "man-in-the-middle" attacks.</para>
|
vulnerable to "man-in-the-middle" attacks.</para>
|
||||||
|
|
||||||
<para>Server Name Indication (SNI) can be used when opening a TLS connection.
|
|
||||||
Entries in <varname>DNS=</varname> should be in format <literal>address#server_name</literal>.</para>
|
|
||||||
|
|
||||||
<para>In addition to this global DNSOverTLS setting
|
<para>In addition to this global DNSOverTLS setting
|
||||||
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||||
also maintains per-link DNSOverTLS settings. For system DNS
|
also maintains per-link DNSOverTLS settings. For system DNS
|
||||||
|
|
|
@ -371,15 +371,7 @@ manpages = [
|
||||||
['sd_bus_wait', '3', [], ''],
|
['sd_bus_wait', '3', [], ''],
|
||||||
['sd_event_add_child',
|
['sd_event_add_child',
|
||||||
'3',
|
'3',
|
||||||
['sd_event_add_child_pidfd',
|
['sd_event_child_handler_t', 'sd_event_source_get_child_pid'],
|
||||||
'sd_event_child_handler_t',
|
|
||||||
'sd_event_source_get_child_pid',
|
|
||||||
'sd_event_source_get_child_pidfd',
|
|
||||||
'sd_event_source_get_child_pidfd_own',
|
|
||||||
'sd_event_source_get_child_process_own',
|
|
||||||
'sd_event_source_send_child_signal',
|
|
||||||
'sd_event_source_set_child_pidfd_own',
|
|
||||||
'sd_event_source_set_child_process_own'],
|
|
||||||
''],
|
''],
|
||||||
['sd_event_add_defer',
|
['sd_event_add_defer',
|
||||||
'3',
|
'3',
|
||||||
|
|
|
@ -17,14 +17,7 @@
|
||||||
|
|
||||||
<refnamediv>
|
<refnamediv>
|
||||||
<refname>sd_event_add_child</refname>
|
<refname>sd_event_add_child</refname>
|
||||||
<refname>sd_event_add_child_pidfd</refname>
|
|
||||||
<refname>sd_event_source_get_child_pid</refname>
|
<refname>sd_event_source_get_child_pid</refname>
|
||||||
<refname>sd_event_source_get_child_pidfd</refname>
|
|
||||||
<refname>sd_event_source_get_child_pidfd_own</refname>
|
|
||||||
<refname>sd_event_source_set_child_pidfd_own</refname>
|
|
||||||
<refname>sd_event_source_get_child_process_own</refname>
|
|
||||||
<refname>sd_event_source_set_child_process_own</refname>
|
|
||||||
<refname>sd_event_source_send_child_signal</refname>
|
|
||||||
<refname>sd_event_child_handler_t</refname>
|
<refname>sd_event_child_handler_t</refname>
|
||||||
|
|
||||||
<refpurpose>Add a child process state change event source to an event loop</refpurpose>
|
<refpurpose>Add a child process state change event source to an event loop</refpurpose>
|
||||||
|
@ -53,77 +46,40 @@
|
||||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_add_child_pidfd</function></funcdef>
|
|
||||||
<paramdef>sd_event *<parameter>event</parameter></paramdef>
|
|
||||||
<paramdef>sd_event_source **<parameter>source</parameter></paramdef>
|
|
||||||
<paramdef>int <parameter>pidfd</parameter></paramdef>
|
|
||||||
<paramdef>int <parameter>options</parameter></paramdef>
|
|
||||||
<paramdef>sd_event_child_handler_t <parameter>handler</parameter></paramdef>
|
|
||||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
<funcdef>int <function>sd_event_source_get_child_pid</function></funcdef>
|
<funcdef>int <function>sd_event_source_get_child_pid</function></funcdef>
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
||||||
<paramdef>pid_t *<parameter>pid</parameter></paramdef>
|
<paramdef>pid_t *<parameter>pid</parameter></paramdef>
|
||||||
</funcprototype>
|
</funcprototype>
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_get_child_pidfd</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_get_child_pidfd_own</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_set_child_pidfd_own</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
<paramdef>int <parameter>own</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_get_child_process_own</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_set_child_process_own</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
<paramdef>int <parameter>own</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
<funcprototype>
|
|
||||||
<funcdef>int <function>sd_event_source_send_child_signal</function></funcdef>
|
|
||||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
|
||||||
<paramdef>int <parameter>sig</parameter></paramdef>
|
|
||||||
<paramdef>const siginfo_t *<parameter>info</parameter></paramdef>
|
|
||||||
<paramdef>unsigned <parameter>flags</parameter></paramdef>
|
|
||||||
</funcprototype>
|
|
||||||
|
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
</refsynopsisdiv>
|
</refsynopsisdiv>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
<title>Description</title>
|
<title>Description</title>
|
||||||
|
|
||||||
<para><function>sd_event_add_child()</function> adds a new child process state change event source to an
|
<para><function>sd_event_add_child()</function> adds a new child
|
||||||
event loop. The event loop object is specified in the <parameter>event</parameter> parameter, the event
|
process state change event source to an event loop. The event loop
|
||||||
source object is returned in the <parameter>source</parameter> parameter. The <parameter>pid</parameter>
|
object is specified in the <parameter>event</parameter> parameter,
|
||||||
parameter specifies the PID of the process to watch, which must be a direct child process of the invoking
|
the event source object is returned in the
|
||||||
process. The <parameter>handler</parameter> must reference a function to call when the process changes
|
<parameter>source</parameter> parameter. The
|
||||||
state. The handler function will be passed the <parameter>userdata</parameter> pointer, which may be
|
<parameter>pid</parameter> parameter specifies the PID of the
|
||||||
chosen freely by the caller. The handler also receives a pointer to a <structname>siginfo_t</structname>
|
process to watch. The <parameter>handler</parameter> must
|
||||||
structure containing information about the child process event. The <parameter>options</parameter>
|
reference a function to call when the process changes state. The
|
||||||
parameter determines which state changes will be watched for. It must contain an OR-ed mask of
|
handler function will be passed the
|
||||||
<constant>WEXITED</constant> (watch for the child process terminating), <constant>WSTOPPED</constant>
|
<parameter>userdata</parameter> pointer, which may be chosen
|
||||||
(watch for the child process being stopped by a signal), and <constant>WCONTINUED</constant> (watch for
|
freely by the caller. The handler also receives a pointer to a
|
||||||
the child process being resumed by a signal). See <citerefentry
|
<structname>siginfo_t</structname> structure containing
|
||||||
project='man-pages'><refentrytitle>waitid</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
information about the child process event. The
|
||||||
further information.</para>
|
<parameter>options</parameter> parameter determines which state
|
||||||
|
changes will be watched for. It must contain an OR-ed mask of
|
||||||
|
<constant>WEXITED</constant> (watch for the child process
|
||||||
|
terminating), <constant>WSTOPPED</constant> (watch for the child
|
||||||
|
process being stopped by a signal), and
|
||||||
|
<constant>WCONTINUED</constant> (watch for the child process being
|
||||||
|
resumed by a signal). See <citerefentry
|
||||||
|
project='man-pages'><refentrytitle>waitid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
|
for further information.</para>
|
||||||
|
|
||||||
<para>Only a single handler may be installed for a specific
|
<para>Only a single handler may be installed for a specific
|
||||||
child process. The handler is enabled for a single event
|
child process. The handler is enabled for a single event
|
||||||
|
@ -144,12 +100,6 @@
|
||||||
<constant>SD_EVENT_OFF</constant> with
|
<constant>SD_EVENT_OFF</constant> with
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
|
<citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
|
||||||
|
|
||||||
<para>The <constant>SIGCHLD</constant> signal must be blocked in all threads before this function is
|
|
||||||
called (using <citerefentry
|
|
||||||
project='man-pages'><refentrytitle>sigprocmask</refentrytitle><manvolnum>2</manvolnum></citerefentry> or
|
|
||||||
<citerefentry
|
|
||||||
project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>).</para>
|
|
||||||
|
|
||||||
<para>If the second parameter of
|
<para>If the second parameter of
|
||||||
<function>sd_event_add_child()</function> is passed as NULL no
|
<function>sd_event_add_child()</function> is passed as NULL no
|
||||||
reference to the event source object is returned. In this case the
|
reference to the event source object is returned. In this case the
|
||||||
|
@ -171,17 +121,6 @@
|
||||||
processed first, it should leave the child processes for which
|
processed first, it should leave the child processes for which
|
||||||
child process state change event sources are installed unreaped.</para>
|
child process state change event sources are installed unreaped.</para>
|
||||||
|
|
||||||
<para><function>sd_event_add_child_pidfd()</function> is similar to
|
|
||||||
<function>sd_event_add_child()</function> but takes a file descriptor referencing the process ("pidfd")
|
|
||||||
instead of the numeric PID. A suitable file descriptor may be acquired via <citerefentry
|
|
||||||
project='man-pages'><refentrytitle>pidfd_open</refentrytitle><manvolnum>2</manvolnum></citerefentry> and
|
|
||||||
related calls. The passed file descriptor is not closed when the event source is freed again, unless
|
|
||||||
<function>sd_event_source_set_child_pidfd_own()</function> is used to turn this behaviour on. Note that
|
|
||||||
regardless which of <function>sd_event_add_child()</function> and
|
|
||||||
<function>sd_event_add_child_pidfd()</function> is used for allocating an event source, the watched
|
|
||||||
process has to be a direct child process of the invoking process. Also in both cases
|
|
||||||
<constant>SIGCHLD</constant> has to be blocked in the invoking process.</para>
|
|
||||||
|
|
||||||
<para><function>sd_event_source_get_child_pid()</function>
|
<para><function>sd_event_source_get_child_pid()</function>
|
||||||
retrieves the configured PID of a child process state change event
|
retrieves the configured PID of a child process state change event
|
||||||
source created previously with
|
source created previously with
|
||||||
|
@ -190,45 +129,6 @@
|
||||||
pointer to a <type>pid_t</type> variable to return the process ID
|
pointer to a <type>pid_t</type> variable to return the process ID
|
||||||
in.
|
in.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para><function>sd_event_source_get_child_pidfd()</function> retrieves the file descriptor referencing
|
|
||||||
the watched process ("pidfd") if this functionality is available. On kernels that support the concept the
|
|
||||||
event loop will make use of pidfds to watch child processes, regardless if the individual event sources
|
|
||||||
are allocated via <function>sd_event_add_child()</function> or
|
|
||||||
<function>sd_event_add_child_pidfd()</function>. If the latter call was used to allocate the event
|
|
||||||
source, this function returns the file descriptor used for allocation. On kernels that do not support the
|
|
||||||
pidfd concept this function will fail with <constant>EOPNOTSUPP</constant>. This call takes the event
|
|
||||||
source object as the <parameter>source</parameter> parameter and returns the numeric file descriptor.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para><function>sd_event_source_get_child_pidfd_own()</function> may be used to query whether the pidfd
|
|
||||||
the event source encapsulates shall be closed when the event source is freed. This function returns zero
|
|
||||||
if the pidfd shall be left open, and positive if it shall be closed automatically. By default this
|
|
||||||
setting defaults to on if the event source was allocated via <function>sd_event_add_child()</function>
|
|
||||||
and off if it was allocated via <function>sd_event_add_child_pidfd()</function>. The
|
|
||||||
<function>sd_event_source_set_child_pidfd_own()</function> function may be used to change the setting and
|
|
||||||
takes a boolean parameter with the new setting.</para>
|
|
||||||
|
|
||||||
<para><function>sd_event_source_get_child_process_own()</function> may be used to query whether the
|
|
||||||
process the event source watches shall be killed (with <constant>SIGKILL</constant>) and reaped when the
|
|
||||||
event source is freed. This function returns zero if the process shell be left running, and positive if
|
|
||||||
it shall be killed and reaped automatically. By default this setting defaults to off. The
|
|
||||||
<function>sd_event_source_set_child_process_own()</function> function may be used to change the setting
|
|
||||||
and takes a boolean parameter with the new setting. Note that currently if the calling process is
|
|
||||||
terminated abnormally the watched process might survive even thought the event source ceases to
|
|
||||||
exist. This behaviour might change eventually.</para>
|
|
||||||
|
|
||||||
<para><function>sd_event_source_send_child_signal()</function> may be used to send a UNIX signal to the
|
|
||||||
watched process. If the pidfd concept is supported in the kernel, this is implemented via <citerefentry
|
|
||||||
project='man-pages'><refentrytitle>pidfd_send_signal</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
|
||||||
and otherwise via <citerefentry
|
|
||||||
project='man-pages'><refentrytitle>rt_sigqueueinfo</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
|
||||||
(or via <citerefentry
|
|
||||||
project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry> in case
|
|
||||||
<parameter>info</parameter> is <constant>NULL</constant>). The specified parameters match those of these
|
|
||||||
underlying system calls, except that the <parameter>info</parameter> is never modified (and is thus
|
|
||||||
declared constant). Like for the underlying system calls, the <parameter>flags</parameter> parameter
|
|
||||||
currently must be zero.</para>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -265,8 +165,8 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><constant>-EBUSY</constant></term>
|
<term><constant>-EBUSY</constant></term>
|
||||||
|
|
||||||
<listitem><para>A handler is already installed for this child process, or
|
<listitem><para>A handler is already installed for this
|
||||||
<constant>SIGCHLD</constant> is not blocked.</para></listitem>
|
child process.</para></listitem>
|
||||||
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -290,12 +190,6 @@
|
||||||
<listitem><para>The passed event source is not a child process event source.</para></listitem>
|
<listitem><para>The passed event source is not a child process event source.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
|
||||||
<term><constant>-EOPNOTSUPP</constant></term>
|
|
||||||
|
|
||||||
<listitem><para>A pidfd was requested but the kernel does not support this concept.</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
@ -320,13 +214,7 @@
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_event_source_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_event_source_set_description</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_event_source_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>waitid</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>waitid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
<citerefentry project='man-pages'><refentrytitle>sigprocmask</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>pidfd_open</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>pidfd_send_signal</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>rt_sigqueueinfo</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -75,13 +75,14 @@
|
||||||
project='man-pages'><refentrytitle>signalfd</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
project='man-pages'><refentrytitle>signalfd</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
for further information.</para>
|
for further information.</para>
|
||||||
|
|
||||||
<para>Only a single handler may be installed for a specific signal. The signal must be blocked in all
|
<para>Only a single handler may be installed for a specific
|
||||||
threads before this function is called (using <citerefentry
|
signal. The signal will be unblocked by this call, and must be
|
||||||
project='man-pages'><refentrytitle>sigprocmask</refentrytitle><manvolnum>2</manvolnum></citerefentry> or
|
blocked before this function is called in all threads (using
|
||||||
<citerefentry
|
<citerefentry
|
||||||
project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>). If
|
project='man-pages'><refentrytitle>sigprocmask</refentrytitle><manvolnum>2</manvolnum></citerefentry>). If
|
||||||
the handler is not specified (<parameter>handler</parameter> is <constant>NULL</constant>), a default
|
the handler is not specified (<parameter>handler</parameter> is
|
||||||
handler which causes the program to exit cleanly will be used.</para>
|
<constant>NULL</constant>), a default handler which causes the
|
||||||
|
program to exit cleanly will be used.</para>
|
||||||
|
|
||||||
<para>By default, the event source is enabled permanently
|
<para>By default, the event source is enabled permanently
|
||||||
(<constant>SD_EVENT_ON</constant>), but this may be changed with
|
(<constant>SD_EVENT_ON</constant>), but this may be changed with
|
||||||
|
@ -188,9 +189,7 @@
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_event_source_set_userdata</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>sd_event_source_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
<citerefentry><refentrytitle>sd_event_source_set_floating</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
<citerefentry project='man-pages'><refentrytitle>signalfd</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
<citerefentry project='man-pages'><refentrytitle>signalfd</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
<citerefentry project='man-pages'><refentrytitle>sigprocmask</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
|
||||||
</para>
|
</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
<filename>hibernate.target</filename>,
|
<filename>hibernate.target</filename>,
|
||||||
<filename>hybrid-sleep.target</filename>,
|
<filename>hybrid-sleep.target</filename>,
|
||||||
<filename>suspend-then-hibernate.target</filename>,
|
<filename>suspend-then-hibernate.target</filename>,
|
||||||
<filename>initrd.target</filename>,
|
|
||||||
<filename>initrd-fs.target</filename>,
|
<filename>initrd-fs.target</filename>,
|
||||||
<filename>initrd-root-device.target</filename>,
|
<filename>initrd-root-device.target</filename>,
|
||||||
<filename>initrd-root-fs.target</filename>,
|
<filename>initrd-root-fs.target</filename>,
|
||||||
|
@ -203,16 +202,14 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><filename>default.target</filename></term>
|
<term><filename>default.target</filename></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The default unit systemd starts at bootup. Usually, this should be aliased (symlinked) to
|
<para>The default unit systemd starts at bootup. Usually,
|
||||||
<filename>multi-user.target</filename> or <filename>graphical.target</filename>. See
|
this should be aliased (symlinked) to
|
||||||
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
<filename>multi-user.target</filename> or
|
||||||
more discussion.</para>
|
<filename>graphical.target</filename>.</para>
|
||||||
|
|
||||||
<para>The default unit systemd starts at bootup can be overridden with the
|
<para>The default unit systemd starts at bootup can be
|
||||||
<varname>systemd.unit=</varname> kernel command line option, or more conveniently, with the short
|
overridden with the <varname>systemd.unit=</varname> kernel
|
||||||
names like <varname>single</varname>, <varname>rescue</varname>, <varname>1</varname>,
|
command line option.</para>
|
||||||
<varname>3</varname>, <varname>5</varname>, …; see
|
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -344,15 +341,6 @@
|
||||||
is active as long as the system is running.</para>
|
is active as long as the system is running.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term><filename>initrd.target</filename></term>
|
|
||||||
<listitem>
|
|
||||||
<para>This is the default target in the initramfs, similar to <filename>default.target</filename>
|
|
||||||
in the main system. It is used to mount the real root and transition to it. See
|
|
||||||
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
|
||||||
more discussion.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><filename>initrd-fs.target</filename></term>
|
<term><filename>initrd-fs.target</filename></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
12
meson.build
12
meson.build
|
@ -517,18 +517,6 @@ foreach ident : [
|
||||||
#include <unistd.h>'''],
|
#include <unistd.h>'''],
|
||||||
['get_mempolicy', '''#include <stdlib.h>
|
['get_mempolicy', '''#include <stdlib.h>
|
||||||
#include <unistd.h>'''],
|
#include <unistd.h>'''],
|
||||||
['pidfd_send_signal', '''#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/wait.h>'''],
|
|
||||||
['pidfd_open', '''#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/wait.h>'''],
|
|
||||||
['rt_sigqueueinfo', '''#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/wait.h>'''],
|
|
||||||
]
|
]
|
||||||
|
|
||||||
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
||||||
|
|
|
@ -86,17 +86,20 @@ unsigned long cap_last_cap(void) {
|
||||||
int capability_update_inherited_set(cap_t caps, uint64_t set) {
|
int capability_update_inherited_set(cap_t caps, uint64_t set) {
|
||||||
unsigned long i;
|
unsigned long i;
|
||||||
|
|
||||||
/* Add capabilities in the set to the inherited caps, drops capabilities not in the set.
|
/* Add capabilities in the set to the inherited caps. Do not apply
|
||||||
* Do not apply them yet. */
|
* them yet. */
|
||||||
|
|
||||||
for (i = 0; i <= cap_last_cap(); i++) {
|
for (i = 0; i <= cap_last_cap(); i++) {
|
||||||
cap_flag_value_t flag = set & (UINT64_C(1) << i) ? CAP_SET : CAP_CLEAR;
|
|
||||||
cap_value_t v;
|
|
||||||
|
|
||||||
v = (cap_value_t) i;
|
if (set & (UINT64_C(1) << i)) {
|
||||||
|
cap_value_t v;
|
||||||
|
|
||||||
if (cap_set_flag(caps, CAP_INHERITABLE, 1, &v, flag) < 0)
|
v = (cap_value_t) i;
|
||||||
return -errno;
|
|
||||||
|
/* Make the capability inheritable. */
|
||||||
|
if (cap_set_flag(caps, CAP_INHERITABLE, 1, &v, CAP_SET) < 0)
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -129,17 +132,6 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) {
|
||||||
/* Add the capability to the ambient set. */
|
/* Add the capability to the ambient set. */
|
||||||
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0)
|
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Drop the capability so we don't inherit capabilities we didn't ask for. */
|
|
||||||
r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
|
|
||||||
if (r < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (r)
|
|
||||||
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, i, 0, 0) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "missing_syscall.h"
|
#include "missing_syscall.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "selinux-util.h"
|
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
|
@ -373,15 +372,7 @@ static int fd_copy_symlink(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
if (symlinkat(target, dt, to) < 0)
|
||||||
r = mac_selinux_create_file_prepare_at(dt, to, S_IFLNK);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
r = symlinkat(target, dt, to);
|
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (r < 0)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (fchownat(dt, to,
|
if (fchownat(dt, to,
|
||||||
|
@ -417,14 +408,7 @@ static int fd_copy_regular(
|
||||||
if (fdf < 0)
|
if (fdf < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare_at(dt, to, S_IFREG);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
fdt = openat(dt, to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, st->st_mode & 07777);
|
fdt = openat(dt, to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, st->st_mode & 07777);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (fdt < 0)
|
if (fdt < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -473,14 +457,7 @@ static int fd_copy_fifo(
|
||||||
assert(st);
|
assert(st);
|
||||||
assert(to);
|
assert(to);
|
||||||
|
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare_at(dt, to, S_IFIFO);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
r = mkfifoat(dt, to, st->st_mode & 07777);
|
r = mkfifoat(dt, to, st->st_mode & 07777);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -511,14 +488,7 @@ static int fd_copy_node(
|
||||||
assert(st);
|
assert(st);
|
||||||
assert(to);
|
assert(to);
|
||||||
|
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare_at(dt, to, st->st_mode & S_IFMT);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
r = mknodat(dt, to, st->st_mode, st->st_rdev);
|
r = mknodat(dt, to, st->st_mode, st->st_rdev);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -586,10 +556,7 @@ static int fd_copy_directory(
|
||||||
if (exists)
|
if (exists)
|
||||||
created = false;
|
created = false;
|
||||||
else {
|
else {
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
r = mkdirat(dt, to, st->st_mode & 07777);
|
||||||
r = mkdirat_label(dt, to, st->st_mode & 07777);
|
|
||||||
else
|
|
||||||
r = mkdirat(dt, to, st->st_mode & 07777);
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
created = true;
|
created = true;
|
||||||
else if (errno == EEXIST && (copy_flags & COPY_MERGE))
|
else if (errno == EEXIST && (copy_flags & COPY_MERGE))
|
||||||
|
@ -829,14 +796,7 @@ int copy_file_full(
|
||||||
assert(to);
|
assert(to);
|
||||||
|
|
||||||
RUN_WITH_UMASK(0000) {
|
RUN_WITH_UMASK(0000) {
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare(to, S_IFREG);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
|
fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (fdt < 0)
|
if (fdt < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
@ -890,29 +850,13 @@ int copy_file_atomic_full(
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare(to, S_IFREG);
|
|
||||||
if (r < 0) {
|
|
||||||
t = mfree(t);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fdt = open(t, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
|
fdt = open(t, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (fdt < 0) {
|
if (fdt < 0) {
|
||||||
t = mfree(t);
|
t = mfree(t);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (copy_flags & COPY_MAC_CREATE) {
|
|
||||||
r = mac_selinux_create_file_prepare(to, S_IFREG);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
|
fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
|
||||||
if (copy_flags & COPY_MAC_CREATE)
|
|
||||||
mac_selinux_create_file_clear();
|
|
||||||
if (fdt < 0)
|
if (fdt < 0)
|
||||||
return fdt;
|
return fdt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ typedef enum CopyFlags {
|
||||||
COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
|
COPY_MERGE_EMPTY = 1 << 4, /* Merge an existing, empty directory with our new tree to copy */
|
||||||
COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
|
COPY_CRTIME = 1 << 5, /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
|
||||||
COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
|
COPY_SIGINT = 1 << 6, /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
|
||||||
COPY_MAC_CREATE = 1 << 7, /* Create files with the correct MAC label (currently SELinux only) */
|
|
||||||
} CopyFlags;
|
} CopyFlags;
|
||||||
|
|
||||||
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
|
typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);
|
||||||
|
|
|
@ -101,11 +101,3 @@ static inline bool ERRNO_IS_PRIVILEGE(int r) {
|
||||||
EACCES,
|
EACCES,
|
||||||
EPERM);
|
EPERM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Three difference errors for "not enough disk space" */
|
|
||||||
static inline bool ERRNO_IS_DISK_SPACE(int r) {
|
|
||||||
return IN_SET(abs(r),
|
|
||||||
ENOSPC,
|
|
||||||
EDQUOT,
|
|
||||||
EFBIG);
|
|
||||||
}
|
|
||||||
|
|
|
@ -80,21 +80,14 @@ static inline void* explicit_bzero_safe(void *p, size_t l) {
|
||||||
void *explicit_bzero_safe(void *p, size_t l);
|
void *explicit_bzero_safe(void *p, size_t l);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void* erase_and_free(void *p) {
|
|
||||||
size_t l;
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
l = malloc_usable_size(p);
|
|
||||||
explicit_bzero_safe(p, l);
|
|
||||||
free(p);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void erase_and_freep(void *p) {
|
static inline void erase_and_freep(void *p) {
|
||||||
erase_and_free(*(void**) p);
|
void *ptr = *(void**) p;
|
||||||
|
|
||||||
|
if (ptr) {
|
||||||
|
size_t l = malloc_usable_size(ptr);
|
||||||
|
explicit_bzero_safe(ptr, l);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use with _cleanup_ to erase a single 'char' when leaving scope */
|
/* Use with _cleanup_ to erase a single 'char' when leaving scope */
|
||||||
|
|
|
@ -5,10 +5,8 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef ARCH_MIPS
|
#ifdef ARCH_MIPS
|
||||||
|
@ -526,45 +524,3 @@ static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
|
||||||
|
|
||||||
#define get_mempolicy missing_get_mempolicy
|
#define get_mempolicy missing_get_mempolicy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !HAVE_PIDFD_OPEN
|
|
||||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
|
||||||
# if ! (defined __NR_pidfd_open && __NR_pidfd_open > 0)
|
|
||||||
# if defined __NR_pidfd_open
|
|
||||||
# undef __NR_pidfd_open
|
|
||||||
# endif
|
|
||||||
# define __NR_pidfd_open 434
|
|
||||||
#endif
|
|
||||||
static inline int pidfd_open(pid_t pid, unsigned flags) {
|
|
||||||
#ifdef __NR_pidfd_open
|
|
||||||
return syscall(__NR_pidfd_open, pid, flags);
|
|
||||||
#else
|
|
||||||
errno = ENOSYS;
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
|
||||||
/* may be (invalid) negative number due to libseccomp, see PR 13319 */
|
|
||||||
# if ! (defined __NR_pidfd_send_signal && __NR_pidfd_send_signal > 0)
|
|
||||||
# if defined __NR_pidfd_send_signal
|
|
||||||
# undef __NR_pidfd_send_signal
|
|
||||||
# endif
|
|
||||||
# define __NR_pidfd_send_signal 424
|
|
||||||
#endif
|
|
||||||
static inline int pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
|
|
||||||
#ifdef __NR_pidfd_open
|
|
||||||
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
|
|
||||||
#else
|
|
||||||
errno = ENOSYS;
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !HAVE_RT_SIGQUEUEINFO
|
|
||||||
static inline int rt_sigqueueinfo(pid_t tgid, int sig, siginfo_t *info) {
|
|
||||||
return syscall(__NR_rt_sigqueueinfo, tgid, sig, info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -50,10 +50,6 @@ static inline void* ordered_set_remove(OrderedSet *s, void *p) {
|
||||||
return ordered_hashmap_remove((OrderedHashmap*) s, p);
|
return ordered_hashmap_remove((OrderedHashmap*) s, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void* ordered_set_first(OrderedSet *s) {
|
|
||||||
return ordered_hashmap_first((OrderedHashmap*) s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void* ordered_set_steal_first(OrderedSet *s) {
|
static inline void* ordered_set_steal_first(OrderedSet *s) {
|
||||||
return ordered_hashmap_steal_first((OrderedHashmap*) s);
|
return ordered_hashmap_steal_first((OrderedHashmap*) s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,6 +365,7 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret_u);
|
||||||
assert(base <= 16);
|
assert(base <= 16);
|
||||||
|
|
||||||
/* strtoul() is happy to parse negative values, and silently
|
/* strtoul() is happy to parse negative values, and silently
|
||||||
|
@ -388,9 +389,7 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||||
if ((unsigned long) (unsigned) l != l)
|
if ((unsigned long) (unsigned) l != l)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (ret_u)
|
*ret_u = (unsigned) l;
|
||||||
*ret_u = (unsigned) l;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +398,7 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret_i);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(s, &x, 0);
|
l = strtol(s, &x, 0);
|
||||||
|
@ -409,9 +409,7 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||||
if ((long) (int) l != l)
|
if ((long) (int) l != l)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (ret_i)
|
*ret_i = (int) l;
|
||||||
*ret_i = (int) l;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +418,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||||
unsigned long long l;
|
unsigned long long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret_llu);
|
||||||
|
|
||||||
s += strspn(s, WHITESPACE);
|
s += strspn(s, WHITESPACE);
|
||||||
|
|
||||||
|
@ -432,9 +431,7 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||||
if (*s == '-')
|
if (*s == '-')
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (ret_llu)
|
*ret_llu = l;
|
||||||
*ret_llu = l;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,6 +440,7 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||||
long long l;
|
long long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret_lli);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtoll(s, &x, 0);
|
l = strtoll(s, &x, 0);
|
||||||
|
@ -451,9 +449,7 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ret_lli)
|
*ret_lli = l;
|
||||||
*ret_lli = l;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,6 +458,7 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
s += strspn(s, WHITESPACE);
|
s += strspn(s, WHITESPACE);
|
||||||
|
|
||||||
|
@ -476,8 +473,7 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||||
if ((unsigned long) (uint8_t) l != l)
|
if ((unsigned long) (uint8_t) l != l)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (ret)
|
*ret = (uint8_t) l;
|
||||||
*ret = (uint8_t) l;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,6 +507,7 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||||
long l;
|
long l;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(s, &x, 0);
|
l = strtol(s, &x, 0);
|
||||||
|
@ -521,9 +518,7 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||||
if ((long) (int16_t) l != l)
|
if ((long) (int16_t) l != l)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
|
||||||
if (ret)
|
*ret = (int16_t) l;
|
||||||
*ret = (int16_t) l;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,6 +528,7 @@ int safe_atod(const char *s, double *ret_d) {
|
||||||
double d = 0;
|
double d = 0;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(ret_d);
|
||||||
|
|
||||||
loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
|
loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
|
||||||
if (loc == (locale_t) 0)
|
if (loc == (locale_t) 0)
|
||||||
|
@ -545,9 +541,7 @@ int safe_atod(const char *s, double *ret_d) {
|
||||||
if (!x || x == s || *x != 0)
|
if (!x || x == s || *x != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (ret_d)
|
*ret_d = (double) d;
|
||||||
*ret_d = (double) d;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#include "rlimit-util.h"
|
#include "rlimit-util.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "stdio-util.h"
|
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
@ -1338,13 +1337,6 @@ int safe_fork_full(
|
||||||
log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
|
log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (flags & FORK_STDOUT_TO_STDERR) {
|
|
||||||
|
|
||||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
|
||||||
log_full_errno(prio, r, "Failed to connect stdout to stderr: %m");
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & FORK_RLIMIT_NOFILE_SAFE) {
|
if (flags & FORK_RLIMIT_NOFILE_SAFE) {
|
||||||
|
@ -1496,38 +1488,6 @@ int set_oom_score_adjust(int value) {
|
||||||
WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
|
WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pidfd_get_pid(int fd, pid_t *ret) {
|
|
||||||
char path[STRLEN("/proc/self/fdinfo/") + DECIMAL_STR_MAX(int)];
|
|
||||||
_cleanup_free_ char *fdinfo = NULL;
|
|
||||||
char *p;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (fd < 0)
|
|
||||||
return -EBADF;
|
|
||||||
|
|
||||||
xsprintf(path, "/proc/self/fdinfo/%i", fd);
|
|
||||||
|
|
||||||
r = read_full_file(path, &fdinfo, NULL);
|
|
||||||
if (r == -ENOENT) /* if fdinfo doesn't exist we assume the process does not exist */
|
|
||||||
return -ESRCH;
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
p = startswith(fdinfo, "Pid:");
|
|
||||||
if (!p) {
|
|
||||||
p = strstr(fdinfo, "\nPid:");
|
|
||||||
if (!p)
|
|
||||||
return -ENOTTY; /* not a pidfd? */
|
|
||||||
|
|
||||||
p += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += strspn(p, WHITESPACE);
|
|
||||||
p[strcspn(p, WHITESPACE)] = 0;
|
|
||||||
|
|
||||||
return parse_pid(p, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *const ioprio_class_table[] = {
|
static const char *const ioprio_class_table[] = {
|
||||||
[IOPRIO_CLASS_NONE] = "none",
|
[IOPRIO_CLASS_NONE] = "none",
|
||||||
[IOPRIO_CLASS_RT] = "realtime",
|
[IOPRIO_CLASS_RT] = "realtime",
|
||||||
|
|
|
@ -147,17 +147,16 @@ void reset_cached_pid(void);
|
||||||
int must_be_root(void);
|
int must_be_root(void);
|
||||||
|
|
||||||
typedef enum ForkFlags {
|
typedef enum ForkFlags {
|
||||||
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
|
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
|
||||||
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
|
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
|
||||||
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
|
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
|
||||||
FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
|
FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
|
||||||
FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
|
FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
|
||||||
FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
|
FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
|
||||||
FORK_WAIT = 1 << 6, /* Wait until child exited */
|
FORK_WAIT = 1 << 6, /* Wait until child exited */
|
||||||
FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
|
FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
|
||||||
FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
|
FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
|
||||||
FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
||||||
FORK_STDOUT_TO_STDERR = 1 << 10, /* Make stdout a copy of stderr */
|
|
||||||
} ForkFlags;
|
} ForkFlags;
|
||||||
|
|
||||||
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
|
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
|
||||||
|
@ -198,5 +197,3 @@ assert_cc(TASKS_MAX <= (unsigned long) PID_T_MAX);
|
||||||
(pid) = 0; \
|
(pid) = 0; \
|
||||||
_pid_; \
|
_pid_; \
|
||||||
})
|
})
|
||||||
|
|
||||||
int pidfd_get_pid(int fd, pid_t *ret);
|
|
||||||
|
|
|
@ -107,26 +107,6 @@ void mac_selinux_finish(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac_selinux_reload(void) {
|
|
||||||
|
|
||||||
#if HAVE_SELINUX
|
|
||||||
struct selabel_handle *backup_label_hnd;
|
|
||||||
|
|
||||||
if (!label_hnd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
backup_label_hnd = TAKE_PTR(label_hnd);
|
|
||||||
|
|
||||||
/* try to initialize new handle
|
|
||||||
* on success close backup
|
|
||||||
* on failure restore backup */
|
|
||||||
if (mac_selinux_init() == 0)
|
|
||||||
selabel_close(backup_label_hnd);
|
|
||||||
else
|
|
||||||
label_hnd = backup_label_hnd;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
||||||
|
|
||||||
#if HAVE_SELINUX
|
#if HAVE_SELINUX
|
||||||
|
|
|
@ -13,7 +13,6 @@ void mac_selinux_retest(void);
|
||||||
|
|
||||||
int mac_selinux_init(void);
|
int mac_selinux_init(void);
|
||||||
void mac_selinux_finish(void);
|
void mac_selinux_finish(void);
|
||||||
void mac_selinux_reload(void);
|
|
||||||
|
|
||||||
int mac_selinux_fix(const char *path, LabelFixFlags flags);
|
int mac_selinux_fix(const char *path, LabelFixFlags flags);
|
||||||
int mac_selinux_apply(const char *path, const char *label);
|
int mac_selinux_apply(const char *path, const char *label);
|
||||||
|
|
|
@ -287,18 +287,3 @@ int signal_from_string(const char *s) {
|
||||||
void nop_signal_handler(int sig) {
|
void nop_signal_handler(int sig) {
|
||||||
/* nothing here */
|
/* nothing here */
|
||||||
}
|
}
|
||||||
|
|
||||||
int signal_is_blocked(int sig) {
|
|
||||||
sigset_t ss;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
|
|
||||||
if (r != 0)
|
|
||||||
return -r;
|
|
||||||
|
|
||||||
r = sigismember(&ss, sig);
|
|
||||||
if (r < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
|
@ -41,5 +41,3 @@ static inline const char* signal_to_string_with_check(int n) {
|
||||||
|
|
||||||
return signal_to_string(n);
|
return signal_to_string(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
int signal_is_blocked(int sig);
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define SPECIAL_DEFAULT_TARGET "default.target"
|
#define SPECIAL_DEFAULT_TARGET "default.target"
|
||||||
#define SPECIAL_INITRD_TARGET "initrd.target"
|
|
||||||
|
|
||||||
/* Shutdown targets */
|
/* Shutdown targets */
|
||||||
#define SPECIAL_UMOUNT_TARGET "umount.target"
|
#define SPECIAL_UMOUNT_TARGET "umount.target"
|
||||||
|
|
|
@ -1064,13 +1064,3 @@ bool string_is_safe(const char *p) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* string_erase(char *x) {
|
|
||||||
if (!x)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* A delicious drop of snake-oil! To be called on memory where we stored passphrases or so, after we
|
|
||||||
* used them. */
|
|
||||||
explicit_bzero_safe(x, strlen(x));
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
|
@ -278,5 +278,3 @@ static inline char* str_realloc(char **p) {
|
||||||
|
|
||||||
return (*p = t);
|
return (*p = t);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* string_erase(char *x);
|
|
||||||
|
|
|
@ -19,60 +19,50 @@
|
||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
#include "umask-util.h"
|
#include "umask-util.h"
|
||||||
|
|
||||||
int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
|
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
FILE *f;
|
||||||
_cleanup_free_ char *t = NULL;
|
char *t;
|
||||||
_cleanup_close_ int fd = -1;
|
int r, fd;
|
||||||
int r;
|
|
||||||
|
|
||||||
if (path) {
|
assert(path);
|
||||||
r = tempfn_xxxxxx(path, NULL, &t);
|
assert(_f);
|
||||||
if (r < 0)
|
assert(_temp_path);
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
const char *d;
|
|
||||||
|
|
||||||
r = tmp_dir(&d);
|
r = tempfn_xxxxxx(path, NULL, &t);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
t = path_join(d, "XXXXXX");
|
|
||||||
if (!t)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = mkostemp_safe(t);
|
fd = mkostemp_safe(t);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
|
free(t);
|
||||||
return -errno;
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
|
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
|
||||||
* context and never shared externally, hence locking is not necessary. */
|
* context and never shared externally, hence locking is not necessary. */
|
||||||
|
|
||||||
r = fdopen_unlocked(fd, "w", &f);
|
r = fdopen_unlocked(fd, "w", &f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
(void) unlink(t);
|
unlink(t);
|
||||||
|
free(t);
|
||||||
|
safe_close(fd);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAKE_FD(fd);
|
*_f = f;
|
||||||
|
*_temp_path = t;
|
||||||
if (ret_f)
|
|
||||||
*ret_f = TAKE_PTR(f);
|
|
||||||
|
|
||||||
if (ret_temp_path)
|
|
||||||
*ret_temp_path = TAKE_PTR(t);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is much like mkostemp() but is subject to umask(). */
|
/* This is much like mkostemp() but is subject to umask(). */
|
||||||
int mkostemp_safe(char *pattern) {
|
int mkostemp_safe(char *pattern) {
|
||||||
|
_unused_ _cleanup_umask_ mode_t u = umask(0077);
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
assert(pattern);
|
assert(pattern);
|
||||||
|
|
||||||
RUN_WITH_UMASK(0077)
|
fd = mkostemp(pattern, O_CLOEXEC);
|
||||||
fd = mkostemp(pattern, O_CLOEXEC);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ char *getusername_malloc(void) {
|
||||||
return uid_to_name(getuid());
|
return uid_to_name(getuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_nologin_shell(const char *shell) {
|
static bool is_nologin_shell(const char *shell) {
|
||||||
|
|
||||||
return PATH_IN_SET(shell,
|
return PATH_IN_SET(shell,
|
||||||
/* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
|
/* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
|
||||||
|
|
|
@ -57,14 +57,6 @@ int take_etc_passwd_lock(const char *root);
|
||||||
|
|
||||||
#define ETC_PASSWD_LOCK_PATH "/etc/.pwd.lock"
|
#define ETC_PASSWD_LOCK_PATH "/etc/.pwd.lock"
|
||||||
|
|
||||||
static inline bool uid_is_system(uid_t uid) {
|
|
||||||
return uid <= SYSTEM_UID_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gid_is_system(gid_t gid) {
|
|
||||||
return gid <= SYSTEM_GID_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool uid_is_dynamic(uid_t uid) {
|
static inline bool uid_is_dynamic(uid_t uid) {
|
||||||
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
|
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
|
||||||
}
|
}
|
||||||
|
@ -73,12 +65,12 @@ static inline bool gid_is_dynamic(gid_t gid) {
|
||||||
return uid_is_dynamic((uid_t) gid);
|
return uid_is_dynamic((uid_t) gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool uid_is_container(uid_t uid) {
|
static inline bool uid_is_system(uid_t uid) {
|
||||||
return CONTAINER_UID_BASE_MIN <= uid && uid <= CONTAINER_UID_BASE_MAX;
|
return uid <= SYSTEM_UID_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool gid_is_container(gid_t gid) {
|
static inline bool gid_is_system(gid_t gid) {
|
||||||
return uid_is_container((uid_t) gid);
|
return gid <= SYSTEM_GID_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer
|
/* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer
|
||||||
|
@ -135,5 +127,3 @@ int putsgent_sane(const struct sgrp *sg, FILE *stream);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int make_salt(char **ret);
|
int make_salt(char **ret);
|
||||||
|
|
||||||
bool is_nologin_shell(const char *shell);
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ enum loader_type {
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CHAR16 *id; /* The unique identifier for this entry */
|
CHAR16 *id; /* The identifier for this entry (note that this id is not necessarily unique though!) */
|
||||||
CHAR16 *title_show;
|
CHAR16 *title_show;
|
||||||
CHAR16 *title;
|
CHAR16 *title;
|
||||||
CHAR16 *version;
|
CHAR16 *version;
|
||||||
|
@ -1310,6 +1310,7 @@ static VOID config_entry_add_from_file(
|
||||||
CHAR8 *line;
|
CHAR8 *line;
|
||||||
UINTN pos = 0;
|
UINTN pos = 0;
|
||||||
CHAR8 *key, *value;
|
CHAR8 *key, *value;
|
||||||
|
UINTN len;
|
||||||
EFI_STATUS err;
|
EFI_STATUS err;
|
||||||
EFI_FILE_HANDLE handle;
|
EFI_FILE_HANDLE handle;
|
||||||
_cleanup_freepool_ CHAR16 *initrd = NULL;
|
_cleanup_freepool_ CHAR16 *initrd = NULL;
|
||||||
|
@ -1430,6 +1431,10 @@ static VOID config_entry_add_from_file(
|
||||||
|
|
||||||
entry->device = device;
|
entry->device = device;
|
||||||
entry->id = StrDuplicate(file);
|
entry->id = StrDuplicate(file);
|
||||||
|
len = StrLen(entry->id);
|
||||||
|
/* remove ".conf" */
|
||||||
|
if (len > 5)
|
||||||
|
entry->id[len - 5] = '\0';
|
||||||
StrLwr(entry->id);
|
StrLwr(entry->id);
|
||||||
|
|
||||||
config_add_entry(config, entry);
|
config_add_entry(config, entry);
|
||||||
|
@ -1770,8 +1775,7 @@ static ConfigEntry *config_entry_add_loader(
|
||||||
CHAR16 *id,
|
CHAR16 *id,
|
||||||
CHAR16 key,
|
CHAR16 key,
|
||||||
CHAR16 *title,
|
CHAR16 *title,
|
||||||
CHAR16 *loader,
|
CHAR16 *loader) {
|
||||||
CHAR16 *version) {
|
|
||||||
|
|
||||||
ConfigEntry *entry;
|
ConfigEntry *entry;
|
||||||
|
|
||||||
|
@ -1779,7 +1783,6 @@ static ConfigEntry *config_entry_add_loader(
|
||||||
*entry = (ConfigEntry) {
|
*entry = (ConfigEntry) {
|
||||||
.type = type,
|
.type = type,
|
||||||
.title = StrDuplicate(title),
|
.title = StrDuplicate(title),
|
||||||
.version = StrDuplicate(version),
|
|
||||||
.device = device,
|
.device = device,
|
||||||
.loader = StrDuplicate(loader),
|
.loader = StrDuplicate(loader),
|
||||||
.id = StrDuplicate(id),
|
.id = StrDuplicate(id),
|
||||||
|
@ -1837,7 +1840,7 @@ static BOOLEAN config_entry_add_loader_auto(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
uefi_call_wrapper(handle->Close, 1, handle);
|
uefi_call_wrapper(handle->Close, 1, handle);
|
||||||
|
|
||||||
entry = config_entry_add_loader(config, device, LOADER_UNDEFINED, id, key, title, loader, NULL);
|
entry = config_entry_add_loader(config, device, LOADER_UNDEFINED, id, key, title, loader);
|
||||||
if (!entry)
|
if (!entry)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1905,12 +1908,10 @@ static VOID config_entry_add_linux(
|
||||||
CHAR8 *line;
|
CHAR8 *line;
|
||||||
UINTN pos = 0;
|
UINTN pos = 0;
|
||||||
CHAR8 *key, *value;
|
CHAR8 *key, *value;
|
||||||
CHAR16 *os_name_pretty = NULL;
|
|
||||||
CHAR16 *os_name = NULL;
|
CHAR16 *os_name = NULL;
|
||||||
CHAR16 *os_id = NULL;
|
CHAR16 *os_id = NULL;
|
||||||
CHAR16 *os_version = NULL;
|
CHAR16 *os_version = NULL;
|
||||||
CHAR16 *os_version_id = NULL;
|
CHAR16 *os_build = NULL;
|
||||||
CHAR16 *os_build_id = NULL;
|
|
||||||
|
|
||||||
err = uefi_call_wrapper(linux_dir->Read, 3, linux_dir, &bufsize, buf);
|
err = uefi_call_wrapper(linux_dir->Read, 3, linux_dir, &bufsize, buf);
|
||||||
if (bufsize == 0 || EFI_ERROR(err))
|
if (bufsize == 0 || EFI_ERROR(err))
|
||||||
|
@ -1926,8 +1927,6 @@ static VOID config_entry_add_linux(
|
||||||
continue;
|
continue;
|
||||||
if (StriCmp(f->FileName + len - 4, L".efi") != 0)
|
if (StriCmp(f->FileName + len - 4, L".efi") != 0)
|
||||||
continue;
|
continue;
|
||||||
if (StrnCmp(f->FileName, L"auto-", 5) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* look for .osrel and .cmdline sections in the .efi binary */
|
/* look for .osrel and .cmdline sections in the .efi binary */
|
||||||
err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
|
err = pe_file_locate_sections(linux_dir, f->FileName, sections, addrs, offs, szs);
|
||||||
|
@ -1941,12 +1940,6 @@ static VOID config_entry_add_linux(
|
||||||
/* read properties from the embedded os-release file */
|
/* read properties from the embedded os-release file */
|
||||||
while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) {
|
while ((line = line_get_key_value(content, (CHAR8 *)"=", &pos, &key, &value))) {
|
||||||
if (strcmpa((CHAR8 *)"PRETTY_NAME", key) == 0) {
|
if (strcmpa((CHAR8 *)"PRETTY_NAME", key) == 0) {
|
||||||
FreePool(os_name_pretty);
|
|
||||||
os_name_pretty = stra_to_str(value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmpa((CHAR8 *)"NAME", key) == 0) {
|
|
||||||
FreePool(os_name);
|
FreePool(os_name);
|
||||||
os_name = stra_to_str(value);
|
os_name = stra_to_str(value);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1964,27 +1957,20 @@ static VOID config_entry_add_linux(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmpa((CHAR8 *)"VERSION_ID", key) == 0) {
|
|
||||||
FreePool(os_version_id);
|
|
||||||
os_version_id = stra_to_str(value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmpa((CHAR8 *)"BUILD_ID", key) == 0) {
|
if (strcmpa((CHAR8 *)"BUILD_ID", key) == 0) {
|
||||||
FreePool(os_build_id);
|
FreePool(os_build);
|
||||||
os_build_id = stra_to_str(value);
|
os_build = stra_to_str(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((os_name_pretty || os_name) && os_id && (os_version || os_version_id || os_build_id)) {
|
if (os_name && os_id && (os_version || os_build)) {
|
||||||
_cleanup_freepool_ CHAR16 *path = NULL;
|
_cleanup_freepool_ CHAR16 *conf = NULL, *path = NULL;
|
||||||
|
|
||||||
|
conf = PoolPrint(L"%s-%s", os_id, os_version ? : os_build);
|
||||||
path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName);
|
path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName);
|
||||||
|
|
||||||
entry = config_entry_add_loader(config, device, LOADER_LINUX, f->FileName, 'l',
|
entry = config_entry_add_loader(config, device, LOADER_LINUX, conf, 'l', os_name, path);
|
||||||
os_name_pretty ? : (os_name ? : os_id), path,
|
|
||||||
os_version ? : (os_version_id ? : os_build_id));
|
|
||||||
|
|
||||||
FreePool(content);
|
FreePool(content);
|
||||||
content = NULL;
|
content = NULL;
|
||||||
|
@ -2003,12 +1989,10 @@ static VOID config_entry_add_linux(
|
||||||
config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
|
config_entry_parse_tries(entry, L"\\EFI\\Linux", f->FileName, L".efi");
|
||||||
}
|
}
|
||||||
|
|
||||||
FreePool(os_name_pretty);
|
|
||||||
FreePool(os_name);
|
FreePool(os_name);
|
||||||
FreePool(os_id);
|
FreePool(os_id);
|
||||||
FreePool(os_version);
|
FreePool(os_version);
|
||||||
FreePool(os_version_id);
|
FreePool(os_build);
|
||||||
FreePool(os_build_id);
|
|
||||||
FreePool(content);
|
FreePool(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2469,12 +2453,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||||
UINT64 key;
|
UINT64 key;
|
||||||
|
|
||||||
err = console_key_read(&key, FALSE);
|
err = console_key_read(&key, FALSE);
|
||||||
|
|
||||||
if (err == EFI_NOT_READY) {
|
|
||||||
uefi_call_wrapper(BS->Stall, 1, 100 * 1000);
|
|
||||||
err = console_key_read(&key, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!EFI_ERROR(err)) {
|
if (!EFI_ERROR(err)) {
|
||||||
INT16 idx;
|
INT16 idx;
|
||||||
|
|
||||||
|
|
|
@ -3595,7 +3595,8 @@ static int exec_child(
|
||||||
|
|
||||||
/* This is done before enforce_user, but ambient set
|
/* This is done before enforce_user, but ambient set
|
||||||
* does not survive over setresuid() if keep_caps is not set. */
|
* does not survive over setresuid() if keep_caps is not set. */
|
||||||
if (!needs_ambient_hack) {
|
if (!needs_ambient_hack &&
|
||||||
|
context->capability_ambient_set != 0) {
|
||||||
r = capability_ambient_set_apply(context->capability_ambient_set, true);
|
r = capability_ambient_set_apply(context->capability_ambient_set, true);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
*exit_status = EXIT_CAPABILITIES;
|
*exit_status = EXIT_CAPABILITIES;
|
||||||
|
|
|
@ -475,15 +475,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||||
if (arg_default_timeout_start_usec <= 0)
|
if (arg_default_timeout_start_usec <= 0)
|
||||||
arg_default_timeout_start_usec = USEC_INFINITY;
|
arg_default_timeout_start_usec = USEC_INFINITY;
|
||||||
|
|
||||||
} else if (proc_cmdline_key_streq(key, "systemd.cpu_affinity")) {
|
|
||||||
|
|
||||||
if (proc_cmdline_value_missing(key, value))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = parse_cpu_set(value, &arg_cpu_affinity);
|
|
||||||
if (r < 0)
|
|
||||||
log_warning_errno(r, "Faile to parse CPU affinity mask '%s', ignoring: %m", value);
|
|
||||||
|
|
||||||
} else if (proc_cmdline_key_streq(key, "systemd.watchdog_device")) {
|
} else if (proc_cmdline_key_streq(key, "systemd.watchdog_device")) {
|
||||||
|
|
||||||
if (proc_cmdline_value_missing(key, value))
|
if (proc_cmdline_value_missing(key, value))
|
||||||
|
@ -1747,8 +1738,6 @@ static int invoke_main_loop(
|
||||||
saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
|
saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
|
||||||
saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
|
saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
|
||||||
|
|
||||||
mac_selinux_reload();
|
|
||||||
|
|
||||||
(void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
|
(void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
|
||||||
|
|
||||||
set_manager_defaults(m);
|
set_manager_defaults(m);
|
||||||
|
@ -1997,36 +1986,20 @@ static int do_queue_default_job(
|
||||||
const char **ret_error_message) {
|
const char **ret_error_message) {
|
||||||
|
|
||||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||||
const char* default_unit;
|
|
||||||
Job *default_unit_job;
|
Job *default_unit_job;
|
||||||
Unit *target = NULL;
|
Unit *target = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (arg_default_unit)
|
log_debug("Activating default unit: %s", arg_default_unit);
|
||||||
default_unit = arg_default_unit;
|
|
||||||
else if (in_initrd())
|
|
||||||
default_unit = SPECIAL_INITRD_TARGET;
|
|
||||||
else
|
|
||||||
default_unit = SPECIAL_DEFAULT_TARGET;
|
|
||||||
|
|
||||||
log_debug("Activating default unit: %s", default_unit);
|
r = manager_load_startable_unit_or_warn(m, arg_default_unit, NULL, &target);
|
||||||
|
|
||||||
r = manager_load_startable_unit_or_warn(m, default_unit, NULL, &target);
|
|
||||||
if (r < 0 && in_initrd() && !arg_default_unit) {
|
|
||||||
/* Fall back to default.target, which we used to always use by default. Only do this if no
|
|
||||||
* explicit configuration was given. */
|
|
||||||
|
|
||||||
log_info("Falling back to " SPECIAL_DEFAULT_TARGET ".");
|
|
||||||
|
|
||||||
r = manager_load_startable_unit_or_warn(m, SPECIAL_DEFAULT_TARGET, NULL, &target);
|
|
||||||
}
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_info("Falling back to " SPECIAL_RESCUE_TARGET ".");
|
log_info("Falling back to rescue target: " SPECIAL_RESCUE_TARGET);
|
||||||
|
|
||||||
r = manager_load_startable_unit_or_warn(m, SPECIAL_RESCUE_TARGET, NULL, &target);
|
r = manager_load_startable_unit_or_warn(m, SPECIAL_RESCUE_TARGET, NULL, &target);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
*ret_error_message = r == -ERFKILL ? SPECIAL_RESCUE_TARGET " masked"
|
*ret_error_message = r == -ERFKILL ? "Rescue target masked"
|
||||||
: "Failed to load " SPECIAL_RESCUE_TARGET;
|
: "Failed to load rescue target";
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2238,6 +2211,15 @@ static int load_configuration(
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize default unit */
|
||||||
|
if (!arg_default_unit) {
|
||||||
|
arg_default_unit = strdup(SPECIAL_DEFAULT_TARGET);
|
||||||
|
if (!arg_default_unit) {
|
||||||
|
*ret_error_message = "Failed to set default unit";
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the show status setting if it hasn't been set explicitly yet */
|
/* Initialize the show status setting if it hasn't been set explicitly yet */
|
||||||
if (arg_show_status == _SHOW_STATUS_INVALID)
|
if (arg_show_status == _SHOW_STATUS_INVALID)
|
||||||
arg_show_status = SHOW_STATUS_YES;
|
arg_show_status = SHOW_STATUS_YES;
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "tmpfile-util.h"
|
|
||||||
#include "umask-util.h"
|
#include "umask-util.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
|
||||||
|
@ -1641,44 +1640,6 @@ int temporary_filesystem_add(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int make_tmp_prefix(const char *prefix) {
|
|
||||||
_cleanup_free_ char *t = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Don't do anything unless we know the dir is actually missing */
|
|
||||||
r = access(prefix, F_OK);
|
|
||||||
if (r >= 0)
|
|
||||||
return 0;
|
|
||||||
if (errno != ENOENT)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
r = mkdir_parents(prefix, 0755);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = tempfn_random(prefix, NULL, &t);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (mkdir(t, 0777) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (chmod(t, 01777) < 0) {
|
|
||||||
r = -errno;
|
|
||||||
(void) rmdir(t);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rename(t, prefix) < 0) {
|
|
||||||
r = -errno;
|
|
||||||
(void) rmdir(t);
|
|
||||||
return r == -EEXIST ? 0 : r; /* it's fine if someone else created the dir by now */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
|
static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
|
||||||
_cleanup_free_ char *x = NULL;
|
_cleanup_free_ char *x = NULL;
|
||||||
char bid[SD_ID128_STRING_MAX];
|
char bid[SD_ID128_STRING_MAX];
|
||||||
|
@ -1700,10 +1661,6 @@ static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
|
||||||
if (!x)
|
if (!x)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
r = make_tmp_prefix(prefix);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
RUN_WITH_UMASK(0077)
|
RUN_WITH_UMASK(0077)
|
||||||
if (!mkdtemp(x))
|
if (!mkdtemp(x))
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
|
@ -126,15 +126,7 @@ static int generate_wants_symlinks(void) {
|
||||||
|
|
||||||
STRV_FOREACH(u, arg_wants) {
|
STRV_FOREACH(u, arg_wants) {
|
||||||
_cleanup_free_ char *p = NULL, *f = NULL;
|
_cleanup_free_ char *p = NULL, *f = NULL;
|
||||||
const char *target;
|
const char *target = arg_default_unit ?: SPECIAL_DEFAULT_TARGET;
|
||||||
|
|
||||||
/* This should match what do_queue_default_job() in core/main.c does. */
|
|
||||||
if (arg_default_unit)
|
|
||||||
target = arg_default_unit;
|
|
||||||
else if (in_initrd())
|
|
||||||
target = SPECIAL_INITRD_TARGET;
|
|
||||||
else
|
|
||||||
target = SPECIAL_DEFAULT_TARGET;
|
|
||||||
|
|
||||||
p = strjoin(arg_dest, "/", target, ".wants/", *u);
|
p = strjoin(arg_dest, "/", target, ".wants/", *u);
|
||||||
if (!p)
|
if (!p)
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
#include "sd-journal.h"
|
#include "sd-journal.h"
|
||||||
|
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
#include "sd-dhcp-server.h"
|
#include "sd-dhcp-server.h"
|
||||||
#include "sd-id128.h"
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "dhcp-internal.h"
|
#include "dhcp-internal.h"
|
||||||
|
@ -14,6 +13,7 @@
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
|
#include "sd-id128.h"
|
||||||
#include "siphash24.h"
|
#include "siphash24.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "unaligned.h"
|
#include "unaligned.h"
|
||||||
|
|
|
@ -682,14 +682,3 @@ global:
|
||||||
sd_bus_object_vtable_format;
|
sd_bus_object_vtable_format;
|
||||||
sd_event_source_disable_unref;
|
sd_event_source_disable_unref;
|
||||||
} LIBSYSTEMD_241;
|
} LIBSYSTEMD_241;
|
||||||
|
|
||||||
LIBSYSTEMD_245 {
|
|
||||||
global:
|
|
||||||
sd_event_add_child_pidfd;
|
|
||||||
sd_event_source_get_child_pidfd;
|
|
||||||
sd_event_source_get_child_pidfd_own;
|
|
||||||
sd_event_source_set_child_pidfd_own;
|
|
||||||
sd_event_source_get_child_process_own;
|
|
||||||
sd_event_source_set_child_process_own;
|
|
||||||
sd_event_source_send_child_signal;
|
|
||||||
} LIBSYSTEMD_243;
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
|
||||||
|
|
||||||
SD_BUS_ERROR_MAP(BUS_ERROR_NO_PRODUCT_UUID, EOPNOTSUPP),
|
SD_BUS_ERROR_MAP(BUS_ERROR_NO_PRODUCT_UUID, EOPNOTSUPP),
|
||||||
|
|
||||||
|
SD_BUS_ERROR_MAP(BUS_ERROR_SPEED_METER_INACTIVE, EOPNOTSUPP),
|
||||||
SD_BUS_ERROR_MAP(BUS_ERROR_UNMANAGED_INTERFACE, EOPNOTSUPP),
|
SD_BUS_ERROR_MAP(BUS_ERROR_UNMANAGED_INTERFACE, EOPNOTSUPP),
|
||||||
|
|
||||||
SD_BUS_ERROR_MAP_END
|
SD_BUS_ERROR_MAP_END
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
|
|
||||||
#define BUS_ERROR_NO_PRODUCT_UUID "org.freedesktop.hostname1.NoProductUUID"
|
#define BUS_ERROR_NO_PRODUCT_UUID "org.freedesktop.hostname1.NoProductUUID"
|
||||||
|
|
||||||
|
#define BUS_ERROR_SPEED_METER_INACTIVE "org.freedesktop.network1.SpeedMeterInactive"
|
||||||
#define BUS_ERROR_UNMANAGED_INTERFACE "org.freedesktop.network1.UnmanagedInterface"
|
#define BUS_ERROR_UNMANAGED_INTERFACE "org.freedesktop.network1.UnmanagedInterface"
|
||||||
|
|
||||||
BUS_ERROR_MAP_ELF_USE(bus_common_errors);
|
BUS_ERROR_MAP_ELF_USE(bus_common_errors);
|
||||||
|
|
|
@ -34,7 +34,7 @@ typedef enum EventSourceType {
|
||||||
* we know how to dispatch it */
|
* we know how to dispatch it */
|
||||||
typedef enum WakeupType {
|
typedef enum WakeupType {
|
||||||
WAKEUP_NONE,
|
WAKEUP_NONE,
|
||||||
WAKEUP_EVENT_SOURCE, /* either I/O or pidfd wakeup */
|
WAKEUP_EVENT_SOURCE,
|
||||||
WAKEUP_CLOCK_DATA,
|
WAKEUP_CLOCK_DATA,
|
||||||
WAKEUP_SIGNAL_DATA,
|
WAKEUP_SIGNAL_DATA,
|
||||||
WAKEUP_INOTIFY_DATA,
|
WAKEUP_INOTIFY_DATA,
|
||||||
|
@ -96,12 +96,6 @@ struct sd_event_source {
|
||||||
siginfo_t siginfo;
|
siginfo_t siginfo;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int options;
|
int options;
|
||||||
int pidfd;
|
|
||||||
bool registered:1; /* whether the pidfd is registered in the epoll */
|
|
||||||
bool pidfd_owned:1; /* close pidfd when event source is freed */
|
|
||||||
bool process_owned:1; /* kill+reap process when event source is freed */
|
|
||||||
bool exited:1; /* true if process exited (i.e. if there's value in SIGKILLing it if we want to get rid of it) */
|
|
||||||
bool waited:1; /* true if process was waited for (i.e. if there's value in waitid(P_PID)'ing it if we want to get rid of it) */
|
|
||||||
} child;
|
} child;
|
||||||
struct {
|
struct {
|
||||||
sd_event_handler_t callback;
|
sd_event_handler_t callback;
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "sd-id128.h"
|
#include "sd-id128.h"
|
||||||
|
|
||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "env-util.h"
|
|
||||||
#include "event-source.h"
|
#include "event-source.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
|
@ -29,14 +28,6 @@
|
||||||
|
|
||||||
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
|
#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
|
||||||
|
|
||||||
static bool EVENT_SOURCE_WATCH_PIDFD(sd_event_source *s) {
|
|
||||||
/* Returns true if this is a PID event source and can be implemented by watching EPOLLIN */
|
|
||||||
return s &&
|
|
||||||
s->type == SOURCE_CHILD &&
|
|
||||||
s->child.pidfd >= 0 &&
|
|
||||||
s->child.options == WEXITED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
|
static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = {
|
||||||
[SOURCE_IO] = "io",
|
[SOURCE_IO] = "io",
|
||||||
[SOURCE_TIME_REALTIME] = "realtime",
|
[SOURCE_TIME_REALTIME] = "realtime",
|
||||||
|
@ -365,6 +356,8 @@ static bool event_pid_changed(sd_event *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void source_io_unregister(sd_event_source *s) {
|
static void source_io_unregister(sd_event_source *s) {
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(s->type == SOURCE_IO);
|
assert(s->type == SOURCE_IO);
|
||||||
|
|
||||||
|
@ -374,7 +367,8 @@ static void source_io_unregister(sd_event_source *s) {
|
||||||
if (!s->io.registered)
|
if (!s->io.registered)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL) < 0)
|
r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
|
||||||
|
if (r < 0)
|
||||||
log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m",
|
log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m",
|
||||||
strna(s->description), event_source_type_to_string(s->type));
|
strna(s->description), event_source_type_to_string(s->type));
|
||||||
|
|
||||||
|
@ -410,51 +404,6 @@ static int source_io_register(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void source_child_pidfd_unregister(sd_event_source *s) {
|
|
||||||
assert(s);
|
|
||||||
assert(s->type == SOURCE_CHILD);
|
|
||||||
|
|
||||||
if (event_pid_changed(s->event))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!s->child.registered)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s))
|
|
||||||
if (epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->child.pidfd, NULL) < 0)
|
|
||||||
log_debug_errno(errno, "Failed to remove source %s (type %s) from epoll: %m",
|
|
||||||
strna(s->description), event_source_type_to_string(s->type));
|
|
||||||
|
|
||||||
s->child.registered = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int source_child_pidfd_register(sd_event_source *s, int enabled) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(s);
|
|
||||||
assert(s->type == SOURCE_CHILD);
|
|
||||||
assert(enabled != SD_EVENT_OFF);
|
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
|
|
||||||
struct epoll_event ev;
|
|
||||||
|
|
||||||
ev = (struct epoll_event) {
|
|
||||||
.events = EPOLLIN | (enabled == SD_EVENT_ONESHOT ? EPOLLONESHOT : 0),
|
|
||||||
.data.ptr = s,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (s->child.registered)
|
|
||||||
r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->child.pidfd, &ev);
|
|
||||||
else
|
|
||||||
r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->child.pidfd, &ev);
|
|
||||||
if (r < 0)
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->child.registered = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static clockid_t event_source_type_to_clock(EventSourceType t) {
|
static clockid_t event_source_type_to_clock(EventSourceType t) {
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
|
@ -665,8 +614,9 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig)
|
||||||
|
|
||||||
assert(e);
|
assert(e);
|
||||||
|
|
||||||
/* Rechecks if the specified signal is still something we are interested in. If not, we'll unmask it,
|
/* Rechecks if the specified signal is still something we are
|
||||||
* and possibly drop the signalfd for it. */
|
* interested in. If not, we'll unmask it, and possibly drop
|
||||||
|
* the signalfd for it. */
|
||||||
|
|
||||||
if (sig == SIGCHLD &&
|
if (sig == SIGCHLD &&
|
||||||
e->n_enabled_child_sources > 0)
|
e->n_enabled_child_sources > 0)
|
||||||
|
@ -757,12 +707,8 @@ static void source_disconnect(sd_event_source *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid));
|
(void) hashmap_remove(s->event->child_sources, PID_TO_PTR(s->child.pid));
|
||||||
}
|
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s))
|
|
||||||
source_child_pidfd_unregister(s);
|
|
||||||
else
|
|
||||||
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -844,44 +790,6 @@ static void source_free(sd_event_source *s) {
|
||||||
if (s->type == SOURCE_IO && s->io.owned)
|
if (s->type == SOURCE_IO && s->io.owned)
|
||||||
s->io.fd = safe_close(s->io.fd);
|
s->io.fd = safe_close(s->io.fd);
|
||||||
|
|
||||||
if (s->type == SOURCE_CHILD) {
|
|
||||||
/* Eventually the kernel will do this automatically for us, but for now let's emulate this (unreliably) in userspace. */
|
|
||||||
|
|
||||||
if (s->child.process_owned) {
|
|
||||||
|
|
||||||
if (!s->child.exited) {
|
|
||||||
bool sent = false;
|
|
||||||
|
|
||||||
if (s->child.pidfd >= 0) {
|
|
||||||
if (pidfd_send_signal(s->child.pidfd, SIGKILL, NULL, 0) < 0) {
|
|
||||||
if (errno == ESRCH) /* Already dead */
|
|
||||||
sent = true;
|
|
||||||
else if (!ERRNO_IS_NOT_SUPPORTED(errno))
|
|
||||||
log_debug_errno(errno, "Failed to kill process " PID_FMT " via pidfd_send_signal(), re-trying via kill(): %m",
|
|
||||||
s->child.pid);
|
|
||||||
} else
|
|
||||||
sent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sent)
|
|
||||||
if (kill(s->child.pid, SIGKILL) < 0)
|
|
||||||
if (errno != ESRCH) /* Already dead */
|
|
||||||
log_debug_errno(errno, "Failed to kill process " PID_FMT " via kill(), ignoring: %m",
|
|
||||||
s->child.pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!s->child.waited) {
|
|
||||||
siginfo_t si = {};
|
|
||||||
|
|
||||||
/* Reap the child if we can */
|
|
||||||
(void) waitid(P_PID, s->child.pid, &si, WEXITED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->child.pidfd_owned)
|
|
||||||
s->child.pidfd = safe_close(s->child.pidfd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->destroy_callback)
|
if (s->destroy_callback)
|
||||||
s->destroy_callback(s->userdata);
|
s->destroy_callback(s->userdata);
|
||||||
|
|
||||||
|
@ -1165,6 +1073,7 @@ _public_ int sd_event_add_signal(
|
||||||
|
|
||||||
_cleanup_(source_freep) sd_event_source *s = NULL;
|
_cleanup_(source_freep) sd_event_source *s = NULL;
|
||||||
struct signal_data *d;
|
struct signal_data *d;
|
||||||
|
sigset_t ss;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert_return(e, -EINVAL);
|
assert_return(e, -EINVAL);
|
||||||
|
@ -1176,10 +1085,11 @@ _public_ int sd_event_add_signal(
|
||||||
if (!callback)
|
if (!callback)
|
||||||
callback = signal_exit_callback;
|
callback = signal_exit_callback;
|
||||||
|
|
||||||
r = signal_is_blocked(sig);
|
r = pthread_sigmask(SIG_SETMASK, NULL, &ss);
|
||||||
if (r < 0)
|
if (r != 0)
|
||||||
return r;
|
return -r;
|
||||||
if (r == 0)
|
|
||||||
|
if (!sigismember(&ss, sig))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (!e->signal_sources) {
|
if (!e->signal_sources) {
|
||||||
|
@ -1214,11 +1124,6 @@ _public_ int sd_event_add_signal(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shall_use_pidfd(void) {
|
|
||||||
/* Mostly relevant for debugging, i.e. this is used in test-event.c to test the event loop once with and once without pidfd */
|
|
||||||
return getenv_bool_secure("SYSTEMD_PIDFD") != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_add_child(
|
_public_ int sd_event_add_child(
|
||||||
sd_event *e,
|
sd_event *e,
|
||||||
sd_event_source **ret,
|
sd_event_source **ret,
|
||||||
|
@ -1239,20 +1144,6 @@ _public_ int sd_event_add_child(
|
||||||
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||||
assert_return(!event_pid_changed(e), -ECHILD);
|
assert_return(!event_pid_changed(e), -ECHILD);
|
||||||
|
|
||||||
if (e->n_enabled_child_sources == 0) {
|
|
||||||
/* Caller must block SIGCHLD before using us to watch children, even if pidfd is available,
|
|
||||||
* for compatibility with pre-pidfd and because we don't want the reap the child processes
|
|
||||||
* ourselves, i.e. call waitid(), and don't want Linux' default internal logic for that to
|
|
||||||
* take effect.
|
|
||||||
*
|
|
||||||
* (As an optimization we only do this check on the first child event source created.) */
|
|
||||||
r = signal_is_blocked(SIGCHLD);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r == 0)
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&e->child_sources, NULL);
|
r = hashmap_ensure_allocated(&e->child_sources, NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1264,144 +1155,30 @@ _public_ int sd_event_add_child(
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
s->wakeup = WAKEUP_EVENT_SOURCE;
|
|
||||||
s->child.pid = pid;
|
s->child.pid = pid;
|
||||||
s->child.options = options;
|
s->child.options = options;
|
||||||
s->child.callback = callback;
|
s->child.callback = callback;
|
||||||
s->userdata = userdata;
|
s->userdata = userdata;
|
||||||
s->enabled = SD_EVENT_ONESHOT;
|
s->enabled = SD_EVENT_ONESHOT;
|
||||||
|
|
||||||
/* We always take a pidfd here if we can, even if we wait for anything else than WEXITED, so that we
|
|
||||||
* pin the PID, and make regular waitid() handling race-free. */
|
|
||||||
|
|
||||||
if (shall_use_pidfd()) {
|
|
||||||
s->child.pidfd = pidfd_open(s->child.pid, 0);
|
|
||||||
if (s->child.pidfd < 0) {
|
|
||||||
/* Propagate errors unless the syscall is not supported or blocked */
|
|
||||||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
|
|
||||||
return -errno;
|
|
||||||
} else
|
|
||||||
s->child.pidfd_owned = true; /* If we allocate the pidfd we own it by default */
|
|
||||||
} else
|
|
||||||
s->child.pidfd = -1;
|
|
||||||
|
|
||||||
r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
e->n_enabled_child_sources++;
|
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
|
|
||||||
/* We have a pidfd and we only want to watch for exit */
|
|
||||||
|
|
||||||
r = source_child_pidfd_register(s, s->enabled);
|
|
||||||
if (r < 0) {
|
|
||||||
e->n_enabled_child_sources--;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* We have no pidfd or we shall wait for some other event than WEXITED */
|
|
||||||
|
|
||||||
r = event_make_signal_data(e, SIGCHLD, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
e->n_enabled_child_sources--;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->need_process_child = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
*ret = s;
|
|
||||||
|
|
||||||
TAKE_PTR(s);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_add_child_pidfd(
|
|
||||||
sd_event *e,
|
|
||||||
sd_event_source **ret,
|
|
||||||
int pidfd,
|
|
||||||
int options,
|
|
||||||
sd_event_child_handler_t callback,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
|
|
||||||
_cleanup_(source_freep) sd_event_source *s = NULL;
|
|
||||||
pid_t pid;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert_return(e, -EINVAL);
|
|
||||||
assert_return(e = event_resolve(e), -ENOPKG);
|
|
||||||
assert_return(pidfd >= 0, -EBADF);
|
|
||||||
assert_return(!(options & ~(WEXITED|WSTOPPED|WCONTINUED)), -EINVAL);
|
|
||||||
assert_return(options != 0, -EINVAL);
|
|
||||||
assert_return(callback, -EINVAL);
|
|
||||||
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
|
||||||
assert_return(!event_pid_changed(e), -ECHILD);
|
|
||||||
|
|
||||||
if (e->n_enabled_child_sources == 0) {
|
|
||||||
r = signal_is_blocked(SIGCHLD);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
if (r == 0)
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = hashmap_ensure_allocated(&e->child_sources, NULL);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = pidfd_get_pid(pidfd, &pid);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (hashmap_contains(e->child_sources, PID_TO_PTR(pid)))
|
|
||||||
return -EBUSY;
|
|
||||||
|
|
||||||
s = source_new(e, !ret, SOURCE_CHILD);
|
|
||||||
if (!s)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
s->wakeup = WAKEUP_EVENT_SOURCE;
|
|
||||||
s->child.pidfd = pidfd;
|
|
||||||
s->child.pid = pid;
|
|
||||||
s->child.options = options;
|
|
||||||
s->child.callback = callback;
|
|
||||||
s->child.pidfd_owned = false; /* If we got the pidfd passed in we don't own it by default (similar to the IO fd case) */
|
|
||||||
s->userdata = userdata;
|
|
||||||
s->enabled = SD_EVENT_ONESHOT;
|
|
||||||
|
|
||||||
r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
|
r = hashmap_put(e->child_sources, PID_TO_PTR(pid), s);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
e->n_enabled_child_sources++;
|
e->n_enabled_child_sources++;
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
|
r = event_make_signal_data(e, SIGCHLD, NULL);
|
||||||
/* We only want to watch for WEXITED */
|
if (r < 0) {
|
||||||
|
e->n_enabled_child_sources--;
|
||||||
r = source_child_pidfd_register(s, s->enabled);
|
return r;
|
||||||
if (r < 0) {
|
|
||||||
e->n_enabled_child_sources--;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* We shall wait for some other event than WEXITED */
|
|
||||||
|
|
||||||
r = event_make_signal_data(e, SIGCHLD, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
e->n_enabled_child_sources--;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
e->need_process_child = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->need_process_child = true;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = s;
|
*ret = s;
|
||||||
|
|
||||||
TAKE_PTR(s);
|
TAKE_PTR(s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1988,7 +1765,7 @@ _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
|
epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2249,11 +2026,7 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
|
||||||
assert(s->event->n_enabled_child_sources > 0);
|
assert(s->event->n_enabled_child_sources > 0);
|
||||||
s->event->n_enabled_child_sources--;
|
s->event->n_enabled_child_sources--;
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s))
|
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
||||||
source_child_pidfd_unregister(s);
|
|
||||||
else
|
|
||||||
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_EXIT:
|
case SOURCE_EXIT:
|
||||||
|
@ -2327,25 +2100,12 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
|
||||||
|
|
||||||
s->enabled = m;
|
s->enabled = m;
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
|
r = event_make_signal_data(s->event, SIGCHLD, NULL);
|
||||||
/* yes, we have pidfd */
|
if (r < 0) {
|
||||||
|
s->enabled = SD_EVENT_OFF;
|
||||||
r = source_child_pidfd_register(s, s->enabled);
|
s->event->n_enabled_child_sources--;
|
||||||
if (r < 0) {
|
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
||||||
s->enabled = SD_EVENT_OFF;
|
return r;
|
||||||
s->event->n_enabled_child_sources--;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* no pidfd, or something other to watch for than WEXITED */
|
|
||||||
|
|
||||||
r = event_make_signal_data(s->event, SIGCHLD, NULL);
|
|
||||||
if (r < 0) {
|
|
||||||
s->enabled = SD_EVENT_OFF;
|
|
||||||
s->event->n_enabled_child_sources--;
|
|
||||||
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -2468,98 +2228,6 @@ _public_ int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_event_source_get_child_pidfd(sd_event_source *s) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
assert_return(!event_pid_changed(s->event), -ECHILD);
|
|
||||||
|
|
||||||
if (s->child.pidfd < 0)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
return s->child.pidfd;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_send_child_signal(sd_event_source *s, int sig, const siginfo_t *si, unsigned flags) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
assert_return(!event_pid_changed(s->event), -ECHILD);
|
|
||||||
assert_return(SIGNAL_VALID(sig), -EINVAL);
|
|
||||||
|
|
||||||
/* If we already have seen indication the process exited refuse sending a signal early. This way we
|
|
||||||
* can be sure we don't accidentally kill the wrong process on PID reuse when pidfds are not
|
|
||||||
* available. */
|
|
||||||
if (s->child.exited)
|
|
||||||
return -ESRCH;
|
|
||||||
|
|
||||||
if (s->child.pidfd >= 0) {
|
|
||||||
siginfo_t copy;
|
|
||||||
|
|
||||||
/* pidfd_send_signal() changes the siginfo_t argument. This is weird, let's hence copy the
|
|
||||||
* structure here */
|
|
||||||
if (si)
|
|
||||||
copy = *si;
|
|
||||||
|
|
||||||
if (pidfd_send_signal(s->child.pidfd, sig, si ? © : NULL, 0) < 0) {
|
|
||||||
/* Let's propagate the error only if the system call is not implemented or prohibited */
|
|
||||||
if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno))
|
|
||||||
return -errno;
|
|
||||||
} else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flags are only supported for pidfd_send_signal(), not for rt_sigqueueinfo(), hence let's refuse
|
|
||||||
* this here. */
|
|
||||||
if (flags != 0)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
if (si) {
|
|
||||||
/* We use rt_sigqueueinfo() only if siginfo_t is specified. */
|
|
||||||
siginfo_t copy = *si;
|
|
||||||
|
|
||||||
if (rt_sigqueueinfo(s->child.pid, sig, ©) < 0)
|
|
||||||
return -errno;
|
|
||||||
} else if (kill(s->child.pid, sig) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_get_child_pidfd_own(sd_event_source *s) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
|
|
||||||
if (s->child.pidfd < 0)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
return s->child.pidfd_owned;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_set_child_pidfd_own(sd_event_source *s, int own) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
|
|
||||||
if (s->child.pidfd < 0)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
s->child.pidfd_owned = own;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_get_child_process_own(sd_event_source *s) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
|
|
||||||
return s->child.process_owned;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_set_child_process_own(sd_event_source *s, int own) {
|
|
||||||
assert_return(s, -EINVAL);
|
|
||||||
assert_return(s->type == SOURCE_CHILD, -EDOM);
|
|
||||||
|
|
||||||
s->child.process_owned = own;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) {
|
_public_ int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *mask) {
|
||||||
assert_return(s, -EINVAL);
|
assert_return(s, -EINVAL);
|
||||||
assert_return(mask, -EINVAL);
|
assert_return(mask, -EINVAL);
|
||||||
|
@ -2870,12 +2538,6 @@ static int process_child(sd_event *e) {
|
||||||
if (s->enabled == SD_EVENT_OFF)
|
if (s->enabled == SD_EVENT_OFF)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (s->child.exited)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (EVENT_SOURCE_WATCH_PIDFD(s)) /* There's a usable pidfd known for this event source? then don't waitid() for it here */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
zero(s->child.siginfo);
|
zero(s->child.siginfo);
|
||||||
r = waitid(P_PID, s->child.pid, &s->child.siginfo,
|
r = waitid(P_PID, s->child.pid, &s->child.siginfo,
|
||||||
WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
|
WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
|
||||||
|
@ -2885,9 +2547,6 @@ static int process_child(sd_event *e) {
|
||||||
if (s->child.siginfo.si_pid != 0) {
|
if (s->child.siginfo.si_pid != 0) {
|
||||||
bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
|
bool zombie = IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED);
|
||||||
|
|
||||||
if (zombie)
|
|
||||||
s->child.exited = true;
|
|
||||||
|
|
||||||
if (!zombie && (s->child.options & WEXITED)) {
|
if (!zombie && (s->child.options & WEXITED)) {
|
||||||
/* If the child isn't dead then let's
|
/* If the child isn't dead then let's
|
||||||
* immediately remove the state change
|
* immediately remove the state change
|
||||||
|
@ -2907,33 +2566,6 @@ static int process_child(sd_event *e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_pidfd(sd_event *e, sd_event_source *s, uint32_t revents) {
|
|
||||||
assert(e);
|
|
||||||
assert(s);
|
|
||||||
assert(s->type == SOURCE_CHILD);
|
|
||||||
|
|
||||||
if (s->pending)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (s->enabled == SD_EVENT_OFF)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!EVENT_SOURCE_WATCH_PIDFD(s))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
zero(s->child.siginfo);
|
|
||||||
if (waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG | WNOWAIT | s->child.options) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (s->child.siginfo.si_pid == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (IN_SET(s->child.siginfo.si_code, CLD_EXITED, CLD_KILLED, CLD_DUMPED))
|
|
||||||
s->child.exited = true;
|
|
||||||
|
|
||||||
return source_set_pending(s, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
|
static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) {
|
||||||
bool read_one = false;
|
bool read_one = false;
|
||||||
int r;
|
int r;
|
||||||
|
@ -3218,10 +2850,8 @@ static int source_dispatch(sd_event_source *s) {
|
||||||
r = s->child.callback(s, &s->child.siginfo, s->userdata);
|
r = s->child.callback(s, &s->child.siginfo, s->userdata);
|
||||||
|
|
||||||
/* Now, reap the PID for good. */
|
/* Now, reap the PID for good. */
|
||||||
if (zombie) {
|
if (zombie)
|
||||||
(void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
|
(void) waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
|
||||||
s->child.waited = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3422,11 +3052,6 @@ _public_ int sd_event_prepare(sd_event *e) {
|
||||||
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||||
assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
|
assert_return(e->state == SD_EVENT_INITIAL, -EBUSY);
|
||||||
|
|
||||||
/* Let's check that if we are a default event loop we are executed in the correct thread. We only do
|
|
||||||
* this check here once, since gettid() is typically not cached, and thus want to minimize
|
|
||||||
* syscalls */
|
|
||||||
assert_return(!e->default_event_ptr || e->tid == gettid(), -EREMOTEIO);
|
|
||||||
|
|
||||||
if (e->exit_requested)
|
if (e->exit_requested)
|
||||||
goto pending;
|
goto pending;
|
||||||
|
|
||||||
|
@ -3522,33 +3147,12 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
|
||||||
|
|
||||||
switch (*t) {
|
switch (*t) {
|
||||||
|
|
||||||
case WAKEUP_EVENT_SOURCE: {
|
case WAKEUP_EVENT_SOURCE:
|
||||||
sd_event_source *s = ev_queue[i].data.ptr;
|
r = process_io(e, ev_queue[i].data.ptr, ev_queue[i].events);
|
||||||
|
|
||||||
assert(s);
|
|
||||||
|
|
||||||
switch (s->type) {
|
|
||||||
|
|
||||||
case SOURCE_IO:
|
|
||||||
r = process_io(e, s, ev_queue[i].events);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SOURCE_CHILD:
|
|
||||||
r = process_pidfd(e, s, ev_queue[i].events);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached("Unexpected event source type");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case WAKEUP_CLOCK_DATA: {
|
case WAKEUP_CLOCK_DATA: {
|
||||||
struct clock_data *d = ev_queue[i].data.ptr;
|
struct clock_data *d = ev_queue[i].data.ptr;
|
||||||
|
|
||||||
assert(d);
|
|
||||||
|
|
||||||
r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
|
r = flush_timer(e, d->fd, ev_queue[i].events, &d->next);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3872,7 +3476,7 @@ _public_ int sd_event_set_watchdog(sd_event *e, int b) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (e->watchdog_fd >= 0) {
|
if (e->watchdog_fd >= 0) {
|
||||||
(void) epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
|
epoll_ctl(e->epoll_fd, EPOLL_CTL_DEL, e->watchdog_fd, NULL);
|
||||||
e->watchdog_fd = safe_close(e->watchdog_fd);
|
e->watchdog_fd = safe_close(e->watchdog_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "missing_syscall.h"
|
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
|
@ -63,11 +62,6 @@ static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata
|
||||||
assert_se(s);
|
assert_se(s);
|
||||||
assert_se(si);
|
assert_se(si);
|
||||||
|
|
||||||
assert_se(si->si_uid == getuid());
|
|
||||||
assert_se(si->si_signo == SIGCHLD);
|
|
||||||
assert_se(si->si_code == CLD_EXITED);
|
|
||||||
assert_se(si->si_status == 78);
|
|
||||||
|
|
||||||
log_info("got child on %c", PTR_TO_INT(userdata));
|
log_info("got child on %c", PTR_TO_INT(userdata));
|
||||||
|
|
||||||
assert_se(userdata == INT_TO_PTR('f'));
|
assert_se(userdata == INT_TO_PTR('f'));
|
||||||
|
@ -81,7 +75,6 @@ static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata
|
||||||
static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
|
static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
|
||||||
sd_event_source *p = NULL;
|
sd_event_source *p = NULL;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
siginfo_t plain_si;
|
|
||||||
|
|
||||||
assert_se(s);
|
assert_se(s);
|
||||||
assert_se(si);
|
assert_se(si);
|
||||||
|
@ -90,41 +83,16 @@ static int signal_handler(sd_event_source *s, const struct signalfd_siginfo *si,
|
||||||
|
|
||||||
assert_se(userdata == INT_TO_PTR('e'));
|
assert_se(userdata == INT_TO_PTR('e'));
|
||||||
|
|
||||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, SIGUSR2, -1) >= 0);
|
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
assert_se(pid >= 0);
|
assert_se(pid >= 0);
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0)
|
||||||
sigset_t ss;
|
_exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
assert_se(sigemptyset(&ss) >= 0);
|
|
||||||
assert_se(sigaddset(&ss, SIGUSR2) >= 0);
|
|
||||||
|
|
||||||
zero(plain_si);
|
|
||||||
assert_se(sigwaitinfo(&ss, &plain_si) >= 0);
|
|
||||||
|
|
||||||
assert_se(plain_si.si_signo == SIGUSR2);
|
|
||||||
assert_se(plain_si.si_value.sival_int == 4711);
|
|
||||||
|
|
||||||
_exit(78);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
|
assert_se(sd_event_add_child(sd_event_source_get_event(s), &p, pid, WEXITED, child_handler, INT_TO_PTR('f')) >= 0);
|
||||||
assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
|
assert_se(sd_event_source_set_enabled(p, SD_EVENT_ONESHOT) >= 0);
|
||||||
assert_se(sd_event_source_set_child_process_own(p, true) >= 0);
|
|
||||||
|
|
||||||
/* We can't use structured initialization here, since the structure contains various unions and these
|
|
||||||
* fields lie in overlapping (carefully aligned) unions that LLVM is allergic to allow assignments
|
|
||||||
* to */
|
|
||||||
zero(plain_si);
|
|
||||||
plain_si.si_signo = SIGUSR2;
|
|
||||||
plain_si.si_code = SI_QUEUE;
|
|
||||||
plain_si.si_pid = getpid();
|
|
||||||
plain_si.si_uid = getuid();
|
|
||||||
plain_si.si_value.sival_int = 4711;
|
|
||||||
|
|
||||||
assert_se(sd_event_source_send_child_signal(p, SIGUSR2, &plain_si, 0) >= 0);
|
|
||||||
|
|
||||||
sd_event_source_unref(s);
|
sd_event_source_unref(s);
|
||||||
|
|
||||||
|
@ -151,7 +119,7 @@ static int defer_handler(sd_event_source *s, void *userdata) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_quit;
|
static bool do_quit = false;
|
||||||
|
|
||||||
static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
|
static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||||
log_info("got timer on %c", PTR_TO_INT(userdata));
|
log_info("got timer on %c", PTR_TO_INT(userdata));
|
||||||
|
@ -193,7 +161,7 @@ static int post_handler(sd_event_source *s, void *userdata) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_basic(bool with_pidfd) {
|
static void test_basic(void) {
|
||||||
sd_event *e = NULL;
|
sd_event *e = NULL;
|
||||||
sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
|
sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
|
||||||
static const char ch = 'x';
|
static const char ch = 'x';
|
||||||
|
@ -201,8 +169,6 @@ static void test_basic(bool with_pidfd) {
|
||||||
uint64_t event_now;
|
uint64_t event_now;
|
||||||
int64_t priority;
|
int64_t priority;
|
||||||
|
|
||||||
assert_se(setenv("SYSTEMD_PIDFD", yes_no(with_pidfd), 1) >= 0);
|
|
||||||
|
|
||||||
assert_se(pipe(a) >= 0);
|
assert_se(pipe(a) >= 0);
|
||||||
assert_se(pipe(b) >= 0);
|
assert_se(pipe(b) >= 0);
|
||||||
assert_se(pipe(d) >= 0);
|
assert_se(pipe(d) >= 0);
|
||||||
|
@ -235,8 +201,6 @@ static void test_basic(bool with_pidfd) {
|
||||||
|
|
||||||
assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
|
assert_se(sd_event_add_io(e, &x, a[0], EPOLLIN, io_handler, INT_TO_PTR('a')) >= 0);
|
||||||
assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
|
assert_se(sd_event_add_io(e, &y, b[0], EPOLLIN, io_handler, INT_TO_PTR('b')) >= 0);
|
||||||
|
|
||||||
do_quit = false;
|
|
||||||
assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
|
assert_se(sd_event_add_time(e, &z, CLOCK_MONOTONIC, 0, 0, time_handler, INT_TO_PTR('c')) >= 0);
|
||||||
assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
|
assert_se(sd_event_add_exit(e, &q, exit_handler, INT_TO_PTR('g')) >= 0);
|
||||||
|
|
||||||
|
@ -294,8 +258,6 @@ static void test_basic(bool with_pidfd) {
|
||||||
safe_close_pair(b);
|
safe_close_pair(b);
|
||||||
safe_close_pair(d);
|
safe_close_pair(d);
|
||||||
safe_close_pair(k);
|
safe_close_pair(k);
|
||||||
|
|
||||||
assert_se(unsetenv("SYSTEMD_PIDFD") >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_sd_event_now(void) {
|
static void test_sd_event_now(void) {
|
||||||
|
@ -520,89 +482,15 @@ static void test_inotify(unsigned n_create_events) {
|
||||||
sd_event_unref(e);
|
sd_event_unref(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pidfd_handler(sd_event_source *s, const siginfo_t *si, void *userdata) {
|
|
||||||
assert_se(s);
|
|
||||||
assert_se(si);
|
|
||||||
|
|
||||||
assert_se(si->si_uid == getuid());
|
|
||||||
assert_se(si->si_signo == SIGCHLD);
|
|
||||||
assert_se(si->si_code == CLD_EXITED);
|
|
||||||
assert_se(si->si_status == 66);
|
|
||||||
|
|
||||||
log_info("got pidfd on %c", PTR_TO_INT(userdata));
|
|
||||||
|
|
||||||
assert_se(userdata == INT_TO_PTR('p'));
|
|
||||||
|
|
||||||
assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
|
|
||||||
sd_event_source_unref(s);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_pidfd(void) {
|
|
||||||
sd_event_source *s = NULL, *t = NULL;
|
|
||||||
sd_event *e = NULL;
|
|
||||||
int pidfd;
|
|
||||||
pid_t pid, pid2;
|
|
||||||
|
|
||||||
assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGCHLD, -1) >= 0);
|
|
||||||
|
|
||||||
pid = fork();
|
|
||||||
if (pid == 0) {
|
|
||||||
/* child */
|
|
||||||
_exit(66);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_se(pid > 1);
|
|
||||||
|
|
||||||
pidfd = pidfd_open(pid, 0);
|
|
||||||
if (pidfd < 0) {
|
|
||||||
/* No pidfd_open() supported or blocked? */
|
|
||||||
assert_se(ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno));
|
|
||||||
(void) wait_for_terminate(pid, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pid2 = fork();
|
|
||||||
if (pid2 == 0)
|
|
||||||
freeze();
|
|
||||||
|
|
||||||
assert_se(pid > 2);
|
|
||||||
|
|
||||||
assert_se(sd_event_default(&e) >= 0);
|
|
||||||
assert_se(sd_event_add_child_pidfd(e, &s, pidfd, WEXITED, pidfd_handler, INT_TO_PTR('p')) >= 0);
|
|
||||||
assert_se(sd_event_source_set_child_pidfd_own(s, true) >= 0);
|
|
||||||
|
|
||||||
/* This one should never trigger, since our second child lives forever */
|
|
||||||
assert_se(sd_event_add_child(e, &t, pid2, WEXITED, pidfd_handler, INT_TO_PTR('q')) >= 0);
|
|
||||||
assert_se(sd_event_source_set_child_process_own(t, true) >= 0);
|
|
||||||
|
|
||||||
assert_se(sd_event_loop(e) >= 0);
|
|
||||||
|
|
||||||
/* Child should still be alive */
|
|
||||||
assert_se(kill(pid2, 0) >= 0);
|
|
||||||
|
|
||||||
t = sd_event_source_unref(t);
|
|
||||||
|
|
||||||
/* Child should now be dead, since we dropped the ref */
|
|
||||||
assert_se(kill(pid2, 0) < 0 && errno == ESRCH);
|
|
||||||
|
|
||||||
sd_event_unref(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
test_setup_logging(LOG_INFO);
|
test_setup_logging(LOG_INFO);
|
||||||
|
|
||||||
test_basic(true); /* test with pidfd */
|
test_basic();
|
||||||
test_basic(false); /* test without pidfd */
|
|
||||||
|
|
||||||
test_sd_event_now();
|
test_sd_event_now();
|
||||||
test_rtqueue();
|
test_rtqueue();
|
||||||
|
|
||||||
test_inotify(100); /* should work without overflow */
|
test_inotify(100); /* should work without overflow */
|
||||||
test_inotify(33000); /* should trigger a q overflow */
|
test_inotify(33000); /* should trigger a q overflow */
|
||||||
|
|
||||||
test_pidfd();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -575,9 +575,7 @@ static int netlink_message_read_internal(sd_netlink_message *m, unsigned short t
|
||||||
assert_return(data, -EINVAL);
|
assert_return(data, -EINVAL);
|
||||||
|
|
||||||
assert(m->n_containers < RTNL_CONTAINER_DEPTH);
|
assert(m->n_containers < RTNL_CONTAINER_DEPTH);
|
||||||
|
assert(m->containers[m->n_containers].attributes);
|
||||||
if (!m->containers[m->n_containers].attributes)
|
|
||||||
return -ENODATA;
|
|
||||||
|
|
||||||
if (type >= m->containers[m->n_containers].n_attributes)
|
if (type >= m->containers[m->n_containers].n_attributes)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
@ -1023,27 +1021,6 @@ int sd_netlink_message_get_errno(const sd_netlink_message *m) {
|
||||||
return err->error;
|
return err->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int netlink_message_parse_error(sd_netlink_message *m) {
|
|
||||||
struct nlmsgerr *err = NLMSG_DATA(m->hdr);
|
|
||||||
size_t hlen = sizeof(struct nlmsgerr);
|
|
||||||
|
|
||||||
/* no TLVs, nothing to do here */
|
|
||||||
if (!(m->hdr->nlmsg_flags & NLM_F_ACK_TLVS))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* if NLM_F_CAPPED is set then the inner err msg was capped */
|
|
||||||
if (!(m->hdr->nlmsg_flags & NLM_F_CAPPED))
|
|
||||||
hlen += err->msg.nlmsg_len - sizeof(struct nlmsghdr);
|
|
||||||
|
|
||||||
if (m->hdr->nlmsg_len <= NLMSG_SPACE(hlen))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return netlink_container_parse(m,
|
|
||||||
&m->containers[m->n_containers],
|
|
||||||
(struct rtattr*)((uint8_t*) NLMSG_DATA(m->hdr) + hlen),
|
|
||||||
NLMSG_PAYLOAD(m->hdr, hlen));
|
|
||||||
}
|
|
||||||
|
|
||||||
int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) {
|
int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) {
|
||||||
const NLType *nl_type;
|
const NLType *nl_type;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
|
@ -1083,13 +1060,10 @@ int sd_netlink_message_rewind(sd_netlink_message *m, sd_netlink *genl) {
|
||||||
|
|
||||||
m->containers[0].type_system = type_system;
|
m->containers[0].type_system = type_system;
|
||||||
|
|
||||||
if (sd_netlink_message_is_error(m))
|
r = netlink_container_parse(m,
|
||||||
r = netlink_message_parse_error(m);
|
&m->containers[m->n_containers],
|
||||||
else
|
(struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)),
|
||||||
r = netlink_container_parse(m,
|
NLMSG_PAYLOAD(m->hdr, size));
|
||||||
&m->containers[m->n_containers],
|
|
||||||
(struct rtattr*)((uint8_t*) NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)),
|
|
||||||
NLMSG_PAYLOAD(m->hdr, size));
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -745,19 +745,9 @@ static const NLTypeSystem rtnl_qdisc_type_system = {
|
||||||
.types = rtnl_qdisc_types,
|
.types = rtnl_qdisc_types,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NLType error_types[] = {
|
|
||||||
[NLMSGERR_ATTR_MSG] = { .type = NETLINK_TYPE_STRING },
|
|
||||||
[NLMSGERR_ATTR_OFFS] = { .type = NETLINK_TYPE_U32 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const NLTypeSystem error_type_system = {
|
|
||||||
.count = ELEMENTSOF(error_types),
|
|
||||||
.types = error_types,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const NLType rtnl_types[] = {
|
static const NLType rtnl_types[] = {
|
||||||
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
|
[NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 },
|
||||||
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) },
|
[NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
|
||||||
[RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
[RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
||||||
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
||||||
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
|
||||||
|
@ -1062,7 +1052,7 @@ const NLTypeSystem genl_family_type_system_root = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NLType genl_types[] = {
|
static const NLType genl_types[] = {
|
||||||
[SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &error_type_system, .size = sizeof(struct nlmsgerr) },
|
[SD_GENL_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) },
|
||||||
[SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system },
|
[SD_GENL_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system },
|
||||||
[SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) },
|
[SD_GENL_ID_CTRL] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_get_family_type_system, .size = sizeof(struct genlmsghdr) },
|
||||||
[SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) },
|
[SD_GENL_NL80211] = { .type = NETLINK_TYPE_NESTED, .type_system = &genl_nl80211_type_system, .size = sizeof(struct genlmsghdr) },
|
||||||
|
|
|
@ -107,10 +107,6 @@ int sd_netlink_open_fd(sd_netlink **ret, int fd) {
|
||||||
rtnl->fd = fd;
|
rtnl->fd = fd;
|
||||||
rtnl->protocol = protocol;
|
rtnl->protocol = protocol;
|
||||||
|
|
||||||
r = setsockopt_int(fd, SOL_NETLINK, NETLINK_EXT_ACK, 1);
|
|
||||||
if (r < 0)
|
|
||||||
log_debug_errno(r, "sd-netlink: Failed to enable NETLINK_EXT_ACK option, ignoring: %m");
|
|
||||||
|
|
||||||
r = socket_bind(rtnl);
|
r = socket_bind(rtnl);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */
|
rtnl->fd = -1; /* on failure, the caller remains owner of the fd, hence don't close it here */
|
||||||
|
|
|
@ -587,7 +587,7 @@ const NetDevVTable bond_vtable = {
|
||||||
.object_size = sizeof(Bond),
|
.object_size = sizeof(Bond),
|
||||||
.init = bond_init,
|
.init = bond_init,
|
||||||
.done = bond_done,
|
.done = bond_done,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Bond\0",
|
.sections = "Match\0NetDev\0Bond\0",
|
||||||
.fill_message_create = netdev_bond_fill_message_create,
|
.fill_message_create = netdev_bond_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_MASTER,
|
.create_type = NETDEV_CREATE_MASTER,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
|
|
@ -355,7 +355,7 @@ static void bridge_init(NetDev *n) {
|
||||||
const NetDevVTable bridge_vtable = {
|
const NetDevVTable bridge_vtable = {
|
||||||
.object_size = sizeof(Bridge),
|
.object_size = sizeof(Bridge),
|
||||||
.init = bridge_init,
|
.init = bridge_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Bridge\0",
|
.sections = "Match\0NetDev\0Bridge\0",
|
||||||
.post_create = netdev_bridge_post_create,
|
.post_create = netdev_bridge_post_create,
|
||||||
.create_type = NETDEV_CREATE_MASTER,
|
.create_type = NETDEV_CREATE_MASTER,
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const NetDevVTable dummy_vtable = {
|
const NetDevVTable dummy_vtable = {
|
||||||
.object_size = sizeof(Dummy),
|
.object_size = sizeof(Dummy),
|
||||||
.sections = NETDEV_COMMON_SECTIONS,
|
.sections = "Match\0NetDev\0",
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -262,7 +262,7 @@ static void fou_tunnel_init(NetDev *netdev) {
|
||||||
const NetDevVTable foutnl_vtable = {
|
const NetDevVTable foutnl_vtable = {
|
||||||
.object_size = sizeof(FouTunnel),
|
.object_size = sizeof(FouTunnel),
|
||||||
.init = fou_tunnel_init,
|
.init = fou_tunnel_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "FooOverUDP\0",
|
.sections = "Match\0NetDev\0FooOverUDP\0",
|
||||||
.create = netdev_fou_tunnel_create,
|
.create = netdev_fou_tunnel_create,
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.config_verify = netdev_fou_tunnel_verify,
|
.config_verify = netdev_fou_tunnel_verify,
|
||||||
|
|
|
@ -348,7 +348,7 @@ static void geneve_init(NetDev *netdev) {
|
||||||
const NetDevVTable geneve_vtable = {
|
const NetDevVTable geneve_vtable = {
|
||||||
.object_size = sizeof(Geneve),
|
.object_size = sizeof(Geneve),
|
||||||
.init = geneve_init,
|
.init = geneve_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "GENEVE\0",
|
.sections = "Match\0NetDev\0GENEVE\0",
|
||||||
.create = netdev_geneve_create,
|
.create = netdev_geneve_create,
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.config_verify = netdev_geneve_verify,
|
.config_verify = netdev_geneve_verify,
|
||||||
|
|
|
@ -74,7 +74,7 @@ static void ipvlan_init(NetDev *n) {
|
||||||
const NetDevVTable ipvlan_vtable = {
|
const NetDevVTable ipvlan_vtable = {
|
||||||
.object_size = sizeof(IPVlan),
|
.object_size = sizeof(IPVlan),
|
||||||
.init = ipvlan_init,
|
.init = ipvlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "IPVLAN\0",
|
.sections = "Match\0NetDev\0IPVLAN\0",
|
||||||
.fill_message_create = netdev_ipvlan_fill_message_create,
|
.fill_message_create = netdev_ipvlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
@ -83,7 +83,7 @@ const NetDevVTable ipvlan_vtable = {
|
||||||
const NetDevVTable ipvtap_vtable = {
|
const NetDevVTable ipvtap_vtable = {
|
||||||
.object_size = sizeof(IPVlan),
|
.object_size = sizeof(IPVlan),
|
||||||
.init = ipvlan_init,
|
.init = ipvlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "IPVTAP\0",
|
.sections = "Match\0NetDev\0IPVTAP\0",
|
||||||
.fill_message_create = netdev_ipvlan_fill_message_create,
|
.fill_message_create = netdev_ipvlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
|
|
@ -723,7 +723,7 @@ static void l2tp_tunnel_done(NetDev *netdev) {
|
||||||
const NetDevVTable l2tptnl_vtable = {
|
const NetDevVTable l2tptnl_vtable = {
|
||||||
.object_size = sizeof(L2tpTunnel),
|
.object_size = sizeof(L2tpTunnel),
|
||||||
.init = l2tp_tunnel_init,
|
.init = l2tp_tunnel_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "L2TP\0L2TPSession\0",
|
.sections = "Match\0NetDev\0L2TP\0L2TPSession\0",
|
||||||
.create_after_configured = l2tp_create_tunnel,
|
.create_after_configured = l2tp_create_tunnel,
|
||||||
.done = l2tp_tunnel_done,
|
.done = l2tp_tunnel_done,
|
||||||
.create_type = NETDEV_CREATE_AFTER_CONFIGURED,
|
.create_type = NETDEV_CREATE_AFTER_CONFIGURED,
|
||||||
|
|
|
@ -1235,7 +1235,7 @@ static void macsec_done(NetDev *netdev) {
|
||||||
const NetDevVTable macsec_vtable = {
|
const NetDevVTable macsec_vtable = {
|
||||||
.object_size = sizeof(MACsec),
|
.object_size = sizeof(MACsec),
|
||||||
.init = macsec_init,
|
.init = macsec_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "MACsec\0MACsecReceiveChannel\0MACsecTransmitAssociation\0MACsecReceiveAssociation\0",
|
.sections = "Match\0NetDev\0MACsec\0MACsecReceiveChannel\0MACsecTransmitAssociation\0MACsecReceiveAssociation\0",
|
||||||
.fill_message_create = netdev_macsec_fill_message_create,
|
.fill_message_create = netdev_macsec_fill_message_create,
|
||||||
.post_create = netdev_macsec_configure,
|
.post_create = netdev_macsec_configure,
|
||||||
.done = macsec_done,
|
.done = macsec_done,
|
||||||
|
|
|
@ -58,7 +58,7 @@ static void macvlan_init(NetDev *n) {
|
||||||
const NetDevVTable macvtap_vtable = {
|
const NetDevVTable macvtap_vtable = {
|
||||||
.object_size = sizeof(MacVlan),
|
.object_size = sizeof(MacVlan),
|
||||||
.init = macvlan_init,
|
.init = macvlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "MACVTAP\0",
|
.sections = "Match\0NetDev\0MACVTAP\0",
|
||||||
.fill_message_create = netdev_macvlan_fill_message_create,
|
.fill_message_create = netdev_macvlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
@ -67,7 +67,7 @@ const NetDevVTable macvtap_vtable = {
|
||||||
const NetDevVTable macvlan_vtable = {
|
const NetDevVTable macvlan_vtable = {
|
||||||
.object_size = sizeof(MacVlan),
|
.object_size = sizeof(MacVlan),
|
||||||
.init = macvlan_init,
|
.init = macvlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "MACVLAN\0",
|
.sections = "Match\0NetDev\0MACVLAN\0",
|
||||||
.fill_message_create = netdev_macvlan_fill_message_create,
|
.fill_message_create = netdev_macvlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
|
|
@ -682,9 +682,9 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
||||||
|
|
||||||
dropin_dirname = strjoina(basename(filename), ".d");
|
dropin_dirname = strjoina(basename(filename), ".d");
|
||||||
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
|
r = config_parse_many(filename, NETWORK_DIRS, dropin_dirname,
|
||||||
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
"Match\0NetDev\0",
|
||||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||||
CONFIG_PARSE_WARN, netdev_raw);
|
CONFIG_PARSE_WARN|CONFIG_PARSE_RELAXED, netdev_raw);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -8,35 +8,6 @@
|
||||||
#include "networkd-link.h"
|
#include "networkd-link.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
#define NETDEV_COMMON_SECTIONS "Match\0NetDev\0"
|
|
||||||
/* This is the list of known sections. We need to ignore them in the initial parsing phase. */
|
|
||||||
#define NETDEV_OTHER_SECTIONS \
|
|
||||||
"-Bond\0" \
|
|
||||||
"-Bridge\0" \
|
|
||||||
"-FooOverUDP\0" \
|
|
||||||
"-GENEVE\0" \
|
|
||||||
"-IPVLAN\0" \
|
|
||||||
"-IPVTAP\0" \
|
|
||||||
"-L2TP\0" \
|
|
||||||
"-L2TPSession\0" \
|
|
||||||
"-MACsec\0" \
|
|
||||||
"-MACsecReceiveChannel\0" \
|
|
||||||
"-MACsecTransmitAssociation\0" \
|
|
||||||
"-MACsecReceiveAssociation\0" \
|
|
||||||
"-MACVTAP\0" \
|
|
||||||
"-MACVLAN\0" \
|
|
||||||
"-Tunnel\0" \
|
|
||||||
"-Tun\0" \
|
|
||||||
"-Tap\0" \
|
|
||||||
"-Peer\0" \
|
|
||||||
"-VLAN\0" \
|
|
||||||
"-VRF\0" \
|
|
||||||
"-VXCAN\0" \
|
|
||||||
"-VXLAN\0" \
|
|
||||||
"-WireGuard\0" \
|
|
||||||
"-WireGuardPeer\0" \
|
|
||||||
"-Xfrm\0"
|
|
||||||
|
|
||||||
typedef struct netdev_join_callback netdev_join_callback;
|
typedef struct netdev_join_callback netdev_join_callback;
|
||||||
|
|
||||||
struct netdev_join_callback {
|
struct netdev_join_callback {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const NetDevVTable netdevsim_vtable = {
|
const NetDevVTable netdevsim_vtable = {
|
||||||
.object_size = sizeof(NetDevSim),
|
.object_size = sizeof(NetDevSim),
|
||||||
.sections = NETDEV_COMMON_SECTIONS,
|
.sections = "Match\0NetDev\0",
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,7 +16,7 @@ static int netdev_nlmon_verify(NetDev *netdev, const char *filename) {
|
||||||
|
|
||||||
const NetDevVTable nlmon_vtable = {
|
const NetDevVTable nlmon_vtable = {
|
||||||
.object_size = sizeof(NLMon),
|
.object_size = sizeof(NLMon),
|
||||||
.sections = NETDEV_COMMON_SECTIONS,
|
.sections = "Match\0NetDev\0",
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.config_verify = netdev_nlmon_verify,
|
.config_verify = netdev_nlmon_verify,
|
||||||
};
|
};
|
||||||
|
|
|
@ -805,7 +805,7 @@ static void ip6tnl_init(NetDev *n) {
|
||||||
const NetDevVTable ipip_vtable = {
|
const NetDevVTable ipip_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = ipip_sit_init,
|
.init = ipip_sit_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_ipip_sit_fill_message_create,
|
.fill_message_create = netdev_ipip_sit_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -815,7 +815,7 @@ const NetDevVTable ipip_vtable = {
|
||||||
const NetDevVTable sit_vtable = {
|
const NetDevVTable sit_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = ipip_sit_init,
|
.init = ipip_sit_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_ipip_sit_fill_message_create,
|
.fill_message_create = netdev_ipip_sit_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -825,7 +825,7 @@ const NetDevVTable sit_vtable = {
|
||||||
const NetDevVTable vti_vtable = {
|
const NetDevVTable vti_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = vti_init,
|
.init = vti_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_vti_fill_message_create,
|
.fill_message_create = netdev_vti_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -835,7 +835,7 @@ const NetDevVTable vti_vtable = {
|
||||||
const NetDevVTable vti6_vtable = {
|
const NetDevVTable vti6_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = vti_init,
|
.init = vti_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_vti_fill_message_create,
|
.fill_message_create = netdev_vti_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -845,7 +845,7 @@ const NetDevVTable vti6_vtable = {
|
||||||
const NetDevVTable gre_vtable = {
|
const NetDevVTable gre_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = gre_erspan_init,
|
.init = gre_erspan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -855,7 +855,7 @@ const NetDevVTable gre_vtable = {
|
||||||
const NetDevVTable gretap_vtable = {
|
const NetDevVTable gretap_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = gre_erspan_init,
|
.init = gre_erspan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -865,7 +865,7 @@ const NetDevVTable gretap_vtable = {
|
||||||
const NetDevVTable ip6gre_vtable = {
|
const NetDevVTable ip6gre_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = ip6gre_init,
|
.init = ip6gre_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_ip6gre_fill_message_create,
|
.fill_message_create = netdev_ip6gre_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -875,7 +875,7 @@ const NetDevVTable ip6gre_vtable = {
|
||||||
const NetDevVTable ip6gretap_vtable = {
|
const NetDevVTable ip6gretap_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = ip6gre_init,
|
.init = ip6gre_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_ip6gre_fill_message_create,
|
.fill_message_create = netdev_ip6gre_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -885,7 +885,7 @@ const NetDevVTable ip6gretap_vtable = {
|
||||||
const NetDevVTable ip6tnl_vtable = {
|
const NetDevVTable ip6tnl_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = ip6tnl_init,
|
.init = ip6tnl_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_ip6tnl_fill_message_create,
|
.fill_message_create = netdev_ip6tnl_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
@ -895,7 +895,7 @@ const NetDevVTable ip6tnl_vtable = {
|
||||||
const NetDevVTable erspan_vtable = {
|
const NetDevVTable erspan_vtable = {
|
||||||
.object_size = sizeof(Tunnel),
|
.object_size = sizeof(Tunnel),
|
||||||
.init = gre_erspan_init,
|
.init = gre_erspan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tunnel\0",
|
.sections = "Match\0NetDev\0Tunnel\0",
|
||||||
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
.fill_message_create = netdev_gre_erspan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_tunnel_verify,
|
.config_verify = netdev_tunnel_verify,
|
||||||
|
|
|
@ -147,7 +147,7 @@ static int tuntap_verify(NetDev *netdev, const char *filename) {
|
||||||
|
|
||||||
const NetDevVTable tun_vtable = {
|
const NetDevVTable tun_vtable = {
|
||||||
.object_size = sizeof(TunTap),
|
.object_size = sizeof(TunTap),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tun\0",
|
.sections = "Match\0NetDev\0Tun\0",
|
||||||
.config_verify = tuntap_verify,
|
.config_verify = tuntap_verify,
|
||||||
.done = tuntap_done,
|
.done = tuntap_done,
|
||||||
.create = netdev_create_tuntap,
|
.create = netdev_create_tuntap,
|
||||||
|
@ -156,7 +156,7 @@ const NetDevVTable tun_vtable = {
|
||||||
|
|
||||||
const NetDevVTable tap_vtable = {
|
const NetDevVTable tap_vtable = {
|
||||||
.object_size = sizeof(TunTap),
|
.object_size = sizeof(TunTap),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Tap\0",
|
.sections = "Match\0NetDev\0Tap\0",
|
||||||
.config_verify = tuntap_verify,
|
.config_verify = tuntap_verify,
|
||||||
.done = tuntap_done,
|
.done = tuntap_done,
|
||||||
.create = netdev_create_tuntap,
|
.create = netdev_create_tuntap,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
const NetDevVTable vcan_vtable = {
|
const NetDevVTable vcan_vtable = {
|
||||||
.object_size = sizeof(VCan),
|
.object_size = sizeof(VCan),
|
||||||
.sections = NETDEV_COMMON_SECTIONS,
|
.sections = "Match\0NetDev\0",
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
};
|
};
|
||||||
|
|
|
@ -85,7 +85,7 @@ static void veth_done(NetDev *n) {
|
||||||
|
|
||||||
const NetDevVTable veth_vtable = {
|
const NetDevVTable veth_vtable = {
|
||||||
.object_size = sizeof(Veth),
|
.object_size = sizeof(Veth),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Peer\0",
|
.sections = "Match\0NetDev\0Peer\0",
|
||||||
.done = veth_done,
|
.done = veth_done,
|
||||||
.fill_message_create = netdev_veth_fill_message_create,
|
.fill_message_create = netdev_veth_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
|
|
|
@ -85,7 +85,7 @@ static void vlan_init(NetDev *netdev) {
|
||||||
const NetDevVTable vlan_vtable = {
|
const NetDevVTable vlan_vtable = {
|
||||||
.object_size = sizeof(VLan),
|
.object_size = sizeof(VLan),
|
||||||
.init = vlan_init,
|
.init = vlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "VLAN\0",
|
.sections = "Match\0NetDev\0VLAN\0",
|
||||||
.fill_message_create = netdev_vlan_fill_message_create,
|
.fill_message_create = netdev_vlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_vlan_verify,
|
.config_verify = netdev_vlan_verify,
|
||||||
|
|
|
@ -25,7 +25,7 @@ static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink
|
||||||
|
|
||||||
const NetDevVTable vrf_vtable = {
|
const NetDevVTable vrf_vtable = {
|
||||||
.object_size = sizeof(Vrf),
|
.object_size = sizeof(Vrf),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "VRF\0",
|
.sections = "Match\0NetDev\0VRF\0",
|
||||||
.fill_message_create = netdev_vrf_fill_message_create,
|
.fill_message_create = netdev_vrf_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_MASTER,
|
.create_type = NETDEV_CREATE_MASTER,
|
||||||
.generate_mac = true,
|
.generate_mac = true,
|
||||||
|
|
|
@ -65,7 +65,7 @@ static void vxcan_done(NetDev *n) {
|
||||||
|
|
||||||
const NetDevVTable vxcan_vtable = {
|
const NetDevVTable vxcan_vtable = {
|
||||||
.object_size = sizeof(VxCan),
|
.object_size = sizeof(VxCan),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "VXCAN\0",
|
.sections = "Match\0NetDev\0VXCAN\0",
|
||||||
.done = vxcan_done,
|
.done = vxcan_done,
|
||||||
.fill_message_create = netdev_vxcan_fill_message_create,
|
.fill_message_create = netdev_vxcan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_INDEPENDENT,
|
.create_type = NETDEV_CREATE_INDEPENDENT,
|
||||||
|
|
|
@ -371,7 +371,7 @@ static void vxlan_init(NetDev *netdev) {
|
||||||
const NetDevVTable vxlan_vtable = {
|
const NetDevVTable vxlan_vtable = {
|
||||||
.object_size = sizeof(VxLan),
|
.object_size = sizeof(VxLan),
|
||||||
.init = vxlan_init,
|
.init = vxlan_init,
|
||||||
.sections = NETDEV_COMMON_SECTIONS "VXLAN\0",
|
.sections = "Match\0NetDev\0VXLAN\0",
|
||||||
.fill_message_create = netdev_vxlan_fill_message_create,
|
.fill_message_create = netdev_vxlan_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED,
|
.create_type = NETDEV_CREATE_STACKED,
|
||||||
.config_verify = netdev_vxlan_verify,
|
.config_verify = netdev_vxlan_verify,
|
||||||
|
|
|
@ -967,7 +967,7 @@ static int wireguard_verify(NetDev *netdev, const char *filename) {
|
||||||
|
|
||||||
const NetDevVTable wireguard_vtable = {
|
const NetDevVTable wireguard_vtable = {
|
||||||
.object_size = sizeof(Wireguard),
|
.object_size = sizeof(Wireguard),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "WireGuard\0WireGuardPeer\0",
|
.sections = "Match\0NetDev\0WireGuard\0WireGuardPeer\0",
|
||||||
.post_create = netdev_wireguard_post_create,
|
.post_create = netdev_wireguard_post_create,
|
||||||
.init = wireguard_init,
|
.init = wireguard_init,
|
||||||
.done = wireguard_done,
|
.done = wireguard_done,
|
||||||
|
|
|
@ -27,7 +27,7 @@ static int xfrm_fill_message_create(NetDev *netdev, Link *link, sd_netlink_messa
|
||||||
|
|
||||||
const NetDevVTable xfrm_vtable = {
|
const NetDevVTable xfrm_vtable = {
|
||||||
.object_size = sizeof(Xfrm),
|
.object_size = sizeof(Xfrm),
|
||||||
.sections = NETDEV_COMMON_SECTIONS "Xfrm\0",
|
.sections = "Match\0NetDev\0Xfrm\0",
|
||||||
.fill_message_create = xfrm_fill_message_create,
|
.fill_message_create = xfrm_fill_message_create,
|
||||||
.create_type = NETDEV_CREATE_STACKED
|
.create_type = NETDEV_CREATE_STACKED
|
||||||
};
|
};
|
||||||
|
|
|
@ -349,7 +349,8 @@ static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
||||||
"org.freedesktop.network1.Link",
|
"org.freedesktop.network1.Link",
|
||||||
"BitRates");
|
"BitRates");
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY);
|
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY) ||
|
||||||
|
sd_bus_error_has_name(&error, BUS_ERROR_SPEED_METER_INACTIVE);
|
||||||
|
|
||||||
return log_full_errno(quiet ? LOG_DEBUG : LOG_WARNING,
|
return log_full_errno(quiet ? LOG_DEBUG : LOG_WARNING,
|
||||||
r, "Failed to query link bit rates: %s", bus_error_message(&error, r));
|
r, "Failed to query link bit rates: %s", bus_error_message(&error, r));
|
||||||
|
@ -367,7 +368,7 @@ static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_parse_error(r);
|
return bus_log_parse_error(r);
|
||||||
|
|
||||||
link->has_bitrates = link->tx_bitrate != UINT64_MAX && link->rx_bitrate != UINT64_MAX;
|
link->has_bitrates = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,7 @@ static int address_label_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set address label");
|
log_link_warning_errno(link, r, "could not set address label: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
|
|
@ -431,7 +431,7 @@ static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not drop address");
|
log_link_warning_errno(link, r, "Could not drop address: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ static int set_brvlan_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *lin
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST)
|
if (r < 0 && r != -EEXIST)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not add VLAN to bridge port");
|
log_link_error_errno(link, r, "Could not add VLAN to bridge port: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
/* we warn but don't fail the link, as it may be brought up later */
|
/* we warn but don't fail the link, as it may be brought up later */
|
||||||
log_link_message_warning_errno(link, m, r, "Could not bring up interface");
|
log_link_warning_errno(link, r, "Could not bring up interface: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Failed to configure CAN link");
|
log_link_error_errno(link, r, "Failed to configure CAN link: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not bring down interface");
|
log_link_warning_errno(link, r, "Could not bring down interface: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,11 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||||
/* It seems kernel does not support that the prefix route cannot be configured with
|
/* It seems kernel does not support that the prefix route cannot be configured with
|
||||||
* route table. Let's once drop the config and reconfigure them later. */
|
* route table. Let's once drop the config and reconfigure them later. */
|
||||||
|
|
||||||
log_link_message_debug_errno(link, m, r, "Could not set DHCPv4 route, retrying later: %m");
|
log_link_debug_errno(link, r, "Could not set DHCPv4 route, retrying later: %m");
|
||||||
link->dhcp4_route_failed = true;
|
link->dhcp4_route_failed = true;
|
||||||
link->manager->dhcp4_prefix_root_cannot_set_table = true;
|
link->manager->dhcp4_prefix_root_cannot_set_table = true;
|
||||||
} else if (r < 0 && r != -EEXIST) {
|
} else if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 route: %m");
|
log_link_error_errno(link, r, "Could not set DHCPv4 route: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -543,7 +543,7 @@ static int dhcp_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
|
log_link_debug_errno(link, r, "Failed to remove DHCPv4 address, ignoring: %m");
|
||||||
else
|
else
|
||||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||||
|
|
||||||
|
@ -665,7 +665,7 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 address");
|
log_link_error_errno(link, r, "Could not set DHCPv4 address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
|
|
@ -112,7 +112,7 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, Lin
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Received error on unreachable route removal for DHCPv6 delegated subnet");
|
log_link_debug_errno(link, r, "Received error on unreachable route removal for DHCPv6 delegated subnet: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST)
|
if (r < 0 && r != -EEXIST)
|
||||||
log_link_message_warning_errno(link, m, r, "Received error when adding unreachable route for DHCPv6 delegated subnet");
|
log_link_debug_errno(link, r, "Received error when adding unreachable route for DHCPv6 delegated subnet: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 address");
|
log_link_error_errno(link, r, "Could not set DHCPv6 address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
@ -714,7 +714,7 @@ static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, Link *
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Received error adding DHCPv6 Prefix Delegation route");
|
log_link_debug_errno(link, r, "Received error adding DHCPv6 Prefix Delegation route: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -780,7 +780,7 @@ static int dhcp6_prefix_remove_handler(sd_netlink *nl, sd_netlink_message *m, Li
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_link_message_warning_errno(link, m, r, "Received error on DHCPv6 Prefix Delegation route removal");
|
log_link_debug_errno(link, r, "Received error on DHCPv6 Prefix Delegation route removal: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ static int set_fdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not add FDB entry");
|
log_link_error_errno(link, r, "Could not add FDB entry: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "could not set ipv4ll address");
|
log_link_error_errno(link, r, "could not set ipv4ll address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
|
|
@ -141,7 +141,7 @@ static int set_ipv6_proxy_ndp_address_handler(sd_netlink *rtnl, sd_netlink_messa
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST)
|
if (r < 0 && r != -EEXIST)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not add IPv6 proxy ndp address entry, ignoring");
|
log_link_error_errno(link, r, "Could not add IPv6 proxy ndp address entry: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,14 @@ static int property_get_bit_rates(
|
||||||
|
|
||||||
manager = link->manager;
|
manager = link->manager;
|
||||||
|
|
||||||
if (!manager->use_speed_meter ||
|
if (!manager->use_speed_meter)
|
||||||
manager->speed_meter_usec_old == 0 ||
|
return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is disabled.");
|
||||||
!link->stats_updated)
|
|
||||||
return sd_bus_message_append(reply, "(tt)", UINT64_MAX, UINT64_MAX);
|
if (manager->speed_meter_usec_old == 0)
|
||||||
|
return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is not active.");
|
||||||
|
|
||||||
|
if (!link->stats_updated)
|
||||||
|
return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Failed to measure bit-rates.");
|
||||||
|
|
||||||
assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
|
assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
|
||||||
interval_sec = (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
|
interval_sec = (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
|
||||||
|
|
|
@ -929,7 +929,7 @@ static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set nexthop");
|
log_link_warning_errno(link, r, "Could not set nexthop: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -981,7 +981,7 @@ static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set route");
|
log_link_warning_errno(link, r, "Could not set route: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1170,7 +1170,7 @@ static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set address");
|
log_link_warning_errno(link, r, "could not set address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
@ -1303,7 +1303,7 @@ static int set_mtu_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set MTU, ignoring");
|
log_link_warning_errno(link, r, "Could not set MTU, ignoring: %m");
|
||||||
else
|
else
|
||||||
log_link_debug(link, "Setting MTU done.");
|
log_link_debug(link, "Setting MTU done.");
|
||||||
|
|
||||||
|
@ -1415,7 +1415,7 @@ static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set link flags, ignoring");
|
log_link_warning_errno(link, r, "Could not set link flags, ignoring: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1582,7 +1582,7 @@ static int link_address_genmode_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set address genmode for interface, ignoring");
|
log_link_warning_errno(link, r, "Could not set address genmode for interface, ignoring: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1656,7 +1656,7 @@ static int link_up_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
/* we warn but don't fail the link, as it may be brought up later */
|
/* we warn but don't fail the link, as it may be brought up later */
|
||||||
log_link_message_warning_errno(link, m, r, "Could not bring up interface");
|
log_link_warning_errno(link, r, "Could not bring up interface: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1713,7 +1713,7 @@ static int link_down_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not bring down interface");
|
log_link_warning_errno(link, r, "Could not bring down interface: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2118,7 +2118,7 @@ static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not join netdev");
|
log_link_error_errno(link, r, "Could not join netdev: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -4053,10 +4053,3 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||||
|
|
||||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
|
|
||||||
const char *err_msg = NULL;
|
|
||||||
|
|
||||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
|
||||||
return log_link_full(link, level, err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
|
|
||||||
}
|
|
||||||
|
|
|
@ -213,13 +213,6 @@ int link_request_set_nexthop(Link *link);
|
||||||
|
|
||||||
int link_reconfigure(Link *link, bool force);
|
int link_reconfigure(Link *link, bool force);
|
||||||
|
|
||||||
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
|
|
||||||
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
|
|
||||||
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
|
|
||||||
#define log_link_message_notice_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_NOTICE, err, msg)
|
|
||||||
#define log_link_message_info_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_INFO, err, msg)
|
|
||||||
#define log_link_message_debug_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_DEBUG, err, msg)
|
|
||||||
|
|
||||||
#define ADDRESS_FMT_VAL(address) \
|
#define ADDRESS_FMT_VAL(address) \
|
||||||
be32toh((address).s_addr) >> 24, \
|
be32toh((address).s_addr) >> 24, \
|
||||||
(be32toh((address).s_addr) >> 16) & 0xFFu, \
|
(be32toh((address).s_addr) >> 16) & 0xFFu, \
|
||||||
|
|
|
@ -41,13 +41,6 @@
|
||||||
/* use 8 MB for receive socket kernel queue. */
|
/* use 8 MB for receive socket kernel queue. */
|
||||||
#define RCVBUF_SIZE (8*1024*1024)
|
#define RCVBUF_SIZE (8*1024*1024)
|
||||||
|
|
||||||
static int log_message_warning_errno(sd_netlink_message *m, int err, const char *msg) {
|
|
||||||
const char *err_msg = NULL;
|
|
||||||
|
|
||||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
|
||||||
return log_warning_errno(err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_default_address_pool(Manager *m) {
|
static int setup_default_address_pool(Manager *m) {
|
||||||
AddressPool *p;
|
AddressPool *p;
|
||||||
int r;
|
int r;
|
||||||
|
@ -290,7 +283,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, vo
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: failed to receive route message, ignoring");
|
log_warning_errno(r, "rtnl: failed to receive route message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -583,7 +576,7 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: failed to receive neighbor message, ignoring");
|
log_warning_errno(r, "rtnl: failed to receive neighbor message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -721,7 +714,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: failed to receive address message, ignoring");
|
log_warning_errno(r, "rtnl: failed to receive address message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -874,7 +867,7 @@ static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *messa
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: Could not receive link message, ignoring");
|
log_warning_errno(r, "rtnl: Could not receive link message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -964,7 +957,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: failed to receive rule message, ignoring");
|
log_warning_errno(r, "rtnl: failed to receive rule message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1177,7 +1170,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||||
if (sd_netlink_message_is_error(message)) {
|
if (sd_netlink_message_is_error(message)) {
|
||||||
r = sd_netlink_message_get_errno(message);
|
r = sd_netlink_message_get_errno(message);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_message_warning_errno(message, r, "rtnl: failed to receive rule message, ignoring");
|
log_warning_errno(r, "rtnl: failed to receive rule message, ignoring: %m");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ static int ndisc_netlink_route_message_handler(sd_netlink *rtnl, sd_netlink_mess
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_error_errno(link, m, r, "Could not set NDisc route or address");
|
log_link_error_errno(link, r, "Could not set NDisc route or address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ static int ndisc_netlink_address_message_handler(sd_netlink *rtnl, sd_netlink_me
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_error_errno(link, m, r, "Could not set NDisc route or address");
|
log_link_error_errno(link, r, "Could not set NDisc route or address: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
} else if (r >= 0)
|
} else if (r >= 0)
|
||||||
|
|
|
@ -102,7 +102,7 @@ static int neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, L
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST)
|
if (r < 0 && r != -EEXIST)
|
||||||
/* Neighbor may not exist yet. So, do not enter failed state here. */
|
/* Neighbor may not exist yet. So, do not enter failed state here. */
|
||||||
log_link_message_warning_errno(link, m, r, "Could not set neighbor, ignoring");
|
log_link_warning_errno(link, r, "Could not set neighbor, ignoring: %m");
|
||||||
|
|
||||||
if (link->neighbor_messages == 0) {
|
if (link->neighbor_messages == 0) {
|
||||||
log_link_debug(link, "Neighbors set");
|
log_link_debug(link, "Neighbors set");
|
||||||
|
@ -171,7 +171,7 @@ static int neighbor_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -ESRCH)
|
if (r < 0 && r != -ESRCH)
|
||||||
/* Neighbor may not exist because it already got deleted, ignore that. */
|
/* Neighbor may not exist because it already got deleted, ignore that. */
|
||||||
log_link_message_warning_errno(link, m, r, "Could not remove neighbor");
|
log_link_warning_errno(link, r, "Could not remove neighbor: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,7 @@ static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -ESRCH)
|
if (r < 0 && r != -ESRCH)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not drop nexthop, ignoring");
|
log_link_warning_errno(link, r, "Could not drop nexthop: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,7 +398,7 @@ static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -ESRCH)
|
if (r < 0 && r != -ESRCH)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not drop route, ignoring");
|
log_link_warning_errno(link, r, "Could not drop route: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -317,7 +317,7 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_message_warning_errno(link, m, r, "Could not drop routing policy rule");
|
log_link_warning_errno(link, r, "Could not drop routing policy rule: %m");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ static int routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_warning_errno(link, m, r, "Could not add routing policy rule");
|
log_link_warning_errno(link, r, "Could not add routing policy rule: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(m);
|
r = sd_netlink_message_get_errno(m);
|
||||||
if (r < 0 && r != -EEXIST) {
|
if (r < 0 && r != -EEXIST) {
|
||||||
log_link_message_error_errno(link, m, r, "Could not set QDisc: %m");
|
log_link_error_errno(link, r, "Could not set QDisc: %m");
|
||||||
link_enter_failed(link);
|
link_enter_failed(link);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,6 @@ systemd_resolved_sources = files('''
|
||||||
resolved-etc-hosts.h
|
resolved-etc-hosts.h
|
||||||
resolved-etc-hosts.c
|
resolved-etc-hosts.c
|
||||||
resolved-dnstls.h
|
resolved-dnstls.h
|
||||||
resolved-util.c
|
|
||||||
resolved-util.h
|
|
||||||
'''.split())
|
'''.split())
|
||||||
|
|
||||||
resolvectl_sources = files('''
|
resolvectl_sources = files('''
|
||||||
|
@ -230,10 +228,4 @@ tests += [
|
||||||
[],
|
[],
|
||||||
[],
|
[],
|
||||||
'ENABLE_RESOLVE', 'manual'],
|
'ENABLE_RESOLVE', 'manual'],
|
||||||
|
|
||||||
[['src/resolve/test-resolved-util.c',
|
|
||||||
'src/resolve/resolved-util.c',
|
|
||||||
'src/resolve/resolved-util.h'],
|
|
||||||
[],
|
|
||||||
[]],
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "resolved-conf.h"
|
#include "resolved-conf.h"
|
||||||
#include "resolved-dnssd.h"
|
#include "resolved-dnssd.h"
|
||||||
#include "resolved-util.h"
|
|
||||||
#include "specifier.h"
|
#include "specifier.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
@ -28,12 +27,11 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons
|
||||||
union in_addr_union address;
|
union in_addr_union address;
|
||||||
int family, r, ifindex = 0;
|
int family, r, ifindex = 0;
|
||||||
DnsServer *s;
|
DnsServer *s;
|
||||||
_cleanup_free_ char *server_name = NULL;
|
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
assert(word);
|
assert(word);
|
||||||
|
|
||||||
r = in_addr_ifindex_name_from_string_auto(word, &family, &address, &ifindex, &server_name);
|
r = in_addr_ifindex_from_string_auto(word, &family, &address, &ifindex);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -54,7 +52,7 @@ static int manager_add_dns_server_by_string(Manager *m, DnsServerType type, cons
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dns_server_new(m, NULL, type, NULL, family, &address, ifindex, server_name);
|
return dns_server_new(m, NULL, type, NULL, family, &address, ifindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
|
int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
|
||||||
|
|
|
@ -25,10 +25,8 @@ int dns_server_new(
|
||||||
Link *l,
|
Link *l,
|
||||||
int family,
|
int family,
|
||||||
const union in_addr_union *in_addr,
|
const union in_addr_union *in_addr,
|
||||||
int ifindex,
|
int ifindex) {
|
||||||
const char *server_name) {
|
|
||||||
|
|
||||||
_cleanup_free_ char *name = NULL;
|
|
||||||
DnsServer *s;
|
DnsServer *s;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
@ -46,12 +44,6 @@ int dns_server_new(
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_name) {
|
|
||||||
name = strdup(server_name);
|
|
||||||
if (!name)
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = new(DnsServer, 1);
|
s = new(DnsServer, 1);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -63,7 +55,6 @@ int dns_server_new(
|
||||||
.family = family,
|
.family = family,
|
||||||
.address = *in_addr,
|
.address = *in_addr,
|
||||||
.ifindex = ifindex,
|
.ifindex = ifindex,
|
||||||
.server_name = TAKE_PTR(name),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
dns_server_reset_features(s);
|
dns_server_reset_features(s);
|
||||||
|
@ -116,7 +107,6 @@ static DnsServer* dns_server_free(DnsServer *s) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(s->server_string);
|
free(s->server_string);
|
||||||
free(s->server_name);
|
|
||||||
return mfree(s);
|
return mfree(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,8 +53,6 @@ struct DnsServer {
|
||||||
|
|
||||||
char *server_string;
|
char *server_string;
|
||||||
|
|
||||||
char *server_name;
|
|
||||||
|
|
||||||
/* The long-lived stream towards this server. */
|
/* The long-lived stream towards this server. */
|
||||||
DnsStream *stream;
|
DnsStream *stream;
|
||||||
|
|
||||||
|
@ -96,8 +94,7 @@ int dns_server_new(
|
||||||
Link *link,
|
Link *link,
|
||||||
int family,
|
int family,
|
||||||
const union in_addr_union *address,
|
const union in_addr_union *address,
|
||||||
int ifindex,
|
int ifindex);
|
||||||
const char *server_string);
|
|
||||||
|
|
||||||
DnsServer* dns_server_ref(DnsServer *s);
|
DnsServer* dns_server_ref(DnsServer *s);
|
||||||
DnsServer* dns_server_unref(DnsServer *s);
|
DnsServer* dns_server_unref(DnsServer *s);
|
||||||
|
|
|
@ -67,12 +67,6 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
|
||||||
gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
|
gnutls_session_set_verify_cert2(gs, &stream->dnstls_data.validation, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->server_name) {
|
|
||||||
r = gnutls_server_name_set(gs, GNUTLS_NAME_DNS, server->server_name, strlen(server->server_name));
|
|
||||||
if (r < 0)
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set server name: %s", gnutls_strerror(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
gnutls_handshake_set_timeout(gs, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
gnutls_handshake_set_timeout(gs, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||||
|
|
||||||
gnutls_transport_set_ptr2(gs, (gnutls_transport_ptr_t) (long) stream->fd, stream);
|
gnutls_transport_set_ptr2(gs, (gnutls_transport_ptr_t) (long) stream->fd, stream);
|
||||||
|
|
|
@ -87,17 +87,6 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
|
||||||
return -ECONNREFUSED;
|
return -ECONNREFUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server->server_name) {
|
|
||||||
r = SSL_set_tlsext_host_name(s, server->server_name);
|
|
||||||
if (r <= 0) {
|
|
||||||
char errbuf[256];
|
|
||||||
|
|
||||||
error = ERR_get_error();
|
|
||||||
ERR_error_string_n(error, errbuf, sizeof(errbuf));
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set server name: %s", errbuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
stream->dnstls_data.handshake = SSL_do_handshake(s);
|
stream->dnstls_data.handshake = SSL_do_handshake(s);
|
||||||
if (stream->dnstls_data.handshake <= 0) {
|
if (stream->dnstls_data.handshake <= 0) {
|
||||||
|
|
|
@ -284,7 +284,7 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
|
||||||
if (s)
|
if (s)
|
||||||
dns_server_move_back_and_unmark(s);
|
dns_server_move_back_and_unmark(s);
|
||||||
else {
|
else {
|
||||||
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i].family, &dns[i].address, 0, NULL);
|
r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, dns[i].family, &dns[i].address, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto clear;
|
goto clear;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,7 +269,7 @@ static int link_update_dns_server_one(Link *l, const char *name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, 0, NULL);
|
return dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int link_update_dns_servers(Link *l) {
|
static int link_update_dns_servers(Link *l) {
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
||||||
|
|
||||||
#include "alloc-util.h"
|
|
||||||
#include "in-addr-util.h"
|
|
||||||
#include "macro.h"
|
|
||||||
#include "resolved-util.h"
|
|
||||||
|
|
||||||
int in_addr_ifindex_name_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex, char **server_name) {
|
|
||||||
_cleanup_free_ char *buf = NULL, *name = NULL;
|
|
||||||
const char *m;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(s);
|
|
||||||
|
|
||||||
m = strchr(s, '#');
|
|
||||||
if (m) {
|
|
||||||
name = strdup(m+1);
|
|
||||||
if (!name)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
buf = strndup(s, m - s);
|
|
||||||
if (!buf)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
s = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = in_addr_ifindex_from_string_auto(s, family, ret, ifindex);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (server_name)
|
|
||||||
*server_name = TAKE_PTR(name);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "in-addr-util.h"
|
|
||||||
|
|
||||||
int in_addr_ifindex_name_from_string_auto(const char *s, int *family, union in_addr_union *ret, int *ifindex, char **server_name);
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue