chiark / gitweb /
nspawn: check with udev before we take possession of an interface
[elogind.git] / src / nspawn / nspawn.c
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));