[systemd-commits] 4 commits - Makefile.am src/network src/timesync

Tom Gundersen tomegun at kemper.freedesktop.org
Thu May 8 06:30:11 PDT 2014


 Makefile.am                        |    1 
 src/network/networkd-link.c        |    2 
 src/network/networkd-wait-online.c |   32 +++++-----
 src/network/networkd-wait-online.h |    1 
 src/timesync/timesyncd.c           |  108 +++++++++++++++++++++++++++++++++++--
 src/timesync/timesyncd.h           |    5 +
 6 files changed, 129 insertions(+), 20 deletions(-)

New commits:
commit e0e5ce237b11f2d97189cd7725bf339b4b8a78de
Author: Tom Gundersen <teg at jklm.no>
Date:   Wed May 7 15:26:47 2014 +0200

    timesyncd: only run when the system has a carrier on a network interface
    
    As the operational state detection in sd-network is still too primitive, timesyncd
    will likely try to connect a bit early, so the first attempt will fail.

diff --git a/Makefile.am b/Makefile.am
index 669eb33..637f5e1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4036,6 +4036,7 @@ systemd_timesyncd_LDADD = \
 	libsystemd-internal.la \
 	libsystemd-shared.la \
 	libsystemd-resolve.la \
+	libsystemd-network.la \
 	-lm
 
 rootlibexec_PROGRAMS += \
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index 1145e20..eb55bc0 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -46,6 +46,9 @@
 #include "sd-event.h"
 #include "sd-resolve.h"
 #include "sd-daemon.h"
+#include "sd-network.h"
+#include "event-util.h"
+#include "network-util.h"
 #include "timesyncd.h"
 
 #define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
