1
0
mirror of https://github.com/systemd/systemd synced 2025-12-28 03:44:45 +01:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Renaud Métrich
5177cb0a9a unit: don't emit PropertiesChanged signal if adding a dependency to a unit is a no-op 2020-10-07 18:16:08 +02:00
Lennart Poettering
b8aaceb9b5 systemctl: drop unsused variable original_stdout_is_tty
Unused since de9a8fe18e0168b65ae50b6dde2865f647fc92a2.
2020-10-07 14:13:19 +02:00
Lennart Poettering
816d460a7c update TODO 2020-10-07 14:12:19 +02:00
Lennart Poettering
1378ac6989
Merge pull request #17231 from poettering/event-source-exit-on-failure
sd-event: add "exit-on-failure" feature for event source
2020-10-07 12:55:56 +02:00
Zbigniew Jędrzejewski-Szmek
206178a9d2 Document some reasonable DNS servers in the example config file
We have an option to set the fallback list, so we don't know what the contents
are. It may in fact be empty. Let's add some examples to make it easy for a user
stranded without any DNS to fill in something that would work. As a bonus, this
also gives names to the entries we provide by default.
(I added google and cloudflare because that's what we have currently, and quad9
because it seems to be a good privacy-concious and fast choice and was requested
in #12499. As a minimum, things we should include should be well-known global
services with a documented privacy policy and both IPv4 and IPv6 support and
decent response times.)
2020-10-07 11:38:07 +02:00
Lennart Poettering
cbda8bd5fb udev: make use of NULL callback in IO handlers 2020-10-07 09:40:32 +02:00
Lennart Poettering
b9350e70aa sd-event: support callback=NULL in IO/child/inotify/defer event sources, too
Also, document this functionality more prominently, including with a
reference from sd_event_exit().

This is mostly to make things complete, as previously we supported NULL
callbacks only in _add_time() and _add_signal(). However, I think this
makes snese for IO event sources too (think: when some fd such as a pipe
end sees SIGHUP or so, exit), as well as defer or post event sources (i.e. exit
once we got nothing else to do). This also adds support for inotify
event sources, simply to complete things (I can't see the immediate use,
but maybe someone else comes up with it).

The only event source type that doesn't allow callback=NULL now are exit
callbacks, but for them they make little sense, as the event loop is
exiting then anyway.
2020-10-07 09:40:16 +02:00
Lennart Poettering
bac0bfc1d0 udev-util: make use of sd-event's NULL callback support 2020-10-07 09:40:12 +02:00
Lennart Poettering
463f9ce3bc test: add test that validates that PTR_TO_INT(INT_TO_PTR()) covers whole int range 2020-10-07 09:40:09 +02:00
Lennart Poettering
ccaa30c199 socket-proxy: port to new sd_event_source_set_exit_on_failure() API 2020-10-07 09:40:05 +02:00
Lennart Poettering
76c59537f3 socket-proxy: close correct fd, log at right log level 2020-10-07 09:40:02 +02:00
Lennart Poettering
647f2ee259 man: add docs for sd_event_source_set_exit_on_failure() 2020-10-07 09:39:39 +02:00
Lennart Poettering
b778cba4bf sd-event: optionally, if an event source fails, exit the event loop
Currently, if an event source callback returns an error, we'll disable
the event source and continue. This adds a per-event source flag that if
turned on goes further: the event loop is also exited, propagating the
error code.

This is inspired by some patterns repeatedly seen in #15206.

The idea is that event sources that server the "primary" function of a
program are marked like this, so that if they fail the failure is
instantly propagated and terminates the program.
2020-10-07 09:38:41 +02:00
21 changed files with 315 additions and 64 deletions

7
TODO
View File

@ -20,6 +20,13 @@ Janitorial Clean-ups:
Features:
* Provide a tool to hook into CONFIG_STATIC_USERMODEHELPER in the kernel, so
that we can collect all usermode helper calls and spawn them as regular
services.
* Add service setting to run a service within the specified VRF. i.e. do the
equivalent of "ip vrf exec".
* systemd-analyze syscall-filter should show a list of syscalls listed in
@known but not in other groups (at least at debug level), since they are
candidates to be added to them.

View File

