Revert "udev: network device renaming - immediately give up if the target name isn...
authorMichael Biebl <biebl@debian.org>
Wed, 17 Jul 2013 23:04:07 +0000 (01:04 +0200)
committerPeter Michael Green <plugwash@raspbian.org>
Thu, 20 Sep 2018 22:47:19 +0000 (23:47 +0100)
This reverts commit 97595710b77aa162ca5e20da57d0a1ed7355eaad.

We need to keep supporting systems with 75-persistent-net-generator.rules
generated names for a while after switching to net.ifnames. Re-apply this old
hack to make the renaming less likely to fail.

Gbp-Pq: Topic debian
Gbp-Pq: Name Revert-udev-network-device-renaming-immediately-give.patch

src/udev/udev-event.c

index fd8406d959fe2e5fcd18de7112f41867b010e563..14c1d26d2ff0f0ab89c1decc51c0d63377829a52 100644 (file)
@@ -819,18 +819,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,