summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-09-24 10:52:09 +0200
committerThomas Haller <thaller@redhat.com>2015-09-24 10:52:09 +0200
commit1b7196ec51c5a369f32e8d471d8837900695ddd3 (patch)
tree2d2612b8ab780b5de25cfd76d0e506ed3c24e2fa
parent94bbe7465f35b69487f306ed60b99ae6d50784e6 (diff)
parent401a2eb834bdddd8931161eb86204eb80d26b2c7 (diff)
downloadNetworkManager-1b7196ec51c5a369f32e8d471d8837900695ddd3.tar.gz
systemd: merge branch 'th/systemd-dhcp-timer-rh1260727'
https://bugzilla.redhat.com/show_bug.cgi?id=1260727
-rw-r--r--src/nm-logging.c5
-rw-r--r--src/systemd/nm-sd-adapt.c76
-rw-r--r--src/systemd/nm-sd-adapt.h7
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c5
4 files changed, 67 insertions, 26 deletions
diff --git a/src/nm-logging.c b/src/nm-logging.c
index f79ba3c2e4..30c754d163 100644
--- a/src/nm-logging.c
+++ b/src/nm-logging.c
@@ -431,8 +431,11 @@ _nm_log_impl (const char *file,
return;
/* Make sure that %m maps to the specified error */
- if (error != 0)
+ if (error != 0) {
+ if (error < 0)
+ error = -error;
errno = error;
+ }
va_start (args, fmt);
msg = g_strdup_vprintf (fmt, args);
diff --git a/src/systemd/nm-sd-adapt.c b/src/systemd/nm-sd-adapt.c
index a6d817278e..24b77c528b 100644
--- a/src/systemd/nm-sd-adapt.c
+++ b/src/systemd/nm-sd-adapt.c
@@ -31,12 +31,28 @@ struct sd_event_source {
gpointer user_data;
GIOChannel *channel;
- sd_event_io_handler_t io_cb;
- uint64_t usec;
- sd_event_time_handler_t time_cb;
+ 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)
{
@@ -62,7 +78,7 @@ sd_event_source_unref (sd_event_source *s)
*/
g_io_channel_unref (s->channel);
}
- g_free (s);
+ g_slice_free (struct sd_event_source, s);
}
return NULL;
}
@@ -81,6 +97,7 @@ static gboolean
io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *source)
{
int r, revents = 0;
+ gboolean result;
if (condition & G_IO_IN)
revents |= EPOLLIN;
@@ -93,13 +110,18 @@ io_ready (GIOChannel *channel, GIOCondition condition, struct sd_event_source *s
if (condition & G_IO_HUP)
revents |= EPOLLHUP;
- r = source->io_cb (source, g_io_channel_unix_get_fd (channel), revents, source->user_data);
- if (r < 0) {
+ 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;
- return G_SOURCE_REMOVE;
- }
+ result = G_SOURCE_REMOVE;
+ } else
+ result = G_SOURCE_CONTINUE;
- return G_SOURCE_CONTINUE;
+ sd_event_source_unref (source);
+
+ return result;
}
int
@@ -109,13 +131,16 @@ sd_event_add_io (sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_e
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 = g_new0 (struct sd_event_source, 1);
- source->refcount = 1;
- source->io_cb = callback;
+ source = source_new ();
+ source->io.cb = callback;
source->user_data = userdata;
source->channel = channel;
@@ -142,14 +167,20 @@ static gboolean
time_ready (struct sd_event_source *source)
{
int r;
+ gboolean result;
+
+ source->refcount++;
- r = source->time_cb (source, source->usec, source->user_data);
- if (r < 0) {
+ r = source->time.cb (source, source->time.usec, source->user_data);
+ if (r < 0 || source->refcount <= 1) {
source->id = 0;
- return G_SOURCE_REMOVE;
- }
+ result = G_SOURCE_REMOVE;
+ } else
+ result = G_SOURCE_CONTINUE;
+
+ sd_event_source_unref (source);
- return G_SOURCE_CONTINUE;
+ return result;
}
int
@@ -158,11 +189,14 @@ sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t us
struct sd_event_source *source;
uint64_t n = now (clock);
- source = g_new0 (struct sd_event_source, 1);
- source->refcount = 1;
- source->time_cb = callback;
+ /* 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);
+
+ source = source_new ();
+ source->time.cb = callback;
source->user_data = userdata;
- source->usec = usec;
+ source->time.usec = usec;
if (usec > 1000)
usec = n < usec - 1000 ? usec - n : 1000;
diff --git a/src/systemd/nm-sd-adapt.h b/src/systemd/nm-sd-adapt.h
index c392879c03..03fda64136 100644
--- a/src/systemd/nm-sd-adapt.h
+++ b/src/systemd/nm-sd-adapt.h
@@ -47,12 +47,13 @@ _slog_level_to_nm (int slevel)
#define log_internal(level, error, file, line, func, format, ...) \
({ \
- int _nm_e = (error); \
- NMLogLevel _nm_l = _slog_level_to_nm ((level)); \
+ const int _nm_e = (error); \
+ const NMLogLevel _nm_l = _slog_level_to_nm ((level)); \
+ \
if (nm_logging_enabled (_nm_l, LOGD_DHCP)) { \
const char *_nm_location = strrchr ((""file), '/'); \
\
- _nm_log_impl (_nm_location ? _nm_location + 1 : (""file), (line), (func), _nm_l, LOGD_DHCP, _nm_e, ("%s"format), "sd-dhcp: ", ## __VA_ARGS__); \
+ _nm_log_impl (_nm_location ? _nm_location + 1 : (""file), (line), (func), _nm_l, LOGD_DHCP, _nm_e, ("%s"format), "libsystemd: ", ## __VA_ARGS__); \
} \
(_nm_e > 0 ? -_nm_e : _nm_e); \
})
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index 5f1393c60c..ee61b4f114 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -864,7 +864,10 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
r = dhcp6_lease_get_preference(client->lease, &pref_lease);
if (r < 0 || pref_advertise > pref_lease) {
- sd_dhcp6_lease_unref(client->lease);
+ if (client->lease) {
+ dhcp6_lease_clear_timers(&client->lease->ia);
+ sd_dhcp6_lease_unref(client->lease);
+ }
client->lease = lease;
lease = NULL;
r = 0;