@ -564,6 +564,10 @@ manpages = [
'SD_EVENT_ONESHOT',
'sd_event_source_get_enabled'],
''],
['sd_event_source_set_exit_on_failure',
'3',
['sd_event_source_get_exit_on_failure'],
''],
['sd_event_source_set_floating', '3', ['sd_event_source_get_floating'], ''],
['sd_event_source_set_prepare', '3', [], ''],
['sd_event_source_set_priority',

View File

@ -150,11 +150,10 @@
<citerefentry
project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>).</para>
<para>If the second parameter of
<function>sd_event_add_child()</function> is passed as NULL no
reference to the event source object is returned. In this case the
event source is considered "floating", and will be destroyed
implicitly when the event loop itself is destroyed.</para>
<para>If the second parameter of <function>sd_event_add_child()</function> is passed as
<constant>NULL</constant> no reference to the event source object is returned. In this case the event
source is considered "floating", and will be destroyed implicitly when the event loop itself is
destroyed.</para>
<para>Note that the <parameter>handler</parameter> function is
invoked at a time where the child process is not reaped yet (and
@ -164,6 +163,12 @@
event sources are installed will not be reaped by the event loop
implementation.</para>
<para>If the <parameter>handler</parameter> parameter to <function>sd_event_add_child()</function> is
<constant>NULL</constant>, and the event source fires, this will be considered a request to exit the
event loop. In this case, the <parameter>userdata</parameter> parameter, cast to an integer, is passed as
the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>If both a child process state change event source and a
<constant>SIGCHLD</constant> signal event source is installed in
the same event loop, the configured event source priorities decide

View File

@ -116,11 +116,17 @@
<constant>SD_EVENT_OFF</constant> with
<citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>If the second parameter of these functions is passed as
NULL no reference to the event source object is returned. In this
case the event source is considered "floating", and will be
destroyed implicitly when the event loop itself is
destroyed.</para>
<para>If the second parameter of these functions is passed as <constant>NULL</constant> no reference to
the event source object is returned. In this case the event source is considered "floating", and will be
destroyed implicitly when the event loop itself is destroyed.</para>
<para>If the <parameter>handler</parameter> parameter to <function>sd_event_add_defer()</function> or
<function>sd_event_add_post()</function> is <constant>NULL</constant>, and the event source fires, this
will be considered a request to exit the event loop. In this case, the <parameter>userdata</parameter>
parameter, cast to an integer, is passed as the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>. Similar
functionality is not available for <function>sd_event_add_exit()</function>, as these types of event
sources are only dispatched when exiting anyway.</para>
</refsect1>
<refsect1>

View File

@ -95,9 +95,16 @@
it with
<citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>If the second parameter of <function>sd_event_add_inotify()</function> is passed as NULL no reference to the
event source object is returned. In this case the event source is considered "floating", and will be destroyed
implicitly when the event loop itself is destroyed.</para>
<para>If the second parameter of <function>sd_event_add_inotify()</function> is passed as
<constant>NULL</constant> no reference to the event source object is returned. In this case the event
source is considered "floating", and will be destroyed implicitly when the event loop itself is
destroyed.</para>
<para>If the <parameter>handler</parameter> parameter to <function>sd_event_add_inotify()</function> is
<constant>NULL</constant>, and the event source fires, this will be considered a request to exit the
event loop. In this case, the <parameter>userdata</parameter> parameter, cast to an integer, is passed as
the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para><function>sd_event_source_get_inotify_mask()</function> retrieves the configured inotify watch mask of an
event source created previously with <function>sd_event_add_inotify()</function>. It takes the event source object

View File

@ -161,6 +161,12 @@
"floating", and will be destroyed implicitly when the event loop
itself is destroyed.</para>
<para>If the <parameter>handler</parameter> to <function>sd_event_add_io()</function> is
<constant>NULL</constant>, and the event source fires, this will be considered a request to exit the
event loop. In this case, the <parameter>userdata</parameter> parameter, cast to an integer, is passed as
the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>Note that this call does not take possession of the file descriptor passed in, ownership (and thus
the duty to close it when it is no longer needed) remains with the caller. However, with the
<function>sd_event_source_set_io_fd_own()</function> call (see below) the event source may optionally

View File

@ -79,9 +79,7 @@
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>). If
the handler is not specified (<parameter>handler</parameter> is <constant>NULL</constant>), a default
handler which causes the program to exit cleanly will be used.</para>
project='man-pages'><refentrytitle>pthread_sigmask</refentrytitle><manvolnum>3</manvolnum></citerefentry>).</para>
<para>By default, the event source is enabled permanently
(<constant>SD_EVENT_ON</constant>), but this may be changed with
@ -107,6 +105,12 @@
"floating", and will be destroyed implicitly when the event loop
itself is destroyed.</para>
<para>If the <parameter>handler</parameter> parameter to <function>sd_event_add_signal()</function> is
<constant>NULL</constant>, and the event source fires, this will be considered a request to exit the
event loop. In this case, the <parameter>userdata</parameter> parameter, cast to an integer, is passed as
the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para><function>sd_event_source_get_signal()</function> returns
the configured signal number of an event source created previously
with <function>sd_event_add_signal()</function>. It takes the

