diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-02-13 14:38:02 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-02-13 14:38:02 +0100 |
commit | 7e2270246b0906675c8f34bc278b1608b969e65c (patch) | |
tree | 5c338eafa0adb55c2d1883a92f5fd8e561204a68 /src/nspawn | |
parent | b88eb17a7a9aad8287df275c46c1d09b1aee09fd (diff) |
nspawn: check with udev before we take possession of an interface
Diffstat (limited to 'src/nspawn')
-rw-r--r-- | src/nspawn/nspawn.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 689592ed73..abcee3fb98 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -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)); |