summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-03-09 12:27:56 +0100
committerThomas Haller <thaller@redhat.com>2016-03-09 17:14:58 +0100
commitad457b1ecf6c0c5b800b1c5f40cb69ac65384324 (patch)
tree677912476fea7d1ed9f2f023c76d762b2f9d3e98
parentcb84ae782c62ed33dceeaaf5b6950508917027f8 (diff)
downloadNetworkManager-th/systemd-lldp.tar.gz
systemd: rework sd-event integration to glibth/systemd-lldp
We don't want to reimplement sd-event, instead we want to hook the original sd-event into glib.
-rw-r--r--src/Makefile.am1
-rw-r--r--src/main.c10
-rw-r--r--src/nm-iface-helper.c6
-rw-r--r--src/systemd/nm-sd-adapt.c259
-rw-r--r--src/systemd/nm-sd-adapt.h12
-rw-r--r--src/systemd/src/libsystemd/sd-event/sd-event.c14
-rw-r--r--src/systemd/src/libsystemd/sd-id128/sd-id128.c2
7 files changed, 110 insertions, 194 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 34483b5ba8..f7f2e73b6e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -156,6 +156,7 @@ libsystemd_nm_la_SOURCES = \
systemd/src/libsystemd-network/sd-ipv4acd.c \
systemd/src/libsystemd-network/sd-ipv4ll.c \
systemd/src/libsystemd-network/sd-lldp.c \
+ systemd/src/libsystemd/sd-event/sd-event.c \
systemd/src/libsystemd/sd-id128/sd-id128.c \
systemd/src/shared/dns-domain.c \
systemd/src/shared/dns-domain.h \
diff --git a/src/main.c b/src/main.c
index 0f074b012d..b96a331316 100644
--- a/src/main.c
+++ b/src/main.c
@@ -50,6 +50,7 @@
#include "nm-auth-manager.h"
#include "nm-core-internal.h"
#include "nm-exported-object.h"
+#include "nm-sd-adapt.h"
#if !defined(NM_DIST_VERSION)
# define NM_DIST_VERSION VERSION
@@ -271,6 +272,7 @@ main (int argc, char *argv[])
gboolean wrote_pidfile = FALSE;
char *bad_domains = NULL;
NMConfigCmdLineOptions *config_cli;
+ guint sd_id;
nm_g_type_init ();
@@ -474,8 +476,11 @@ main (int argc, char *argv[])
success = TRUE;
- if (configure_and_quit == FALSE)
+ if (configure_and_quit == FALSE) {
+ sd_id = nm_sd_event_attach (NULL, NULL);
+
g_main_loop_run (main_loop);
+ }
done:
nm_exported_object_class_set_quitting ();
@@ -486,5 +491,8 @@ done:
unlink (global_opt.pidfile);
nm_log_info (LOGD_CORE, "exiting (%s)", success ? "success" : "error");
+
+ nm_clear_g_source (&sd_id);
+
exit (success ? 0 : 1);
}
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index 225464c094..9e53fb73d9 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -44,6 +44,7 @@ extern unsigned int if_nametoindex (const char *__ifname);
#include "nm-lndp-rdisc.h"
#include "nm-utils.h"
#include "nm-setting-ip6-config.h"
+#include "nm-sd-adapt.h"
#if !defined(NM_DIST_VERSION)
# define NM_DIST_VERSION VERSION
@@ -345,6 +346,7 @@ main (int argc, char *argv[])
size_t hwaddr_len = 0;
gconstpointer tmp;
gs_free NMUtilsIPv6IfaceId *iid = NULL;
+ guint sd_id;
nm_g_type_init ();
@@ -494,6 +496,8 @@ main (int argc, char *argv[])
nm_rdisc_start (rdisc);
}
+ sd_id = nm_sd_event_attach (NULL, NULL);
+
g_main_loop_run (main_loop);
g_clear_pointer (&hwaddr, g_byte_array_unref);
@@ -502,6 +506,8 @@ main (int argc, char *argv[])
unlink (pidfile);
nm_log_info (LOGD_CORE, "exiting");
+
+ nm_clear_g_source (&sd_id);
exit (0);
}
diff --git a/src/systemd/nm-sd-adapt.c b/src/systemd/nm-sd-adapt.c
index 40d52e76b4..8e2de17ee9 100644
--- a/src/systemd/nm-sd-adapt.c
+++ b/src/systemd/nm-sd-adapt.c
@@ -20,233 +20,108 @@
#include "nm-sd-adapt.h"
-#include <unistd.h>
-#include <errno.h>
-
#include "sd-event.h"
#include "fd-util.h"
-#include "time-util.h"
-struct sd_event_source {
- guint refcount;
- guint id;
- gpointer user_data;
-
- GIOChannel *channel;
-
- union {
- struct {
- sd_event_io_handler_t cb;
- } io;
- struct {
- sd_event_time_handler_t cb;
- uint64_t usec;
- } time;
- };
-};
-
-static struct sd_event_source *
-source_new (void)
-{
- struct sd_event_source *source;
-
- source = g_slice_new0 (struct sd_event_source);
- source->refcount = 1;
- return source;
-}
+/*****************************************************************************/
int
-sd_event_source_set_priority (sd_event_source *s, int64_t priority)
-{
- return 0;
+asynchronous_close (int fd) {
+ safe_close (fd);
+ return -1;
}
-int
-sd_event_source_set_enabled (sd_event_source *s, int m)
-{
- /* TODO */
- g_return_val_if_reached (-EINVAL);
-}
+/*****************************************************************************
+ * Integrating sd_event into glib. Taken and adjusted from
+ * https://www.freedesktop.org/software/systemd/man/sd_event_get_fd.html
+ *****************************************************************************/
-int
-sd_event_source_set_time (sd_event_source *s, uint64_t usec)
-{
- /* TODO */
- g_return_val_if_reached (-EINVAL);
-}
+typedef struct SDEventSource {
+ GSource source;
+ GPollFD pollfd;
+ sd_event *event;
+} SDEventSource;
-sd_event_source*
-sd_event_source_unref (sd_event_source *s)
+static gboolean
+event_prepare (GSource *source, gint *timeout_)
{
-
- if (!s)
- return NULL;
-
- g_return_val_if_fail (s->refcount, NULL);
-
- s->refcount--;
- if (s->refcount == 0) {
- if (s->id)
- g_source_remove (s->id);
- if (s->channel) {
- /* Don't shut down the channel since systemd will soon close
- * the file descriptor itself, which would cause -EBADF.
- */
- g_io_channel_unref (s->channel);
- }
- g_slice_free (struct sd_event_source, s);
- }
- return NULL;
+ return sd_event_prepare (((SDEventSource *) source)->event) > 0;
}
-int
-sd_event_source_set_description(sd_event_source *s, const char *description)
+static gboolean
+event_check (GSource *source)
{
- if (!s)
- return -EINVAL;
-
- g_source_set_name_by_id (s->id, description);
- return 0;
+ return sd_event_wait (((SDEventSource *) source)->event, 0) > 0;
}
static gboolean
-io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *source)
+event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data)
{
- int r, revents = 0;
- gboolean result;
-
- if (condition & G_IO_IN)
- revents |= EPOLLIN;
- if (condition & G_IO_OUT)
- revents |= EPOLLOUT;
- if (condition & G_IO_PRI)
- revents |= EPOLLPRI;
- if (condition & G_IO_ERR)
- revents |= EPOLLERR;
- if (condition & G_IO_HUP)
- revents |= EPOLLHUP;
-
- source->refcount++;
-
- r = source->io.cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
- if (r < 0 || source->refcount <= 1) {
- source->id = 0;
- result = G_SOURCE_REMOVE;
- } else
- result = G_SOURCE_CONTINUE;
-
- sd_event_source_unref (source);
-
- return result;
+ return sd_event_dispatch (((SDEventSource *)source)->event) > 0;
}
-int
-sd_event_add_io (sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata)
+static void
+event_finalize (GSource *source)
{
- struct sd_event_source *source;
- GIOChannel *channel;
- GIOCondition condition = 0;
-
- /* systemd supports floating sd_event_source by omitting the @s argument.
- * We don't have such users and don't implement floating references. */
- g_return_val_if_fail (s, -EINVAL);
-
- channel = g_io_channel_unix_new (fd);
- if (!channel)
- return -EINVAL;
-
- source = source_new ();
- source->io.cb = callback;
- source->user_data = userdata;
- source->channel = channel;
-
- if (events & EPOLLIN)
- condition |= G_IO_IN;
- if (events & EPOLLOUT)
- condition |= G_IO_OUT;
- if (events & EPOLLPRI)
- condition |= G_IO_PRI;
- if (events & EPOLLERR)
- condition |= G_IO_ERR;
- if (events & EPOLLHUP)
- condition |= G_IO_HUP;
-
- g_io_channel_set_encoding (source->channel, NULL, NULL);
- g_io_channel_set_buffered (source->channel, FALSE);
- source->id = g_io_add_watch (source->channel, condition, (GIOFunc) io_ready, source);
-
- *s = source;
- return 0;
+ sd_event_unref (((SDEventSource *) source)->event);
}
-static gboolean
-time_ready (struct sd_event_source *source)
+static SDEventSource *
+event_create_source (sd_event *event)
{
- source->refcount++;
+ static GSourceFuncs event_funcs = {
+ .prepare = event_prepare,
+ .check = event_check,
+ .dispatch = event_dispatch,
+ .finalize = event_finalize,
+ };
+ SDEventSource *source;
- source->time.cb (source, source->time.usec, source->user_data);
- source->id = 0;
+ g_return_val_if_fail (event, NULL);
- sd_event_source_unref (source);
+ source = (SDEventSource *) g_source_new (&event_funcs, sizeof (SDEventSource));
- return G_SOURCE_REMOVE;
-}
+ source->event = sd_event_ref (event);
+ source->pollfd.fd = sd_event_get_fd (event);
+ source->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
-int
-sd_event_add_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)
-{
- struct sd_event_source *source;
- uint64_t n = now (clock);
-
- /* systemd supports floating sd_event_source by omitting the @s argument.
- * We don't have such users and don't implement floating references. */
- g_return_val_if_fail (s, -EINVAL);
+ g_source_add_poll ((GSource *) source, &source->pollfd);
- source = source_new ();
- source->time.cb = callback;
- source->user_data = userdata;
- source->time.usec = usec;
+ return source;
+}
- if (usec > 1000)
- usec = n < usec - 1000 ? usec - n : 1000;
- source->id = g_timeout_add (usec / 1000, (GSourceFunc) time_ready, source);
+guint
+nm_sd_event_attach (sd_event *event, GMainContext *context)
+{
+ SDEventSource *source;
+ guint id;
+ int r;
+ sd_event *e = event;
- *s = source;
- return 0;
-}
+ if (!e) {
-/* sd_event is basically a GMainContext; but since we only
- * ever use the default context, nothing to do here.
- */
+ if (sd_event_default (NULL)) {
+ /* we *must* create a new default-event, otherwise it's unclear whether the
+ * existing event is already registered or whether we should re-register.
+ * Just don't allow that. */
+ g_return_val_if_reached (0);
+ }
-int
-sd_event_default (sd_event **e)
-{
- *e = GUINT_TO_POINTER (1);
- return 0;
-}
+ r = sd_event_default (&e);
+ if (r < 0)
+ g_return_val_if_reached (0);
+ }
-sd_event*
-sd_event_ref (sd_event *e)
-{
- return e;
-}
+ source = event_create_source (e);
+ id = g_source_attach ((GSource *) source, context);
+ g_source_unref ((GSource *) source);
-sd_event*
-sd_event_unref (sd_event *e)
-{
- return NULL;
-}
+ if (!event)
+ sd_event_unref (e);
-int
-sd_event_now (sd_event *e, clockid_t clock, uint64_t *usec)
-{
- *usec = now (clock);
- return 0;
+ g_return_val_if_fail (id, 0);
+ return id;
}
-int asynchronous_close(int fd) {
- safe_close(fd);
- return -1;
-}
+/*****************************************************************************/
diff --git a/src/systemd/nm-sd-adapt.h b/src/systemd/nm-sd-adapt.h
index 1547f12748..66a1a1f064 100644
--- a/src/systemd/nm-sd-adapt.h
+++ b/src/systemd/nm-sd-adapt.h
@@ -26,6 +26,10 @@
#include <sys/resource.h>
#include <time.h>
+struct sd_event;
+
+guint nm_sd_event_attach (struct sd_event *event, GMainContext *context);
+
#define noreturn G_GNUC_NORETURN
#ifndef CLOCK_BOOTTIME
@@ -123,6 +127,14 @@ typedef guint32 char32_t;
/*****************************************************************************/
+#define PID_TO_PTR(p) ((void*) ((uintptr_t) p))
+
+static inline int
+sd_notify (int unset_environment, const char *state)
+{
+ return 0;
+}
+
/* Can't include both net/if.h and linux/if.h; so have to define this here */
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c
index 841358ed03..31e8e7fa66 100644
--- a/src/systemd/src/libsystemd/sd-event/sd-event.c
+++ b/src/systemd/src/libsystemd/sd-event/sd-event.c
@@ -17,11 +17,15 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "nm-sd-adapt.h"
+
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/wait.h>
+#if 0 /* NM_IGNORED */
#include "sd-daemon.h"
+#endif
#include "sd-event.h"
#include "sd-id128.h"
@@ -30,11 +34,17 @@
#include "hashmap.h"
#include "list.h"
#include "macro.h"
+#if 0 /* NM_IGNORED */
#include "missing.h"
+#endif
#include "prioq.h"
+#if 0 /* NM_IGNORED */
#include "process-util.h"
+#endif
#include "set.h"
+#if 0 /* NM_IGNORED */
#include "signal-util.h"
+#endif
#include "string-table.h"
#include "string-util.h"
#include "time-util.h"
@@ -1126,6 +1136,7 @@ fail:
return r;
}
+#if 0 /* NM_IGNORED */
static int signal_exit_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
@@ -1192,6 +1203,7 @@ _public_ int sd_event_add_signal(
return 0;
}
+#endif /* NM_IGNORED */
_public_ int sd_event_add_child(
sd_event *e,
@@ -2818,6 +2830,7 @@ _public_ int sd_event_default(sd_event **ret) {
return 1;
}
+#if 0 /* NM_IGNORED */
_public_ int sd_event_get_tid(sd_event *e, pid_t *tid) {
assert_return(e, -EINVAL);
assert_return(tid, -EINVAL);
@@ -2889,3 +2902,4 @@ _public_ int sd_event_get_watchdog(sd_event *e) {
return e->watchdog;
}
+#endif /* NM_IGNORED */
diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
index ea09d19e4e..01b805a104 100644
--- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c
+++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c
@@ -155,7 +155,6 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
return 0;
}
-#if 0 /* NM_IGNORED */
_public_ int sd_id128_get_boot(sd_id128_t *ret) {
static thread_local sd_id128_t saved_boot_id;
static thread_local bool saved_boot_id_valid = false;
@@ -211,6 +210,7 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
return 0;
}
+#if 0 /* NM_IGNORED */
_public_ int sd_id128_randomize(sd_id128_t *ret) {
sd_id128_t t;
int r;