[systemd-commits] 5 commits - Makefile.am man/systemd-networkd-wait-online.service.xml src/libsystemd src/network src/systemd TODO units/systemd-networkd.service.in units/systemd-networkd.socket
Tom Gundersen
tomegun at kemper.freedesktop.org
Mon Feb 2 03:00:19 PST 2015
Makefile.am | 2 +
TODO | 6 ---
man/systemd-networkd-wait-online.service.xml | 7 ++++
src/libsystemd/sd-event/sd-event.c | 10 +++++
src/libsystemd/sd-rtnl/sd-rtnl.c | 27 ++++++++++++++-
src/network/networkd-manager.c | 47 ++++++++++++++++++++++-----
src/network/networkd-wait-online-manager.c | 21 ++++++++++--
src/network/networkd-wait-online.c | 27 ++++++++++++---
src/network/networkd-wait-online.h | 2 -
src/systemd/sd-rtnl.h | 1
units/systemd-networkd.service.in | 1
units/systemd-networkd.socket | 20 +++++++++++
12 files changed, 146 insertions(+), 25 deletions(-)
New commits:
commit 5544ee85163733eaa50f598fcf3bd9421d4a42f9
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Feb 1 22:13:26 2015 +0100
networkd: support socket activation
Still keep the non-socket activation code around for starting from the commandline, but
will likely drop that too in the future.
diff --git a/Makefile.am b/Makefile.am
index e3ba11c..fdadda7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5668,9 +5668,11 @@ tests += \
nodist_systemunit_DATA += \
units/systemd-networkd.service \
+ units/systemd-networkd.socket \
units/systemd-networkd-wait-online.service
GENERAL_ALIASES += \
+ $(systemunitdir)/systemd-networkd.socket $(pkgsysconfdir)/system/sockets.target.wants/systemd-networkd.socket \
$(systemunitdir)/systemd-networkd.service $(pkgsysconfdir)/system/multi-user.target.wants/systemd-networkd.service \
$(systemunitdir)/systemd-networkd-wait-online.service $(pkgsysconfdir)/system/network-online.target.wants/systemd-networkd-wait-online.service
diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 767c583..45ba50a 100644
--- a/src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/src/libsystemd/sd-rtnl/sd-rtnl.c
@@ -74,7 +74,7 @@ int sd_rtnl_new_from_netlink(sd_rtnl **ret, int fd) {
assert_return(ret, -EINVAL);
- r = sd_rtnl_new(ret);
+ r = sd_rtnl_new(&rtnl);
if (r < 0)
return r;
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 4c90434..49e353a 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -35,6 +35,7 @@
#include "virt.h"
#include "sd-rtnl.h"
+#include "sd-daemon.h"
/* use 8 MB for receive socket kernel queue. */
#define RCVBUF_SIZE (8*1024*1024)
@@ -75,9 +76,33 @@ static int setup_default_address_pool(Manager *m) {
return 0;
}
+static int systemd_netlink_fd(int *ret) {
+ int n, fd, rtnl_fd = -1;
+
+ n = sd_listen_fds(true);
+ if (n <= 0)
+ return -EINVAL;
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++) {
+ if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
+ if (rtnl_fd >= 0)
+ return -EINVAL;
+
+ rtnl_fd = fd;
+ }
+ }
+
+ if (rtnl_fd < 0)
+ return -EINVAL;
+
+ *ret = rtnl_fd;
+
+ return 0;
+}
+
int manager_new(Manager **ret) {
_cleanup_manager_free_ Manager *m = NULL;
- int r;
+ int r, fd;
m = new0(Manager, 1);
if (!m)
@@ -96,14 +121,20 @@ int manager_new(Manager **ret) {
sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
- r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
- RTNLGRP_IPV6_IFADDR);
- if (r < 0)
- return r;
+ if (systemd_netlink_fd(&fd) < 0) {
+ r = sd_rtnl_open(&m->rtnl, 3, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR,
+ RTNLGRP_IPV6_IFADDR);
+ if (r < 0)
+ return r;
- r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
- if (r < 0)
- return r;
+ r = sd_rtnl_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
+ if (r < 0)
+ return r;
+ } else {
+ r = sd_rtnl_new_from_netlink(&m->rtnl, fd);
+ if (r < 0)
+ return r;
+ }
r = sd_bus_default_system(&m->bus);
if (r < 0 && r != -ENOENT) /* TODO: drop when we can rely on kdbus */
diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
index fe92da2..fab278e 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -29,3 +29,4 @@ WatchdogSec=1min
[Install]
WantedBy=multi-user.target
+Also=systemd-networkd.socket
diff --git a/units/systemd-networkd.socket b/units/systemd-networkd.socket
new file mode 100644
index 0000000..d15ee9e
--- /dev/null
+++ b/units/systemd-networkd.socket
@@ -0,0 +1,20 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=networkd rtnetlink socket
+Documentation=man:systemd-networkd.service(8) man:rtnetlink(7)
+DefaultDependencies=no
+Before=sockets.target
+
+[Socket]
+ReceiveBuffer=8M
+ListenNetlink=route 273
+PassCredentials=yes
+
+[Install]
+WantedBy=sockets.target
commit a9944163fe5600bce85898dae78cd68442a6ff7c
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Feb 1 22:12:33 2015 +0100
sd-rtnl: introduce sd_rtnl_new_from_netlink
diff --git a/src/libsystemd/sd-rtnl/sd-rtnl.c b/src/libsystemd/sd-rtnl/sd-rtnl.c
index 7f1ec30..767c583 100644
--- a/src/libsystemd/sd-rtnl/sd-rtnl.c
+++ b/src/libsystemd/sd-rtnl/sd-rtnl.c
@@ -67,6 +67,31 @@ static int sd_rtnl_new(sd_rtnl **ret) {
return 0;
}
+int sd_rtnl_new_from_netlink(sd_rtnl **ret, int fd) {
+ _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+ socklen_t addrlen;
+ int r;
+
+ assert_return(ret, -EINVAL);
+
+ r = sd_rtnl_new(ret);
+ if (r < 0)
+ return r;
+
+ addrlen = sizeof(rtnl->sockaddr);
+
+ r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
+ if (r < 0)
+ return -errno;
+
+ rtnl->fd = fd;
+
+ *ret = rtnl;
+ rtnl = NULL;
+
+ return 0;
+}
+
static bool rtnl_pid_changed(sd_rtnl *rtnl) {
assert(rtnl);
@@ -126,7 +151,7 @@ static int rtnl_open_fd_ap(sd_rtnl **ret, int fd, unsigned n_groups, va_list ap)
r = getsockname(fd, &rtnl->sockaddr.sa, &addrlen);
if (r < 0)
- return r;
+ return -errno;
rtnl->fd = fd;
diff --git a/src/systemd/sd-rtnl.h b/src/systemd/sd-rtnl.h
index 7919172..0eb5547 100644
--- a/src/systemd/sd-rtnl.h
+++ b/src/systemd/sd-rtnl.h
@@ -41,6 +41,7 @@ typedef struct sd_rtnl_message sd_rtnl_message;
typedef int (*sd_rtnl_message_handler_t)(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata);
/* bus */
+int sd_rtnl_new_from_netlink(sd_rtnl **nl, int fd);
int sd_rtnl_open(sd_rtnl **nl, unsigned n_groups, ...);
int sd_rtnl_open_fd(sd_rtnl **nl, int fd, unsigned n_groups, ...);
int sd_rtnl_inc_rcvbuf(const sd_rtnl *const rtnl, const int size);
commit e56cdb7ae2657d62c9a8b6d3427382b209dff8e7
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Feb 1 21:04:35 2015 +0100
networkd-wait-online: add timeout
Default to timing out after 120 seconds without a network connection. Setting a
timeout of 0 disables the timeout.
diff --git a/TODO b/TODO
index 1d9ca39..c7b530b 100644
--- a/TODO
+++ b/TODO
@@ -34,8 +34,6 @@ External:
Features:
-* network-wait-online should have a configurable timeout, maybe as --timeout-usec=
-
* The udev blkid built-in should expose a property that reflects
whether media was sensed in USB CF/SD card readers. This should then
be used to control SYSTEMD_READY=1/0 so that USB card readers aren't
@@ -156,8 +154,6 @@ Features:
* timesyncd + resolved: add ugly bus calls to set NTP and DNS servers per-interface, for usage by NM
-* networkd-wait-online really should have a timeout by default
-
* add infrastructure to allocate dynamic/transient users and UID ranges, for use in user-namespaced containers, per-seat gdm login screens and gdm guest sessions
* machined: add an API so that libvirt-lxc can inform us about network interfaces being removed or added to an existing machine
diff --git a/man/systemd-networkd-wait-online.service.xml b/man/systemd-networkd-wait-online.service.xml
index 0cb41a3..4f039fe 100644
--- a/man/systemd-networkd-wait-online.service.xml
+++ b/man/systemd-networkd-wait-online.service.xml
@@ -90,6 +90,13 @@
more than once to ignore multiple network interfaces.
</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--timeout=</option></term>
+ <listitem><para>Fail the service if the network is not
+ online by the time the timeout elapses. A timeout of 0
+ disables the timeout. Defaults to 120 seconds.
+ </para></listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/network/networkd-wait-online-manager.c b/src/network/networkd-wait-online-manager.c
index d127372..cafe110 100644
--- a/src/network/networkd-wait-online-manager.c
+++ b/src/network/networkd-wait-online-manager.c
@@ -31,6 +31,7 @@
#include "networkd-wait-online.h"
#include "util.h"
+#include "time-util.h"
bool manager_ignore_link(Manager *m, Link *link) {
char **ignore;
@@ -262,7 +263,7 @@ static int manager_network_monitor_listen(Manager *m) {
return 0;
}
-int manager_new(Manager **ret, char **interfaces, char **ignore) {
+int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;
@@ -282,6 +283,16 @@ int manager_new(Manager **ret, char **interfaces, char **ignore) {
sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
+ if (timeout > 0) {
+ usec_t usec;
+
+ usec = now(clock_boottime_or_monotonic()) + timeout;
+
+ r = sd_event_add_time(m->event, NULL, clock_boottime_or_monotonic(), usec, 0, NULL, INT_TO_PTR(-ETIMEDOUT));
+ if (r < 0)
+ return r;
+ }
+
sd_event_set_watchdog(m->event, true);
r = manager_network_monitor_listen(m);
diff --git a/src/network/networkd-wait-online.c b/src/network/networkd-wait-online.c
index 826ab92..f0ca6de 100644
--- a/src/network/networkd-wait-online.c
+++ b/src/network/networkd-wait-online.c
@@ -28,6 +28,7 @@
#include "build.h"
static bool arg_quiet = false;
+static usec_t arg_timeout = 120 * USEC_PER_SEC;
static char **arg_interfaces = NULL;
static char **arg_ignore = NULL;
@@ -39,6 +40,7 @@ static void help(void) {
" -q --quiet Do not show status information\n"
" -i --interface=INTERFACE Block until at least these interfaces have appeared\n"
" --ignore=INTERFACE Don't take these interfaces into account\n"
+ " --timeout=SECS Maximum time to wait for network connectivity\n"
, program_invocation_short_name);
}
@@ -47,6 +49,7 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_IGNORE,
+ ARG_TIMEOUT,
};
static const struct option options[] = {
@@ -55,10 +58,11 @@ static int parse_argv(int argc, char *argv[]) {
{ "quiet", no_argument, NULL, 'q' },
{ "interface", required_argument, NULL, 'i' },
{ "ignore", required_argument, NULL, ARG_IGNORE },
+ { "timeout", required_argument, NULL, ARG_TIMEOUT },
{}
};
- int c;
+ int c, r;
assert(argc >= 0);
assert(argv);
@@ -92,6 +96,13 @@ static int parse_argv(int argc, char *argv[]) {
break;
+ case ARG_TIMEOUT:
+ r = parse_sec(optarg, &arg_timeout);
+ if (r < 0)
+ return r;
+
+ break;
+
case '?':
return -EINVAL;
@@ -121,7 +132,7 @@ int main(int argc, char *argv[]) {
assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
- r = manager_new(&m, arg_interfaces, arg_ignore);
+ r = manager_new(&m, arg_interfaces, arg_ignore, arg_timeout);
if (r < 0) {
log_error_errno(r, "Could not create manager: %m");
goto finish;
@@ -143,10 +154,16 @@ int main(int argc, char *argv[]) {
}
finish:
- sd_notify(false, "STATUS=All interfaces configured...");
-
strv_free(arg_interfaces);
strv_free(arg_ignore);
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ if (r >= 0) {
+ sd_notify(false, "STATUS=All interfaces configured...");
+
+ return EXIT_SUCCESS;
+ } else {
+ sd_notify(false, "STATUS=Failed waiting for network connectivity...");
+
+ return EXIT_FAILURE;
+ }
}
diff --git a/src/network/networkd-wait-online.h b/src/network/networkd-wait-online.h
index eb78647..66b865c 100644
--- a/src/network/networkd-wait-online.h
+++ b/src/network/networkd-wait-online.h
@@ -49,7 +49,7 @@ struct Manager {
};
void manager_free(Manager *m);
-int manager_new(Manager **ret, char **interfaces, char **ignore);
+int manager_new(Manager **ret, char **interfaces, char **ignore, usec_t timeout);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
commit c4f1aff2306e4fb10efeda75f7015e5d043d4e8d
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Feb 1 18:06:40 2015 +0100
sd-event: treat NULL callback for timer events like sig events
In both cases exit the event loop.
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index f9fa54d..25089a0 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -891,6 +891,12 @@ static int event_setup_timer_fd(
return 0;
}
+static int time_exit_callback(sd_event_source *s, uint64_t usec, void *userdata) {
+ assert(s);
+
+ return sd_event_exit(sd_event_source_get_event(s), PTR_TO_INT(userdata));
+}
+
_public_ int sd_event_add_time(
sd_event *e,
sd_event_source **ret,
@@ -908,10 +914,12 @@ _public_ int sd_event_add_time(
assert_return(e, -EINVAL);
assert_return(usec != (uint64_t) -1, -EINVAL);
assert_return(accuracy != (uint64_t) -1, -EINVAL);
- assert_return(callback, -EINVAL);
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
assert_return(!event_pid_changed(e), -ECHILD);
+ if (!callback)
+ callback = time_exit_callback;
+
type = clock_to_event_source_type(clock);
assert_return(type >= 0, -ENOTSUP);
commit 5d8689d749ffc50ade3d5c8598c1d3d11f5240f2
Author: Tom Gundersen <teg at jklm.no>
Date: Sun Feb 1 15:13:17 2015 +0100
networkd-wait-online: support globbing for ignored devices
diff --git a/TODO b/TODO
index e9615cc..1d9ca39 100644
--- a/TODO
+++ b/TODO
@@ -34,8 +34,6 @@ External:
Features:
-* network-wait-online should support globbing for interfaces.
-
* network-wait-online should have a configurable timeout, maybe as --timeout-usec=
* The udev blkid built-in should expose a property that reflects
diff --git a/src/network/networkd-wait-online-manager.c b/src/network/networkd-wait-online-manager.c
index c66470c..d127372 100644
--- a/src/network/networkd-wait-online-manager.c
+++ b/src/network/networkd-wait-online-manager.c
@@ -21,6 +21,7 @@
#include <netinet/ether.h>
#include <linux/if.h>
+#include <fnmatch.h>
#include "rtnl-util.h"
@@ -32,14 +33,17 @@
#include "util.h"
bool manager_ignore_link(Manager *m, Link *link) {
+ char **ignore;
+
assert(m);
assert(link);
if (link->flags & IFF_LOOPBACK)
return true;
- if (strv_contains(m->ignore, link->ifname))
- return true;
+ STRV_FOREACH(ignore, m->ignore)
+ if (fnmatch(*ignore, link->ifname, 0) == 0)
+ return true;
return false;
}
More information about the systemd-commits
mailing list