diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c index fa1ec05b622..83ce62877a0 100644 --- a/src/nspawn/nspawn-network.c +++ b/src/nspawn/nspawn-network.c @@ -395,39 +395,49 @@ int remove_bridge(const char *bridge_name) { } static int parse_interface(const char *name) { - _cleanup_(sd_device_unrefp) sd_device *d = NULL; int ifi, r; r = parse_ifindex_or_ifname(name, &ifi); if (r < 0) return log_error_errno(r, "Failed to resolve interface %s: %m", name); - if (path_is_read_only_fs("/sys") <= 0) { - char ifi_str[2 + DECIMAL_STR_MAX(int)]; - - /* udev should be around. */ - - sprintf(ifi_str, "n%i", ifi); - r = sd_device_new_from_device_id(&d, ifi_str); - if (r < 0) - return log_error_errno(r, "Failed to get device %s: %m", name); - - r = sd_device_get_is_initialized(d); - if (r < 0) - return log_error_errno(r, "Failed to determine whether interface %s is initialized: %m", name); - if (r == 0) - return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Network interface %s is not initialized yet.", name); - - r = device_is_renaming(d); - if (r < 0) - return log_error_errno(r, "Failed to determine the interface %s is being renamed: %m", name); - if (r > 0) - return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Interface %s is being renamed.", name); - } - return ifi; } +int test_network_interface_initialized(const char *name) { + _cleanup_(sd_device_unrefp) sd_device *d = NULL; + int ifi, r; + char ifi_str[2 + DECIMAL_STR_MAX(int)]; + + if (path_is_read_only_fs("/sys")) + return 0; + + /* udev should be around. */ + + ifi = parse_interface(name); + if (ifi < 0) + return ifi; + + sprintf(ifi_str, "n%i", ifi); + r = sd_device_new_from_device_id(&d, ifi_str); + if (r < 0) + return log_error_errno(r, "Failed to get device %s: %m", name); + + r = sd_device_get_is_initialized(d); + if (r < 0) + return log_error_errno(r, "Failed to determine whether interface %s is initialized: %m", name); + if (r == 0) + return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Network interface %s is not initialized yet.", name); + + r = device_is_renaming(d); + if (r < 0) + return log_error_errno(r, "Failed to determine the interface %s is being renamed: %m", name); + if (r > 0) + return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Interface %s is being renamed.", name); + + return 0; +} + int move_network_interfaces(pid_t pid, char **ifaces) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; char **i; diff --git a/src/nspawn/nspawn-network.h b/src/nspawn/nspawn-network.h index 32ea21ccc80..7e83d10bfee 100644 --- a/src/nspawn/nspawn-network.h +++ b/src/nspawn/nspawn-network.h @@ -5,6 +5,8 @@ #include #include +int test_network_interface_initialized(const char *name); + int setup_veth(const char *machine_name, pid_t pid, char iface_name[IFNAMSIZ], bool bridge); int setup_veth_extra(const char *machine_name, pid_t pid, char **pairs); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 9113f6e323c..13c91c40bfc 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -848,6 +848,10 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Network interface name not valid: %s", optarg); + r = test_network_interface_initialized(optarg); + if (r < 0) + return r; + if (strv_extend(&arg_network_interfaces, optarg) < 0) return log_oom(); @@ -861,6 +865,10 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "MACVLAN network interface name not valid: %s", optarg); + r = test_network_interface_initialized(optarg); + if (r < 0) + return r; + if (strv_extend(&arg_network_macvlan, optarg) < 0) return log_oom(); @@ -874,6 +882,10 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "IPVLAN network interface name not valid: %s", optarg); + r = test_network_interface_initialized(optarg); + if (r < 0) + return r; + if (strv_extend(&arg_network_ipvlan, optarg) < 0) return log_oom();