@@ -1002,6 +1005,9 @@ static void manager_free(Manager *m) {
 
         sd_event_source_unref(m->event_retry);
 
+        sd_event_source_unref(m->network_event_source);
+        sd_network_monitor_unref(m->network_monitor);
+
         sd_resolve_unref(m->resolve);
         sd_event_unref(m->event);
 
@@ -1056,6 +1062,94 @@ static int manager_parse_config_file(Manager *m) {
         return r;
 }
 
+static bool network_is_online(void) {
+        _cleanup_free_ unsigned *indices = NULL;
+        int r, n, i;
+
+        n = sd_network_get_ifindices(&indices);
+        if (n <= 0)
+                return false;
+
+        for (i = 0; i < n; i++) {
+                _cleanup_free_ char *oper_state = NULL;
+
+                if (sd_network_link_is_loopback(indices[i]))
+                        /* ignore loopback devices */
+                        continue;
+
+                r = sd_network_get_link_operational_state(indices[i], &oper_state);
+                if (r >= 0 && streq(oper_state, "carrier"))
+                        return true;
+        }
+
+        return false;
+}
+
+static int manager_network_event_handler(sd_event_source *s, int fd, uint32_t revents,
+                                         void *userdata) {
+        Manager *m = userdata;
+        bool connected, online;
+        int r;
+
+        assert(m);
+
+        /* check if the machine is online */
+        online = network_is_online();
+
+        /* check if the client is currently connected */
+        connected = (m->server_socket != -1);
+
+        if (connected && !online) {
+                log_info("No network connectivity. Suspending.");
+                manager_disconnect(m);
+        } else if (!connected && online) {
+                log_info("Network connectivity detected. Resuming.");
+                if (m->current_server_address) {
+                        r = manager_begin(m);
+                        if (r < 0)
+                                return r;
+                } else {
+                        r = manager_connect(m);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        sd_network_monitor_flush(m->network_monitor);
+
+        return 0;
+}
+
+static int manager_network_monitor_listen(Manager *m) {
+        _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
+        _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
+        int r, fd, events;
+
+        r = sd_network_monitor_new(NULL, &monitor);
+        if (r < 0)
+                return r;
+
+        fd = sd_network_monitor_get_fd(monitor);
+        if (fd < 0)
+                return fd;
+
+        events = sd_network_monitor_get_events(monitor);
+        if (events < 0)
+                return events;
+
+        r = sd_event_add_io(m->event, &event_source, fd, events,
+                            &manager_network_event_handler, m);
+        if (r < 0)
+                return r;
+
+        m->network_monitor = monitor;
+        m->network_event_source = event_source;
+        monitor = NULL;
+        event_source = NULL;
+
+        return 0;
+}
+
 int main(int argc, char *argv[]) {
         _cleanup_manager_free_ Manager *m = NULL;
         int r;
@@ -1083,12 +1177,20 @@ int main(int argc, char *argv[]) {
         manager_add_server_string(m, NTP_SERVERS);
         manager_parse_config_file(m);
 
+        r = manager_network_monitor_listen(m);
+        if (r < 0) {
+                log_error("Failed to listen to networkd events: %s", strerror(-r));
+                goto out;
+        }
+
         log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
         sd_notify(false, "READY=1");
 
-        r = manager_connect(m);
-        if (r < 0)
-                goto out;
+        if (network_is_online()) {
+                r = manager_connect(m);
+                if (r < 0)
+                        goto out;
+        }
 
         r = sd_event_loop(m->event);
         if (r < 0) {
diff --git a/src/timesync/timesyncd.h b/src/timesync/timesyncd.h
index 6dd1388..370b966 100644
--- a/src/timesync/timesyncd.h
+++ b/src/timesync/timesyncd.h
@@ -24,6 +24,7 @@
 #include "ratelimit.h"
 #include "sd-event.h"
 #include "sd-resolve.h"
+#include "sd-network.h"
 
 typedef struct Manager Manager;
 typedef struct ServerAddress ServerAddress;
@@ -49,6 +50,10 @@ struct Manager {
 
         RateLimit ratelimit;
 
+        /* network */
+        sd_event_source *network_event_source;
+        sd_network_monitor *network_monitor;
+
         /* peer */
         sd_resolve_query *resolve_query;
         sd_event_source *event_receive;

commit 3a9c5a32bec18dc1cca68af46fd1aebfad7e9fd7
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu May 8 13:14:42 2014 +0200

    networkd-wait-online: flush monitor events after processing
    
    Otherwise the event will trigger immediately again.

diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index a42fef2..3ea7a83 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -202,6 +202,8 @@ static int monitor_event_handler(sd_event_source *s, int fd, uint32_t revents,
         if (all_configured(m))
                 sd_event_exit(m->event, 0);
 
+        sd_network_monitor_flush(m->monitor);
+
         return 1;
 }
 
@@ -218,7 +220,6 @@ void manager_free(Manager *m) {
 int main(int argc, char *argv[]) {
         _cleanup_manager_free_ Manager *m = NULL;
         _cleanup_event_source_unref_ sd_event_source *event_source = NULL;
-        _cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
         int r, fd, events;
 
         umask(0022);
@@ -237,25 +238,31 @@ int main(int argc, char *argv[]) {
         if (!m)
                 return log_oom();
 
-        r = sd_network_monitor_new(NULL, &monitor);
+        r = sd_event_new(&m->event);
         if (r < 0) {
-                log_error("Could not create monitor: %s", strerror(-r));
+                log_error("Could not create event: %s", strerror(-r));
                 goto out;
         }
 
-        r = sd_event_new(&m->event);
+        r = sd_rtnl_open(&m->rtnl, 0);
         if (r < 0) {
-                log_error("Could not create event: %s", strerror(-r));
+                log_error("Could not create rtnl: %s", strerror(-r));
                 goto out;
         }
 
-        fd = sd_network_monitor_get_fd(monitor);
+        r = sd_network_monitor_new(NULL, &m->monitor);
+        if (r < 0) {
+                log_error("Could not create monitor: %s", strerror(-r));
+                goto out;
+        }
+
+        fd = sd_network_monitor_get_fd(m->monitor);
         if (fd < 0) {
                 log_error("Could not get monitor fd: %s", strerror(-r));
                 goto out;
         }
 
-        events = sd_network_monitor_get_events(monitor);
+        events = sd_network_monitor_get_events(m->monitor);
         if (events < 0) {
                 log_error("Could not get monitor events: %s", strerror(-r));
                 goto out;
@@ -268,12 +275,6 @@ int main(int argc, char *argv[]) {
                 goto out;
         }
 
-        r = sd_rtnl_open(&m->rtnl, 0);
-        if (r < 0) {
-                log_error("Could not create rtnl: %s", strerror(-r));
-                goto out;
-        }
-
         if (all_configured(m)) {
                 r = 0;
                 goto out;
diff --git a/src/network/networkd-wait-online.h b/src/network/networkd-wait-online.h
index 91edce1..e894351 100644
--- a/src/network/networkd-wait-online.h
+++ b/src/network/networkd-wait-online.h
@@ -29,6 +29,7 @@
 typedef struct Manager {
         sd_event *event;
         sd_rtnl *rtnl;
+        sd_network_monitor *monitor;
 } Manager;
 
 void manager_free(Manager *m);

commit d91d3c1580ee3c50139eec8ab794c634a54044fb
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu May 8 13:11:23 2014 +0200

    networkd-wait-online: fix false positives when checking if a link is managed by networkd

diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index a4729f4..a42fef2 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -178,10 +178,9 @@ static bool all_configured(Manager *m) {
                         continue;
 
                 r = sd_network_get_link_state(indices[i], &state);
-                if (r != -EUNATCH && (r < 0 || !streq(state, "configured"))) {
-                        /* managed by networkd, but not yet configured */
+                if (r == -EBUSY || (r >= 0 && !streq(state, "configured")))
+                        /* not yet processed by udev, or managed by networkd, but not yet configured */
                         return false;
-                }
 
                 r = sd_network_get_link_operational_state(indices[i], &oper_state);
                 if (r >= 0 && streq(oper_state, "carrier"))

commit 75adc2189bb3b4f993e50f5160c9dff3efaec0b1
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu May 8 12:32:11 2014 +0200

    networkd: link - operstate is an enum, not a bitmask

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 0f2004d..04b2265 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1693,7 +1693,7 @@ int link_save(Link *link) {
         admin_state = link_state_to_string(link->state);
         assert(admin_state);
 
-        if (link->operstate & IF_OPER_DORMANT)
+        if (link->operstate == IF_OPER_DORMANT)
                 oper_state = "dormant";
         else if (link_has_carrier(link->flags, link->operstate))
                 oper_state = "carrier";



More information about the systemd-commits mailing list