From: Robert Milasan Date: Thu, 28 Mar 2013 09:24:43 +0000 Subject: udev always rename network udev: ensure that the network interfaces are renamed even if they exist (bnc#809843). --- src/udev/udev-event.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) Index: systemd-204/src/udev/udev-event.c =================================================================== --- systemd-204.orig/src/udev/udev-event.c +++ systemd-204/src/udev/udev-event.c @@ -750,6 +750,7 @@ static int rename_netif(struct udev_even struct udev_device *dev = event->dev; int sk; struct ifreq ifr; + int loop; int err; log_debug("changing net interface name from '%s' to '%s'\n", @@ -766,12 +767,51 @@ static int rename_netif(struct udev_even strscpy(ifr.ifr_name, IFNAMSIZ, udev_device_get_sysname(dev)); strscpy(ifr.ifr_newname, IFNAMSIZ, event->name); err = ioctl(sk, SIOCSIFNAME, &ifr); - if (err >= 0) { + if (err == 0) { print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); - } else { + goto out; + } + + /* keep trying if the destination interface name already exists */ + err = -errno; + if (err != -EEXIST) { + goto out; + } + + /* free our own name, another process may wait for us */ + snprintf(ifr.ifr_newname, IFNAMSIZ, "rename%u", udev_device_get_ifindex(dev)); + err = ioctl(sk, SIOCSIFNAME, &ifr); + if (err < 0) { err = -errno; - log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname); + goto out; } + + /* log temporary name */ + print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); + + /* wait a maximum of 90 seconds for our target to become available */ + strscpy(ifr.ifr_name, IFNAMSIZ, ifr.ifr_newname); + strscpy(ifr.ifr_newname, IFNAMSIZ, event->name); + loop = 90 * 20; + while (loop--) { + const struct timespec duration = { 0, 1000 * 1000 * 1000 / 20 }; + + log_debug("wait for netif '%s' to become free, loop=%i\n", event->name, (90 * 20) - loop); + nanosleep(&duration, NULL); + + err = ioctl(sk, SIOCSIFNAME, &ifr); + if (err == 0) { + print_kmsg("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname); + break; + } + err = -errno; + if (err != -EEXIST) + break; + } + +out: + if (err < 0) + log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname); close(sk); return err; }