From: Tom Gundersen Date: Sun, 1 Feb 2015 21:13:26 +0000 (+0100) Subject: networkd: support socket activation X-Git-Tag: v219~201 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=5544ee85163733eaa50f598fcf3bd9421d4a42f9 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 e3ba11c8c..fdadda7d3 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 767c58373..45ba50a85 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 4c9043486..49e353a7b 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 fe92da212..fab278e92 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 000000000..d15ee9ed8 --- /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