From a137a1c3ffffb4cb8528e736ec4bf634902493fa Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Nov 2018 17:30:42 +0900 Subject: [PATCH 01/19] sd-event: split definition of event_source to event-source.h --- meson.build | 1 + src/libsystemd/meson.build | 7 +- src/libsystemd/sd-event/event-source.h | 206 +++++++++++++++++++++++++ src/libsystemd/sd-event/sd-event.c | 194 +---------------------- 4 files changed, 214 insertions(+), 194 deletions(-) create mode 100644 src/libsystemd/sd-event/event-source.h diff --git a/meson.build b/meson.build index d3cea0cfdf..ccea945720 100644 --- a/meson.build +++ b/meson.build @@ -1363,6 +1363,7 @@ includes = include_directories('src/basic', 'src/core', 'src/libsystemd/sd-bus', 'src/libsystemd/sd-device', + 'src/libsystemd/sd-event', 'src/libsystemd/sd-hwdb', 'src/libsystemd/sd-id128', 'src/libsystemd/sd-netlink', diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index c0eeae7e2f..2208b6de12 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -7,7 +7,12 @@ id128_sources = files(''' '''.split()) sd_daemon_c = files('sd-daemon/sd-daemon.c') -sd_event_c = files('sd-event/sd-event.c') + +sd_event_c = files(''' + sd-event/event-source.h + sd-event/sd-event.c +'''.split()) + sd_login_c = files('sd-login/sd-login.c') libsystemd_sources = files(''' diff --git a/src/libsystemd/sd-event/event-source.h b/src/libsystemd/sd-event/event-source.h new file mode 100644 index 0000000000..99ab8fc169 --- /dev/null +++ b/src/libsystemd/sd-event/event-source.h @@ -0,0 +1,206 @@ +#pragma once +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include +#include +#include + +#include "sd-event.h" + +#include "fs-util.h" +#include "hashmap.h" +#include "list.h" +#include "prioq.h" + +typedef enum EventSourceType { + SOURCE_IO, + SOURCE_TIME_REALTIME, + SOURCE_TIME_BOOTTIME, + SOURCE_TIME_MONOTONIC, + SOURCE_TIME_REALTIME_ALARM, + SOURCE_TIME_BOOTTIME_ALARM, + SOURCE_SIGNAL, + SOURCE_CHILD, + SOURCE_DEFER, + SOURCE_POST, + SOURCE_EXIT, + SOURCE_WATCHDOG, + SOURCE_INOTIFY, + _SOURCE_EVENT_SOURCE_TYPE_MAX, + _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 +} EventSourceType; + +/* All objects we use in epoll events start with this value, so that + * we know how to dispatch it */ +typedef enum WakeupType { + WAKEUP_NONE, + WAKEUP_EVENT_SOURCE, + WAKEUP_CLOCK_DATA, + WAKEUP_SIGNAL_DATA, + WAKEUP_INOTIFY_DATA, + _WAKEUP_TYPE_MAX, + _WAKEUP_TYPE_INVALID = -1, +} WakeupType; + +struct inode_data; + +struct sd_event_source { + WakeupType wakeup; + + unsigned n_ref; + + sd_event *event; + void *userdata; + sd_event_handler_t prepare; + + char *description; + + EventSourceType type:5; + signed int enabled:3; + bool pending:1; + bool dispatching:1; + bool floating:1; + + int64_t priority; + unsigned pending_index; + unsigned prepare_index; + uint64_t pending_iteration; + uint64_t prepare_iteration; + + sd_event_destroy_t destroy_callback; + + LIST_FIELDS(sd_event_source, sources); + + union { + struct { + sd_event_io_handler_t callback; + int fd; + uint32_t events; + uint32_t revents; + bool registered:1; + bool owned:1; + } io; + struct { + sd_event_time_handler_t callback; + usec_t next, accuracy; + unsigned earliest_index; + unsigned latest_index; + } time; + struct { + sd_event_signal_handler_t callback; + struct signalfd_siginfo siginfo; + int sig; + } signal; + struct { + sd_event_child_handler_t callback; + siginfo_t siginfo; + pid_t pid; + int options; + } child; + struct { + sd_event_handler_t callback; + } defer; + struct { + sd_event_handler_t callback; + } post; + struct { + sd_event_handler_t callback; + unsigned prioq_index; + } exit; + struct { + sd_event_inotify_handler_t callback; + uint32_t mask; + struct inode_data *inode_data; + LIST_FIELDS(sd_event_source, by_inode_data); + } inotify; + }; +}; + +struct clock_data { + WakeupType wakeup; + int fd; + + /* For all clocks we maintain two priority queues each, one + * ordered for the earliest times the events may be + * dispatched, and one ordered by the latest times they must + * have been dispatched. The range between the top entries in + * the two prioqs is the time window we can freely schedule + * wakeups in */ + + Prioq *earliest; + Prioq *latest; + usec_t next; + + bool needs_rearm:1; +}; + +struct signal_data { + WakeupType wakeup; + + /* For each priority we maintain one signal fd, so that we + * only have to dequeue a single event per priority at a + * time. */ + + int fd; + int64_t priority; + sigset_t sigset; + sd_event_source *current; +}; + +/* A structure listing all event sources currently watching a specific inode */ +struct inode_data { + /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */ + ino_t ino; + dev_t dev; + + /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can + * rearrange the priority still until then, as we need the original inode to change the priority as we need to + * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the + * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of + * the sd-event object, so that it is efficient to close everything, before entering the next event loop + * iteration. */ + int fd; + + /* The inotify "watch descriptor" */ + int wd; + + /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has + * most recently been set on the watch descriptor. */ + uint32_t combined_mask; + + /* All event sources subscribed to this inode */ + LIST_HEAD(sd_event_source, event_sources); + + /* The inotify object we watch this inode with */ + struct inotify_data *inotify_data; + + /* A linked list of all inode data objects with fds to close (see above) */ + LIST_FIELDS(struct inode_data, to_close); +}; + +/* A structure encapsulating an inotify fd */ +struct inotify_data { + WakeupType wakeup; + + /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at + * a time */ + + int fd; + int64_t priority; + + Hashmap *inodes; /* The inode_data structures keyed by dev+ino */ + Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */ + + /* The buffer we read inotify events into */ + union inotify_event_buffer buffer; + size_t buffer_filled; /* fill level of the buffer */ + + /* How many event sources are currently marked pending for this inotify. We won't read new events off the + * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing + * the events locally if they can't be coalesced). */ + unsigned n_pending; + + /* A linked list of all inotify objects with data already read, that still need processing. We keep this list + * to make it efficient to figure out what inotify objects to process data on next. */ + LIST_FIELDS(struct inotify_data, buffered); +}; diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c index 66824c6c78..f0c58a589a 100644 --- a/src/libsystemd/sd-event/sd-event.c +++ b/src/libsystemd/sd-event/sd-event.c @@ -9,6 +9,7 @@ #include "sd-id128.h" #include "alloc-util.h" +#include "event-source.h" #include "fd-util.h" #include "fs-util.h" #include "hashmap.h" @@ -26,24 +27,6 @@ #define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC) -typedef enum EventSourceType { - SOURCE_IO, - SOURCE_TIME_REALTIME, - SOURCE_TIME_BOOTTIME, - SOURCE_TIME_MONOTONIC, - SOURCE_TIME_REALTIME_ALARM, - SOURCE_TIME_BOOTTIME_ALARM, - SOURCE_SIGNAL, - SOURCE_CHILD, - SOURCE_DEFER, - SOURCE_POST, - SOURCE_EXIT, - SOURCE_WATCHDOG, - SOURCE_INOTIFY, - _SOURCE_EVENT_SOURCE_TYPE_MAX, - _SOURCE_EVENT_SOURCE_TYPE_INVALID = -1 -} EventSourceType; - static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] = { [SOURCE_IO] = "io", [SOURCE_TIME_REALTIME] = "realtime", @@ -62,183 +45,8 @@ static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX] DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int); -/* All objects we use in epoll events start with this value, so that - * we know how to dispatch it */ -typedef enum WakeupType { - WAKEUP_NONE, - WAKEUP_EVENT_SOURCE, - WAKEUP_CLOCK_DATA, - WAKEUP_SIGNAL_DATA, - WAKEUP_INOTIFY_DATA, - _WAKEUP_TYPE_MAX, - _WAKEUP_TYPE_INVALID = -1, -} WakeupType; - #define EVENT_SOURCE_IS_TIME(t) IN_SET((t), SOURCE_TIME_REALTIME, SOURCE_TIME_BOOTTIME, SOURCE_TIME_MONOTONIC, SOURCE_TIME_REALTIME_ALARM, SOURCE_TIME_BOOTTIME_ALARM) -struct inode_data; - -struct sd_event_source { - WakeupType wakeup; - - unsigned n_ref; - - sd_event *event; - void *userdata; - sd_event_handler_t prepare; - - char *description; - - EventSourceType type:5; - signed int enabled:3; - bool pending:1; - bool dispatching:1; - bool floating:1; - - int64_t priority; - unsigned pending_index; - unsigned prepare_index; - uint64_t pending_iteration; - uint64_t prepare_iteration; - - sd_event_destroy_t destroy_callback; - - LIST_FIELDS(sd_event_source, sources); - - union { - struct { - sd_event_io_handler_t callback; - int fd; - uint32_t events; - uint32_t revents; - bool registered:1; - bool owned:1; - } io; - struct { - sd_event_time_handler_t callback; - usec_t next, accuracy; - unsigned earliest_index; - unsigned latest_index; - } time; - struct { - sd_event_signal_handler_t callback; - struct signalfd_siginfo siginfo; - int sig; - } signal; - struct { - sd_event_child_handler_t callback; - siginfo_t siginfo; - pid_t pid; - int options; - } child; - struct { - sd_event_handler_t callback; - } defer; - struct { - sd_event_handler_t callback; - } post; - struct { - sd_event_handler_t callback; - unsigned prioq_index; - } exit; - struct { - sd_event_inotify_handler_t callback; - uint32_t mask; - struct inode_data *inode_data; - LIST_FIELDS(sd_event_source, by_inode_data); - } inotify; - }; -}; - -struct clock_data { - WakeupType wakeup; - int fd; - - /* For all clocks we maintain two priority queues each, one - * ordered for the earliest times the events may be - * dispatched, and one ordered by the latest times they must - * have been dispatched. The range between the top entries in - * the two prioqs is the time window we can freely schedule - * wakeups in */ - - Prioq *earliest; - Prioq *latest; - usec_t next; - - bool needs_rearm:1; -}; - -struct signal_data { - WakeupType wakeup; - - /* For each priority we maintain one signal fd, so that we - * only have to dequeue a single event per priority at a - * time. */ - - int fd; - int64_t priority; - sigset_t sigset; - sd_event_source *current; -}; - -/* A structure listing all event sources currently watching a specific inode */ -struct inode_data { - /* The identifier for the inode, the combination of the .st_dev + .st_ino fields of the file */ - ino_t ino; - dev_t dev; - - /* An fd of the inode to watch. The fd is kept open until the next iteration of the loop, so that we can - * rearrange the priority still until then, as we need the original inode to change the priority as we need to - * add a watch descriptor to the right inotify for the priority which we can only do if we have a handle to the - * original inode. We keep a list of all inode_data objects with an open fd in the to_close list (see below) of - * the sd-event object, so that it is efficient to close everything, before entering the next event loop - * iteration. */ - int fd; - - /* The inotify "watch descriptor" */ - int wd; - - /* The combination of the mask of all inotify watches on this inode we manage. This is also the mask that has - * most recently been set on the watch descriptor. */ - uint32_t combined_mask; - - /* All event sources subscribed to this inode */ - LIST_HEAD(sd_event_source, event_sources); - - /* The inotify object we watch this inode with */ - struct inotify_data *inotify_data; - - /* A linked list of all inode data objects with fds to close (see above) */ - LIST_FIELDS(struct inode_data, to_close); -}; - -/* A structure encapsulating an inotify fd */ -struct inotify_data { - WakeupType wakeup; - - /* For each priority we maintain one inotify fd, so that we only have to dequeue a single event per priority at - * a time */ - - int fd; - int64_t priority; - - Hashmap *inodes; /* The inode_data structures keyed by dev+ino */ - Hashmap *wd; /* The inode_data structures keyed by the watch descriptor for each */ - - /* The buffer we read inotify events into */ - union inotify_event_buffer buffer; - size_t buffer_filled; /* fill level of the buffer */ - - /* How many event sources are currently marked pending for this inotify. We won't read new events off the - * inotify fd as long as there are still pending events on the inotify (because we have no strategy of queuing - * the events locally if they can't be coalesced). */ - unsigned n_pending; - - /* A linked list of all inotify objects with data already read, that still need processing. We keep this list - * to make it efficient to figure out what inotify objects to process data on next. */ - LIST_FIELDS(struct inotify_data, buffered); -}; - struct sd_event { unsigned n_ref; From 764c08e6b73644d73d3f88392bec9c08856c01d7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Nov 2018 17:32:20 +0900 Subject: [PATCH 02/19] sd-event: introduce event_reset_time() --- src/libsystemd/meson.build | 2 + src/libsystemd/sd-event/event-util.c | 82 ++++++++++++++++++++++++++++ src/libsystemd/sd-event/event-util.h | 11 ++++ 3 files changed, 95 insertions(+) create mode 100644 src/libsystemd/sd-event/event-util.c create mode 100644 src/libsystemd/sd-event/event-util.h diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 2208b6de12..071691327b 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -10,6 +10,8 @@ sd_daemon_c = files('sd-daemon/sd-daemon.c') sd_event_c = files(''' sd-event/event-source.h + sd-event/event-util.c + sd-event/event-util.h sd-event/sd-event.c '''.split()) diff --git a/src/libsystemd/sd-event/event-util.c b/src/libsystemd/sd-event/event-util.c new file mode 100644 index 0000000000..2da5592bd0 --- /dev/null +++ b/src/libsystemd/sd-event/event-util.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include + +#include "event-source.h" +#include "event-util.h" +#include "log.h" +#include "string-util.h" + +int event_reset_time( + sd_event *e, + sd_event_source **s, + clockid_t clock, + uint64_t usec, + uint64_t accuracy, + sd_event_time_handler_t callback, + void *userdata, + int64_t priority, + const char *description, + bool force_reset) { + + bool created = false; + int enabled, r; + clockid_t c; + + assert(e); + assert(s); + + if (*s) { + if (!force_reset) { + r = sd_event_source_get_enabled(*s, &enabled); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to query whether event source \"%s\" is enabled or not: %m", + strna((*s)->description ?: description)); + + if (enabled != SD_EVENT_OFF) + return 0; + } + + r = sd_event_source_get_time_clock(*s, &c); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to get clock id of event source \"%s\": %m", strna((*s)->description ?: description)); + + if (c != clock) + return log_debug_errno(EINVAL, "sd-event: Current clock id %i of event source \"%s\" is different from specified one %i.", + (int) c, strna((*s)->description ?: description), (int) clock); + + r = sd_event_source_set_time(*s, usec); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to set time for event source \"%s\": %m", strna((*s)->description ?: description)); + + r = sd_event_source_set_time_accuracy(*s, accuracy); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to set accuracy for event source \"%s\": %m", strna((*s)->description ?: description)); + + /* callback function is not updated, as we do not have sd_event_source_set_time_callback(). */ + + (void) sd_event_source_set_userdata(*s, userdata); + + r = sd_event_source_set_enabled(*s, SD_EVENT_ONESHOT); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to enable event source \"%s\": %m", strna((*s)->description ?: description)); + } else { + r = sd_event_add_time(e, s, clock, usec, accuracy, callback, userdata); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to create timer event \"%s\": %m", strna(description)); + + created = true; + } + + r = sd_event_source_set_priority(*s, priority); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to set priority for event source \"%s\": %m", strna((*s)->description ?: description)); + + if (description) { + r = sd_event_source_set_description(*s, description); + if (r < 0) + return log_debug_errno(r, "sd-event: Failed to set description for event source \"%s\": %m", description); + } + + return created; +} diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h new file mode 100644 index 0000000000..aa9411e2ff --- /dev/null +++ b/src/libsystemd/sd-event/event-util.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include + +#include "sd-event.h" + +int event_reset_time(sd_event *e, sd_event_source **s, + clockid_t clock, uint64_t usec, uint64_t accuracy, + sd_event_time_handler_t callback, void *userdata, + int64_t priority, const char *description, bool force_reset); From 2701983ce8ee0a6b6a4885ca7e2e8dd4c2586594 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 13:34:44 +0900 Subject: [PATCH 03/19] sd-event: introduce event_source_disable() --- src/libsystemd/sd-event/event-util.c | 7 +++++++ src/libsystemd/sd-event/event-util.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/libsystemd/sd-event/event-util.c b/src/libsystemd/sd-event/event-util.c index 2da5592bd0..4f3a2fec31 100644 --- a/src/libsystemd/sd-event/event-util.c +++ b/src/libsystemd/sd-event/event-util.c @@ -80,3 +80,10 @@ int event_reset_time( return created; } + +int event_source_disable(sd_event_source *s) { + if (!s) + return 0; + + return sd_event_source_set_enabled(s, SD_EVENT_OFF); +} diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h index aa9411e2ff..7f9cced5a3 100644 --- a/src/libsystemd/sd-event/event-util.h +++ b/src/libsystemd/sd-event/event-util.h @@ -9,3 +9,4 @@ int event_reset_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata, int64_t priority, const char *description, bool force_reset); +int event_source_disable(sd_event_source *s); From d44325cb96310b22f5fa629e83d7d36118e2e4c8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Nov 2018 07:02:35 +0900 Subject: [PATCH 04/19] sd-event: also introduce event_source_is_enabled() --- src/libsystemd/sd-event/event-util.c | 7 +++++++ src/libsystemd/sd-event/event-util.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/libsystemd/sd-event/event-util.c b/src/libsystemd/sd-event/event-util.c index 4f3a2fec31..488a0230ea 100644 --- a/src/libsystemd/sd-event/event-util.c +++ b/src/libsystemd/sd-event/event-util.c @@ -87,3 +87,10 @@ int event_source_disable(sd_event_source *s) { return sd_event_source_set_enabled(s, SD_EVENT_OFF); } + +int event_source_is_enabled(sd_event_source *s) { + if (!s) + return false; + + return sd_event_source_get_enabled(s, NULL); +} diff --git a/src/libsystemd/sd-event/event-util.h b/src/libsystemd/sd-event/event-util.h index 7f9cced5a3..00180955f9 100644 --- a/src/libsystemd/sd-event/event-util.h +++ b/src/libsystemd/sd-event/event-util.h @@ -10,3 +10,4 @@ int event_reset_time(sd_event *e, sd_event_source **s, sd_event_time_handler_t callback, void *userdata, int64_t priority, const char *description, bool force_reset); int event_source_disable(sd_event_source *s); +int event_source_is_enabled(sd_event_source *s); From 6d63048a777c253cd08b65bbd1291d52a040d0b2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 13:16:41 +0900 Subject: [PATCH 05/19] udevd: use event_reset_time() to update kill_workers_event --- src/udev/udevd.c | 48 ++++-------------------------------------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 409d32b8b5..982e1c221b 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -35,6 +35,7 @@ #include "cpu-set-util.h" #include "dev-setup.h" #include "device-util.h" +#include "event-util.h" #include "fd-util.h" #include "fileio.h" #include "format-util.h" @@ -764,49 +765,6 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda return 1; } -static int manager_enable_kill_workers_event(Manager *manager) { - int enabled, r; - - assert(manager); - - if (!manager->kill_workers_event) - goto create_new; - - r = sd_event_source_get_enabled(manager->kill_workers_event, &enabled); - if (r < 0) { - log_debug_errno(r, "Failed to query whether event source for killing idle workers is enabled or not, trying to create new event source: %m"); - manager->kill_workers_event = sd_event_source_unref(manager->kill_workers_event); - goto create_new; - } - - if (enabled == SD_EVENT_ONESHOT) - return 0; - - r = sd_event_source_set_time(manager->kill_workers_event, now(CLOCK_MONOTONIC) + 3 * USEC_PER_SEC); - if (r < 0) { - log_debug_errno(r, "Failed to set time to event source for killing idle workers, trying to create new event source: %m"); - manager->kill_workers_event = sd_event_source_unref(manager->kill_workers_event); - goto create_new; - } - - r = sd_event_source_set_enabled(manager->kill_workers_event, SD_EVENT_ONESHOT); - if (r < 0) { - log_debug_errno(r, "Failed to enable event source for killing idle workers, trying to create new event source: %m"); - manager->kill_workers_event = sd_event_source_unref(manager->kill_workers_event); - goto create_new; - } - - return 0; - -create_new: - r = sd_event_add_time(manager->event, &manager->kill_workers_event, CLOCK_MONOTONIC, - now(CLOCK_MONOTONIC) + 3 * USEC_PER_SEC, USEC_PER_SEC, on_kill_workers_event, manager); - if (r < 0) - return log_warning_errno(r, "Failed to create timer event for killing idle workers: %m"); - - return 0; -} - static int manager_disable_kill_workers_event(Manager *manager) { int r; @@ -1334,7 +1292,9 @@ static int on_post(sd_event_source *s, void *userdata) { if (!hashmap_isempty(manager->workers)) { /* There are idle workers */ - (void) manager_enable_kill_workers_event(manager); + (void) event_reset_time(manager->event, &manager->kill_workers_event, CLOCK_MONOTONIC, + now(CLOCK_MONOTONIC) + 3 * USEC_PER_SEC, USEC_PER_SEC, + on_kill_workers_event, manager, 0, "kill-workers-event", false); return 1; } From 0725c4b9d1afd67f6501048d2e15c59709b1ff3c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 13:37:17 +0900 Subject: [PATCH 06/19] udevd: use event_source_disable() --- src/udev/udevd.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 982e1c221b..de7b035125 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -765,22 +765,10 @@ static int on_kill_workers_event(sd_event_source *s, uint64_t usec, void *userda return 1; } -static int manager_disable_kill_workers_event(Manager *manager) { - int r; - - if (!manager->kill_workers_event) - return 0; - - r = sd_event_source_set_enabled(manager->kill_workers_event, SD_EVENT_OFF); - if (r < 0) - return log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); - - return 0; -} - static void event_queue_start(Manager *manager) { struct event *event; usec_t usec; + int r; assert(manager); @@ -799,7 +787,9 @@ static void event_queue_start(Manager *manager) { manager->last_usec = usec; } - (void) manager_disable_kill_workers_event(manager); + r = event_source_disable(manager->kill_workers_event); + if (r < 0) + log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); udev_builtin_init(); @@ -1169,10 +1159,13 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda union inotify_event_buffer buffer; struct inotify_event *e; ssize_t l; + int r; assert(manager); - (void) manager_disable_kill_workers_event(manager); + r = event_source_disable(manager->kill_workers_event); + if (r < 0) + log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); l = read(fd, &buffer, sizeof(buffer)); if (l < 0) { @@ -1224,6 +1217,7 @@ static int on_sighup(sd_event_source *s, const struct signalfd_siginfo *si, void static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { Manager *manager = userdata; + int r; assert(manager); @@ -1274,8 +1268,11 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi event_queue_start(manager); /* Disable unnecessary cleanup event */ - if (hashmap_isempty(manager->workers) && manager->kill_workers_event) - (void) sd_event_source_set_enabled(manager->kill_workers_event, SD_EVENT_OFF); + if (hashmap_isempty(manager->workers)) { + r = event_source_disable(manager->kill_workers_event); + if (r < 0) + log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); + } return 1; } From be6bf4a786d36e9bce52b0efa81abb97abc35522 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 13:49:12 +0900 Subject: [PATCH 07/19] dhcp-client: use structured initializer at one more place --- src/libsystemd-network/sd-dhcp-client.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index c538362488..ee2b80018c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1982,19 +1982,20 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) { assert_return(ret, -EINVAL); - client = new0(sd_dhcp_client, 1); + client = new(sd_dhcp_client, 1); if (!client) return -ENOMEM; - client->n_ref = 1; - client->state = DHCP_STATE_INIT; - client->ifindex = -1; - client->fd = -1; - client->attempt = 1; - client->mtu = DHCP_DEFAULT_MIN_SIZE; - client->port = DHCP_PORT_CLIENT; - - client->anonymize = !!anonymize; + *client = (sd_dhcp_client) { + .n_ref = 1, + .state = DHCP_STATE_INIT, + .ifindex = -1, + .fd = -1, + .attempt = 1, + .mtu = DHCP_DEFAULT_MIN_SIZE, + .port = DHCP_PORT_CLIENT, + .anonymize = !!anonymize, + }; /* NOTE: this could be moved to a function. */ if (anonymize) { client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize); From a3fa4287f5c1273ede6735979262da1f70db82ff Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 13:50:08 +0900 Subject: [PATCH 08/19] dhcp-client: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-dhcp-client.c | 159 +++++++----------------- 1 file changed, 47 insertions(+), 112 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index ee2b80018c..df9428518f 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -21,6 +21,7 @@ #include "dhcp-lease-internal.h" #include "dhcp-protocol.h" #include "dns-domain.h" +#include "event-util.h" #include "hostname-util.h" #include "random-util.h" #include "string-util.h" @@ -546,11 +547,10 @@ static int client_initialize(sd_dhcp_client *client) { client->fd = asynchronous_close(client->fd); - client->timeout_resend = sd_event_source_unref(client->timeout_resend); - - client->timeout_t1 = sd_event_source_unref(client->timeout_t1); - client->timeout_t2 = sd_event_source_unref(client->timeout_t2); - client->timeout_expire = sd_event_source_unref(client->timeout_expire); + (void) event_source_disable(client->timeout_resend); + (void) event_source_disable(client->timeout_t1); + (void) event_source_disable(client->timeout_t2); + (void) event_source_disable(client->timeout_expire); client->attempt = 1; @@ -1065,22 +1065,11 @@ static int client_timeout_resend( next_timeout += (random_u32() & 0x1fffff); - client->timeout_resend = sd_event_source_unref(client->timeout_resend); - - r = sd_event_add_time(client->event, - &client->timeout_resend, - clock_boottime_or_monotonic(), - next_timeout, 10 * USEC_PER_MSEC, - client_timeout_resend, client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_resend, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); + r = event_reset_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + next_timeout, 10 * USEC_PER_MSEC, + client_timeout_resend, client, + client->event_priority, "dhcp4-resend-timer", true); if (r < 0) goto error; @@ -1177,31 +1166,16 @@ static int client_initialize_time_events(sd_dhcp_client *client) { assert(client); assert(client->event); - client->timeout_resend = sd_event_source_unref(client->timeout_resend); - if (client->start_delay) { assert_se(sd_event_now(client->event, clock_boottime_or_monotonic(), &usec) >= 0); usec += client->start_delay; } - r = sd_event_add_time(client->event, - &client->timeout_resend, - clock_boottime_or_monotonic(), - usec, 0, - client_timeout_resend, client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_resend, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); - if (r < 0) - goto error; - -error: + r = event_reset_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + usec, 0, + client_timeout_resend, client, + client->event_priority, "dhcp4-resend-timer", true); if (r < 0) client_stop(client, r); @@ -1459,13 +1433,14 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { assert(client->lease); assert(client->lease->lifetime); - client->timeout_t1 = sd_event_source_unref(client->timeout_t1); - client->timeout_t2 = sd_event_source_unref(client->timeout_t2); - client->timeout_expire = sd_event_source_unref(client->timeout_expire); - /* don't set timers for infinite leases */ - if (client->lease->lifetime == 0xffffffff) + if (client->lease->lifetime == 0xffffffff) { + (void) event_source_disable(client->timeout_t1); + (void) event_source_disable(client->timeout_t2); + (void) event_source_disable(client->timeout_expire); + return 0; + } r = sd_event_now(client->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) @@ -1517,19 +1492,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { } /* arm lifetime timeout */ - r = sd_event_add_time(client->event, &client->timeout_expire, - clock_boottime_or_monotonic(), - lifetime_timeout, 10 * USEC_PER_MSEC, - client_timeout_expire, client); - if (r < 0) - return r; - - r = sd_event_source_set_priority(client->timeout_expire, - client->event_priority); - if (r < 0) - return r; - - r = sd_event_source_set_description(client->timeout_expire, "dhcp4-lifetime"); + r = event_reset_time(client->event, &client->timeout_expire, + clock_boottime_or_monotonic(), + lifetime_timeout, 10 * USEC_PER_MSEC, + client_timeout_expire, client, + client->event_priority, "dhcp4-lifetime", true); if (r < 0) return r; @@ -1541,21 +1508,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { return 0; /* arm T2 timeout */ - r = sd_event_add_time(client->event, - &client->timeout_t2, - clock_boottime_or_monotonic(), - t2_timeout, - 10 * USEC_PER_MSEC, - client_timeout_t2, client); - if (r < 0) - return r; - - r = sd_event_source_set_priority(client->timeout_t2, - client->event_priority); - if (r < 0) - return r; - - r = sd_event_source_set_description(client->timeout_t2, "dhcp4-t2-timeout"); + r = event_reset_time(client->event, &client->timeout_t2, + clock_boottime_or_monotonic(), + t2_timeout, 10 * USEC_PER_MSEC, + client_timeout_t2, client, + client->event_priority, "dhcp4-t2-timeout", true); if (r < 0) return r; @@ -1567,20 +1524,11 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) { return 0; /* arm T1 timeout */ - r = sd_event_add_time(client->event, - &client->timeout_t1, - clock_boottime_or_monotonic(), - t1_timeout, 10 * USEC_PER_MSEC, - client_timeout_t1, client); - if (r < 0) - return r; - - r = sd_event_source_set_priority(client->timeout_t1, - client->event_priority); - if (r < 0) - return r; - - r = sd_event_source_set_description(client->timeout_t1, "dhcp4-t1-timer"); + r = event_reset_time(client->event, &client->timeout_t1, + clock_boottime_or_monotonic(), + t1_timeout, 10 * USEC_PER_MSEC, + client_timeout_t1, client, + client->event_priority, "dhcp4-t1-timer", true); if (r < 0) return r; @@ -1605,26 +1553,14 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i r = client_handle_offer(client, message, len); if (r >= 0) { - client->timeout_resend = - sd_event_source_unref(client->timeout_resend); - client->state = DHCP_STATE_REQUESTING; client->attempt = 1; - r = sd_event_add_time(client->event, - &client->timeout_resend, - clock_boottime_or_monotonic(), - 0, 0, - client_timeout_resend, client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_resend, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend, "dhcp4-resend-timer"); + r = event_reset_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + 0, 0, + client_timeout_resend, client, + client->event_priority, "dhcp4-resend-timer", true); if (r < 0) goto error; } else if (r == -ENOMSG) @@ -1641,8 +1577,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i r = client_handle_ack(client, message, len); if (r >= 0) { client->start_delay = 0; - client->timeout_resend = - sd_event_source_unref(client->timeout_resend); + (void) event_source_disable(client->timeout_resend); client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); @@ -1682,9 +1617,6 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i } else if (r == -EADDRNOTAVAIL) { /* got a NAK, let's restart the client */ - client->timeout_resend = - sd_event_source_unref(client->timeout_resend); - client_notify(client, SD_DHCP_CLIENT_EVENT_EXPIRED); r = client_initialize(client); @@ -1960,9 +1892,12 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) { log_dhcp_client(client, "FREE"); - client_initialize(client); + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + client->timeout_expire = sd_event_source_unref(client->timeout_expire); - client->receive_message = sd_event_source_unref(client->receive_message); + client_initialize(client); sd_dhcp_client_detach_event(client); From a5f07d2a16912a4c7151ab262aa43941f519926d Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 16 Nov 2018 07:09:43 +0900 Subject: [PATCH 09/19] sd-dhcp6: fix crash by unrefing event sources before re-adding them In certain cases the timeouts may not have been unref'ed before they need to be re-added. Add the appropriate unref calls to ensure we don't register the timeout multiple times. This fixes possible cases where timeouts are triggered multiple times and even on destroyed DHCPv6 clients. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/73 Fixes #10749. --- src/libsystemd-network/sd-dhcp6-client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 15aece87d8..ac21afbb17 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1332,6 +1332,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { log_dhcp6_client(client, "T1 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); r = sd_event_add_time(client->event, &client->timeout_t1, clock_boottime_or_monotonic(), time_now + timeout, @@ -1354,6 +1355,7 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { log_dhcp6_client(client, "T2 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); r = sd_event_add_time(client->event, &client->timeout_t2, clock_boottime_or_monotonic(), time_now + timeout, From 8b8ecac85bd41e94742e62f3d2fa03fabee586b5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:04:37 +0900 Subject: [PATCH 10/19] dhcp6-client: use structured initializer at one more place --- src/libsystemd-network/sd-dhcp6-client.c | 34 +++++++++++++----------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index ac21afbb17..1e8c0a1317 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -1520,28 +1520,32 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp6_client, sd_dhcp6_client, dhcp6_client_fre int sd_dhcp6_client_new(sd_dhcp6_client **ret) { _cleanup_(sd_dhcp6_client_unrefp) sd_dhcp6_client *client = NULL; + _cleanup_free_ be16_t *req_opts = NULL; size_t t; assert_return(ret, -EINVAL); - client = new0(sd_dhcp6_client, 1); + req_opts = new(be16_t, ELEMENTSOF(default_req_opts)); + if (!req_opts) + return -ENOMEM; + + for (t = 0; t < ELEMENTSOF(default_req_opts); t++) + req_opts[t] = htobe16(default_req_opts[t]); + + client = new(sd_dhcp6_client, 1); if (!client) return -ENOMEM; - client->n_ref = 1; - client->ia_na.type = SD_DHCP6_OPTION_IA_NA; - client->ia_pd.type = SD_DHCP6_OPTION_IA_PD; - client->ifindex = -1; - client->request = DHCP6_REQUEST_IA_NA; - client->fd = -1; - - client->req_opts_len = ELEMENTSOF(default_req_opts); - client->req_opts = new0(be16_t, client->req_opts_len); - if (!client->req_opts) - return -ENOMEM; - - for (t = 0; t < client->req_opts_len; t++) - client->req_opts[t] = htobe16(default_req_opts[t]); + *client = (sd_dhcp6_client) { + .n_ref = 1, + .ia_na.type = SD_DHCP6_OPTION_IA_NA, + .ia_pd.type = SD_DHCP6_OPTION_IA_PD, + .ifindex = -1, + .request = DHCP6_REQUEST_IA_NA, + .fd = -1, + .req_opts_len = ELEMENTSOF(default_req_opts), + .req_opts = TAKE_PTR(req_opts), + }; *ret = TAKE_PTR(client); From c9393e8c41c7ce24734623e378e23d895c7cbb5b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:05:07 +0900 Subject: [PATCH 11/19] dhcp6-client: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-dhcp6-client.c | 128 ++++++++--------------- 1 file changed, 42 insertions(+), 86 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 1e8c0a1317..c81c0f0955 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -16,6 +16,7 @@ #include "dhcp6-lease-internal.h" #include "dhcp6-protocol.h" #include "dns-domain.h" +#include "event-util.h" #include "fd-util.h" #include "hostname-util.h" #include "in-addr-util.h" @@ -408,12 +409,11 @@ static int client_reset(sd_dhcp6_client *client) { client->retransmit_time = 0; client->retransmit_count = 0; - client->timeout_resend = sd_event_source_unref(client->timeout_resend); - client->timeout_resend_expire = - sd_event_source_unref(client->timeout_resend_expire); - client->timeout_t1 = sd_event_source_unref(client->timeout_t1); - client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + (void) event_source_disable(client->timeout_resend); + (void) event_source_disable(client->timeout_resend_expire); + (void) event_source_disable(client->timeout_t1); + (void) event_source_disable(client->timeout_t2); client->state = DHCP6_STATE_STOPPED; @@ -600,8 +600,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) assert(client); assert(client->lease); - client->timeout_t2 = - sd_event_source_unref(client->timeout_t2); + (void) event_source_disable(client->timeout_t2); log_dhcp6_client(client, "Timeout T2"); @@ -617,8 +616,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) assert(client); assert(client->lease); - client->timeout_t1 = - sd_event_source_unref(client->timeout_t1); + (void) event_source_disable(client->timeout_t1); log_dhcp6_client(client, "Timeout T1"); @@ -666,7 +664,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda assert(client); assert(client->event); - client->timeout_resend = sd_event_source_unref(client->timeout_resend); + (void) event_source_disable(client->timeout_resend); switch (client->state) { case DHCP6_STATE_INFORMATION_REQUEST: @@ -708,7 +706,7 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda init_retransmit_time = DHCP6_REB_TIMEOUT; max_retransmit_time = DHCP6_REB_MAX_RT; - if (!client->timeout_resend_expire) { + if (event_source_is_enabled(client->timeout_resend_expire) <= 0) { r = dhcp6_lease_ia_rebind_expire(&client->lease->ia, &expire); if (r < 0) { @@ -757,43 +755,24 @@ static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userda log_dhcp6_client(client, "Next retransmission in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, client->retransmit_time, USEC_PER_SEC)); - r = sd_event_add_time(client->event, &client->timeout_resend, - clock_boottime_or_monotonic(), - time_now + client->retransmit_time, - 10 * USEC_PER_MSEC, client_timeout_resend, - client); + r = event_reset_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + time_now + client->retransmit_time, 10 * USEC_PER_MSEC, + client_timeout_resend, client, + client->event_priority, "dhcp6-resend-timer", true); if (r < 0) goto error; - r = sd_event_source_set_priority(client->timeout_resend, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timer"); - if (r < 0) - goto error; - - if (max_retransmit_duration && !client->timeout_resend_expire) { + if (max_retransmit_duration && event_source_is_enabled(client->timeout_resend_expire) <= 0) { log_dhcp6_client(client, "Max retransmission duration %"PRIu64" secs", max_retransmit_duration / USEC_PER_SEC); - r = sd_event_add_time(client->event, - &client->timeout_resend_expire, - clock_boottime_or_monotonic(), - time_now + max_retransmit_duration, - USEC_PER_SEC, - client_timeout_resend_expire, client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_resend_expire, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend_expire, "dhcp6-resend-expire-timer"); + r = event_reset_time(client->event, &client->timeout_resend_expire, + clock_boottime_or_monotonic(), + time_now + max_retransmit_duration, USEC_PER_SEC, + client_timeout_resend_expire, client, + client->event_priority, "dhcp6-resend-expire-timer", true); if (r < 0) goto error; } @@ -1263,9 +1242,8 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { assert_return(client->ifindex > 0, -EINVAL); assert_return(client->state != state, -EINVAL); - client->timeout_resend_expire = - sd_event_source_unref(client->timeout_resend_expire); - client->timeout_resend = sd_event_source_unref(client->timeout_resend); + (void) event_source_disable(client->timeout_resend_expire); + (void) event_source_disable(client->timeout_resend); client->retransmit_time = 0; client->retransmit_count = 0; @@ -1332,21 +1310,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { log_dhcp6_client(client, "T1 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); - client->timeout_t1 = sd_event_source_unref(client->timeout_t1); - r = sd_event_add_time(client->event, - &client->timeout_t1, - clock_boottime_or_monotonic(), time_now + timeout, - 10 * USEC_PER_SEC, client_timeout_t1, - client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_t1, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_t1, "dhcp6-t1-timeout"); + r = event_reset_time(client->event, &client->timeout_t1, + clock_boottime_or_monotonic(), + time_now + timeout, 10 * USEC_PER_SEC, + client_timeout_t1, client, + client->event_priority, "dhcp6-t1-timeout", true); if (r < 0) goto error; @@ -1355,21 +1323,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { log_dhcp6_client(client, "T2 expires in %s", format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); - client->timeout_t2 = sd_event_source_unref(client->timeout_t2); - r = sd_event_add_time(client->event, - &client->timeout_t2, - clock_boottime_or_monotonic(), time_now + timeout, - 10 * USEC_PER_SEC, client_timeout_t2, - client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_t2, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_t2, "dhcp6-t2-timeout"); + r = event_reset_time(client->event, &client->timeout_t2, + clock_boottime_or_monotonic(), + time_now + timeout, 10 * USEC_PER_SEC, + client_timeout_t2, client, + client->event_priority, "dhcp6-t2-timeout", true); if (r < 0) goto error; @@ -1381,18 +1339,11 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) { client->transaction_id = random_u32() & htobe32(0x00ffffff); client->transaction_start = time_now; - r = sd_event_add_time(client->event, &client->timeout_resend, - clock_boottime_or_monotonic(), 0, 0, client_timeout_resend, - client); - if (r < 0) - goto error; - - r = sd_event_source_set_priority(client->timeout_resend, - client->event_priority); - if (r < 0) - goto error; - - r = sd_event_source_set_description(client->timeout_resend, "dhcp6-resend-timeout"); + r = event_reset_time(client->event, &client->timeout_resend, + clock_boottime_or_monotonic(), + 0, 0, + client_timeout_resend, client, + client->event_priority, "dhcp6-resend-timeout", true); if (r < 0) goto error; @@ -1505,6 +1456,11 @@ sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client) { static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) { assert(client); + client->timeout_resend = sd_event_source_unref(client->timeout_resend); + client->timeout_resend_expire = sd_event_source_unref(client->timeout_resend_expire); + client->timeout_t1 = sd_event_source_unref(client->timeout_t1); + client->timeout_t2 = sd_event_source_unref(client->timeout_t2); + client_reset(client); client->fd = safe_close(client->fd); From 4ca5acb35f0b698f11d27aa6dce3e8b87568fc9a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:17:20 +0900 Subject: [PATCH 12/19] ipv4acd: use structured initializer at one more place --- src/libsystemd-network/sd-ipv4acd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index 6c12b5144e..b9081a4a43 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -113,14 +113,16 @@ int sd_ipv4acd_new(sd_ipv4acd **ret) { assert_return(ret, -EINVAL); - acd = new0(sd_ipv4acd, 1); + acd = new(sd_ipv4acd, 1); if (!acd) return -ENOMEM; - acd->n_ref = 1; - acd->state = IPV4ACD_STATE_INIT; - acd->ifindex = -1; - acd->fd = -1; + *acd = (sd_ipv4acd) { + .n_ref = 1, + .state = IPV4ACD_STATE_INIT, + .ifindex = -1, + .fd = -1, + }; *ret = TAKE_PTR(acd); From 32ab66c5eec1d2e680161060584aadea3922e0f9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:18:41 +0900 Subject: [PATCH 13/19] ipv4acd: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-ipv4acd.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c index b9081a4a43..59359aec79 100644 --- a/src/libsystemd-network/sd-ipv4acd.c +++ b/src/libsystemd-network/sd-ipv4acd.c @@ -14,6 +14,7 @@ #include "alloc-util.h" #include "arp-util.h" #include "ether-addr-util.h" +#include "event-util.h" #include "fd-util.h" #include "in-addr-util.h" #include "list.h" @@ -89,7 +90,7 @@ static void ipv4acd_set_state(sd_ipv4acd *acd, IPv4ACDState st, bool reset_count static void ipv4acd_reset(sd_ipv4acd *acd) { assert(acd); - acd->timer_event_source = sd_event_source_unref(acd->timer_event_source); + (void) event_source_disable(acd->timer_event_source); acd->receive_message_event_source = sd_event_source_unref(acd->receive_message_event_source); acd->fd = safe_close(acd->fd); @@ -100,6 +101,8 @@ static void ipv4acd_reset(sd_ipv4acd *acd) { static sd_ipv4acd *ipv4acd_free(sd_ipv4acd *acd) { assert(acd); + acd->timer_event_source = sd_event_source_unref(acd->timer_event_source); + ipv4acd_reset(acd); sd_ipv4acd_detach_event(acd); @@ -153,9 +156,7 @@ int sd_ipv4acd_stop(sd_ipv4acd *acd) { static int ipv4acd_on_timeout(sd_event_source *s, uint64_t usec, void *userdata); static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_usec) { - _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL; usec_t next_timeout, time_now; - int r; assert(acd); @@ -166,20 +167,11 @@ static int ipv4acd_set_next_wakeup(sd_ipv4acd *acd, usec_t usec, usec_t random_u assert_se(sd_event_now(acd->event, clock_boottime_or_monotonic(), &time_now) >= 0); - r = sd_event_add_time(acd->event, &timer, clock_boottime_or_monotonic(), time_now + next_timeout, 0, ipv4acd_on_timeout, acd); - if (r < 0) - return r; - - r = sd_event_source_set_priority(timer, acd->event_priority); - if (r < 0) - return r; - - (void) sd_event_source_set_description(timer, "ipv4acd-timer"); - - sd_event_source_unref(acd->timer_event_source); - acd->timer_event_source = TAKE_PTR(timer); - - return 0; + return event_reset_time(acd->event, &acd->timer_event_source, + clock_boottime_or_monotonic(), + time_now + next_timeout, 0, + ipv4acd_on_timeout, acd, + acd->event_priority, "ipv4acd-timer", true); } static bool ipv4acd_arp_conflict(sd_ipv4acd *acd, struct ether_arp *arp) { From 8158b90d5967b195c73368e71eb17a465a20cdde Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:26:00 +0900 Subject: [PATCH 14/19] lldp: use structured initializer at one more place --- src/libsystemd-network/sd-lldp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index 993ca13727..ffc6db030c 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -361,14 +361,16 @@ _public_ int sd_lldp_new(sd_lldp **ret) { assert_return(ret, -EINVAL); - lldp = new0(sd_lldp, 1); + lldp = new(sd_lldp, 1); if (!lldp) return -ENOMEM; - lldp->n_ref = 1; - lldp->fd = -1; - lldp->neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX; - lldp->capability_mask = (uint16_t) -1; + *lldp = (sd_lldp) { + .n_ref = 1, + .fd = -1, + .neighbors_max = LLDP_DEFAULT_NEIGHBORS_MAX, + .capability_mask = (uint16_t) -1, + }; lldp->neighbor_by_id = hashmap_new(&lldp_neighbor_id_hash_ops); if (!lldp->neighbor_by_id) From 6ec11d46dc368a2a2385af148161dfe66eda860f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:26:33 +0900 Subject: [PATCH 15/19] lldp: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-lldp.c | 38 +++++++++----------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index ffc6db030c..4e3ee53cd7 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -7,6 +7,7 @@ #include "alloc-util.h" #include "ether-addr-util.h" +#include "event-util.h" #include "fd-util.h" #include "lldp-internal.h" #include "lldp-neighbor.h" @@ -235,7 +236,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v static void lldp_reset(sd_lldp *lldp) { assert(lldp); - lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source); + (void) event_source_disable(lldp->timer_event_source); lldp->io_event_source = sd_event_source_unref(lldp->io_event_source); lldp->fd = safe_close(lldp->fd); } @@ -344,6 +345,8 @@ _public_ int sd_lldp_set_ifindex(sd_lldp *lldp, int ifindex) { static sd_lldp* lldp_free(sd_lldp *lldp) { assert(lldp); + lldp->timer_event_source = sd_event_source_unref(lldp->timer_event_source); + lldp_reset(lldp); sd_lldp_detach_event(lldp); lldp_flush_neighbors(lldp); @@ -406,7 +409,6 @@ static int on_timer_event(sd_event_source *s, uint64_t usec, void *userdata) { static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) { sd_lldp_neighbor *n; - int r; assert(lldp); @@ -414,35 +416,17 @@ static int lldp_start_timer(sd_lldp *lldp, sd_lldp_neighbor *neighbor) { lldp_neighbor_start_ttl(neighbor); n = prioq_peek(lldp->neighbor_by_expiry); - if (!n) { - - if (lldp->timer_event_source) - return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_OFF); - - return 0; - } - - if (lldp->timer_event_source) { - r = sd_event_source_set_time(lldp->timer_event_source, n->until); - if (r < 0) - return r; - - return sd_event_source_set_enabled(lldp->timer_event_source, SD_EVENT_ONESHOT); - } + if (!n) + return event_source_disable(lldp->timer_event_source); if (!lldp->event) return 0; - r = sd_event_add_time(lldp->event, &lldp->timer_event_source, clock_boottime_or_monotonic(), n->until, 0, on_timer_event, lldp); - if (r < 0) - return r; - - r = sd_event_source_set_priority(lldp->timer_event_source, lldp->event_priority); - if (r < 0) - return r; - - (void) sd_event_source_set_description(lldp->timer_event_source, "lldp-timer"); - return 0; + return event_reset_time(lldp->event, &lldp->timer_event_source, + clock_boottime_or_monotonic(), + n->until, 0, + on_timer_event, lldp, + lldp->event_priority, "lldp-timer", true); } _public_ int sd_lldp_get_neighbors(sd_lldp *lldp, sd_lldp_neighbor ***ret) { From 78f9d24f7b2c4818d7f5079f389c508744b4a961 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:28:16 +0900 Subject: [PATCH 16/19] sd-radv: use structured initializer at one more place --- src/libsystemd-network/sd-radv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 89c5a33497..2f4a5c03fa 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -27,14 +27,14 @@ _public_ int sd_radv_new(sd_radv **ret) { assert_return(ret, -EINVAL); - ra = new0(sd_radv, 1); + ra = new(sd_radv, 1); if (!ra) return -ENOMEM; - ra->n_ref = 1; - ra->fd = -1; - - LIST_HEAD_INIT(ra->prefixes); + *ra = (sd_radv) { + .n_ref = 1, + .fd = -1, + }; *ret = TAKE_PTR(ra); From 807a8edeb16ca34a607e25bbc1556be14131a4e0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:32:12 +0900 Subject: [PATCH 17/19] sd-radv: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-radv.c | 48 +++++++++++--------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index 2f4a5c03fa..ffe22faac3 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -12,6 +12,7 @@ #include "macro.h" #include "alloc-util.h" #include "dns-domain.h" +#include "event-util.h" #include "fd-util.h" #include "icmp6-util.h" #include "in-addr-util.h" @@ -77,8 +78,7 @@ _public_ sd_event *sd_radv_get_event(sd_radv *ra) { static void radv_reset(sd_radv *ra) { assert(ra); - ra->timeout_event_source = - sd_event_source_unref(ra->timeout_event_source); + (void) event_source_disable(ra->timeout_event_source); ra->recv_event_source = sd_event_source_unref(ra->recv_event_source); @@ -99,6 +99,8 @@ static sd_radv *radv_free(sd_radv *ra) { free(ra->rdnss); free(ra->dnssl); + ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source); + radv_reset(ra); sd_radv_detach_event(ra); @@ -289,8 +291,6 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) { assert(ra); assert(ra->event); - ra->timeout_event_source = sd_event_source_unref(ra->timeout_event_source); - r = sd_event_now(ra->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) goto fail; @@ -311,28 +311,20 @@ static int radv_timeout(sd_event_source *s, uint64_t usec, void *userdata) { format_timespan(time_string, FORMAT_TIMESPAN_MAX, timeout, USEC_PER_SEC)); - r = sd_event_add_time(ra->event, &ra->timeout_event_source, - clock_boottime_or_monotonic(), - time_now + timeout, MSEC_PER_SEC, - radv_timeout, ra); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(ra->timeout_event_source, - ra->event_priority); - if (r < 0) - goto fail; - - r = sd_event_source_set_description(ra->timeout_event_source, - "radv-timeout"); + r = event_reset_time(ra->event, &ra->timeout_event_source, + clock_boottime_or_monotonic(), + time_now + timeout, MSEC_PER_SEC, + radv_timeout, ra, + ra->event_priority, "radv-timeout", true); if (r < 0) goto fail; ra->ra_sent++; + return 0; + fail: - if (r < 0) - sd_radv_stop(ra); + sd_radv_stop(ra); return 0; } @@ -370,20 +362,14 @@ _public_ int sd_radv_start(sd_radv *ra) { if (ra->state != SD_RADV_STATE_IDLE) return 0; - r = sd_event_add_time(ra->event, &ra->timeout_event_source, - clock_boottime_or_monotonic(), 0, 0, - radv_timeout, ra); + r = event_reset_time(ra->event, &ra->timeout_event_source, + clock_boottime_or_monotonic(), + 0, 0, + radv_timeout, ra, + ra->event_priority, "radv-timeout", true); if (r < 0) goto fail; - r = sd_event_source_set_priority(ra->timeout_event_source, - ra->event_priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(ra->timeout_event_source, - "radv-timeout"); - r = icmp6_bind_router_advertisement(ra->ifindex); if (r < 0) goto fail; From 144faa8ea505158d2d8a3fd9bbe58addefd05077 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:33:41 +0900 Subject: [PATCH 18/19] sd-ndisc: use structured initializer at one more place --- src/libsystemd-network/sd-ndisc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index b2fd087987..6715f72d34 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -136,12 +136,14 @@ _public_ int sd_ndisc_new(sd_ndisc **ret) { assert_return(ret, -EINVAL); - nd = new0(sd_ndisc, 1); + nd = new(sd_ndisc, 1); if (!nd) return -ENOMEM; - nd->n_ref = 1; - nd->fd = -1; + *nd = (sd_ndisc) { + .n_ref = 1, + .fd = -1, + }; *ret = TAKE_PTR(nd); From ff4b0321067a322009c79ad3a56d6ea549d7d25a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 13 Nov 2018 14:40:02 +0900 Subject: [PATCH 19/19] sd-ndisc: do not unref() event sources when update or disable them --- src/libsystemd-network/sd-ndisc.c | 65 ++++++++++++------------------- 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/src/libsystemd-network/sd-ndisc.c b/src/libsystemd-network/sd-ndisc.c index 6715f72d34..79b2ea8bf2 100644 --- a/src/libsystemd-network/sd-ndisc.c +++ b/src/libsystemd-network/sd-ndisc.c @@ -9,6 +9,7 @@ #include "sd-ndisc.h" #include "alloc-util.h" +#include "event-util.h" #include "fd-util.h" #include "icmp6-util.h" #include "in-addr-util.h" @@ -114,8 +115,8 @@ _public_ sd_event *sd_ndisc_get_event(sd_ndisc *nd) { static void ndisc_reset(sd_ndisc *nd) { assert(nd); - nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); - nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra); + (void) event_source_disable(nd->timeout_event_source); + (void) event_source_disable(nd->timeout_no_ra); nd->retransmit_time = 0; nd->recv_event_source = sd_event_source_unref(nd->recv_event_source); nd->fd = safe_close(nd->fd); @@ -124,6 +125,9 @@ static void ndisc_reset(sd_ndisc *nd) { static sd_ndisc *ndisc_free(sd_ndisc *nd) { assert(nd); + nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); + nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra); + ndisc_reset(nd); sd_ndisc_detach_event(nd); return mfree(nd); @@ -246,7 +250,7 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda return 0; } - nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); + (void) event_source_disable(nd->timeout_event_source); return ndisc_handle_datagram(nd, rt); } @@ -258,10 +262,10 @@ static usec_t ndisc_timeout_compute_random(usec_t val) { } static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) { + char time_string[FORMAT_TIMESPAN_MAX]; sd_ndisc *nd = userdata; usec_t time_now; int r; - char time_string[FORMAT_TIMESPAN_MAX]; assert(s); assert(nd); @@ -269,8 +273,6 @@ static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) { assert_se(sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now) >= 0); - nd->timeout_event_source = sd_event_source_unref(nd->timeout_event_source); - if (!nd->retransmit_time) nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL); else { @@ -280,25 +282,14 @@ static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) { nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time); } - r = sd_event_add_time(nd->event, &nd->timeout_event_source, - clock_boottime_or_monotonic(), - time_now + nd->retransmit_time, - 10 * USEC_PER_MSEC, ndisc_timeout, nd); + r = event_reset_time(nd->event, &nd->timeout_event_source, + clock_boottime_or_monotonic(), + time_now + nd->retransmit_time, 10 * USEC_PER_MSEC, + ndisc_timeout, nd, + nd->event_priority, "ndisc-timeout-no-ra", true); if (r < 0) goto fail; - r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout-no-ra"); - - r = sd_event_source_set_enabled(nd->timeout_event_source, SD_EVENT_ONESHOT); - if (r < 0) { - log_ndisc_errno(r, "Error reenabling timer: %m"); - goto fail; - } - r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr); if (r < 0) { log_ndisc_errno(r, "Error sending Router Solicitation: %m"); @@ -324,7 +315,7 @@ static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata log_ndisc("No RA received before link confirmation timeout"); - nd->timeout_no_ra = sd_event_source_unref(nd->timeout_no_ra); + (void) event_source_disable(nd->timeout_no_ra); ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL); return 0; @@ -354,7 +345,6 @@ _public_ int sd_ndisc_start(sd_ndisc *nd) { return 0; assert(!nd->recv_event_source); - assert(!nd->timeout_event_source); r = sd_event_now(nd->event, clock_boottime_or_monotonic(), &time_now); if (r < 0) @@ -374,29 +364,22 @@ _public_ int sd_ndisc_start(sd_ndisc *nd) { (void) sd_event_source_set_description(nd->recv_event_source, "ndisc-receive-message"); - r = sd_event_add_time(nd->event, &nd->timeout_event_source, clock_boottime_or_monotonic(), 0, 0, ndisc_timeout, nd); + r = event_reset_time(nd->event, &nd->timeout_event_source, + clock_boottime_or_monotonic(), + 0, 0, + ndisc_timeout, nd, + nd->event_priority, "ndisc-timeout", true); if (r < 0) goto fail; - r = sd_event_source_set_priority(nd->timeout_event_source, nd->event_priority); + r = event_reset_time(nd->event, &nd->timeout_no_ra, + clock_boottime_or_monotonic(), + time_now + NDISC_TIMEOUT_NO_RA_USEC, 10 * USEC_PER_MSEC, + ndisc_timeout_no_ra, nd, + nd->event_priority, "ndisc-timeout-no-ra", true); if (r < 0) goto fail; - (void) sd_event_source_set_description(nd->timeout_event_source, "ndisc-timeout"); - - r = sd_event_add_time(nd->event, &nd->timeout_no_ra, - clock_boottime_or_monotonic(), - time_now + NDISC_TIMEOUT_NO_RA_USEC, - 10 * USEC_PER_MSEC, ndisc_timeout_no_ra, nd); - if (r < 0) - goto fail; - - r = sd_event_source_set_priority(nd->timeout_no_ra, nd->event_priority); - if (r < 0) - goto fail; - - (void) sd_event_source_set_description(nd->timeout_no_ra, "ndisc-timeout-no-ra"); - log_ndisc("Started IPv6 Router Solicitation client"); return 1;