From: Michael Biebl Date: Thu, 18 Jul 2013 01:04:07 +0200 Subject: Revert "udev: network device renaming - immediately give up if the target name isn't available" This reverts commit 97595710b77aa162ca5e20da57d0a1ed7355eaad. Since we are keeping the old persistent network interface naming for now, and make the new naming scheme [1] explictly opt-in [2], re-apply this old hack to make the renaming less likely to fail. [1] http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/ [2] d5051f7666e25ecf2b32c7076ce18c1de969d01b --- src/udev/udev-event.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index bc115f1..a673f51 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -769,18 +769,53 @@ static int rename_netif(struct udev_event *event) { char name[IFNAMSIZ]; const char *oldname; int r; + int loop; oldname = udev_device_get_sysname(dev); strscpy(name, IFNAMSIZ, event->name); r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name); + if (r >= 0) { + log_debug("renamed network interface %s to %s\n", oldname, name); + goto out; + } + + /* keep trying if the destination interface name already exists */ + if (r != -EEXIST) + goto out; + + /* free our own name, another process may wait for us */ + snprintf(name, IFNAMSIZ, "rename%u", udev_device_get_ifindex(dev)); + r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name); if (r < 0) - return log_error_errno(r, "Error changing net interface name '%s' to '%s': %m", oldname, name); + goto out; - log_debug("renamed network interface '%s' to '%s'", oldname, name); + /* log temporary name */ + log_debug("renamed network interface %s to %s\n", oldname, name); - return 0; + /* wait a maximum of 90 seconds for our target to become available */ + strscpy(name, IFNAMSIZ, event->name); + loop = 90 * 20; + while (loop--) { + const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 }; + + nanosleep(&duration, NULL); + + r = rtnl_set_link_name(&event->rtnl, udev_device_get_ifindex(dev), name); + if (r >= 0) { + log_debug("renamed network interface %s to %s\n", oldname, name); + break; + } + if (r != -EEXIST) + break; + } + +out: + if (r < 0) + log_error("error changing net interface name '%s' to '%s': %s", + oldname, name, strerror(-r)); + return r; } void udev_event_execute_rules(struct udev_event *event,