View File

@ -161,12 +161,10 @@
"floating", and will be destroyed implicitly when the event loop
itself is destroyed.</para>
<para>If the <parameter>handler</parameter> to
<function>sd_event_add_time()</function> is
<constant>NULL</constant>, and the event source fires, this will
be considered a request to exit the event loop. In this case, the
<parameter>userdata</parameter> parameter, cast to an integer, is
used for the exit code passed to
<para>If the <parameter>handler</parameter> parameter to <function>sd_event_add_time()</function> is
<constant>NULL</constant>, and the event source fires, this will be considered a request to exit the
event loop. In this case, the <parameter>userdata</parameter> parameter, cast to an integer, is passed as
the exit code parameter to
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para>
<para>Use <constant>CLOCK_BOOTTIME_ALARM</constant> and

View File

@ -74,6 +74,16 @@
conflict with regular exit codes returned by
<function>sd_event_loop()</function>, if these exit codes shall be
distinguishable.</para>
<para>Note that for most event source types passing the callback pointer as <constant>NULL</constant> in
the respective constructor call (i.e. in
<citerefentry><refentrytitle>sd_event_add_time</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
…) has the effect of <function>sd_event_exit()</function> being invoked once the event source triggers,
with the specified userdata pointer cast to an integer as the exit code parameter. This is useful to
automatically terminate an event loop after some condition, such as a time-out or reception of
<constant>SIGTERM</constant> or similar. See the documentation for the respective constructor call for
details.</para>
</refsect1>
<refsect1>
@ -128,7 +138,12 @@
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>
<citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_time</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_io</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_defer</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_inotify</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>

View File

@ -0,0 +1,108 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
<refentry id="sd_event_source_set_exit_on_failure" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sd_event_source_set_exit_on_failure</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sd_event_source_set_exit_on_failure</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_event_source_set_exit_on_failure</refname>
<refname>sd_event_source_get_exit_on_failure</refname>
<refpurpose>Set or retrieve the exit-on-failure feature of event sources</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;systemd/sd-event.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_event_source_set_exit_on_failure</function></funcdef>
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
<paramdef>int <parameter>b</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_event_source_get_exit_on_failure</function></funcdef>
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>sd_event_source_set_exit_on_failure()</function> may be used to set/unset the
exit-on-failure flag of the event source object specified as <parameter>source</parameter>. The flag
defaults to off. If on and the callback function set for the event source returns a failure code (i.e. a
negative value) the event loop is exited too, using the callback return code as the exit code for
<citerefentry><refentrytitle>sd_event_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
off, the event source is disabled but the event loop continues to run. Setting this flag is useful for
"dominant" event sources that define the purpose and reason for the event loop, and whose failure hence
should propagate to the event loop itself — as opposed to "auxiliary" event sources whose failures should
remain local and affect the event source, but not propagate further.</para>
<para><function>sd_event_source_get_exit_on_failure()</function> may be used to query the flag currently
set for the event source object <parameter>source</parameter>.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>On success, <function>sd_event_source_set_exit_on_failure()</function> returns a non-negative
integer. <function>sd_event_source_get_exit_on_failure()</function> returns 0 if the flag is off, &gt; 0
if the flag is on. On failure, both return a negative errno-style error code.</para>
<refsect2>
<title>Errors</title>
<para>Returned errors may indicate the following problems:</para>
<variablelist>
<varlistentry>
<term><constant>-EINVAL</constant></term>
<listitem><para><parameter>source</parameter> is not a valid pointer to an
<structname>sd_event_source</structname> object.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-EDOM</constant></term>
<listitem><para>The event source refers to an exit event source (as created with
<citerefentry><refentrytitle>sd_event_add_exit</refentrytitle><manvolnum>3</manvolnum></citerefentry>),
for which this functionality is not supported.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<xi:include href="libsystemd-pkgconfig.xml" />
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_io</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_time</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_signal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_child</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_inotify</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_event_add_defer</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -3020,6 +3020,9 @@ int unit_add_dependency(
};
Unit *original_u = u, *original_other = other;
int r;
/* Helper to know whether sending a notification is necessary or not:
* if the dependency is already there, no need to notify! */
bool noop = true;
assert(u);
assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
@ -3057,24 +3060,33 @@ int unit_add_dependency(
r = unit_add_dependency_hashmap(u->dependencies + d, other, mask, 0);
if (r < 0)
return r;
else if (r > 0)
noop = false;
if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
r = unit_add_dependency_hashmap(other->dependencies + inverse_table[d], u, 0, mask);
if (r < 0)
return r;
else if (r > 0)
noop = false;
}
if (add_reference) {
r = unit_add_dependency_hashmap(u->dependencies + UNIT_REFERENCES, other, mask, 0);
if (r < 0)
return r;
else if (r > 0)
noop = false;
r = unit_add_dependency_hashmap(other->dependencies + UNIT_REFERENCED_BY, u, 0, mask);
if (r < 0)
return r;
else if (r > 0)
noop = false;
}
unit_add_to_dbus_queue(u);
if (!noop)
unit_add_to_dbus_queue(u);
return 0;
}

