chiark / gitweb /
nspawn: check with udev before we take possession of an interface
authorLennart Poettering <lennart@poettering.net>
Thu, 13 Feb 2014 13:38:02 +0000 (14:38 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 13 Feb 2014 13:38:02 +0000 (14:38 +0100)
Makefile.am
src/nspawn/nspawn.c

index 713a3aad93f9f0f4b80f89c1d56a3d6fef9484a6..61d678f7d20bd143c2aad89cf6a287fcc127955b 100644 (file)
@@ -1849,6 +1849,7 @@ systemd_nspawn_LDADD = \
        libsystemd-capability.la \
        libsystemd-internal.la \
        libsystemd-daemon-internal.la \
+       libudev-internal.la \
        libsystemd-shared.la
 
 # ------------------------------------------------------------------------------
index 689592ed7332f9b30bd04491c6ae0b26bdc5a6c6..abcee3fb98162fae7c7553a0e1e79f1e2d2bf9ee 100644 (file)
@@ -73,6 +73,7 @@
 #include "env-util.h"
 #include "def.h"
 #include "rtnl-util.h"
+#include "udev-util.h"
 
 typedef enum LinkJournal {
         LINK_NO,
@@ -1256,6 +1257,7 @@ static int reset_audit_loginuid(void) {
 
 static int move_network_interfaces(pid_t pid) {
         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
         char **i;
         int r;
 
@@ -1271,8 +1273,16 @@ static int move_network_interfaces(pid_t pid) {
                 return r;
         }
 
+        udev = udev_new();
+        if (!udev) {
+                log_error("Failed to connect to udev.");
+                return -ENOMEM;
+        }
+
         STRV_FOREACH(i, arg_network_interfaces) {
                 _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+                char ifi_str[2 + DECIMAL_STR_MAX(int)];
                 int ifi;
 
                 ifi = (int) if_nametoindex(*i);
@@ -1281,6 +1291,18 @@ static int move_network_interfaces(pid_t pid) {
                         return -errno;
                 }
 
+                sprintf(ifi_str, "n%i", ifi);
+                d = udev_device_new_from_device_id(udev, ifi_str);
+                if (!d) {
+                        log_error("Failed to get udev device for interface %s: %m", *i);
+                        return -errno;
+                }
+
+                if (udev_device_get_is_initialized(d) <= 0) {
+                        log_error("Network interface %s is not initialized yet.", *i);
+                        return -EBUSY;
+                }
+
                 r = sd_rtnl_message_new_link(RTM_NEWLINK, ifi, &m);
                 if (r < 0) {
                         log_error("Failed to allocate netlink message: %s", strerror(-r));