systemd: merge branch systemd into master
This commit is contained in:
@@ -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;
|
||||
|
@@ -974,6 +974,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,
|
||||
@@ -989,10 +995,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;
|
||||
@@ -1238,6 +1246,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;
|
||||
@@ -1259,10 +1273,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
|
||||
@@ -1360,10 +1376,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)
|
||||
@@ -1430,6 +1448,12 @@ _public_ int sd_event_add_child_pidfd(
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
||||
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,
|
||||
@@ -1441,10 +1465,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;
|
||||
@@ -1475,10 +1501,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;
|
||||
@@ -1830,6 +1858,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,
|
||||
@@ -1848,10 +1882,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. */
|
||||
@@ -3187,16 +3223,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)
|
||||
@@ -3303,9 +3344,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);
|
||||
@@ -3338,9 +3385,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);
|
||||
@@ -3979,4 +4032,22 @@ _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;
|
||||
}
|
||||
#endif /* NM_IGNORED */
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user