View File

@ -726,6 +726,8 @@ LIBSYSTEMD_247 {
global:
sd_event_add_time_relative;
sd_event_source_set_time_relative;
sd_event_source_get_exit_on_failure;
sd_event_source_set_exit_on_failure;
sd_bus_error_has_names_sentinel;

View File

@ -60,6 +60,7 @@ struct sd_event_source {
bool pending:1;
bool dispatching:1;
bool floating:1;
bool exit_on_failure:1;
int64_t priority;
unsigned pending_index;

View File

@ -972,6 +972,12 @@ static sd_event_source *source_new(sd_event *e, bool floating, EventSourceType t
return s;
}
static int io_exit_callback(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
assert(s);
return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
}
_public_ int sd_event_add_io(
sd_event *e,
sd_event_source **ret,
@ -987,10 +993,12 @@ _public_ int sd_event_add_io(
assert_return(e = event_resolve(e), -ENOPKG);
assert_return(fd >= 0, -EBADF);
assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
assert_return(callback, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
if (!callback)
callback = io_exit_callback;
s = source_new(e, !ret, SOURCE_IO);
if (!s)
return -ENOMEM;
@ -1235,6 +1243,12 @@ _public_ int sd_event_add_signal(
return 0;
}
static int child_exit_callback(sd_event_source *s, const siginfo_t *si, void *userdata) {
assert(s);
return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
}
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;
@ -1256,10 +1270,12 @@ _public_ int sd_event_add_child(
assert_return(pid > 1, -EINVAL);
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 (!callback)
callback = child_exit_callback;
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
@ -1357,10 +1373,12 @@ _public_ int sd_event_add_child_pidfd(
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 (!callback)
callback = child_exit_callback;
if (e->n_enabled_child_sources == 0) {
r = signal_is_blocked(SIGCHLD);
if (r < 0)
@ -1426,6 +1444,12 @@ _public_ int sd_event_add_child_pidfd(
return 0;
}
static int generic_exit_callback(sd_event_source *s, void *userdata) {
assert(s);
return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
}
_public_ int sd_event_add_defer(
sd_event *e,
sd_event_source **ret,
@ -1437,10 +1461,12 @@ _public_ int sd_event_add_defer(
assert_return(e, -EINVAL);
assert_return(e = event_resolve(e), -ENOPKG);
assert_return(callback, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
if (!callback)
callback = generic_exit_callback;
s = source_new(e, !ret, SOURCE_DEFER);
if (!s)
return -ENOMEM;
@ -1471,10 +1497,12 @@ _public_ int sd_event_add_post(
assert_return(e, -EINVAL);
assert_return(e = event_resolve(e), -ENOPKG);
assert_return(callback, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
if (!callback)
callback = generic_exit_callback;
s = source_new(e, !ret, SOURCE_POST);
if (!s)
return -ENOMEM;
@ -1826,6 +1854,12 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) {
return 1;
}
static int inotify_exit_callback(sd_event_source *s, const struct inotify_event *event, void *userdata) {
assert(s);
return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
}
_public_ int sd_event_add_inotify(
sd_event *e,
sd_event_source **ret,
@ -1844,10 +1878,12 @@ _public_ int sd_event_add_inotify(
assert_return(e, -EINVAL);
assert_return(e = event_resolve(e), -ENOPKG);
assert_return(path, -EINVAL);
assert_return(callback, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
if (!callback)
callback = inotify_exit_callback;
/* Refuse IN_MASK_ADD since we coalesce watches on the same inode, and hence really don't want to merge
* masks. Or in other words, this whole code exists only to manage IN_MASK_ADD type operations for you, hence
* the user can't use them for us. */
@ -3183,16 +3219,21 @@ static int process_inotify(sd_event *e) {
}
static int source_dispatch(sd_event_source *s) {
_cleanup_(sd_event_unrefp) sd_event *saved_event = NULL;
EventSourceType saved_type;
int r = 0;
assert(s);
assert(s->pending || s->type == SOURCE_EXIT);
/* Save the event source type, here, so that we still know it after the event callback which might invalidate
* the event. */
/* Save the event source type, here, so that we still know it after the event callback which might
* invalidate the event. */
saved_type = s->type;
/* Similar, store a reference to the event loop object, so that we can still access it after the
* callback might have invalidated/disconnected the event source. */
saved_event = sd_event_ref(s->event);
if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
r = source_set_pending(s, false);
if (r < 0)
@ -3299,9 +3340,15 @@ static int source_dispatch(sd_event_source *s) {
s->dispatching = false;
if (r < 0)
log_debug_errno(r, "Event source %s (type %s) returned error, disabling: %m",
strna(s->description), event_source_type_to_string(saved_type));
if (r < 0) {
log_debug_errno(r, "Event source %s (type %s) returned error, %s: %m",
strna(s->description),
event_source_type_to_string(saved_type),
s->exit_on_failure ? "exiting" : "disabling");
if (s->exit_on_failure)
(void) sd_event_exit(saved_event, r);
}
if (s->n_ref == 0)
source_free(s);
@ -3334,9 +3381,15 @@ static int event_prepare(sd_event *e) {
r = s->prepare(s, s->userdata);
s->dispatching = false;
if (r < 0)
log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, disabling: %m",
strna(s->description), event_source_type_to_string(s->type));
if (r < 0) {
log_debug_errno(r, "Prepare callback of event source %s (type %s) returned error, %s: %m",
strna(s->description),
event_source_type_to_string(s->type),
s->exit_on_failure ? "exiting" : "disabling");
if (s->exit_on_failure)
(void) sd_event_exit(e, r);
}
if (s->n_ref == 0)
source_free(s);
@ -3974,3 +4027,21 @@ _public_ int sd_event_source_set_floating(sd_event_source *s, int b) {
return 1;
}
_public_ int sd_event_source_get_exit_on_failure(sd_event_source *s) {
assert_return(s, -EINVAL);
assert_return(s->type != SOURCE_EXIT, -EDOM);
return s->exit_on_failure;
}
_public_ int sd_event_source_set_exit_on_failure(sd_event_source *s, int b) {
assert_return(s, -EINVAL);
assert_return(s->type != SOURCE_EXIT, -EDOM);
if (s->exit_on_failure == !!b)
return 0;
s->exit_on_failure = b;
return 1;
}

View File

@ -12,6 +12,10 @@
# See resolved.conf(5) for details
[Resolve]
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
# Cloudflare: 1.1.1.1 1.0.0.1 2606:4700:4700::1111 2606:4700:4700::1001
# Google: 8.8.8.8 8.8.4.4 2001:4860:4860::8888 2001:4860:4860::8844
# Quad9: 9.9.9.9 2620:fe::fe
#DNS=
#FallbackDNS=@DNS_SERVERS@
#Domains=

View File

@ -175,10 +175,6 @@ found:
return sd_event_exit(sd_device_monitor_get_event(monitor), 0);
}
static int device_timeout_handler(sd_event_source *s, uint64_t usec, void *userdata) {
return sd_event_exit(sd_event_source_get_event(s), -ETIMEDOUT);
}
static int device_wait_for_initialization_internal(
sd_device *_device,
const char *devlink,
@ -248,7 +244,7 @@ static int device_wait_for_initialization_internal(
r = sd_event_add_time_relative(
event, &timeout_source,
CLOCK_MONOTONIC, timeout, 0,
device_timeout_handler, NULL);
NULL, INT_TO_PTR(-ETIMEDOUT));
if (r < 0)
return log_error_errno(r, "Failed to add timeout event source: %m");
}

View File

@ -522,17 +522,14 @@ static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdat
r = add_connection_socket(context, nfd);
if (r < 0) {
log_error_errno(r, "Failed to accept connection, ignoring: %m");
safe_close(fd);
log_warning_errno(r, "Failed to accept connection, ignoring: %m");
safe_close(nfd);
}
}
r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
if (r < 0) {
log_error_errno(r, "Error while re-enabling listener with ONESHOT: %m");
sd_event_exit(context->event, r);
return r;
}
if (r < 0)
return log_error_errno(r, "Error while re-enabling listener with ONESHOT: %m");
return 1;
}
@ -561,11 +558,14 @@ static int add_listen_socket(Context *context, int fd) {
r = set_ensure_put(&context->listen, NULL, source);
if (r < 0) {
log_error_errno(r, "Failed to add source to set: %m");
sd_event_source_unref(source);
return r;
return log_error_errno(r, "Failed to add source to set: %m");
}
r = sd_event_source_set_exit_on_failure(source, true);
if (r < 0)
return log_error_errno(r, "Failed to enable exit-on-failure logic: %m");
/* Set the watcher to oneshot in case other processes are also
* watching to accept(). */
r = sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);

View File

@ -191,8 +191,6 @@ static int trivial_method(int argc, char *argv[], void *userdata);
static int halt_now(enum action a);
static int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *active_state);
static bool original_stdout_is_tty;
typedef enum BusFocus {
BUS_FULL, /* The full bus indicated via --system or --user */
BUS_MANAGER, /* The manager itself, possibly directly, possibly via the bus */
@ -9401,11 +9399,6 @@ static int run(int argc, char *argv[]) {
sigbus_install();
/* Explicitly not on_tty() to avoid setting cached value.
* This becomes relevant for piping output which might be
* ellipsized. */
original_stdout_is_tty = isatty(STDOUT_FILENO);
r = parse_argv(argc, argv);
if (r <= 0)
goto finish;

View File

@ -160,6 +160,8 @@ int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t
int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret);
int sd_event_source_get_floating(sd_event_source *s);
int sd_event_source_set_floating(sd_event_source *s, int b);
int sd_event_source_get_exit_on_failure(sd_event_source *s);
int sd_event_source_set_exit_on_failure(sd_event_source *s, int b);
/* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref);

View File

@ -414,6 +414,8 @@ static void test_foreach_pointer(void) {
int a, b, c, *i;
size_t k = 0;
log_info("/* %s */", __func__);
FOREACH_POINTER(i, &a, &b, &c) {
switch (k) {
@ -489,6 +491,17 @@ static void test_foreach_pointer(void) {
assert(k == 11);
}
static void test_ptr_to_int(void) {
log_info("/* %s */", __func__);
/* Primary reason to have this test is to validate that pointers are large enough to hold entire int range */
assert_se(PTR_TO_INT(INT_TO_PTR(0)) == 0);
assert_se(PTR_TO_INT(INT_TO_PTR(1)) == 1);
assert_se(PTR_TO_INT(INT_TO_PTR(-1)) == -1);
assert_se(PTR_TO_INT(INT_TO_PTR(INT_MAX)) == INT_MAX);
assert_se(PTR_TO_INT(INT_TO_PTR(INT_MIN)) == INT_MIN);
}
int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO);
@ -508,6 +521,7 @@ int main(int argc, char *argv[]) {
test_system_tasks_max();
test_system_tasks_max_scale();
test_foreach_pointer();
test_ptr_to_int();
return 0;
}

View File

@ -355,10 +355,6 @@ int udev_ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int in
return 0;
}
static int udev_ctrl_wait_io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
return sd_event_exit(sd_event_source_get_event(s), 0);
}
int udev_ctrl_wait(struct udev_ctrl *uctrl, usec_t timeout) {
_cleanup_(sd_event_source_unrefp) sd_event_source *source_io = NULL, *source_timeout = NULL;
int r;
@ -385,7 +381,7 @@ int udev_ctrl_wait(struct udev_ctrl *uctrl, usec_t timeout) {
return r;
}
r = sd_event_add_io(uctrl->event, &source_io, uctrl->sock, EPOLLIN, udev_ctrl_wait_io_handler, NULL);
r = sd_event_add_io(uctrl->event, &source_io, uctrl->sock, EPOLLIN, NULL, INT_TO_PTR(0));
if (r < 0)
return r;